Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Commit

Permalink
Merge pull request #8155 from adobe/randy/update-tern
Browse files Browse the repository at this point in the history
JS Code Hints Crash Preventer
  • Loading branch information
dangoor committed Jun 19, 2014
2 parents c6c6ccf + 51939a5 commit 0d3603e
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 97 deletions.
3 changes: 2 additions & 1 deletion src/extensions/default/JavaScriptCodeHints/ScopeManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,8 @@ define(function (require, exports, module) {
type : MessageIds.TERN_INIT_MSG,
dir : dir,
files : files,
env : ternEnvironment
env : ternEnvironment,
timeout : PreferencesManager.get("jscodehints.inferenceTimeout")
};

if (config.debug) {
Expand Down
5 changes: 4 additions & 1 deletion src/extensions/default/JavaScriptCodeHints/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ define(function (require, exports, module) {
ignoreChange; // can ignore next "change" event if true;

// Define the defaultExclusions which are files that are known to cause Tern to run out of control.
PreferencesManager.definePreference("jscodehints.defaultExclusions", "array", ["ionic*.min.js"]);
PreferencesManager.definePreference("jscodehints.defaultExclusions", "array", []);

// This preference controls when Tern will time out when trying to understand files
PreferencesManager.definePreference("jscodehints.inferenceTimeout", "number", 5000);

/**
* Sets the configuration, generally for testing/debugging use.
Expand Down
216 changes: 126 additions & 90 deletions src/extensions/default/JavaScriptCodeHints/tern-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ var config = {};
Tern = tern;
Infer = infer;

var ternServer = null;
var ternServer = null,
inferenceTimeout;

// Save the tern callbacks for when we get the contents of the file
var fileCallBacks = {};
Expand All @@ -63,6 +64,28 @@ var config = {};
});
}

/**
* Send a log message back from the worker to the main thread
* @private
* @param {string} msg - the log message
*/
function _log(msg) {
self.postMessage({log: msg });
}

/**
* Report exception
* @private
* @param {Error} e - the error object
*/
function _reportError(e, file) {
if (e instanceof Infer.TimedOut) {
_log("Timeout during Tern processing of " + file);
} else {
_log("Error thrown in tern_worker:" + e.message + "\n" + e.stack);
}
}

/**
* Handle a response from the main thread providing the contents of a file
* @param {string} file - the name of the file
Expand All @@ -71,7 +94,11 @@ var config = {};
function handleGetFile(file, text) {
var next = fileCallBacks[file];
if (next) {
next(null, text);
try {
next(null, text);
} catch (e) {
_reportError(e, file);
}
}
delete fileCallBacks[file];
}
Expand Down Expand Up @@ -154,23 +181,14 @@ var config = {};
query.expandWordForward = false;
query.lineCharPositions = true;

var request = {query: query, files: [], offset: offset};
var request = {query: query, files: [], offset: offset, timeout: inferenceTimeout};
if (fileInfo.type !== MessageIds.TERN_FILE_INFO_TYPE_EMPTY) {
request.files.push(fileInfo);
}

return request;
}

/**
* Send a log message back from the worker to the main thread
*
* @param {string} msg - the log message
*/
function _log(msg) {
self.postMessage({log: msg });
}

/**
* Get definition location
* @param {{type: string, name: string, offsetLines: number, text: string}} fileInfo
Expand All @@ -184,35 +202,40 @@ var config = {};
function getJumptoDef(fileInfo, offset) {
var request = buildRequest(fileInfo, "definition", offset);
// request.query.typeOnly = true; // FIXME: tern doesn't work exactly right yet.
ternServer.request(request, function (error, data) {
if (error) {
_log("Error returned from Tern 'definition' request: " + error);
self.postMessage({type: MessageIds.TERN_JUMPTODEF_MSG, file: fileInfo.name, offset: offset});
return;
}
var isFunc = false,
response = {type: MessageIds.TERN_JUMPTODEF_MSG,
file: fileInfo.name,
resultFile: data.file,
offset: offset,
start: data.start,
end: data.end
};

request = buildRequest(fileInfo, "type", offset);
// See if we can tell if the reference is to a Function type

try {
ternServer.request(request, function (error, data) {
if (!error) {
response.isFunction = data.type.length > 2 && data.type.substring(0, 2) === "fn";
if (error) {
_log("Error returned from Tern 'definition' request: " + error);
self.postMessage({type: MessageIds.TERN_JUMPTODEF_MSG, file: fileInfo.name, offset: offset});
return;
}

// Post a message back to the main thread with the definition
self.postMessage(response);
});
var isFunc = false,
response = {type: MessageIds.TERN_JUMPTODEF_MSG,
file: fileInfo.name,
resultFile: data.file,
offset: offset,
start: data.start,
end: data.end
};

request = buildRequest(fileInfo, "type", offset);
// See if we can tell if the reference is to a Function type
ternServer.request(request, function (error, data) {
if (!error) {
response.isFunction = data.type.length > 2 && data.type.substring(0, 2) === "fn";
}

});
// Post a message back to the main thread with the definition
self.postMessage(response);
});

});
} catch (e) {
_reportError(e, fileInfo.name);
}
}

/**
* Get all the known properties for guessing.
*
Expand All @@ -230,25 +253,29 @@ var config = {};
var request = buildRequest(fileInfo, "properties", offset),
i;
//_log("tern properties: request " + request.type + dir + " " + file);
ternServer.request(request, function (error, data) {
var properties = [];
if (error) {
_log("Error returned from Tern 'properties' request: " + error);
} else {
//_log("tern properties: completions = " + data.completions.length);
for (i = 0; i < data.completions.length; ++i) {
var property = data.completions[i];
properties.push({value: property, type: property.type, guess: true});
try {
ternServer.request(request, function (error, data) {
var properties = [];
if (error) {
_log("Error returned from Tern 'properties' request: " + error);
} else {
//_log("tern properties: completions = " + data.completions.length);
for (i = 0; i < data.completions.length; ++i) {
var property = data.completions[i];
properties.push({value: property, type: property.type, guess: true});
}
}
}

// Post a message back to the main thread with the completions
self.postMessage({type: type,
file: fileInfo.name,
offset: offset,
properties: properties
});
});

// Post a message back to the main thread with the completions
self.postMessage({type: type,
file: fileInfo.name,
offset: offset,
properties: properties
});
});
} catch (e) {
_reportError(e, fileInfo.name);
}
}

/**
Expand All @@ -270,31 +297,35 @@ var config = {};
i;

//_log("request " + dir + " " + file + " " + offset /*+ " " + text */);
ternServer.request(request, function (error, data) {
var completions = [];
if (error) {
_log("Error returned from Tern 'completions' request: " + error);
} else {
//_log("found " + data.completions.length + " for " + file + "@" + offset);
for (i = 0; i < data.completions.length; ++i) {
var completion = data.completions[i];
completions.push({value: completion.name, type: completion.type, depth: completion.depth,
guess: completion.guess, origin: completion.origin});
try {
ternServer.request(request, function (error, data) {
var completions = [];
if (error) {
_log("Error returned from Tern 'completions' request: " + error);
} else {
//_log("found " + data.completions.length + " for " + file + "@" + offset);
for (i = 0; i < data.completions.length; ++i) {
var completion = data.completions[i];
completions.push({value: completion.name, type: completion.type, depth: completion.depth,
guess: completion.guess, origin: completion.origin});
}
}
}

if (completions.length > 0 || !isProperty) {
// Post a message back to the main thread with the completions
self.postMessage({type: MessageIds.TERN_COMPLETIONS_MSG,
file: fileInfo.name,
offset: offset,
completions: completions
});
} else {
// if there are no completions, then get all the properties
getTernProperties(fileInfo, offset, MessageIds.TERN_COMPLETIONS_MSG);
}
});

if (completions.length > 0 || !isProperty) {
// Post a message back to the main thread with the completions
self.postMessage({type: MessageIds.TERN_COMPLETIONS_MSG,
file: fileInfo.name,
offset: offset,
completions: completions
});
} else {
// if there are no completions, then get all the properties
getTernProperties(fileInfo, offset, MessageIds.TERN_COMPLETIONS_MSG);
}
});
} catch (e) {
_reportError(e, fileInfo.name);
}
}

/**
Expand Down Expand Up @@ -512,8 +543,7 @@ var config = {};
}
});
} catch (e) {
error = e.message;
_log("Error thrown in tern_worker:" + error + "\n" + e.stack);
_reportError(e, fileInfo.name);
}

// Post a message back to the main thread with the completions
Expand Down Expand Up @@ -561,15 +591,19 @@ var config = {};
* @param {string} path - the path of the file
*/
function handlePrimePump(path) {
var fileInfo = createEmptyUpdate(path);
var request = buildRequest(fileInfo, "completions", {line: 0, ch: 0});

ternServer.request(request, function (error, data) {
// Post a message back to the main thread
self.postMessage({type: MessageIds.TERN_PRIME_PUMP_MSG,
path: path
});
});
var fileInfo = createEmptyUpdate(path),
request = buildRequest(fileInfo, "completions", {line: 0, ch: 0});

try {
ternServer.request(request, function (error, data) {
// Post a message back to the main thread
self.postMessage({type: MessageIds.TERN_PRIME_PUMP_MSG,
path: path
});
});
} catch (e) {
_reportError(e, path);
}
}

/**
Expand All @@ -594,6 +628,8 @@ var config = {};

var env = request.env,
files = request.files;
inferenceTimeout = request.timeout;

initTernServer(env, files);
} else if (type === MessageIds.TERN_COMPLETIONS_MSG) {
offset = request.offset;
Expand Down
Submodule acorn updated from b1623b to 443501
2 changes: 1 addition & 1 deletion src/extensions/default/JavaScriptCodeHints/thirdparty/tern
Submodule tern updated from c7df88 to ed952d
7 changes: 4 additions & 3 deletions src/extensions/default/JavaScriptCodeHints/unittests.js
Original file line number Diff line number Diff line change
Expand Up @@ -841,10 +841,11 @@ define(function (require, exports, module) {
});

it("should list matching property names", function () {
var start = { line: 12, ch: 10 };
var cursor1 = { line: 12, ch: 0 },
cursor2 = { line: 12, ch: 6 };

testDoc.replaceRange("param", start, start);
testEditor.setCursorPos(start);
testDoc.replaceRange("paramB", cursor1, cursor1);
testEditor.setCursorPos(cursor2);
var hintObj = expectHints(JSCodeHints.jsHintProvider);
runs(function () {
hintsPresentExact(hintObj, ["paramB1", "paramB2"]);
Expand Down

0 comments on commit 0d3603e

Please sign in to comment.