mirror of
https://github.com/atom/atom.git
synced 2026-01-25 06:48:28 -05:00
Merge pull request #13916 from atom/as-ns-startup-snapshot
Startup Snapshot
This commit is contained in:
@@ -30,6 +30,7 @@ cache:
|
||||
- apm/node_modules
|
||||
- script/node_modules
|
||||
- ~/.atom/compile-cache
|
||||
- ~/.atom/snapshot-cache
|
||||
|
||||
notifications:
|
||||
email:
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "1.16.1"
|
||||
"atom-package-manager": "1.17.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,3 +52,4 @@ cache:
|
||||
- '%APPVEYOR_BUILD_FOLDER%\electron'
|
||||
- '%USERPROFILE%\.atom\.apm'
|
||||
- '%USERPROFILE%\.atom\compile-cache'
|
||||
- '%USERPROFILE%\.atom\snapshot-cache'
|
||||
|
||||
@@ -29,6 +29,7 @@ dependencies:
|
||||
- script/node_modules
|
||||
- node_modules
|
||||
- ~/.atom/compile-cache
|
||||
- ~/.atom/snapshot-cache
|
||||
|
||||
test:
|
||||
override:
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"url": "https://github.com/atom/atom/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"electronVersion": "1.3.13",
|
||||
"electronVersion": "1.3.14",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "8.0.2",
|
||||
@@ -33,7 +33,7 @@
|
||||
"cached-run-in-this-context": "0.4.1",
|
||||
"chai": "3.5.0",
|
||||
"chart.js": "^2.3.0",
|
||||
"clear-cut": "^2.0.1",
|
||||
"clear-cut": "^2.0.2",
|
||||
"coffee-script": "1.11.1",
|
||||
"color": "^0.7.3",
|
||||
"dedent": "^0.6.0",
|
||||
|
||||
@@ -35,6 +35,7 @@ const dumpSymbols = require('./lib/dump-symbols')
|
||||
const generateAPIDocs = require('./lib/generate-api-docs')
|
||||
const generateMetadata = require('./lib/generate-metadata')
|
||||
const generateModuleCache = require('./lib/generate-module-cache')
|
||||
const generateStartupSnapshot = require('./lib/generate-startup-snapshot')
|
||||
const installApplication = require('./lib/install-application')
|
||||
const packageApplication = require('./lib/package-application')
|
||||
const prebuildLessCache = require('./lib/prebuild-less-cache')
|
||||
@@ -61,6 +62,7 @@ generateMetadata()
|
||||
generateAPIDocs()
|
||||
dumpSymbols()
|
||||
.then(packageApplication)
|
||||
.then(packagedAppPath => generateStartupSnapshot(packagedAppPath).then(() => packagedAppPath))
|
||||
.then(packagedAppPath => {
|
||||
if (process.platform === 'darwin') {
|
||||
if (argv.codeSign) {
|
||||
|
||||
@@ -7,16 +7,27 @@ const semver = require('semver')
|
||||
module.exports = function () {
|
||||
// Chromedriver should be specified as ~x.y where x and y match Electron major/minor
|
||||
const chromedriverVer = buildMetadata.dependencies['electron-chromedriver']
|
||||
const mksnapshotVer = buildMetadata.dependencies['electron-mksnapshot']
|
||||
|
||||
// Always use tilde on electron-chromedriver so that it can pick up the best patch vesion
|
||||
if (!chromedriverVer.startsWith('~')) {
|
||||
throw new Error(`electron-chromedriver version in script/package.json should start with a tilde to match latest patch version.`)
|
||||
}
|
||||
|
||||
if (!mksnapshotVer.startsWith('~')) {
|
||||
throw new Error(`electron-mksnapshot version in script/package.json should start with a tilde to match latest patch version.`)
|
||||
}
|
||||
|
||||
const electronVer = CONFIG.appMetadata.electronVersion
|
||||
if (!semver.satisfies(electronVer, chromedriverVer)) {
|
||||
throw new Error(`electron-chromedriver ${chromedriverVer} incompatible with electron ${electronVer}.\n` +
|
||||
'Did you upgrade electron in package.json and forget to upgrade electron-chromedriver in ' +
|
||||
`script/package.json to '~${semver.major(electronVer)}.${semver.minor(electronVer)}' ?`)
|
||||
}
|
||||
|
||||
if (!semver.satisfies(electronVer, mksnapshotVer)) {
|
||||
throw new Error(`electron-mksnapshot ${mksnapshotVer} incompatible with electron ${electronVer}.\n` +
|
||||
'Did you upgrade electron in package.json and forget to upgrade electron-mksnapshot in ' +
|
||||
`script/package.json to '~${semver.major(electronVer)}.${semver.minor(electronVer)}' ?`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ module.exports = function (packagedAppPath) {
|
||||
|
||||
console.log(`Copying icon into "${debianPackageIconsDirPath}"`)
|
||||
fs.copySync(
|
||||
path.join(packagedAppPath, 'resources', 'app.asar.unpacked', 'resources', 'atom.png'),
|
||||
path.join(packagedAppPath, 'resources', 'app', 'resources', 'atom.png'),
|
||||
path.join(debianPackageIconsDirPath, `${atomExecutableName}.png`)
|
||||
)
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ function buildBundledPackagesMetadata () {
|
||||
const packagePath = path.join(CONFIG.intermediateAppPath, 'node_modules', packageName)
|
||||
const packageMetadataPath = path.join(packagePath, 'package.json')
|
||||
const packageMetadata = JSON.parse(fs.readFileSync(packageMetadataPath, 'utf8'))
|
||||
normalizePackageData(packageMetadata, () => {
|
||||
throw new Error(`Invalid package metadata. ${metadata.name}: ${msg}`)
|
||||
normalizePackageData(packageMetadata, (msg) => {
|
||||
console.warn(`Invalid package metadata. ${packageMetadata.name}: ${msg}`)
|
||||
}, true)
|
||||
if (packageMetadata.repository && packageMetadata.repository.url && packageMetadata.repository.type === 'git') {
|
||||
packageMetadata.repository.url = packageMetadata.repository.url.replace(/^git\+/, '')
|
||||
|
||||
86
script/lib/generate-startup-snapshot.js
Normal file
86
script/lib/generate-startup-snapshot.js
Normal file
@@ -0,0 +1,86 @@
|
||||
const childProcess = require('child_process')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const electronLink = require('electron-link')
|
||||
const CONFIG = require('../config')
|
||||
const vm = require('vm')
|
||||
|
||||
module.exports = function (packagedAppPath) {
|
||||
const snapshotScriptPath = path.join(CONFIG.buildOutputPath, 'startup.js')
|
||||
const coreModules = new Set(['electron', 'atom', 'shell', 'WNdb', 'lapack', 'remote'])
|
||||
const baseDirPath = path.join(CONFIG.intermediateAppPath, 'static')
|
||||
let processedFiles = 0
|
||||
|
||||
return electronLink({
|
||||
baseDirPath,
|
||||
mainPath: path.resolve(baseDirPath, '..', 'src', 'initialize-application-window.js'),
|
||||
cachePath: path.join(CONFIG.atomHomeDirPath, 'snapshot-cache'),
|
||||
shouldExcludeModule: (modulePath) => {
|
||||
if (processedFiles > 0) {
|
||||
process.stdout.write('\r')
|
||||
}
|
||||
process.stdout.write(`Generating snapshot script at "${snapshotScriptPath}" (${++processedFiles})`)
|
||||
|
||||
const relativePath = path.relative(baseDirPath, modulePath)
|
||||
return (
|
||||
modulePath.endsWith('.node') ||
|
||||
coreModules.has(modulePath) ||
|
||||
(relativePath.startsWith(path.join('..', 'src')) && relativePath.endsWith('-element.js')) ||
|
||||
relativePath == path.join('..', 'exports', 'atom.js') ||
|
||||
relativePath == path.join('..', 'src', 'config-schema.js') ||
|
||||
relativePath == path.join('..', 'src', 'electron-shims.js') ||
|
||||
relativePath == path.join('..', 'src', 'safe-clipboard.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'atom-keymap', 'lib', 'command-event.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'babel-core', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'cached-run-in-this-context', 'lib', 'main.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'coffee-script', 'lib', 'coffee-script', 'register.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'cson-parser', 'node_modules', 'coffee-script', 'lib', 'coffee-script', 'register.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'decompress-zip', 'lib', 'decompress-zip.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'debug', 'node.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'git-utils', 'lib', 'git.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'glob', 'glob.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'htmlparser2', 'lib', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'iconv-lite', 'encodings', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'less', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'less', 'lib', 'less', 'fs.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'less', 'lib', 'less-node', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'less', 'node_modules', 'graceful-fs', 'graceful-fs.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'superstring', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'oniguruma', 'lib', 'oniguruma.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'request', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'resolve', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'resolve', 'lib', 'core.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'settings-view', 'node_modules', 'glob', 'glob.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'spellchecker', 'lib', 'spellchecker.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'spelling-manager', 'node_modules', 'natural', 'lib', 'natural', 'index.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'tar', 'tar.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'temp', 'lib', 'temp.js') ||
|
||||
relativePath == path.join('..', 'node_modules', 'tmp', 'lib', 'tmp.js')
|
||||
)
|
||||
}
|
||||
}).then((snapshotScriptContent) => {
|
||||
fs.writeFileSync(snapshotScriptPath, snapshotScriptContent)
|
||||
process.stdout.write('\n')
|
||||
|
||||
console.log('Verifying if snapshot can be executed via `mksnapshot`')
|
||||
vm.runInNewContext(snapshotScriptContent, undefined, {filename: snapshotScriptPath, displayErrors: true})
|
||||
|
||||
const generatedStartupBlobPath = path.join(CONFIG.buildOutputPath, 'snapshot_blob.bin')
|
||||
console.log(`Generating startup blob at "${generatedStartupBlobPath}"`)
|
||||
childProcess.execFileSync(
|
||||
path.join(CONFIG.repositoryRootPath, 'script', 'node_modules', 'electron-mksnapshot', 'bin', 'mksnapshot'),
|
||||
[snapshotScriptPath, '--startup_blob', generatedStartupBlobPath]
|
||||
)
|
||||
|
||||
let startupBlobDestinationPath
|
||||
if (process.platform === 'darwin') {
|
||||
startupBlobDestinationPath = `${packagedAppPath}/Contents/Frameworks/Electron Framework.framework/Resources/snapshot_blob.bin`
|
||||
} else {
|
||||
startupBlobDestinationPath = path.join(packagedAppPath, 'snapshot_blob.bin')
|
||||
}
|
||||
|
||||
console.log(`Moving generated startup blob into "${startupBlobDestinationPath}"`)
|
||||
fs.unlinkSync(startupBlobDestinationPath)
|
||||
fs.renameSync(generatedStartupBlobPath, startupBlobDestinationPath)
|
||||
})
|
||||
}
|
||||
@@ -19,7 +19,6 @@ module.exports = function () {
|
||||
'app-copyright': `Copyright © 2014-${(new Date()).getFullYear()} GitHub, Inc. All rights reserved.`,
|
||||
'app-version': CONFIG.appMetadata.version,
|
||||
'arch': process.platform === 'darwin' ? 'x64' : process.arch, // OS X is 64-bit only
|
||||
'asar': {unpack: buildAsarUnpackGlobExpression()},
|
||||
'build-version': CONFIG.appMetadata.version,
|
||||
'download': {cache: CONFIG.electronDownloadPath},
|
||||
'dir': CONFIG.intermediateAppPath,
|
||||
@@ -96,20 +95,6 @@ function chmodNodeFiles (packagedAppPath) {
|
||||
childProcess.execSync(`find "${packagedAppPath}" -type f -name *.node -exec chmod a-x {} \\;`)
|
||||
}
|
||||
|
||||
function buildAsarUnpackGlobExpression () {
|
||||
const unpack = [
|
||||
'*.node',
|
||||
'ctags-config',
|
||||
'ctags-darwin',
|
||||
'ctags-linux',
|
||||
'ctags-win32.exe',
|
||||
path.join('**', 'node_modules', 'spellchecker', '**'),
|
||||
path.join('**', 'resources', 'atom.png')
|
||||
]
|
||||
|
||||
return `{${unpack.join(',')}}`
|
||||
}
|
||||
|
||||
function getAppName () {
|
||||
if (process.platform === 'darwin') {
|
||||
return CONFIG.channel === 'beta' ? 'Atom Beta' : 'Atom'
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"csslint": "1.0.2",
|
||||
"donna": "1.0.13",
|
||||
"electron-chromedriver": "~1.3",
|
||||
"electron-link": "0.0.18",
|
||||
"electron-mksnapshot": "~1.3",
|
||||
"electron-packager": "7.3.0",
|
||||
"electron-winstaller": "2.5.1",
|
||||
"fs-extra": "0.30.0",
|
||||
|
||||
@@ -14,78 +14,75 @@ describe "FileSystemBlobStore", ->
|
||||
fs.removeSync(storageDirectory)
|
||||
|
||||
it "is empty when the file doesn't exist", ->
|
||||
expect(blobStore.get("foo", "invalidation-key-1")).toBeUndefined()
|
||||
expect(blobStore.get("bar", "invalidation-key-2")).toBeUndefined()
|
||||
expect(blobStore.get("foo")).toBeUndefined()
|
||||
expect(blobStore.get("bar")).toBeUndefined()
|
||||
|
||||
it "allows to read and write buffers from/to memory without persisting them", ->
|
||||
blobStore.set("foo", "invalidation-key-1", new Buffer("foo"))
|
||||
blobStore.set("bar", "invalidation-key-2", new Buffer("bar"))
|
||||
blobStore.set("foo", new Buffer("foo"))
|
||||
blobStore.set("bar", new Buffer("bar"))
|
||||
|
||||
expect(blobStore.get("foo", "invalidation-key-1")).toEqual(new Buffer("foo"))
|
||||
expect(blobStore.get("bar", "invalidation-key-2")).toEqual(new Buffer("bar"))
|
||||
expect(blobStore.get("foo")).toEqual(new Buffer("foo"))
|
||||
expect(blobStore.get("bar")).toEqual(new Buffer("bar"))
|
||||
|
||||
expect(blobStore.get("foo", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("bar", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("baz")).toBeUndefined()
|
||||
expect(blobStore.get("qux")).toBeUndefined()
|
||||
|
||||
it "persists buffers when saved and retrieves them on load, giving priority to in-memory ones", ->
|
||||
blobStore.set("foo", "invalidation-key-1", new Buffer("foo"))
|
||||
blobStore.set("bar", "invalidation-key-2", new Buffer("bar"))
|
||||
blobStore.set("foo", new Buffer("foo"))
|
||||
blobStore.set("bar", new Buffer("bar"))
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
expect(blobStore.get("foo", "invalidation-key-1")).toEqual(new Buffer("foo"))
|
||||
expect(blobStore.get("bar", "invalidation-key-2")).toEqual(new Buffer("bar"))
|
||||
expect(blobStore.get("foo", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("bar", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("foo")).toEqual(new Buffer("foo"))
|
||||
expect(blobStore.get("bar")).toEqual(new Buffer("bar"))
|
||||
expect(blobStore.get("baz")).toBeUndefined()
|
||||
expect(blobStore.get("qux")).toBeUndefined()
|
||||
|
||||
blobStore.set("foo", "new-key", new Buffer("changed"))
|
||||
blobStore.set("foo", new Buffer("changed"))
|
||||
|
||||
expect(blobStore.get("foo", "new-key")).toEqual(new Buffer("changed"))
|
||||
expect(blobStore.get("foo", "invalidation-key-1")).toBeUndefined()
|
||||
expect(blobStore.get("foo")).toEqual(new Buffer("changed"))
|
||||
|
||||
it "persists both in-memory and previously stored buffers when saved", ->
|
||||
blobStore.set("foo", "invalidation-key-1", new Buffer("foo"))
|
||||
blobStore.set("bar", "invalidation-key-2", new Buffer("bar"))
|
||||
it "persists in-memory and previously stored buffers, and deletes unused keys when saved", ->
|
||||
blobStore.set("foo", new Buffer("foo"))
|
||||
blobStore.set("bar", new Buffer("bar"))
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
blobStore.set("bar", "invalidation-key-3", new Buffer("changed"))
|
||||
blobStore.set("qux", "invalidation-key-4", new Buffer("qux"))
|
||||
blobStore.set("bar", new Buffer("changed"))
|
||||
blobStore.set("qux", new Buffer("qux"))
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
expect(blobStore.get("foo", "invalidation-key-1")).toEqual(new Buffer("foo"))
|
||||
expect(blobStore.get("bar", "invalidation-key-3")).toEqual(new Buffer("changed"))
|
||||
expect(blobStore.get("qux", "invalidation-key-4")).toEqual(new Buffer("qux"))
|
||||
expect(blobStore.get("foo", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("bar", "invalidation-key-2")).toBeUndefined()
|
||||
expect(blobStore.get("qux", "unexisting-key")).toBeUndefined()
|
||||
expect(blobStore.get("foo")).toBeUndefined()
|
||||
expect(blobStore.get("bar")).toEqual(new Buffer("changed"))
|
||||
expect(blobStore.get("qux")).toEqual(new Buffer("qux"))
|
||||
|
||||
it "allows to delete keys from both memory and stored buffers", ->
|
||||
blobStore.set("a", "invalidation-key-1", new Buffer("a"))
|
||||
blobStore.set("b", "invalidation-key-2", new Buffer("b"))
|
||||
blobStore.set("a", new Buffer("a"))
|
||||
blobStore.set("b", new Buffer("b"))
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
blobStore.set("b", "invalidation-key-3", new Buffer("b"))
|
||||
blobStore.set("c", "invalidation-key-4", new Buffer("c"))
|
||||
blobStore.get("a") # prevent the key from being deleted on save
|
||||
blobStore.set("b", new Buffer("b"))
|
||||
blobStore.set("c", new Buffer("c"))
|
||||
blobStore.delete("b")
|
||||
blobStore.delete("c")
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
expect(blobStore.get("a", "invalidation-key-1")).toEqual(new Buffer("a"))
|
||||
expect(blobStore.get("b", "invalidation-key-2")).toBeUndefined()
|
||||
expect(blobStore.get("b", "invalidation-key-3")).toBeUndefined()
|
||||
expect(blobStore.get("c", "invalidation-key-4")).toBeUndefined()
|
||||
expect(blobStore.get("a")).toEqual(new Buffer("a"))
|
||||
expect(blobStore.get("b")).toBeUndefined()
|
||||
expect(blobStore.get("b")).toBeUndefined()
|
||||
expect(blobStore.get("c")).toBeUndefined()
|
||||
|
||||
it "ignores errors when loading an invalid blob store", ->
|
||||
blobStore.set("a", "invalidation-key-1", new Buffer("a"))
|
||||
blobStore.set("b", "invalidation-key-2", new Buffer("b"))
|
||||
blobStore.set("a", new Buffer("a"))
|
||||
blobStore.set("b", new Buffer("b"))
|
||||
blobStore.save()
|
||||
|
||||
# Simulate corruption
|
||||
@@ -95,14 +92,14 @@ describe "FileSystemBlobStore", ->
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
expect(blobStore.get("a", "invalidation-key-1")).toBeUndefined()
|
||||
expect(blobStore.get("b", "invalidation-key-2")).toBeUndefined()
|
||||
expect(blobStore.get("a")).toBeUndefined()
|
||||
expect(blobStore.get("b")).toBeUndefined()
|
||||
|
||||
blobStore.set("a", "invalidation-key-1", new Buffer("x"))
|
||||
blobStore.set("b", "invalidation-key-2", new Buffer("y"))
|
||||
blobStore.set("a", new Buffer("x"))
|
||||
blobStore.set("b", new Buffer("y"))
|
||||
blobStore.save()
|
||||
|
||||
blobStore = FileSystemBlobStore.load(storageDirectory)
|
||||
|
||||
expect(blobStore.get("a", "invalidation-key-1")).toEqual(new Buffer("x"))
|
||||
expect(blobStore.get("b", "invalidation-key-2")).toEqual(new Buffer("y"))
|
||||
expect(blobStore.get("a")).toEqual(new Buffer("x"))
|
||||
expect(blobStore.get("b")).toEqual(new Buffer("y"))
|
||||
|
||||
@@ -9,16 +9,18 @@ describe "NativeCompileCache", ->
|
||||
beforeEach ->
|
||||
cachedFiles = []
|
||||
fakeCacheStore = jasmine.createSpyObj("cache store", ["set", "get", "has", "delete"])
|
||||
fakeCacheStore.has.andCallFake (cacheKey, invalidationKey) ->
|
||||
fakeCacheStore.get(cacheKey, invalidationKey)?
|
||||
fakeCacheStore.get.andCallFake (cacheKey, invalidationKey) ->
|
||||
|
||||
fakeCacheStore.has.andCallFake (cacheKey) ->
|
||||
fakeCacheStore.get(cacheKey)?
|
||||
|
||||
fakeCacheStore.get.andCallFake (cacheKey) ->
|
||||
for entry in cachedFiles by -1
|
||||
continue if entry.cacheKey isnt cacheKey
|
||||
continue if entry.invalidationKey isnt invalidationKey
|
||||
return entry.cacheBuffer
|
||||
return
|
||||
fakeCacheStore.set.andCallFake (cacheKey, invalidationKey, cacheBuffer) ->
|
||||
cachedFiles.push({cacheKey, invalidationKey, cacheBuffer})
|
||||
|
||||
fakeCacheStore.set.andCallFake (cacheKey, cacheBuffer) ->
|
||||
cachedFiles.push({cacheKey, cacheBuffer})
|
||||
|
||||
nativeCompileCache.setCacheStore(fakeCacheStore)
|
||||
nativeCompileCache.setV8Version("a-v8-version")
|
||||
@@ -29,13 +31,10 @@ describe "NativeCompileCache", ->
|
||||
fn2 = require('./fixtures/native-cache/file-2')
|
||||
|
||||
expect(cachedFiles.length).toBe(2)
|
||||
|
||||
expect(cachedFiles[0].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-1'))
|
||||
expect(cachedFiles[0].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[0].cacheBuffer.length).toBeGreaterThan(0)
|
||||
expect(fn1()).toBe(1)
|
||||
|
||||
expect(cachedFiles[1].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-2'))
|
||||
expect(cachedFiles[1].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[1].cacheBuffer.length).toBeGreaterThan(0)
|
||||
expect(fn2()).toBe(2)
|
||||
@@ -51,7 +50,6 @@ describe "NativeCompileCache", ->
|
||||
fn4 = require('./fixtures/native-cache/file-4')
|
||||
|
||||
expect(cachedFiles.length).toBe(1)
|
||||
expect(cachedFiles[0].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-4'))
|
||||
expect(cachedFiles[0].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[0].cacheBuffer.length).toBeGreaterThan(0)
|
||||
expect(fn4()).toBe("file-4")
|
||||
@@ -61,8 +59,6 @@ describe "NativeCompileCache", ->
|
||||
fn4 = require('./fixtures/native-cache/file-4')
|
||||
|
||||
expect(cachedFiles.length).toBe(2)
|
||||
expect(cachedFiles[1].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-4'))
|
||||
expect(cachedFiles[1].invalidationKey).not.toBe(cachedFiles[0].invalidationKey)
|
||||
expect(cachedFiles[1].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[1].cacheBuffer.length).toBeGreaterThan(0)
|
||||
|
||||
@@ -79,7 +75,6 @@ describe "NativeCompileCache", ->
|
||||
fn5 = require('./fixtures/native-cache/file-5')
|
||||
|
||||
expect(cachedFiles.length).toBe(1)
|
||||
expect(cachedFiles[0].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-5'))
|
||||
expect(cachedFiles[0].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[0].cacheBuffer.length).toBeGreaterThan(0)
|
||||
expect(fn5()).toBe("file-5")
|
||||
@@ -89,8 +84,6 @@ describe "NativeCompileCache", ->
|
||||
fn5 = require('./fixtures/native-cache/file-5')
|
||||
|
||||
expect(cachedFiles.length).toBe(2)
|
||||
expect(cachedFiles[1].cacheKey).toBe(require.resolve('./fixtures/native-cache/file-5'))
|
||||
expect(cachedFiles[1].invalidationKey).not.toBe(cachedFiles[0].invalidationKey)
|
||||
expect(cachedFiles[1].cacheBuffer).toBeInstanceOf(Uint8Array)
|
||||
expect(cachedFiles[1].cacheBuffer.length).toBeGreaterThan(0)
|
||||
|
||||
@@ -100,5 +93,5 @@ describe "NativeCompileCache", ->
|
||||
|
||||
fn3 = require('./fixtures/native-cache/file-3')
|
||||
|
||||
expect(fakeCacheStore.delete).toHaveBeenCalledWith(require.resolve('./fixtures/native-cache/file-3'))
|
||||
expect(fakeCacheStore.delete).toHaveBeenCalled()
|
||||
expect(fn3()).toBe(3)
|
||||
|
||||
@@ -131,7 +131,7 @@ class AtomEnvironment extends Model
|
||||
|
||||
# Call .loadOrCreate instead
|
||||
constructor: (params={}) ->
|
||||
{@blobStore, @applicationDelegate, @window, @document, @clipboard, @configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params
|
||||
{@applicationDelegate, @window, @document, @blobStore, @clipboard, @configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params
|
||||
|
||||
@nextProxyRequestId = 0
|
||||
@unloaded = false
|
||||
@@ -740,6 +740,10 @@ class AtomEnvironment extends Model
|
||||
@saveBlobStoreSync()
|
||||
@unloaded = true
|
||||
|
||||
saveBlobStoreSync: ->
|
||||
if @enablePersistence
|
||||
@blobStore.save()
|
||||
|
||||
openInitialEmptyEditorIfNecessary: ->
|
||||
return unless @config.get('core.openEmptyEditorOnStart')
|
||||
if @getLoadSettings().initialPaths?.length is 0 and @workspace.getPaneItems().length is 0
|
||||
@@ -873,11 +877,6 @@ class AtomEnvironment extends Model
|
||||
showSaveDialogSync: (options={}) ->
|
||||
@applicationDelegate.showSaveDialog(options)
|
||||
|
||||
saveBlobStoreSync: ->
|
||||
return unless @enablePersistence
|
||||
|
||||
@blobStore.save()
|
||||
|
||||
saveState: (options) ->
|
||||
new Promise (resolve, reject) =>
|
||||
if @enablePersistence and @project
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
var path = require('path')
|
||||
var fs = require('fs-plus')
|
||||
var sourceMapSupport = require('source-map-support')
|
||||
|
||||
var PackageTranspilationRegistry = require('./package-transpilation-registry')
|
||||
var CSON = null
|
||||
@@ -113,109 +114,112 @@ function writeCachedJavascript (relativeCachePath, code) {
|
||||
|
||||
var INLINE_SOURCE_MAP_REGEXP = /\/\/[#@]\s*sourceMappingURL=([^'"\n]+)\s*$/mg
|
||||
|
||||
require('source-map-support').install({
|
||||
handleUncaughtExceptions: false,
|
||||
exports.install = function (nodeRequire) {
|
||||
sourceMapSupport.install({
|
||||
handleUncaughtExceptions: false,
|
||||
|
||||
// Most of this logic is the same as the default implementation in the
|
||||
// source-map-support module, but we've overridden it to read the javascript
|
||||
// code from our cache directory.
|
||||
retrieveSourceMap: function (filePath) {
|
||||
if (!cacheDirectory || !fs.isFileSync(filePath)) {
|
||||
return null
|
||||
}
|
||||
// Most of this logic is the same as the default implementation in the
|
||||
// source-map-support module, but we've overridden it to read the javascript
|
||||
// code from our cache directory.
|
||||
retrieveSourceMap: function (filePath) {
|
||||
if (!cacheDirectory || !fs.isFileSync(filePath)) {
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
var sourceCode = fs.readFileSync(filePath, 'utf8')
|
||||
} catch (error) {
|
||||
console.warn('Error reading source file', error.stack)
|
||||
return null
|
||||
}
|
||||
try {
|
||||
var sourceCode = fs.readFileSync(filePath, 'utf8')
|
||||
} catch (error) {
|
||||
console.warn('Error reading source file', error.stack)
|
||||
return null
|
||||
}
|
||||
|
||||
var compiler = COMPILERS[path.extname(filePath)]
|
||||
if (!compiler) compiler = COMPILERS['.js']
|
||||
var compiler = COMPILERS[path.extname(filePath)]
|
||||
if (!compiler) compiler = COMPILERS['.js']
|
||||
|
||||
try {
|
||||
var fileData = readCachedJavascript(compiler.getCachePath(sourceCode, filePath))
|
||||
} catch (error) {
|
||||
console.warn('Error reading compiled file', error.stack)
|
||||
return null
|
||||
}
|
||||
try {
|
||||
var fileData = readCachedJavascript(compiler.getCachePath(sourceCode, filePath))
|
||||
} catch (error) {
|
||||
console.warn('Error reading compiled file', error.stack)
|
||||
return null
|
||||
}
|
||||
|
||||
if (fileData == null) {
|
||||
return null
|
||||
}
|
||||
if (fileData == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
var match, lastMatch
|
||||
INLINE_SOURCE_MAP_REGEXP.lastIndex = 0
|
||||
while ((match = INLINE_SOURCE_MAP_REGEXP.exec(fileData))) {
|
||||
lastMatch = match
|
||||
}
|
||||
if (lastMatch == null) {
|
||||
return null
|
||||
}
|
||||
var match, lastMatch
|
||||
INLINE_SOURCE_MAP_REGEXP.lastIndex = 0
|
||||
while ((match = INLINE_SOURCE_MAP_REGEXP.exec(fileData))) {
|
||||
lastMatch = match
|
||||
}
|
||||
if (lastMatch == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
var sourceMappingURL = lastMatch[1]
|
||||
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1)
|
||||
var sourceMappingURL = lastMatch[1]
|
||||
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1)
|
||||
|
||||
try {
|
||||
var sourceMap = JSON.parse(new Buffer(rawData, 'base64'))
|
||||
} catch (error) {
|
||||
console.warn('Error parsing source map', error.stack)
|
||||
return null
|
||||
}
|
||||
try {
|
||||
var sourceMap = JSON.parse(new Buffer(rawData, 'base64'))
|
||||
} catch (error) {
|
||||
console.warn('Error parsing source map', error.stack)
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
map: sourceMap,
|
||||
url: null
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
var prepareStackTraceWithSourceMapping = Error.prepareStackTrace
|
||||
var prepareStackTrace = prepareStackTraceWithSourceMapping
|
||||
|
||||
function prepareStackTraceWithRawStackAssignment (error, frames) {
|
||||
if (error.rawStack) { // avoid infinite recursion
|
||||
return prepareStackTraceWithSourceMapping(error, frames)
|
||||
} else {
|
||||
error.rawStack = frames
|
||||
return prepareStackTrace(error, frames)
|
||||
}
|
||||
}
|
||||
|
||||
Error.stackTraceLimit = 30
|
||||
|
||||
Object.defineProperty(Error, 'prepareStackTrace', {
|
||||
get: function () {
|
||||
return prepareStackTraceWithRawStackAssignment
|
||||
},
|
||||
|
||||
set: function (newValue) {
|
||||
prepareStackTrace = newValue
|
||||
process.nextTick(function () {
|
||||
prepareStackTrace = prepareStackTraceWithSourceMapping
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Error.prototype.getRawStack = function () { // eslint-disable-line no-extend-native
|
||||
// Access this.stack to ensure prepareStackTrace has been run on this error
|
||||
// because it assigns this.rawStack as a side-effect
|
||||
this.stack
|
||||
return this.rawStack
|
||||
}
|
||||
|
||||
Object.keys(COMPILERS).forEach(function (extension) {
|
||||
var compiler = COMPILERS[extension]
|
||||
|
||||
Object.defineProperty(require.extensions, extension, {
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: function (module, filePath) {
|
||||
var code = compileFileAtPath(compiler, filePath, extension)
|
||||
return module._compile(code, filePath)
|
||||
return {
|
||||
map: sourceMap,
|
||||
url: null
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
var prepareStackTraceWithSourceMapping = Error.prepareStackTrace
|
||||
var prepareStackTrace = prepareStackTraceWithSourceMapping
|
||||
|
||||
function prepareStackTraceWithRawStackAssignment (error, frames) {
|
||||
if (error.rawStack) { // avoid infinite recursion
|
||||
return prepareStackTraceWithSourceMapping(error, frames)
|
||||
} else {
|
||||
error.rawStack = frames
|
||||
return prepareStackTrace(error, frames)
|
||||
}
|
||||
}
|
||||
|
||||
Error.stackTraceLimit = 30
|
||||
|
||||
Object.defineProperty(Error, 'prepareStackTrace', {
|
||||
get: function () {
|
||||
return prepareStackTraceWithRawStackAssignment
|
||||
},
|
||||
|
||||
set: function (newValue) {
|
||||
prepareStackTrace = newValue
|
||||
process.nextTick(function () {
|
||||
prepareStackTrace = prepareStackTraceWithSourceMapping
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Error.prototype.getRawStack = function () { // eslint-disable-line no-extend-native
|
||||
// Access this.stack to ensure prepareStackTrace has been run on this error
|
||||
// because it assigns this.rawStack as a side-effect
|
||||
this.stack
|
||||
return this.rawStack
|
||||
}
|
||||
|
||||
Object.keys(COMPILERS).forEach(function (extension) {
|
||||
var compiler = COMPILERS[extension]
|
||||
|
||||
Object.defineProperty(nodeRequire.extensions, extension, {
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: function (module, filePath) {
|
||||
var code = compileFileAtPath(compiler, filePath, extension)
|
||||
return module._compile(code, filePath)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
exports.supportedExtensions = Object.keys(COMPILERS)
|
||||
exports.resetCacheStats()
|
||||
|
||||
@@ -14,16 +14,15 @@ class FileSystemBlobStore {
|
||||
constructor (directory) {
|
||||
this.blobFilename = path.join(directory, 'BLOB')
|
||||
this.blobMapFilename = path.join(directory, 'MAP')
|
||||
this.invalidationKeysFilename = path.join(directory, 'INVKEYS')
|
||||
this.lockFilename = path.join(directory, 'LOCK')
|
||||
this.reset()
|
||||
}
|
||||
|
||||
reset () {
|
||||
this.inMemoryBlobs = new Map()
|
||||
this.invalidationKeys = {}
|
||||
this.storedBlob = new Buffer(0)
|
||||
this.storedBlobMap = {}
|
||||
this.usedKeys = new Set()
|
||||
}
|
||||
|
||||
load () {
|
||||
@@ -33,14 +32,10 @@ class FileSystemBlobStore {
|
||||
if (!fs.existsSync(this.blobFilename)) {
|
||||
return
|
||||
}
|
||||
if (!fs.existsSync(this.invalidationKeysFilename)) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
this.storedBlob = fs.readFileSync(this.blobFilename)
|
||||
this.storedBlobMap = JSON.parse(fs.readFileSync(this.blobMapFilename))
|
||||
this.invalidationKeys = JSON.parse(fs.readFileSync(this.invalidationKeysFilename))
|
||||
} catch (e) {
|
||||
this.reset()
|
||||
}
|
||||
@@ -50,7 +45,6 @@ class FileSystemBlobStore {
|
||||
let dump = this.getDump()
|
||||
let blobToStore = Buffer.concat(dump[0])
|
||||
let mapToStore = JSON.stringify(dump[1])
|
||||
let invalidationKeysToStore = JSON.stringify(this.invalidationKeys)
|
||||
|
||||
let acquiredLock = false
|
||||
try {
|
||||
@@ -59,7 +53,6 @@ class FileSystemBlobStore {
|
||||
|
||||
fs.writeFileSync(this.blobFilename, blobToStore)
|
||||
fs.writeFileSync(this.blobMapFilename, mapToStore)
|
||||
fs.writeFileSync(this.invalidationKeysFilename, invalidationKeysToStore)
|
||||
} catch (error) {
|
||||
// Swallow the exception silently only if we fail to acquire the lock.
|
||||
if (error.code !== 'EEXIST') {
|
||||
@@ -72,20 +65,19 @@ class FileSystemBlobStore {
|
||||
}
|
||||
}
|
||||
|
||||
has (key, invalidationKey) {
|
||||
let containsKey = this.inMemoryBlobs.has(key) || this.storedBlobMap.hasOwnProperty(key)
|
||||
let isValid = this.invalidationKeys[key] === invalidationKey
|
||||
return containsKey && isValid
|
||||
has (key) {
|
||||
return this.inMemoryBlobs.has(key) || this.storedBlobMap.hasOwnProperty(key)
|
||||
}
|
||||
|
||||
get (key, invalidationKey) {
|
||||
if (this.has(key, invalidationKey)) {
|
||||
get (key) {
|
||||
if (this.has(key)) {
|
||||
this.usedKeys.add(key)
|
||||
return this.getFromMemory(key) || this.getFromStorage(key)
|
||||
}
|
||||
}
|
||||
|
||||
set (key, invalidationKey, buffer) {
|
||||
this.invalidationKeys[key] = invalidationKey
|
||||
set (key, buffer) {
|
||||
this.usedKeys.add(key)
|
||||
return this.inMemoryBlobs.set(key, buffer)
|
||||
}
|
||||
|
||||
@@ -119,11 +111,13 @@ class FileSystemBlobStore {
|
||||
}
|
||||
|
||||
for (let key of this.inMemoryBlobs.keys()) {
|
||||
dump(key, this.getFromMemory.bind(this))
|
||||
if (this.usedKeys.has(key)) {
|
||||
dump(key, this.getFromMemory.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
for (let key of Object.keys(this.storedBlobMap)) {
|
||||
if (!blobMap[key]) {
|
||||
if (!blobMap[key] && this.usedKeys.has(key)) {
|
||||
dump(key, this.getFromStorage.bind(this))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,60 @@
|
||||
AtomEnvironment = require './atom-environment'
|
||||
ApplicationDelegate = require './application-delegate'
|
||||
Clipboard = require './clipboard'
|
||||
TextEditor = require './text-editor'
|
||||
TextEditorComponent = require './text-editor-component'
|
||||
FileSystemBlobStore = require './file-system-blob-store'
|
||||
NativeCompileCache = require './native-compile-cache'
|
||||
CompileCache = require './compile-cache'
|
||||
ModuleCache = require './module-cache'
|
||||
|
||||
require('about')
|
||||
require('archive-view')
|
||||
require('autocomplete-atom-api')
|
||||
require('autocomplete-css')
|
||||
require('autocomplete-html')
|
||||
require('autocomplete-plus')
|
||||
require('autocomplete-snippets')
|
||||
require('autoflow')
|
||||
require('autosave')
|
||||
require('background-tips')
|
||||
require('bookmarks')
|
||||
require('bracket-matcher')
|
||||
require('command-palette')
|
||||
require('deprecation-cop')
|
||||
require('dev-live-reload')
|
||||
require('encoding-selector')
|
||||
require('exception-reporting')
|
||||
require('dalek')
|
||||
require('find-and-replace')
|
||||
require('fuzzy-finder')
|
||||
require('git-diff')
|
||||
require('go-to-line')
|
||||
require('grammar-selector')
|
||||
require('image-view')
|
||||
require('incompatible-packages')
|
||||
require('keybinding-resolver')
|
||||
require('line-ending-selector')
|
||||
require('link')
|
||||
require('markdown-preview')
|
||||
require('metrics')
|
||||
require('notifications')
|
||||
require('open-on-github')
|
||||
require('package-generator')
|
||||
require('settings-view')
|
||||
require('snippets')
|
||||
require('spell-check')
|
||||
require('status-bar')
|
||||
require('styleguide')
|
||||
require('symbols-view')
|
||||
require('tabs')
|
||||
require('timecop')
|
||||
require('tree-view')
|
||||
require('update-package-dependencies')
|
||||
require('welcome')
|
||||
require('whitespace')
|
||||
require('wrap-guide')
|
||||
|
||||
# Like sands through the hourglass, so are the days of our lives.
|
||||
module.exports = ({blobStore}) ->
|
||||
{updateProcessEnv} = require('./update-process-env')
|
||||
@@ -16,11 +73,6 @@ module.exports = ({blobStore}) ->
|
||||
# Make React faster
|
||||
process.env.NODE_ENV ?= 'production' unless devMode
|
||||
|
||||
AtomEnvironment = require './atom-environment'
|
||||
ApplicationDelegate = require './application-delegate'
|
||||
Clipboard = require './clipboard'
|
||||
TextEditor = require './text-editor'
|
||||
|
||||
clipboard = new Clipboard
|
||||
TextEditor.setClipboard(clipboard)
|
||||
|
||||
@@ -32,7 +84,7 @@ module.exports = ({blobStore}) ->
|
||||
env: process.env
|
||||
})
|
||||
|
||||
atom.startEditorWindow().then ->
|
||||
window.atom.startEditorWindow().then ->
|
||||
# Workaround for focus getting cleared upon window creation
|
||||
windowFocused = ->
|
||||
window.removeEventListener('focus', windowFocused)
|
||||
|
||||
@@ -2,24 +2,24 @@ CursorsComponent = require './cursors-component'
|
||||
LinesTileComponent = require './lines-tile-component'
|
||||
TiledComponent = require './tiled-component'
|
||||
|
||||
DummyLineNode = document.createElement('div')
|
||||
DummyLineNode.className = 'line'
|
||||
DummyLineNode.style.position = 'absolute'
|
||||
DummyLineNode.style.visibility = 'hidden'
|
||||
DummyLineNode.appendChild(document.createElement('span'))
|
||||
DummyLineNode.appendChild(document.createElement('span'))
|
||||
DummyLineNode.appendChild(document.createElement('span'))
|
||||
DummyLineNode.appendChild(document.createElement('span'))
|
||||
DummyLineNode.children[0].textContent = 'x'
|
||||
DummyLineNode.children[1].textContent = '我'
|
||||
DummyLineNode.children[2].textContent = 'ハ'
|
||||
DummyLineNode.children[3].textContent = '세'
|
||||
|
||||
module.exports =
|
||||
class LinesComponent extends TiledComponent
|
||||
placeholderTextDiv: null
|
||||
|
||||
constructor: ({@views, @presenter, @domElementPool, @assert}) ->
|
||||
@DummyLineNode = document.createElement('div')
|
||||
@DummyLineNode.className = 'line'
|
||||
@DummyLineNode.style.position = 'absolute'
|
||||
@DummyLineNode.style.visibility = 'hidden'
|
||||
@DummyLineNode.appendChild(document.createElement('span'))
|
||||
@DummyLineNode.appendChild(document.createElement('span'))
|
||||
@DummyLineNode.appendChild(document.createElement('span'))
|
||||
@DummyLineNode.appendChild(document.createElement('span'))
|
||||
@DummyLineNode.children[0].textContent = 'x'
|
||||
@DummyLineNode.children[1].textContent = '我'
|
||||
@DummyLineNode.children[2].textContent = 'ハ'
|
||||
@DummyLineNode.children[3].textContent = '세'
|
||||
|
||||
@domNode = document.createElement('div')
|
||||
@domNode.classList.add('lines')
|
||||
@tilesNode = document.createElement("div")
|
||||
@@ -78,15 +78,15 @@ class LinesComponent extends TiledComponent
|
||||
getTilesNode: -> @tilesNode
|
||||
|
||||
measureLineHeightAndDefaultCharWidth: ->
|
||||
@domNode.appendChild(DummyLineNode)
|
||||
@domNode.appendChild(@DummyLineNode)
|
||||
|
||||
lineHeightInPixels = DummyLineNode.getBoundingClientRect().height
|
||||
defaultCharWidth = DummyLineNode.children[0].getBoundingClientRect().width
|
||||
doubleWidthCharWidth = DummyLineNode.children[1].getBoundingClientRect().width
|
||||
halfWidthCharWidth = DummyLineNode.children[2].getBoundingClientRect().width
|
||||
koreanCharWidth = DummyLineNode.children[3].getBoundingClientRect().width
|
||||
lineHeightInPixels = @DummyLineNode.getBoundingClientRect().height
|
||||
defaultCharWidth = @DummyLineNode.children[0].getBoundingClientRect().width
|
||||
doubleWidthCharWidth = @DummyLineNode.children[1].getBoundingClientRect().width
|
||||
halfWidthCharWidth = @DummyLineNode.children[2].getBoundingClientRect().width
|
||||
koreanCharWidth = @DummyLineNode.children[3].getBoundingClientRect().width
|
||||
|
||||
@domNode.removeChild(DummyLineNode)
|
||||
@domNode.removeChild(@DummyLineNode)
|
||||
|
||||
@presenter.setLineHeight(lineHeightInPixels)
|
||||
@presenter.setBaseCharacterWidth(defaultCharWidth, doubleWidthCharWidth, halfWidthCharWidth, koreanCharWidth)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
if (typeof snapshotResult !== 'undefined') {
|
||||
snapshotResult.setGlobals(global, process, global, {}, require) // eslint-disable-line no-undef
|
||||
}
|
||||
|
||||
const startTime = Date.now()
|
||||
|
||||
const electron = require('electron')
|
||||
|
||||
@@ -83,4 +83,5 @@ function handleStartupEventWithSquirrel () {
|
||||
function setupCompileCache () {
|
||||
const CompileCache = require('../compile-cache')
|
||||
CompileCache.setAtomHomeDirectory(process.env.ATOM_HOME)
|
||||
CompileCache.install(require)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class Range extends semver.Range
|
||||
@unmatchedVersions.add(version)
|
||||
matches
|
||||
|
||||
nativeModules = process.binding('natives')
|
||||
nativeModules = null
|
||||
|
||||
cache =
|
||||
builtins: {}
|
||||
@@ -171,6 +171,7 @@ resolveModulePath = (relativePath, parentModule) ->
|
||||
return unless relativePath
|
||||
return unless parentModule?.filename
|
||||
|
||||
nativeModules ?= process.binding('natives')
|
||||
return if nativeModules.hasOwnProperty(relativePath)
|
||||
return if relativePath[0] is '.'
|
||||
return if isAbsolute(relativePath)
|
||||
@@ -212,35 +213,6 @@ registerBuiltins = (devMode) ->
|
||||
for builtin in rendererBuiltins
|
||||
cache.builtins[builtin] = path.join(rendererRoot, "#{builtin}.js")
|
||||
|
||||
if cache.debug
|
||||
cache.findPathCount = 0
|
||||
cache.findPathTime = 0
|
||||
cache.loadCount = 0
|
||||
cache.requireTime = 0
|
||||
global.moduleCache = cache
|
||||
|
||||
originalLoad = Module::load
|
||||
Module::load = ->
|
||||
cache.loadCount++
|
||||
originalLoad.apply(this, arguments)
|
||||
|
||||
originalRequire = Module::require
|
||||
Module::require = ->
|
||||
startTime = Date.now()
|
||||
exports = originalRequire.apply(this, arguments)
|
||||
cache.requireTime += Date.now() - startTime
|
||||
exports
|
||||
|
||||
originalFindPath = Module._findPath
|
||||
Module._findPath = (request, paths) ->
|
||||
cacheKey = JSON.stringify({request, paths})
|
||||
cache.findPathCount++ unless Module._pathCache[cacheKey]
|
||||
|
||||
startTime = Date.now()
|
||||
foundPath = originalFindPath.apply(global, arguments)
|
||||
cache.findPathTime += Date.now() - startTime
|
||||
foundPath
|
||||
|
||||
exports.create = (modulePath) ->
|
||||
fs = require 'fs-plus'
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
const Module = require('module')
|
||||
const path = require('path')
|
||||
const cachedVm = require('cached-run-in-this-context')
|
||||
@@ -38,7 +36,6 @@ class NativeCompileCache {
|
||||
|
||||
overrideModuleCompile () {
|
||||
let self = this
|
||||
let resolvedArgv = null
|
||||
// Here we override Node's module.js
|
||||
// (https://github.com/atom/node/blob/atom/lib/module.js#L378), changing
|
||||
// only the bits that affect compilation in order to use the cached one.
|
||||
@@ -63,11 +60,10 @@ class NativeCompileCache {
|
||||
// create wrapper function
|
||||
let wrapper = Module.wrap(content)
|
||||
|
||||
let cacheKey = filename
|
||||
let invalidationKey = computeHash(wrapper + self.v8Version)
|
||||
let cacheKey = computeHash(wrapper + self.v8Version)
|
||||
let compiledWrapper = null
|
||||
if (self.cacheStore.has(cacheKey, invalidationKey)) {
|
||||
let buffer = self.cacheStore.get(cacheKey, invalidationKey)
|
||||
if (self.cacheStore.has(cacheKey)) {
|
||||
let buffer = self.cacheStore.get(cacheKey)
|
||||
let compilationResult = cachedVm.runInThisContextCached(wrapper, filename, buffer)
|
||||
compiledWrapper = compilationResult.result
|
||||
if (compilationResult.wasRejected) {
|
||||
@@ -82,29 +78,11 @@ class NativeCompileCache {
|
||||
throw err
|
||||
}
|
||||
if (compilationResult.cacheBuffer) {
|
||||
self.cacheStore.set(cacheKey, invalidationKey, compilationResult.cacheBuffer)
|
||||
self.cacheStore.set(cacheKey, compilationResult.cacheBuffer)
|
||||
}
|
||||
compiledWrapper = compilationResult.result
|
||||
}
|
||||
if (global.v8debug) {
|
||||
if (!resolvedArgv) {
|
||||
// we enter the repl if we're not given a filename argument.
|
||||
if (process.argv[1]) {
|
||||
resolvedArgv = Module._resolveFilename(process.argv[1], null)
|
||||
} else {
|
||||
resolvedArgv = 'repl'
|
||||
}
|
||||
}
|
||||
|
||||
// Set breakpoint on module start
|
||||
if (filename === resolvedArgv) {
|
||||
// Installing this dummy debug event listener tells V8 to start
|
||||
// the debugger. Without it, the setBreakPoint() fails with an
|
||||
// 'illegal access' error.
|
||||
global.v8debug.Debug.setListener(function () {})
|
||||
global.v8debug.Debug.setBreakPoint(compiledWrapper, 0, 0)
|
||||
}
|
||||
}
|
||||
let args = [moduleSelf.exports, require, moduleSelf, filename, dirname, process, global]
|
||||
return compiledWrapper.apply(moduleSelf.exports, args)
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ class Package
|
||||
@metadata ?= @packageManager.loadPackageMetadata(@path)
|
||||
@bundledPackage = @packageManager.isBundledPackagePath(@path)
|
||||
@name = @metadata?.name ? path.basename(@path)
|
||||
ModuleCache.add(@path, @metadata)
|
||||
unless @bundledPackage
|
||||
ModuleCache.add(@path, @metadata)
|
||||
@reset()
|
||||
|
||||
###
|
||||
@@ -502,7 +503,7 @@ class Package
|
||||
path.join(@path, @metadata.main)
|
||||
else
|
||||
path.join(@path, 'index')
|
||||
@mainModulePath = fs.resolveExtension(mainModulePath, ["", _.keys(require.extensions)...])
|
||||
@mainModulePath = fs.resolveExtension(mainModulePath, ["", CompileCache.supportedExtensions...])
|
||||
|
||||
activationShouldBeDeferred: ->
|
||||
@hasActivationCommands() or @hasActivationHooks()
|
||||
|
||||
@@ -70,7 +70,13 @@ class Task
|
||||
compileCachePath = require('./compile-cache').getCacheDirectory()
|
||||
taskBootstrapRequire = "require('#{require.resolve('./task-bootstrap')}');"
|
||||
bootstrap = """
|
||||
#{compileCacheRequire}.setCacheDirectory('#{compileCachePath}');
|
||||
if (typeof snapshotResult !== 'undefined') {
|
||||
snapshotResult.setGlobals(global, process, global, {}, require)
|
||||
}
|
||||
|
||||
CompileCache = #{compileCacheRequire}
|
||||
CompileCache.setCacheDirectory('#{compileCachePath}');
|
||||
CompileCache.install(require)
|
||||
#{taskBootstrapRequire}
|
||||
"""
|
||||
bootstrap = bootstrap.replace(/\\/g, "\\\\")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** @babel */
|
||||
|
||||
import {Emitter, Disposable, CompositeDisposable} from 'event-kit'
|
||||
import {Point, Range} from 'atom'
|
||||
import {Point, Range} from 'text-buffer'
|
||||
import TextEditor from './text-editor'
|
||||
import ScopeDescriptor from './scope-descriptor'
|
||||
|
||||
|
||||
112
static/index.js
112
static/index.js
@@ -1,35 +1,66 @@
|
||||
(function () {
|
||||
var path = require('path')
|
||||
var FileSystemBlobStore = require('../src/file-system-blob-store')
|
||||
var NativeCompileCache = require('../src/native-compile-cache')
|
||||
var getWindowLoadSettings = require('../src/get-window-load-settings')
|
||||
// Eagerly require cached-run-in-this-context to prevent a circular require
|
||||
// when using `NativeCompileCache` for the first time.
|
||||
require('cached-run-in-this-context')
|
||||
|
||||
var blobStore = null
|
||||
const electron = require('electron')
|
||||
const path = require('path')
|
||||
const Module = require('module')
|
||||
const getWindowLoadSettings = require('../src/get-window-load-settings')
|
||||
const entryPointDirPath = __dirname
|
||||
let blobStore = null
|
||||
let useSnapshot = false
|
||||
|
||||
window.onload = function () {
|
||||
try {
|
||||
var startTime = Date.now()
|
||||
const startTime = Date.now()
|
||||
|
||||
process.on('unhandledRejection', function (error, promise) {
|
||||
console.error('Unhandled promise rejection %o with error: %o', promise, error)
|
||||
})
|
||||
|
||||
blobStore = FileSystemBlobStore.load(
|
||||
path.join(process.env.ATOM_HOME, 'blob-store/')
|
||||
)
|
||||
NativeCompileCache.setCacheStore(blobStore)
|
||||
NativeCompileCache.setV8Version(process.versions.v8)
|
||||
NativeCompileCache.install()
|
||||
|
||||
// Normalize to make sure drive letter case is consistent on Windows
|
||||
process.resourcesPath = path.normalize(process.resourcesPath)
|
||||
|
||||
var devMode = getWindowLoadSettings().devMode || !getWindowLoadSettings().resourcePath.startsWith(process.resourcesPath + path.sep)
|
||||
setupAtomHome()
|
||||
const devMode = getWindowLoadSettings().devMode || !getWindowLoadSettings().resourcePath.startsWith(process.resourcesPath + path.sep)
|
||||
useSnapshot = !devMode && typeof snapshotResult !== 'undefined'
|
||||
|
||||
if (devMode) {
|
||||
setupDeprecatedPackages()
|
||||
const metadata = require('../package.json')
|
||||
if (!metadata._deprecatedPackages) {
|
||||
try {
|
||||
metadata._deprecatedPackages = require('../script/deprecated-packages.json')
|
||||
} catch (requireError) {
|
||||
console.error('Failed to setup deprecated packages list', requireError.stack)
|
||||
}
|
||||
}
|
||||
} else if (useSnapshot) {
|
||||
Module.prototype.require = function (module) {
|
||||
const absoluteFilePath = Module._resolveFilename(module, this, false)
|
||||
let relativeFilePath = path.relative(entryPointDirPath, absoluteFilePath)
|
||||
if (process.platform === 'win32') {
|
||||
relativeFilePath = relativeFilePath.replace(/\\/g, '/')
|
||||
}
|
||||
let cachedModule = snapshotResult.customRequire.cache[relativeFilePath] // eslint-disable-line no-undef
|
||||
if (!cachedModule) {
|
||||
cachedModule = {exports: Module._load(module, this, false)}
|
||||
snapshotResult.customRequire.cache[relativeFilePath] = cachedModule // eslint-disable-line no-undef
|
||||
}
|
||||
return cachedModule.exports
|
||||
}
|
||||
|
||||
snapshotResult.setGlobals(global, process, window, document, require) // eslint-disable-line no-undef
|
||||
}
|
||||
|
||||
const FileSystemBlobStore = useSnapshot ? snapshotResult.customRequire('../src/file-system-blob-store.js') : require('../src/file-system-blob-store') // eslint-disable-line no-undef
|
||||
blobStore = FileSystemBlobStore.load(path.join(process.env.ATOM_HOME, 'blob-store'))
|
||||
|
||||
const NativeCompileCache = useSnapshot ? snapshotResult.customRequire('../src/native-compile-cache.js') : require('../src/native-compile-cache') // eslint-disable-line no-undef
|
||||
NativeCompileCache.setCacheStore(blobStore)
|
||||
NativeCompileCache.setV8Version(process.versions.v8)
|
||||
NativeCompileCache.install()
|
||||
|
||||
if (getWindowLoadSettings().profileStartup) {
|
||||
profileStartup(Date.now() - startTime)
|
||||
} else {
|
||||
@@ -48,7 +79,7 @@
|
||||
}
|
||||
|
||||
function handleSetupError (error) {
|
||||
var currentWindow = require('electron').remote.getCurrentWindow()
|
||||
const currentWindow = electron.remote.getCurrentWindow()
|
||||
currentWindow.setSize(800, 600)
|
||||
currentWindow.center()
|
||||
currentWindow.show()
|
||||
@@ -57,53 +88,30 @@
|
||||
}
|
||||
|
||||
function setupWindow () {
|
||||
var CompileCache = require('../src/compile-cache')
|
||||
const CompileCache = useSnapshot ? snapshotResult.customRequire('../src/compile-cache.js') : require('../src/compile-cache') // eslint-disable-line no-undef
|
||||
CompileCache.setAtomHomeDirectory(process.env.ATOM_HOME)
|
||||
CompileCache.install(require)
|
||||
|
||||
var ModuleCache = require('../src/module-cache')
|
||||
const ModuleCache = useSnapshot ? snapshotResult.customRequire('../src/module-cache.js') : require('../src/module-cache') // eslint-disable-line no-undef
|
||||
ModuleCache.register(getWindowLoadSettings())
|
||||
ModuleCache.add(getWindowLoadSettings().resourcePath)
|
||||
|
||||
// By explicitly passing the app version here, we could save the call
|
||||
// of "require('remote').require('app').getVersion()".
|
||||
var startCrashReporter = require('../src/crash-reporter-start')
|
||||
const startCrashReporter = useSnapshot ? snapshotResult.customRequire('../src/crash-reporter-start.js') : require('../src/crash-reporter-start') // eslint-disable-line no-undef
|
||||
startCrashReporter({_version: getWindowLoadSettings().appVersion})
|
||||
|
||||
setupVmCompatibility()
|
||||
setupCsonCache(CompileCache.getCacheDirectory())
|
||||
const CSON = useSnapshot ? snapshotResult.customRequire('../node_modules/season/lib/cson.js') : require('season') // eslint-disable-line no-undef
|
||||
CSON.setCacheDir(path.join(CompileCache.getCacheDirectory(), 'cson'))
|
||||
|
||||
var initialize = require(getWindowLoadSettings().windowInitializationScript)
|
||||
const initScriptPath = path.relative(entryPointDirPath, getWindowLoadSettings().windowInitializationScript)
|
||||
const initialize = useSnapshot ? snapshotResult.customRequire(initScriptPath) : require(initScriptPath) // eslint-disable-line no-undef
|
||||
return initialize({blobStore: blobStore}).then(function () {
|
||||
require('electron').ipcRenderer.send('window-command', 'window:loaded')
|
||||
electron.ipcRenderer.send('window-command', 'window:loaded')
|
||||
})
|
||||
}
|
||||
|
||||
function setupCsonCache (cacheDir) {
|
||||
require('season').setCacheDir(path.join(cacheDir, 'cson'))
|
||||
}
|
||||
|
||||
function setupVmCompatibility () {
|
||||
var vm = require('vm')
|
||||
if (!vm.Script.createContext) {
|
||||
vm.Script.createContext = vm.createContext
|
||||
}
|
||||
}
|
||||
|
||||
function setupDeprecatedPackages () {
|
||||
var metadata = require('../package.json')
|
||||
if (!metadata._deprecatedPackages) {
|
||||
try {
|
||||
metadata._deprecatedPackages = require('../script/deprecated-packages.json')
|
||||
} catch (requireError) {
|
||||
console.error('Failed to setup deprecated packages list', requireError.stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function profileStartup (initialTime) {
|
||||
function profile () {
|
||||
console.profile('startup')
|
||||
var startTime = Date.now()
|
||||
const startTime = Date.now()
|
||||
setupWindow().then(function () {
|
||||
setLoadTime(Date.now() - startTime + initialTime)
|
||||
console.profileEnd('startup')
|
||||
@@ -111,7 +119,7 @@
|
||||
})
|
||||
}
|
||||
|
||||
const webContents = require('electron').remote.getCurrentWindow().webContents
|
||||
const webContents = electron.remote.getCurrentWindow().webContents
|
||||
if (webContents.devToolsWebContents) {
|
||||
profile()
|
||||
} else {
|
||||
@@ -120,7 +128,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
var setupAtomHome = function () {
|
||||
function setupAtomHome () {
|
||||
if (process.env.ATOM_HOME) {
|
||||
return
|
||||
}
|
||||
@@ -132,6 +140,4 @@
|
||||
process.env.ATOM_HOME = getWindowLoadSettings().atomHome
|
||||
}
|
||||
}
|
||||
|
||||
setupAtomHome()
|
||||
})()
|
||||
|
||||
Reference in New Issue
Block a user