-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Fix async issues in brackets-shell #1185
Changes from all commits
bfee8c7
f3f78a8
a7b184a
a4eb8c5
2060d8a
28a4ec4
0f557ac
a4378ae
2630cd8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -198,7 +198,7 @@ define(function (require, exports, module) { | |
|
||
/** | ||
* Adds the given file to the end of the working set list, if it is not already in the list. | ||
* Does not change which document is currently open in the editor. | ||
* Does not change which document is currently open in the editor. Completes synchronously. | ||
* @param {!FileEntry} file | ||
*/ | ||
function addToWorkingSet(file) { | ||
|
@@ -291,11 +291,11 @@ define(function (require, exports, module) { | |
* Moves document to the front of the MRU list, IF it's in the working set; no-op otherwise. | ||
* @param {!Document} | ||
*/ | ||
function _markMostRecent(document) { | ||
var mruI = findInWorkingSet(document.file.fullPath, _workingSetMRUOrder); | ||
function _markMostRecent(doc) { | ||
var mruI = findInWorkingSet(doc.file.fullPath, _workingSetMRUOrder); | ||
if (mruI !== -1) { | ||
_workingSetMRUOrder.splice(mruI, 1); | ||
_workingSetMRUOrder.unshift(document.file); | ||
_workingSetMRUOrder.unshift(doc.file); | ||
} | ||
} | ||
|
||
|
@@ -331,28 +331,28 @@ define(function (require, exports, module) { | |
* @param {!Document} document The Document to make current. May or may not already be in the | ||
* working set. | ||
*/ | ||
function setCurrentDocument(document) { | ||
function setCurrentDocument(doc) { | ||
|
||
// If this doc is already current, do nothing | ||
if (_currentDocument === document) { | ||
if (_currentDocument === doc) { | ||
return; | ||
} | ||
|
||
var perfTimerName = PerfUtils.markStart("setCurrentDocument:\t" + (!document || document.file.fullPath)); | ||
var perfTimerName = PerfUtils.markStart("setCurrentDocument:\t" + doc.file.fullPath); | ||
|
||
// If file not within project tree, add it to working set right now (don't wait for it to | ||
// become dirty) | ||
if (!ProjectManager.isWithinProject(document.file.fullPath)) { | ||
addToWorkingSet(document.file); | ||
if (!ProjectManager.isWithinProject(doc.file.fullPath)) { | ||
addToWorkingSet(doc.file); | ||
} | ||
|
||
// Adjust MRU working set ordering (except while in the middle of a Ctrl+Tab sequence) | ||
if (!_documentNavPending) { | ||
_markMostRecent(document); | ||
_markMostRecent(doc); | ||
} | ||
|
||
// Make it the current document | ||
_currentDocument = document; | ||
_currentDocument = doc; | ||
$(exports).triggerHandler("currentDocumentChange"); | ||
// (this event triggers EditorManager to actually switch editors in the UI) | ||
|
||
|
@@ -823,7 +823,8 @@ define(function (require, exports, module) { | |
/** | ||
* Gets an existing open Document for the given file, or creates a new one if the Document is | ||
* not currently open ('open' means referenced by the UI somewhere). Always use this method to | ||
* get Documents; do not call the Document constructor directly. | ||
* get Documents; do not call the Document constructor directly. This method is safe to call | ||
* in parallel. | ||
* | ||
* If you are going to hang onto the Document for more than just the duration of a command - e.g. | ||
* if you are going to display its contents in a piece of UI - then you must addRef() the Document | ||
|
@@ -835,33 +836,60 @@ define(function (require, exports, module) { | |
* with a FileError if the file is not yet open and can't be read from disk. | ||
*/ | ||
function getDocumentForPath(fullPath) { | ||
var result = new $.Deferred(), | ||
doc = _openDocuments[fullPath]; | ||
|
||
PerfUtils.markStart(PerfUtils.DOCUMENT_MANAGER_GET_DOCUMENT_FOR_PATH); | ||
result.done(function () { | ||
PerfUtils.addMeasurement(PerfUtils.DOCUMENT_MANAGER_GET_DOCUMENT_FOR_PATH); | ||
}).fail(function () { | ||
PerfUtils.finalizeMeasurement(PerfUtils.DOCUMENT_MANAGER_GET_DOCUMENT_FOR_PATH); | ||
}); | ||
var doc = _openDocuments[fullPath], | ||
pendingPromise = getDocumentForPath._pendingDocumentPromises[fullPath]; | ||
|
||
if (doc) { | ||
result.resolve(doc); | ||
// use existing document | ||
return new $.Deferred().resolve(doc).promise(); | ||
} else if (pendingPromise) { | ||
// wait for the result of a previous request | ||
return pendingPromise; | ||
} else { | ||
var fileEntry = new NativeFileSystem.FileEntry(fullPath); | ||
var result = new $.Deferred(), | ||
promise = result.promise(); | ||
|
||
// log this document's Promise as pending | ||
getDocumentForPath._pendingDocumentPromises[fullPath] = promise; | ||
|
||
// create a new document | ||
var fileEntry = new NativeFileSystem.FileEntry(fullPath), | ||
perfTimerName = PerfUtils.markStart("getDocumentForPath:\t" + fullPath); | ||
|
||
result.done(function () { | ||
PerfUtils.addMeasurement(perfTimerName); | ||
}).fail(function () { | ||
PerfUtils.finalizeMeasurement(perfTimerName); | ||
}); | ||
|
||
FileUtils.readAsText(fileEntry) | ||
.always(function () { | ||
// document is no longer pending | ||
delete getDocumentForPath._pendingDocumentPromises[fullPath]; | ||
}) | ||
.done(function (rawText, readTimestamp) { | ||
doc = new Document(fileEntry, readTimestamp, rawText); | ||
result.resolve(doc); | ||
}) | ||
.fail(function (fileError) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fail case also needs to clean up the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
result.reject(fileError); | ||
}); | ||
|
||
return promise; | ||
} | ||
|
||
return result.promise(); | ||
} | ||
|
||
/** | ||
* Document promises that are waiting to be resolved. It is possible for multiple clients | ||
* to request the same document simultaneously before the initial request has completed. | ||
* In particular, this happens at app startup where the working set is created and the | ||
* intial active document is opened in an editor. This is essential to ensure that only | ||
* 1 Document exists for any FileEntry. | ||
* @private | ||
* @type {Object.<string, $.Promise>} | ||
*/ | ||
getDocumentForPath._pendingDocumentPromises = {}; | ||
|
||
/** | ||
* Returns the existing open Document for the given file, or null if the file is not open ('open' | ||
* means referenced by the UI somewhere). If you will hang onto the Document, you must addRef() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -530,7 +530,6 @@ define(function (require, exports, module) { | |
*/ | ||
function findMatchingRules(selector, htmlDocument) { | ||
var result = new $.Deferred(), | ||
cssFilesResult = FileIndexManager.getFileInfoList("css"), | ||
resultSelectors = []; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 to @gruehle |
||
|
||
// Synchronously search for matches in <style> blocks | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1061,7 +1061,7 @@ define(function (require, exports, module) { | |
CSSUtils.findMatchingRules("#issue403") | ||
.done(function (result) { rules = result; }); | ||
}); | ||
waitsFor(function () { return rules !== null; }, "CSSUtils.findMatchingRules() timeout", 1000); | ||
waitsFor(function () { return rules !== undefined; }, "CSSUtils.findMatchingRules() timeout", 1000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey, while you're in this file -- it looks like there's an indentation error on line 1084 (JSLint flagged it). Mind fixing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops fixed. I had to use sublime while i was fixing the async issues. :) |
||
|
||
runs(function () { | ||
expect(rules.length).toBe(1); | ||
|
@@ -1081,7 +1081,7 @@ define(function (require, exports, module) { | |
ProjectManager, | ||
brackets; | ||
|
||
beforeEach(function () { | ||
beforeEach(function () { | ||
SpecRunnerUtils.createTestWindowAndRun(this, function (testWindow) { | ||
// Load module instances from brackets.test | ||
brackets = testWindow.brackets; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good to add a comment here noting that
addToWorkingSet()
is synchronous. (On my copy of the fix I also added "Completes synchronously." to the docs onaddToWorkingSet()
itself since it differs from what feels like the norm for DocumentManager APIs).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed and fixed