From ac7bb27e220a78b2876e7aff397274cf390bb699 Mon Sep 17 00:00:00 2001 From: Amy Troschinetz Date: Fri, 20 May 2016 17:52:14 -0500 Subject: [PATCH 01/21] Select the replaced text post replacement. --- spec/text-editor-spec.coffee | 12 +++++++++--- src/text-editor.coffee | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 81c69f63f..3cb771ec7 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -4868,8 +4868,8 @@ describe "TextEditor", -> editor.replaceSelectedText {}, -> '123' expect(buffer.lineForRow(0)).toBe '123var quicksort = function () {' - editor.replaceSelectedText {selectWordIfEmpty: true}, -> 'var' editor.setCursorBufferPosition([0]) + editor.replaceSelectedText {selectWordIfEmpty: true}, -> 'var' expect(buffer.lineForRow(0)).toBe 'var quicksort = function () {' editor.setCursorBufferPosition([10]) @@ -4882,6 +4882,12 @@ describe "TextEditor", -> editor.replaceSelectedText {}, -> 'ia' expect(buffer.lineForRow(0)).toBe 'via quicksort = function () {' + it "replaces the selected text and selects the replacement text", -> + editor.setSelectedBufferRange([[0, 4], [0, 9]]) + editor.replaceSelectedText {}, -> 'whatnot' + expect(buffer.lineForRow(0)).toBe 'var whatnotsort = function () {' + expect(editor.getSelectedBufferRange()).toEqual [[0, 4], [0, 11]] + describe ".transpose()", -> it "swaps two characters", -> editor.buffer.setText("abc") @@ -4902,7 +4908,7 @@ describe "TextEditor", -> editor.setCursorScreenPosition([0, 1]) editor.upperCase() expect(editor.lineTextForBufferRow(0)).toBe 'ABC' - expect(editor.getSelectedBufferRange()).toEqual [[0, 1], [0, 1]] + expect(editor.getSelectedBufferRange()).toEqual [[0, 0], [0, 3]] describe "when there is a selection", -> it "upper cases the current selection", -> @@ -4919,7 +4925,7 @@ describe "TextEditor", -> editor.setCursorScreenPosition([0, 1]) editor.lowerCase() expect(editor.lineTextForBufferRow(0)).toBe 'abc' - expect(editor.getSelectedBufferRange()).toEqual [[0, 1], [0, 1]] + expect(editor.getSelectedBufferRange()).toEqual [[0, 0], [0, 3]] describe "when there is a selection", -> it "lower cases the current selection", -> diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 8095632fd..96f30ddf9 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -1328,12 +1328,12 @@ class TextEditor extends Model replaceSelectedText: (options={}, fn) -> {selectWordIfEmpty} = options @mutateSelectedText (selection) -> - range = selection.getBufferRange() + selection.getBufferRange() if selectWordIfEmpty and selection.isEmpty() selection.selectWord() text = selection.getText() selection.deleteSelectedText() - selection.insertText(fn(text)) + range = selection.insertText(fn(text)) selection.setBufferRange(range) # Split multi-line selections into one selection per line. From e85ed1dc7f6a87e90f1e075e745b37540613e37d Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Thu, 9 Mar 2017 14:25:16 -0800 Subject: [PATCH 02/21] Refactor open; separate creation and placement of items This is a refactoring that sets up the work for #13878 (docks). Because items will be able to dictate their preferred locations, we need to detangle the item creation from their placement. --- src/workspace.js | 108 +++++++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 46 deletions(-) diff --git a/src/workspace.js b/src/workspace.js index 8ff8aa51d..a386b5ff7 100644 --- a/src/workspace.js +++ b/src/workspace.js @@ -511,9 +511,8 @@ module.exports = class Workspace extends Model { // // Returns a {Promise} that resolves to the {TextEditor} for the file URI. open (uri_, options = {}) { - const { searchAllPanes } = options - const { split } = options const uri = this.project.resolvePath(uri_) + const {searchAllPanes, split} = options if (!atom.config.get('core.allowPendingPaneItems')) { options.pending = false @@ -526,7 +525,7 @@ module.exports = class Workspace extends Model { } let pane - if (searchAllPanes) { pane = this.paneContainer.paneForURI(uri) } + if (searchAllPanes) { pane = this.paneForURI(uri) } if (pane == null) { switch (split) { case 'left': @@ -547,7 +546,16 @@ module.exports = class Workspace extends Model { } } - return this.openURIInPane(uri, pane, options) + let item + if (uri != null) { + item = pane.itemForURI(uri) + } + if (item == null) { + item = this.createItemForURI(uri, options) + } + + return Promise.resolve(item) + .then(item => this.openItem(item, Object.assign({pane, uri}, options))) } // Open Atom's license in the active pane. @@ -597,26 +605,28 @@ module.exports = class Workspace extends Model { } openURIInPane (uri, pane, options = {}) { - const activatePane = options.activatePane != null ? options.activatePane : true - const activateItem = options.activateItem != null ? options.activateItem : true - let item if (uri != null) { item = pane.itemForURI(uri) - if (item == null) { - for (let opener of this.getOpeners()) { - item = opener(uri, options) - if (item != null) break - } - } else if (!options.pending && (pane.getPendingItem() === item)) { - pane.clearPendingItem() + } + if (item == null) { + item = this.createItemForURI(uri, options) + } + return Promise.resolve(item) + .then(item => this.openItem(item, Object.assign({pane, uri}, options))) + } + + // Returns a {Promise} that resolves to the {TextEditor} (or other item) for the given URI. + createItemForURI (uri, options) { + if (uri != null) { + for (let opener of this.getOpeners()) { + const item = opener(uri, options) + if (item != null) return Promise.resolve(item) } } try { - if (item == null) { - item = this.openTextFile(uri, options) - } + return this.openTextFile(uri, options) } catch (error) { switch (error.code) { case 'CANCELLED': @@ -644,40 +654,46 @@ module.exports = class Workspace extends Model { throw error } } + } - return Promise.resolve(item) - .then(item => { - let initialColumn - if (pane.isDestroyed()) { - return item - } + openItem (item, options = {}) { + const {pane} = options - this.itemOpened(item) - if (activateItem) { - pane.activateItem(item, {pending: options.pending}) - } - if (activatePane) { - pane.activate() - } + if (item == null) return undefined + if (pane.isDestroyed()) return item - let initialLine = initialColumn = 0 - if (!Number.isNaN(options.initialLine)) { - initialLine = options.initialLine - } - if (!Number.isNaN(options.initialColumn)) { - initialColumn = options.initialColumn - } - if ((initialLine >= 0) || (initialColumn >= 0)) { - if (typeof item.setCursorBufferPosition === 'function') { - item.setCursorBufferPosition([initialLine, initialColumn]) - } - } + if (!options.pending && (pane.getPendingItem() === item)) { + pane.clearPendingItem() + } - const index = pane.getActiveItemIndex() - this.emitter.emit('did-open', {uri, pane, item, index}) - return item + const activatePane = options.activatePane != null ? options.activatePane : true + const activateItem = options.activateItem != null ? options.activateItem : true + this.itemOpened(item) + if (activateItem) { + pane.activateItem(item, {pending: options.pending}) + } + if (activatePane) { + pane.activate() + } + + let initialColumn = 0 + let initialLine = 0 + if (!Number.isNaN(options.initialLine)) { + initialLine = options.initialLine + } + if (!Number.isNaN(options.initialColumn)) { + initialColumn = options.initialColumn + } + if ((initialLine >= 0) || (initialColumn >= 0)) { + if (typeof item.setCursorBufferPosition === 'function') { + item.setCursorBufferPosition([initialLine, initialColumn]) } - ) + } + + const index = pane.getActiveItemIndex() + const uri = options.uri == null && typeof item.getURI === 'function' ? item.getURI() : options.uri + this.emitter.emit('did-open', {uri, pane, item, index}) + return item } openTextFile (uri, options) { From 6eca9d470955c97ebe1767bc420ac6f8a778ee0f Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Fri, 10 Mar 2017 09:54:28 -0800 Subject: [PATCH 03/21] Ensure Windows builds fail when Squirrel packaging fails --- script/lib/create-windows-installer.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/script/lib/create-windows-installer.js b/script/lib/create-windows-installer.js index 8a0dc0f61..22a22701c 100644 --- a/script/lib/create-windows-installer.js +++ b/script/lib/create-windows-installer.js @@ -10,7 +10,7 @@ const spawnSync = require('./spawn-sync') const CONFIG = require('../config') -module.exports = function (packagedAppPath, codeSign) { +module.exports = (packagedAppPath, codeSign) => { const archSuffix = process.arch === 'ia32' ? '' : '-' + process.arch const options = { appDirectory: packagedAppPath, @@ -23,7 +23,7 @@ module.exports = function (packagedAppPath, codeSign) { } const signing = codeSign && (process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL || process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) - let certPath = process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH; + let certPath = process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH if (signing) { if (!certPath) { @@ -42,7 +42,7 @@ module.exports = function (packagedAppPath, codeSign) { console.log('Skipping code-signing. Specify the --code-sign option and provide a ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL environment variable to perform code-signing'.gray) } - const cleanUp = function () { + const cleanUp = () => { if (fs.existsSync(certPath) && !process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) { console.log(`Deleting certificate at ${certPath}`) fs.removeSync(certPath) @@ -57,7 +57,7 @@ module.exports = function (packagedAppPath, codeSign) { } // Squirrel signs its own copy of the executables but we need them for the portable ZIP - const extractSignedExes = function() { + const extractSignedExes = () => { if (signing) { for (let nupkgPath of glob.sync(`${CONFIG.buildOutputPath}/*-full.nupkg`)) { if (nupkgPath.includes(CONFIG.appMetadata.version)) { @@ -73,12 +73,9 @@ module.exports = function (packagedAppPath, codeSign) { console.log(`Creating Windows Installer for ${packagedAppPath}`) return electronInstaller.createWindowsInstaller(options) - .then(extractSignedExes, function (error) { - console.log(`Extracting signed executables failed:\n${error}`) - cleanUp() - }) - .then(cleanUp, function (error) { - console.log(`Windows installer creation failed:\n${error}`) + .then(extractSignedExes) + .then(cleanUp, error => { cleanUp() + return Promise.reject(error) }) } From 865294f3c8b70d97f0db8b69fca06fc032b04feb Mon Sep 17 00:00:00 2001 From: Dirk Thomas Date: Sun, 29 Jan 2017 10:33:07 -0800 Subject: [PATCH 04/21] pass through line count options --- src/default-directory-searcher.coffee | 5 ++++- src/scan-handler.coffee | 4 ++-- src/text-editor.coffee | 12 +++++++++++- src/workspace.js | 6 ++++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/default-directory-searcher.coffee b/src/default-directory-searcher.coffee index 6b8ffe3e3..3955d38e3 100644 --- a/src/default-directory-searcher.coffee +++ b/src/default-directory-searcher.coffee @@ -11,13 +11,16 @@ class DirectorySearch excludeVcsIgnores: options.excludeVcsIgnores globalExclusions: options.exclusions follow: options.follow + searchOptions = + leadingContextLineCount: options.leadingContextLineCount + trailingContextLineCount: options.trailingContextLineCount @task = new Task(require.resolve('./scan-handler')) @task.on 'scan:result-found', options.didMatch @task.on 'scan:file-error', options.didError @task.on 'scan:paths-searched', options.didSearchPaths @promise = new Promise (resolve, reject) => @task.on('task:cancelled', reject) - @task.start rootPaths, regex.source, scanHandlerOptions, => + @task.start rootPaths, regex.source, scanHandlerOptions, searchOptions, => @task.terminate() resolve() diff --git a/src/scan-handler.coffee b/src/scan-handler.coffee index 8ee8f715e..db2e8299b 100644 --- a/src/scan-handler.coffee +++ b/src/scan-handler.coffee @@ -2,13 +2,13 @@ path = require "path" async = require "async" {PathSearcher, PathScanner, search} = require 'scandal' -module.exports = (rootPaths, regexSource, options) -> +module.exports = (rootPaths, regexSource, options, searchOptions={}) -> callback = @async() PATHS_COUNTER_SEARCHED_CHUNK = 50 pathsSearched = 0 - searcher = new PathSearcher() + searcher = new PathSearcher(searchOptions) searcher.on 'file-error', ({code, path, message}) -> emit('scan:file-error', {code, path, message}) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 8095632fd..73fb7f954 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2826,6 +2826,11 @@ class TextEditor extends Model # {::backwardsScanInBufferRange} to avoid tripping over your own changes. # # * `regex` A {RegExp} to search for. + # * `options` (optional) {Object} + # * `leadingContextLineCount` {Number} default `0`; The number of lines + # before the matched line to include in the results object. + # * `trailingContextLineCount` {Number} default `0`; The number of lines + # after the matched line to include in the results object. # * `iterator` A {Function} that's called on each match # * `object` {Object} # * `match` The current regular expression match. @@ -2833,7 +2838,12 @@ class TextEditor extends Model # * `range` The {Range} of the match. # * `stop` Call this {Function} to terminate the scan. # * `replace` Call this {Function} with a {String} to replace the match. - scan: (regex, iterator) -> @buffer.scan(regex, iterator) + scan: (regex, options={}, iterator) -> + if _.isFunction(options) + iterator = options + options = {} + + @buffer.scan(regex, options, iterator) # Essential: Scan regular expression matches in a given range, calling the given # iterator function on each match. diff --git a/src/workspace.js b/src/workspace.js index a386b5ff7..6c5daba12 100644 --- a/src/workspace.js +++ b/src/workspace.js @@ -1202,6 +1202,10 @@ module.exports = class Workspace extends Model { // * `paths` An {Array} of glob patterns to search within. // * `onPathsSearched` (optional) {Function} to be periodically called // with number of paths searched. + // * `leadingContextLineCount` {Number} default `0`; The number of lines + // before the matched line to include in the results object. + // * `trailingContextLineCount` {Number} default `0`; The number of lines + // after the matched line to include in the results object. // * `iterator` {Function} callback on each file found. // // Returns a {Promise} with a `cancel()` method that will cancel all @@ -1261,6 +1265,8 @@ module.exports = class Workspace extends Model { excludeVcsIgnores: this.config.get('core.excludeVcsIgnoredPaths'), exclusions: this.config.get('core.ignoredNames'), follow: this.config.get('core.followSymlinks'), + leadingContextLineCount: options.leadingContextLineCount || 0, + trailingContextLineCount: options.trailingContextLineCount || 0, didMatch: result => { if (!this.project.isPathModified(result.filePath)) { return iterator(result) From 159ab1c435d546fc2a04cee3498a92d6e8a5906f Mon Sep 17 00:00:00 2001 From: Dirk Thomas Date: Thu, 9 Mar 2017 10:03:05 -0800 Subject: [PATCH 05/21] :arrow_up: scandal 3.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 46f5dc165..b23e6e6fc 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "random-words": "0.0.1", "resolve": "^1.1.6", "runas": "^3.1", - "scandal": "^3.0.0", + "scandal": "^3.1.0", "scoped-property-store": "^0.17.0", "scrollbar-style": "^3.2", "season": "^6.0.0", From 348553049adc80c3a0bedaba100ba063b5a73b03 Mon Sep 17 00:00:00 2001 From: Dirk Thomas Date: Thu, 9 Mar 2017 19:29:45 -0800 Subject: [PATCH 06/21] update specs --- spec/workspace-spec.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spec/workspace-spec.js b/spec/workspace-spec.js index 43e4fbae4..b04d8cbd7 100644 --- a/spec/workspace-spec.js +++ b/spec/workspace-spec.js @@ -1336,7 +1336,9 @@ i = /test/; #FIXME\ it('calls the callback with all regex results in all files in the project', () => { const results = [] waitsForPromise(() => - atom.workspace.scan(/(a)+/, result => results.push(result)) + atom.workspace.scan( + /(a)+/, {leadingContextLineCount: 1, trailingContextLineCount: 1}, + result => results.push(result)) ) runs(() => { @@ -1349,14 +1351,16 @@ i = /test/; #FIXME\ lineTextOffset: 0, range: [[0, 0], [0, 3]], leadingContextLines: [], - trailingContextLines: [] + trailingContextLines: ['cc aa cc'] }) }) }) it('works with with escaped literals (like $ and ^)', () => { const results = [] - waitsForPromise(() => atom.workspace.scan(/\$\w+/, result => results.push(result))) + waitsForPromise(() => atom.workspace.scan( + /\$\w+/, {leadingContextLineCount: 1, trailingContextLineCount: 1}, + result => results.push(result))) runs(() => { expect(results.length).toBe(1) @@ -1368,7 +1372,7 @@ i = /test/; #FIXME\ lineText: 'dollar$bill', lineTextOffset: 0, range: [[2, 6], [2, 11]], - leadingContextLines: [], + leadingContextLines: ['cc aa cc'], trailingContextLines: [] }) }) From a792fa378fc931df48d49808ae1687d82f0a6e42 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 10 Mar 2017 19:47:37 +0100 Subject: [PATCH 07/21] :arrow_up: service-hub --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 46f5dc165..95956bb1c 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "scrollbar-style": "^3.2", "season": "^6.0.0", "semver": "^4.3.3", - "service-hub": "^0.7.2", + "service-hub": "^0.7.3", "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", From 7408fc87317ad128da66eda6fa191ffe89ed17e4 Mon Sep 17 00:00:00 2001 From: liuderchi Date: Fri, 10 Mar 2017 23:51:49 +0800 Subject: [PATCH 08/21] :art: add 'Run Benchmark' menu item for win32 and linux platform --- menus/linux.cson | 1 + menus/win32.cson | 1 + 2 files changed, 2 insertions(+) diff --git a/menus/linux.cson b/menus/linux.cson index 94fb90a30..2a1ca47f8 100644 --- a/menus/linux.cson +++ b/menus/linux.cson @@ -137,6 +137,7 @@ { label: 'Open In &Dev Mode…', command: 'application:open-dev' } { label: '&Reload Window', command: 'window:reload' } { label: 'Run Package &Specs', command: 'window:run-package-specs' } + { label: 'Run &Benchmarks', command: 'window:run-benchmarks' } { label: 'Toggle Developer &Tools', command: 'window:toggle-dev-tools' } ] } diff --git a/menus/win32.cson b/menus/win32.cson index 70bb1487d..553b6017e 100644 --- a/menus/win32.cson +++ b/menus/win32.cson @@ -136,6 +136,7 @@ { label: 'Open In &Dev Mode…', command: 'application:open-dev' } { label: '&Reload Window', command: 'window:reload' } { label: 'Run Package &Specs', command: 'window:run-package-specs' } + { label: 'Run &Benchmarks', command: 'window:run-benchmarks' } { label: 'Toggle Developer &Tools', command: 'window:toggle-dev-tools' } ] } From 0d29004723c478ee2acaa8475dedf8f833819d02 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 13 Mar 2017 19:11:53 +0100 Subject: [PATCH 09/21] Speed up FileSystemBlobStore.load by not storing invalidation keys This was unneeded because we can simply compute the cache key by concatenating the v8 version and the file's contents. --- spec/file-system-blob-store-spec.coffee | 84 ++++++++++++------------- spec/native-compile-cache-spec.coffee | 25 +++----- src/file-system-blob-store.js | 21 ++----- src/native-compile-cache.js | 9 ++- 4 files changed, 58 insertions(+), 81 deletions(-) diff --git a/spec/file-system-blob-store-spec.coffee b/spec/file-system-blob-store-spec.coffee index 70e4d2b8d..ff1c81eb6 100644 --- a/spec/file-system-blob-store-spec.coffee +++ b/spec/file-system-blob-store-spec.coffee @@ -14,79 +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 in-memory and previously stored buffers, and deletes unused keys when saved", -> - 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) - 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")).toBeUndefined() - 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.get("a", "invalidation-key-1") # prevent the key from being deleted on save - 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 @@ -96,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")) diff --git a/spec/native-compile-cache-spec.coffee b/spec/native-compile-cache-spec.coffee index 1531deaf9..a43cbe815 100644 --- a/spec/native-compile-cache-spec.coffee +++ b/spec/native-compile-cache-spec.coffee @@ -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) diff --git a/src/file-system-blob-store.js b/src/file-system-blob-store.js index 828e23e94..67a959735 100644 --- a/src/file-system-blob-store.js +++ b/src/file-system-blob-store.js @@ -14,14 +14,12 @@ 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() @@ -34,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() } @@ -51,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 { @@ -60,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') { @@ -73,22 +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) { + set (key, buffer) { this.usedKeys.add(key) - this.invalidationKeys[key] = invalidationKey return this.inMemoryBlobs.set(key, buffer) } diff --git a/src/native-compile-cache.js b/src/native-compile-cache.js index b1867ff55..09a62b186 100644 --- a/src/native-compile-cache.js +++ b/src/native-compile-cache.js @@ -60,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) { @@ -79,7 +78,7 @@ class NativeCompileCache { throw err } if (compilationResult.cacheBuffer) { - self.cacheStore.set(cacheKey, invalidationKey, compilationResult.cacheBuffer) + self.cacheStore.set(cacheKey, compilationResult.cacheBuffer) } compiledWrapper = compilationResult.result } From 56aae269e9cc9e5be65ee13a482b427d8520719b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 14 Mar 2017 15:03:34 +0100 Subject: [PATCH 10/21] :arrow_up: autocomplete-plus --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f398dad46..b0577caa5 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.15.1", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.34.2", + "autocomplete-plus": "2.35.0", "autocomplete-snippets": "1.11.0", "autoflow": "0.29.0", "autosave": "0.24.1", From 4f87dad60453710649d6c1f99014f2d0af9506c2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 14 Mar 2017 18:01:04 +0100 Subject: [PATCH 11/21] :arrow_up: incompatible-packages --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b0577caa5..2aebbcb25 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "go-to-line": "0.32.0", "grammar-selector": "0.49.3", "image-view": "0.61.2", - "incompatible-packages": "0.27.1", + "incompatible-packages": "0.27.2", "keybinding-resolver": "0.36.4", "line-ending-selector": "0.6.2", "link": "0.31.3", From 09b9e57cb4ab4f2fb58ad17f52f3149bbed7cb28 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 14 Mar 2017 11:57:26 -0700 Subject: [PATCH 12/21] :arrow_up: Upgrade to Electron 1.3.14 with snapshot patch --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f972b4890..71ce9bb07 100644 --- a/package.json +++ b/package.json @@ -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", From 52fb79172c1a2d9723108f5a309c958ae41878fb Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 14 Mar 2017 12:17:50 -0700 Subject: [PATCH 13/21] Dowloading -> Downloading --- script/lib/download-file-from-github.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/download-file-from-github.js b/script/lib/download-file-from-github.js index 2969ea2dc..13e04e99e 100644 --- a/script/lib/download-file-from-github.js +++ b/script/lib/download-file-from-github.js @@ -5,7 +5,7 @@ const path = require('path') const syncRequest = require('sync-request') module.exports = function (downloadURL, destinationPath) { - console.log(`Dowloading file from GitHub Repository to ${destinationPath}`) + console.log(`Downloading file from GitHub Repository to ${destinationPath}`) const response = syncRequest('GET', downloadURL, { 'headers': {'Accept': 'application/vnd.github.v3.raw', 'User-Agent': 'Atom Build'} }) From 7caeb3d8529f6e0e29bebf1c29297d660825eb9a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 15 Mar 2017 09:49:05 +0100 Subject: [PATCH 14/21] Clear compile-cache on AppVeyor --- appveyor.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index e94e75441..7c243fec9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -51,5 +51,4 @@ cache: - '%APPVEYOR_BUILD_FOLDER%\node_modules' - '%APPVEYOR_BUILD_FOLDER%\electron' - '%USERPROFILE%\.atom\.apm' - - '%USERPROFILE%\.atom\compile-cache' - '%USERPROFILE%\.atom\snapshot-cache' From d95a5f1d3c94463b3e9b0d491f52572672daf828 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 15 Mar 2017 10:38:13 +0100 Subject: [PATCH 15/21] Revert "Clear compile-cache on AppVeyor" This reverts commit 7caeb3d8529f6e0e29bebf1c29297d660825eb9a. --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 7c243fec9..e94e75441 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -51,4 +51,5 @@ cache: - '%APPVEYOR_BUILD_FOLDER%\node_modules' - '%APPVEYOR_BUILD_FOLDER%\electron' - '%USERPROFILE%\.atom\.apm' + - '%USERPROFILE%\.atom\compile-cache' - '%USERPROFILE%\.atom\snapshot-cache' From b2983f63bab0b74988a2a6bc58157a8c9d616d8f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 15 Mar 2017 13:26:29 +0100 Subject: [PATCH 16/21] Replace backward with forward slashes when requiring files on Windows --- static/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/static/index.js b/static/index.js index f7d2d4c2f..6297eb5ef 100644 --- a/static/index.js +++ b/static/index.js @@ -38,7 +38,10 @@ } else if (useSnapshot) { Module.prototype.require = function (module) { const absoluteFilePath = Module._resolveFilename(module, this, false) - const relativeFilePath = path.relative(entryPointDirPath, absoluteFilePath) + 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)} From 9ff213d27ba60329cd76eb4d4f38e2c78257547e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 16 Mar 2017 10:13:41 +0100 Subject: [PATCH 17/21] :arrow_up: autocomplete-html --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2aebbcb25..8d31fc6f3 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "archive-view": "0.63.1", "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.15.1", - "autocomplete-html": "0.7.2", + "autocomplete-html": "0.7.3", "autocomplete-plus": "2.35.0", "autocomplete-snippets": "1.11.0", "autoflow": "0.29.0", From 6da748ee6702ece78d26b5e4dcc5a5a4301f047b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 16 Mar 2017 10:52:09 +0100 Subject: [PATCH 18/21] :arrow_up: autocomplete-atom-api and autocomplete-css --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 8d31fc6f3..1a8fc774c 100644 --- a/package.json +++ b/package.json @@ -97,8 +97,8 @@ "solarized-light-syntax": "1.1.2", "about": "1.7.5", "archive-view": "0.63.1", - "autocomplete-atom-api": "0.10.0", - "autocomplete-css": "0.15.1", + "autocomplete-atom-api": "0.10.1", + "autocomplete-css": "0.15.2", "autocomplete-html": "0.7.3", "autocomplete-plus": "2.35.0", "autocomplete-snippets": "1.11.0", From ad6a5ac3bf23620e17308093928d6436a749c8c3 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 16 Mar 2017 15:57:44 +0100 Subject: [PATCH 19/21] Don't send `did-resolve-proxy` messages to destroyed windows This should fix some main process test failures we are observing on AppVeyor. --- src/main-process/atom-application.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main-process/atom-application.coffee b/src/main-process/atom-application.coffee index e6f40379d..1faab1b78 100644 --- a/src/main-process/atom-application.coffee +++ b/src/main-process/atom-application.coffee @@ -284,7 +284,9 @@ class AtomApplication @restart() @disposable.add ipcHelpers.on ipcMain, 'resolve-proxy', (event, requestId, url) -> - event.sender.session.resolveProxy url, (proxy) -> event.sender.send('did-resolve-proxy', requestId, proxy) + event.sender.session.resolveProxy url, (proxy) -> + unless event.sender.isDestroyed() + event.sender.send('did-resolve-proxy', requestId, proxy) @disposable.add ipcHelpers.on ipcMain, 'did-change-history-manager', (event) => for atomWindow in @windows From df1210cc3fc3b72529dac6a1b13e6327d5ec7cac Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 16 Mar 2017 09:34:19 -0700 Subject: [PATCH 20/21] :arrow_up: find-and-replace --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 699559ac7..5c7dd601b 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "dev-live-reload": "0.47.1", "encoding-selector": "0.23.2", "exception-reporting": "0.41.3", - "find-and-replace": "0.207.2", + "find-and-replace": "0.207.3", "fuzzy-finder": "1.5.1", "git-diff": "1.3.4", "go-to-line": "0.32.0", From 306968aa53fa8ce2d186768f8f67fef8bcab7494 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 16 Mar 2017 13:20:32 -0600 Subject: [PATCH 21/21] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5c7dd601b..86509a786 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "11.3.0", + "text-buffer": "11.4.0", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1",