From 0a8c3567b2e52c3c3369cfd8e22e4bb94640bc4f Mon Sep 17 00:00:00 2001 From: Troy Tao Date: Thu, 21 Apr 2016 15:48:01 -0400 Subject: [PATCH] Bug 491512 - [acorn] Investigate pre-resolving paths to dependency literals Resolve module paths in orionAcron.js; attach the result to AST node.resolved; remove the resolver.js part in node.js and requirejs.js plugins; remove the fix for bug 481271 Change-Id: I805a5d8458cd42fb07b73e86331900eb5fe7c839 Signed-off-by: Troy Tao --- diff --git a/bundles/org.eclipse.orion.client.javascript/web/javascript/hover.js b/bundles/org.eclipse.orion.client.javascript/web/javascript/hover.js index f394cf4..e4658c6 100644 --- a/bundles/org.eclipse.orion.client.javascript/web/javascript/hover.js +++ b/bundles/org.eclipse.orion.client.javascript/web/javascript/hover.js @@ -20,7 +20,7 @@ 'orion/i18nUtil', 'doctrine/doctrine' ], function(Objects, Finder, URITemplate, Deferred, Messages, i18nUtil, doctrine) { - + /** * @description Formats the hover info as markdown text * @param {String} node The text to format diff --git a/bundles/org.eclipse.orion.client.javascript/web/javascript/orionAcorn.js b/bundles/org.eclipse.orion.client.javascript/web/javascript/orionAcorn.js index 295c0b6..3d8b50c 100644 --- a/bundles/org.eclipse.orion.client.javascript/web/javascript/orionAcorn.js +++ b/bundles/org.eclipse.orion.client.javascript/web/javascript/orionAcorn.js @@ -42,6 +42,9 @@ this.currentOptions = {}; }; + OrionAcorn.prototype.attachTernServer = function attachTernServer(ternServer){ + OrionAcorn.prototype.ternServer = ternServer; + }; /** * @name onToken * @description Function called when recording a token @@ -275,6 +278,87 @@ if(extra.deps && node.type === "Literal") { if (!extra.deps[node.value]) { extra.deps[node.value] = 1; + var resetPending = function(key) { + clearTimeout(that.pendingModules[key].timeout); + delete that.pendingModules[key].pending; + that.ternServer.finishAsyncAction("Read operation timed out."); + }; + if (extra.envs.node === true) { + if (that.ternServer){ + var sourceFile = node.sourceFile.name; + var folderLoc = sourceFile.slice(0, sourceFile.lastIndexOf("/")+1); + var nativeModulesWithNode = [ '_debug_agent','_debugger','_linklist','assert','buffer','child_process','console','constants','crypto','cluster','dgram','dns','domain','events','freelist','fs','http','_http_agent','_http_client','_http_common','_http_incoming','_http_outgoing','_http_server','https','module','net','os','path','process','punycode','querystring','readline','repl','stream','_stream_readable','_stream_writable','_stream_duplex','_stream_transform','_stream_passthrough','_stream_wrap','string_decoder','sys','timers','tls','_tls_common','_tls_legacy','_tls_wrap','tty','url','util','v8','vm','zlib','internal/child_process','internal/cluster','internal/freelist','internal/module','internal/socket_list','internal/repl','internal/util','internal/streams/lazy_transform']; + if (!/^[\.]+/.test(node.value) && nativeModulesWithNode.indexOf(node.value) === -1){ + var pacJsonLoc = folderLoc+"node_modules/"+node.value+"/package.json"; + that.ternServer.startAsyncAction(); + if (!that.pendingModules) that.pendingModules=[]; + var index = that.pendingModules.length; + that.pendingModules.push({ + pending: true, + timeout: setTimeout(resetPending, 4000, index) + }); + that.ternServer.options.getFile(pacJsonLoc, function(err, _file){ + clearTimeout(that.pendingModules[index].timeout); + delete that.pendingModules[index].pending; + if(!err){ + var val = JSON.parse(_file); + var mainPath = null; + var main = val.main; + if (main) { + if (!/(\.js)$/.test(main)) { + main += ".js"; + } + mainPath = folderLoc + "node_modules/" + node.value + "/" + main; + } else { + main = "index.js"; + mainPath = folderLoc + "node_modules/" + node.value + "/index.js"; + } + node.resolved = { + file: mainPath, + contents: null, + logical: node.value, + err: err + }; + that.ternServer.startAsyncAction(); + index = that.pendingModules.length; + that.pendingModules.push({ + pending: true, + timeout: setTimeout(resetPending, 4000, index) + }); + that.ternServer.options.getFile(mainPath, function(err, contents) { + clearTimeout(that.pendingModules[index].timeout); + node.resolved.contents = contents; + delete that.pendingModules[index].pending; + that.ternServer.finishAsyncAction(err); + }); + } + that.ternServer.finishAsyncAction(err); + }); + } + } + } else if (extra.envs.amd === true){ + if (that.ternServer){ + that.ternServer.startAsyncAction(); + if (!that.pendingModules) that.pendingModules=[]; + var index = that.pendingModules.length; + that.pendingModules.push({ + pending: true, + timeout: setTimeout(resetPending, 4000, index) + }); + var opts = {logical: node.value, file: node.sourceFile ? node.sourceFile.name : null}; + that.ternServer.options.getFile(opts, function(err, _file) { + clearTimeout(that.pendingModules[index].timeout); + node.resolved = { + file: _file.file, + contents: typeof _file.contents === 'string' ? _file.contents : '', + logical: _file.logical, + err: err + }; + delete that.pendingModules[index].pending; + that.ternServer.finishAsyncAction(err); + }); + } + } } } } @@ -433,6 +517,5 @@ ast.environments = this.environments; ast.errors = Util.serializeAstErrors(ast); }; - return OrionAcorn; }); diff --git a/bundles/org.eclipse.orion.client.javascript/web/javascript/plugins/javascriptPlugin.js b/bundles/org.eclipse.orion.client.javascript/web/javascript/plugins/javascriptPlugin.js index 0e2e926..5f5d6d4 100644 --- a/bundles/org.eclipse.orion.client.javascript/web/javascript/plugins/javascriptPlugin.js +++ b/bundles/org.eclipse.orion.client.javascript/web/javascript/plugins/javascriptPlugin.js @@ -233,100 +233,29 @@ if(typeof request.args.file === 'object') { var _l = request.args.file.logical; response.args.logical = _l; - if(request.args.file.node) { - // only load modules - if (!/^[\.]+/.test(_l)) { - //do node_modules read - var project = ternProjectManager.getProjectFile(); - if(project) { - fileClient.read(project+"node_modules/"+_l+"/package.json").then(function(json) { - if(json) { - var val = JSON.parse(json); - var mainPath = null; - var main = val.main; - if (main) { - if (!/(\.js)$/.test(main)) { - main += ".js"; - } - mainPath = project + "node_modules/" + _l + "/" + main; - } else { - main = "index.js"; - mainPath = project + "node_modules/" + _l + "/index.js"; - } - fileClient.read(mainPath).then(function(contents) { - response.args.contents = contents; - response.args.file = mainPath; - response.args.path = main; - ternWorker.postMessage(response); - }, - function(err) { - response.args.error = "Failed to read node_modules folder"; - response.args.message = err.toString(); - ternWorker.postMessage(response); - }); - } - }, - function(err) { - response.args.error = i18nUtil.formatMessage(javascriptMessages['failedToReadFile'], _l); - response.args.message = err.toString(); - ternWorker.postMessage(response); - }); - } else { - //don't search for now - response.args.error = i18nUtil.formatMessage(javascriptMessages['failedToReadFile'], _l); - ternWorker.postMessage(response); - } - } else { - // try to get the current folder from request.args.file.file - var currentFile = request.args.file.file; - if (currentFile) { - var lastIndex = currentFile.lastIndexOf('/'); - var filePath = currentFile.substring(0, lastIndex + 1) + _l; - if (!/(\.js)$/.test(_l)) { - filePath += ".js"; - } - fileClient.read(filePath).then(function(contents) { + scriptresolver.getWorkspaceFile(_l).then(function(files) { + if(files && files.length > 0) { + var rel = scriptresolver.resolveRelativeFiles(_l, files, {location: request.args.file.file, contentType: {name: 'JavaScript'}}); //$NON-NLS-1$ + if(rel && rel.length > 0) { + return fileClient.read(rel[0].location).then(function(contents) { response.args.contents = contents; - response.args.file = filePath; - response.args.path = _l; - ternWorker.postMessage(response); - }, - function(err) { - response.args.error = i18nUtil.formatMessage(javascriptMessages['failedToReadFile'], filePath); - response.args.message = err.toString(); + response.args.file = rel[0].location; + response.args.path = rel[0].path; ternWorker.postMessage(response); }); - } else { - // could be a require('./....'); inside a module code - response.args.error = i18nUtil.formatMessage(javascriptMessages['failedToReadFile'], _l); - ternWorker.postMessage(response); } - } - } else { - scriptresolver.getWorkspaceFile(_l).then(function(files) { - if(files && files.length > 0) { - var rel = scriptresolver.resolveRelativeFiles(_l, files, {location: request.args.file.file, contentType: {name: 'JavaScript'}}); //$NON-NLS-1$ - if(rel && rel.length > 0) { - return fileClient.read(rel[0].location).then(function(contents) { - response.args.contents = contents; - response.args.file = rel[0].location; - response.args.path = rel[0].path; - ternWorker.postMessage(response); - }); - } - response.args.error = i18nUtil.formatMessage(javascriptMessages['failedToReadFile'], _l); - ternWorker.postMessage(response); - } else { - response.args.error = i18nUtil.formatMessage(javascriptMessages['failedToReadFile'], _l); - ternWorker.postMessage(response); - } - }, - function(err) { response.args.error = i18nUtil.formatMessage(javascriptMessages['failedToReadFile'], _l); - response.args.message = err.toString(); ternWorker.postMessage(response); - }); - } + } else { + response.args.error = i18nUtil.formatMessage(javascriptMessages['failedToReadFile'], _l); + ternWorker.postMessage(response); + } + }, + function(err) { + response.args.error = i18nUtil.formatMessage(javascriptMessages['failedToReadFile'], _l); + response.args.message = err.toString(); + ternWorker.postMessage(response); + }); } else { var file = request.args.file; response.args.file = file; diff --git a/bundles/org.eclipse.orion.client.javascript/web/javascript/ternPlugins/ast.js b/bundles/org.eclipse.orion.client.javascript/web/javascript/ternPlugins/ast.js index 24d740f..e174b33 100644 --- a/bundles/org.eclipse.orion.client.javascript/web/javascript/ternPlugins/ast.js +++ b/bundles/org.eclipse.orion.client.javascript/web/javascript/ternPlugins/ast.js @@ -22,6 +22,7 @@ orionAcorn.initialize(); }); + orionAcorn.attachTernServer(server); return { passes: { /** diff --git a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/node.js b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/node.js index 214a62b..a39e30c 100644 --- a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/node.js +++ b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/node.js @@ -108,7 +108,7 @@ result = data.modules[name] = scope.exports; } } else { - var _f = resolver.getResolved(name); //ORION + var _f = argNodes[0].resolved; //ORION var modName = name; if(_f && _f.file) { name = _f.file; @@ -238,25 +238,8 @@ passes: {preCondenseReach: preCondenseReach, postLoadDef: postLoadDef, completion: findCompletions, - typeAt: findTypeAt, - /** - * @callback - * Orion - */ - postParse: function postParse(ast, text) { - if(ast && ast.environments && ast.environments.node) { - resolver.doPostParse(server, ast, infer.cx().definitions, null, {node:true}); - } - }, - /** - * @callback - * Orion - */ - preInfer: function preInfer(ast, scope) { - if(ast && ast.environments && ast.environments.node) { - resolver.doPreInfer(server); - } - }}}; + typeAt: findTypeAt + }}; }); // Completes CommonJS module names in strings passed to require diff --git a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/requirejs.js b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/requirejs.js index cb9e81d..88dae30 100644 --- a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/requirejs.js +++ b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/requirejs.js @@ -4,9 +4,9 @@ if (typeof exports == "object" && typeof module == "object") // CommonJS return mod(require("../lib/infer"), require("../lib/tern")); if (typeof define == "function" && define.amd) // AMD - return define(["../lib/infer", "../lib/tern", "javascript/ternPlugins/resolver"], mod); + return define(["../lib/infer", "../lib/tern"], mod); mod(tern, tern); -})(function(infer, tern, resolver) { +})(function(infer, tern) { "use strict"; //ORION @@ -57,7 +57,7 @@ return _exports; } - function getInterface(name, data) { + function getInterface(name, data, resolved) { if (data.options.override && Object.prototype.hasOwnProperty.call(data.options.override, name)) { var over = data.options.override[name]; if (typeof over === "string" && over.charAt(0) === "=") return infer.def.parsePath(over.slice(1)); @@ -70,25 +70,25 @@ } name = over; } - known = getModule(name, data); + known = getModule(name, data, resolved); if (known) { data.server.addFile(known.origin, known.contents, data.currentFile); } return known; } - function getKnownModule(name, data) { - var val = resolver.getResolved(name); //ORION + function getKnownModule(name, data, resolved) { + var val = resolved; //ORION if(val && val.file) { return data.interfaces[stripJSExt(val.file)]; } return null; } - function getModule(name, data) { - var known = getKnownModule(name, data); + function getModule(name, data, resolved) { + var known = getKnownModule(name, data, resolved); if (!known) { - var val = resolver.getResolved(name); //ORION + var val = resolved; //ORION if(val && val.file) { known = data.interfaces[stripJSExt(val.file)] = new infer.AVal(); known.origin = val.file; @@ -113,11 +113,11 @@ var deps = [], fn, _exports, mod; - function interf(name) { + function interf(name, resolved) { if (name == "require") return getRequire(data); if (name == "exports") return _exports || (_exports = getExports(data)); if (name == "module") return mod || (mod = getModuleInterface(data, _exports || (_exports = getExports(data)))); - return getInterface(name, data); + return getInterface(name, data, resolved); } if (argNodes && args.length > 1) { @@ -127,7 +127,7 @@ } else if (node.type == "ArrayExpression") for (var i = 0; i < node.elements.length; ++i) { var elt = node.elements[i]; if (elt.type == "Literal" && typeof elt.value == "string") { - addInterfaceDep(interf(elt.value), deps); //ORION + addInterfaceDep(interf(elt.value, elt.resolved), deps); //ORION } } } else if (argNodes && args.length == 1 && argNodes[0].type == "FunctionExpression" && argNodes[0].params.length) { @@ -223,21 +223,7 @@ passes: { preCondenseReach: preCondenseReach, postLoadDef: postLoadDef, - typeAt: findTypeAt, - /** - * @callback - * Orion - */ - postParse: function postParse(ast, text) { - resolver.doPostParse(server, ast, infer.cx().definitions); - }, - /** - * @callback - * Orion - */ - preInfer: function preInfer(ast, scope) { - resolver.doPreInfer(server); - } + typeAt: findTypeAt } }; });