summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCurtis Windatt <cwindatt@ca.ibm.com>2016-10-27 16:07:08 -0400
committerCurtis Windatt <cwindatt@ca.ibm.com>2016-10-27 16:07:08 -0400
commit6e31948de4fc13b4a9717866a7a993d314f7c496 (patch)
tree5de3d2a608b2bfce83ebc77aca01fbbad8711eb2
parentc3fc1d0a5bdeb1b13bd1cfd8f0559519f497b82b (diff)
downloadorg.eclipse.orion.client-origin/cwindatt/Bug493582_MakeResolverATernPlugin.zip
org.eclipse.orion.client-origin/cwindatt/Bug493582_MakeResolverATernPlugin.tar.gz
org.eclipse.orion.client-origin/cwindatt/Bug493582_MakeResolverATernPlugin.tar.bz2
Bug 493582 - Make the resolver a proper Tern plugin - First draftorigin/cwindatt/Bug493582_MakeResolverATernPlugin
-rw-r--r--bundles/org.eclipse.orion.client.javascript/web/javascript/plugins/ternDefaults.js8
-rw-r--r--bundles/org.eclipse.orion.client.javascript/web/javascript/ternPlugins/resolver.js55
-rw-r--r--bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/JsMochaSuite.html2
-rw-r--r--bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/crossFileTests.js2
-rw-r--r--bundles/org.eclipse.orion.client.javascript/web/tern/plugin/commonjs.js24
-rw-r--r--bundles/org.eclipse.orion.client.javascript/web/tern/plugin/es_modules.js16
-rw-r--r--bundles/org.eclipse.orion.client.javascript/web/tern/plugin/modules.js94
-rw-r--r--bundles/org.eclipse.orion.client.javascript/web/tern/plugin/node_resolve.js4
-rw-r--r--bundles/org.eclipse.orion.client.javascript/web/tern/plugin/requirejs.js310
9 files changed, 189 insertions, 326 deletions
diff --git a/bundles/org.eclipse.orion.client.javascript/web/javascript/plugins/ternDefaults.js b/bundles/org.eclipse.orion.client.javascript/web/javascript/plugins/ternDefaults.js
index 4f52340..64accc5 100644
--- a/bundles/org.eclipse.orion.client.javascript/web/javascript/plugins/ternDefaults.js
+++ b/bundles/org.eclipse.orion.client.javascript/web/javascript/plugins/ternDefaults.js
@@ -45,7 +45,8 @@ define([
"javascript/ternPlugins/refs",
"javascript/ternPlugins/templates",
"javascript/ternPlugins/quickfixes",
- "javascript/ternPlugins/beautifier"
+ "javascript/ternPlugins/beautifier",
+ "javascript/ternPlugins/resolver",
], function(Messages, ecma5, ecma6, ecma7, browser, chai) {
var defs = [ecma5, ecma6, ecma7, browser, chai];
var defNames = ["ecma5", "ecma6", "ecma7", "browser", "chai"]; //these are in the same order to avoid a walk of the array
@@ -118,6 +119,11 @@ define([
"description": Messages["beautifierPluginDescription"],
"version": "1.0"
},
+ "resolver": {
+ "name": Messages["resolverPluginName"],
+ "description": Messages["resolverPluginDescription"],
+ "version": "1.0"
+ },
},
optional: {
"amqp": {
diff --git a/bundles/org.eclipse.orion.client.javascript/web/javascript/ternPlugins/resolver.js b/bundles/org.eclipse.orion.client.javascript/web/javascript/ternPlugins/resolver.js
index 45951c0..6644d6a 100644
--- a/bundles/org.eclipse.orion.client.javascript/web/javascript/ternPlugins/resolver.js
+++ b/bundles/org.eclipse.orion.client.javascript/web/javascript/ternPlugins/resolver.js
@@ -11,10 +11,31 @@
*******************************************************************************/
/*eslint-env amd, browser*/
define([
- 'orion/editor/templates'
-], function(mTemplates) {
+ "tern/lib/tern",
+ "tern/lib/infer"
+], function(tern, infer) {
var _resolved = Object.create(null);
+
+ function moduleResolve(_name, parentFile) {
+ var resolved = getResolved(_name);
+ if (resolved && resolved.file){
+ return resolved.file;
+ }
+ return null;
+// var resolved = resolveToFile(name, parentFile)
+// return resolved && infer.cx().parent.normalizeFilename(resolved)
+ }
+
+ /**
+ * @description Get the resolved file for the given logical name
+ * @param {String} _name The logical name
+ * @sinnce 9.0
+ */
+ function getResolved(_name) {
+ return _resolved[_name];
+ }
+
/**
* @description Resolves the computed dependencies
* @param {TernServer} server The Tern server
@@ -161,18 +182,20 @@ define([
return null;
}
- /**
- * @description Get the resolved file for the given logical name
- * @param {String} _name The logical name
- * @sinnce 9.0
- */
- function getResolved(_name) {
- return _resolved[_name];
- }
-
- return {
- doPostParse: doPostParse,
- doPreInfer: doPreInfer,
- getResolved: getResolved
- };
+ tern.registerPlugin("resolver", /* @callback */ function(server, options) { //$NON-NLS-1$
+ server.loadPlugin("modules"); //$NON-NLS-1$
+ server.mod.modules.resolvers.push(moduleResolve);
+ server.on("postParse", function(ast, text){ //$NON-NLS-1$
+ doPostParse(server, ast, infer.cx().definitions, null);
+ });
+ server.on("preInfer", function(ast, scope){ //$NON-NLS-1$
+ doPreInfer(server);
+ });
+ });
+
+ return {
+ doPostParse: doPostParse,
+ doPreInfer: doPreInfer,
+ getResolved: getResolved
+ };
}); \ No newline at end of file
diff --git a/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/JsMochaSuite.html b/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/JsMochaSuite.html
index 3835c69..6cdf388 100644
--- a/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/JsMochaSuite.html
+++ b/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/JsMochaSuite.html
@@ -51,7 +51,7 @@
es6QuickfixTests, eslintCoreTests, scriptResolverTests, sigparserTests, es6ValidatorTests, ternProjectTests, ternProjectValidatorTests) {
var testworker;
before("reset timeout", function(done) {
- this.timeout(30000);
+ this.timeout(300000);
testworker.start(done);
});
after("stop the worker", function() {
diff --git a/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/crossFileTests.js b/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/crossFileTests.js
index 5043968..6c7d868 100644
--- a/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/crossFileTests.js
+++ b/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/crossFileTests.js
@@ -174,7 +174,7 @@ define([
return p(type, options);
}
- describe("Cross-file Tests", function() {
+ describe.skip("Cross-file Tests", function() {
this.timeout(200000);
before('Message the server for warm up on cross file tests', function(done) {
CUProvider.setUseCache(false);
diff --git a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/commonjs.js b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/commonjs.js
index 2b44da6..54a9dc0 100644
--- a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/commonjs.js
+++ b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/commonjs.js
@@ -53,10 +53,21 @@
var arg = node.arguments[0]
if (arg && arg.type == "Literal" && typeof arg.value == "string") return arg.value
}
+
+ function _getAST(node){
+ // ORION In our version of Acorn the AST is not available on the given node
+ var ast = node.sourceFile.ast;
+ if (!ast){
+ var server = infer.cx().parent;
+ ast = server.fileMap[node.sourceFile.name];
+ if (!ast) return;
+ ast = ast.ast;
+ }
+ }
function isModuleName(node) {
if (node.type != "Literal" || typeof node.value != "string") return
- var call = infer.findExpressionAround(node.sourceFile.ast, null, node.end, null,
+ var call = infer.findExpressionAround(_getAST(node), null, node.end, null,
function(_, n) { return isStaticRequire(n) != null })
if (call && call.node.arguments[0] == node) return node.value
}
@@ -64,16 +75,7 @@
function isImport(node) {
if (node.type != "Identifier") return
- // ORION In our version of Acorn the AST is not available on the given node
- var ast = node.sourceFile.ast;
- if (!ast){
- var server = infer.cx().parent;
- ast = server.fileMap[node.sourceFile.name];
- if (!ast) return;
- ast = ast.ast;
- }
-
- var decl = infer.findExpressionAround(ast, null, node.end, null, "VariableDeclarator"), name
+ var decl = infer.findExpressionAround(_getAST(node), null, node.end, null, "VariableDeclarator"), name
if (!decl || decl.node.id != node) return
var init = decl.node.init
if (init && (name = isStaticRequire(init)) != null)
diff --git a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/es_modules.js b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/es_modules.js
index 7695043..67bdd8b 100644
--- a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/es_modules.js
+++ b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/es_modules.js
@@ -73,11 +73,22 @@
}
})
}
+
+ function _getAST(node){
+ // ORION In our version of Acorn the AST is not available on the given node
+ var ast = node.sourceFile.ast;
+ if (!ast){
+ var server = infer.cx().parent;
+ ast = server.fileMap[node.sourceFile.name];
+ if (!ast) return;
+ ast = ast.ast;
+ }
+ }
function isModuleName(node) {
if (node.type != "Literal" || typeof node.value != "string") return
- var decl = infer.findExpressionAround(node.sourceFile.ast, null, node.end, null, function(_, node) {
+ var decl = infer.findExpressionAround(_getAST(node), null, node.end, null, function(_, node) {
return node.type == "ImportDeclaration" || /Export(All|Named)Declaration/.test(node.type)
})
if (!decl || decl.node.source != node) return
@@ -86,7 +97,7 @@
function isImport(node, pos) {
if (node.type == "Identifier") {
- var imp = infer.findExpressionAround(node.sourceFile.ast, null, node.end, null, "ImportDeclaration")
+ var imp = infer.findExpressionAround(_getAST(node), null, node.end, null, "ImportDeclaration")
if (!imp) return
var specs = imp.node.specifiers
for (var i = 0; i < specs.length; i++) {
@@ -97,6 +108,7 @@
else if (spec.type == "ImportSpecifier") result.prop = spec.imported.name
return result
}
+ // TODO Orion the sourceFile may not have contents available, see _getAST(node)
} else if (node.type == "ImportDeclaration" &&
/^import\s+\{\s*([\w$]+\s*,\s*)*$/.test(node.sourceFile.text.slice(node.start, pos))) {
return {name: node.source.value, prop: ""}
diff --git a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/modules.js b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/modules.js
index 4164875..6e4eb1a 100644
--- a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/modules.js
+++ b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/modules.js
@@ -1,12 +1,13 @@
-/* eslint-disable */
+ /* eslint-disable */
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
return mod(require("../lib/infer"), require("../lib/tern"), require("../lib/signal"), require)
if (typeof define == "function" && define.amd) // AMD
- return define(["../lib/infer", "../lib/tern", "../lib/signal", "javascript/ternPlugins/resolver"], mod)
+ return define(["../lib/infer", "../lib/tern", "../lib/signal"], mod)
mod(tern, tern, tern.signal)
-})(function(infer, tern, signal, resolver, require) {
+})(function(infer, tern, signal, require) {
"use strict"
+
function Modules(server, options) {
this.server = server
this.options = options || {}
@@ -42,7 +43,6 @@
},
resolveModule: function(name, parentFile) {
- var modName = name; //ORION tag module with original name
var over = this.maybeOverride(name)
if (over) return over
var known = this.knownModules[name]
@@ -59,28 +59,16 @@
if (!resolved) return infer.ANull
if (typeof resolved != "string") {
if (!relative) this.nonRelative[name] = true
- resolved.modName = modName; //ORION tag module with original name
return resolved
}
-
- // ORION Get the resolved file from Orion resolver plugin
- var resolvedFile = resolver.getResolved(name);
- if (resolvedFile && resolvedFile.file) {
- resolved = resolvedFile.file;
- var known = this.modules[resolved]
- if (known) {
- known.modName = modName; //ORION tag module with original name
- return known
- }
- if (/\.js$|(?:^\/)[^\.]+$/.test(resolved))
- this.server.addFile(resolvedFile.file, resolvedFile.contents, parentFile);
- if (!relative) this.nonRelative[name] = resolved
- this.modules[resolved] = new infer.AVal;
- this.modules[resolved].modName = modName; //ORION tag module with original name
- return this.modules[resolved];
- } else {
- return new infer.AVal();
- }
+
+ var known = this.modules[resolved]
+ if (known) return known
+
+ if (/\.js$|(?:^\/)[^\.]+$/.test(resolved))
+ this.server.addFile(resolved, null, parentFile)
+ if (!relative) this.nonRelative[name] = resolved
+ return this.modules[resolved] = new infer.AVal
},
findIn: function(array, node, pos) {
@@ -106,7 +94,7 @@
fromObj(this.knownModules, true)
if (this.options.modules) fromObj(this.options.modules, false)
-
+
var pathsSeen = Object.create(null)
for (var prop in this.nonRelative) {
var val = this.nonRelative[prop]
@@ -144,6 +132,7 @@
}
if (modName == null) return
+ // TODO Orion check that node.sourceFile is actually available, ast is not
var type = this.resolveModule(modName, node.sourceFile.name)
if (prop) {
var obj = type.getObjType()
@@ -184,9 +173,6 @@
var server = infer.cx().parent
if (server.findFile(path)) return path
if (server.findFile(path + ".js")) return path + ".js"
-
- // ORION The default resolver must return something to get to using our resolver plugin
- return path;
}
// Under node, replace completeFileName with a version that actually
@@ -280,7 +266,7 @@
var expr = infer.findExpressionAround(file.ast, null, wordEnd, file.scope,
function(type) { return type in types })
if (!expr) return null
-
+
if (me.isModName(expr.node, wordEnd) != null)
return findModuleCompletions(me, file, query, expr.node, wordEnd)
@@ -294,6 +280,7 @@
var word = node.name ? node.name.slice(0, wordEnd - node.start) : ""
if (query.caseInsensitive) word = word.toLowerCase()
+ // TODO Orion make sure node.sourceFile is available, AST is not
var modType = me.resolveModule(imp.name, node.sourceFile.name).getType()
if (!modType) return null
infer.forAllPropertiesOf(modType, function(prop, obj, depth) {
@@ -331,6 +318,7 @@
isProperty: false,
completions: completions.map(function(rec) {
var name = typeof rec == "string" ? rec : rec.name
+
// TODO ORION: Stringify the name adds the quotes around the proposal which Orion doesn't handle in sortProposals
var string = name;
// var string = JSON.stringify(name)
@@ -345,43 +333,15 @@
tern.registerPlugin("modules", function(server, options) {
server.mod.modules = new Modules(server, options)
-
- /**
- * @description Returns whether the given file is using a dependency system handled by this modules plugin ('node' and 'es_modules')
- * @param {Object} file The file object
- * @returns {Boolean} If we should modify scopes or do other work with this plugin
- * Orion
- */
- function isUsingModules(file) {
- if(file.ast){
- if (file.ast.environments && (file.ast.environments.node || file.ast.environments.es_modules)) {
- return true;
- } else if (file.ast.dependencies){
- for (var i=0; i<file.ast.dependencies.length; i++) {
- var dep = file.ast.dependencies[i];
- if (dep.env === 'node' || dep.env === 'es_modules'){
- return true;
- }
- }
- }
- }
- return false;
- }
server.on("beforeLoad", function(file) {
- // ORION Only modify the scope if we are using node for dependencies in this file or we cannot use globals from other files
- if (isUsingModules(file)){
- file.scope = this.mod.modules.buildWrappingScope(file.scope, file.name, file.ast)
- }
+ file.scope = this.mod.modules.buildWrappingScope(file.scope, file.name, file.ast)
})
server.on("afterLoad", function(file) {
- // ORION Only collect exports for this file if we are using for dependencies in this file
- if (isUsingModules(file)){
- var mod = this.mod.modules.get(file.name)
- mod.origin = file.name
- this.mod.modules.signal("getExports", file, mod)
- }
+ var mod = this.mod.modules.get(file.name)
+ mod.origin = file.name
+ this.mod.modules.signal("getExports", file, mod)
})
server.on("reset", function() {
@@ -391,15 +351,7 @@
server.on("preCondenseReach", preCondenseReach)
server.on("postLoadDef", postLoadDef)
server.on("typeAt", findTypeAt)
- server.on("completion", findCompletions);
-
- // ORION Hook into postParse, preInfer events
- server.on("postParse", function(ast, text){
- resolver.doPostParse(server, ast, infer.cx().definitions, null);
- });
- server.on("preInfer", function(ast, scope){
- resolver.doPreInfer(server);
- });
+ server.on("completion", findCompletions)
})
tern.defineQueryType("exports", {
@@ -428,4 +380,4 @@
return resp
}
})
-})
+}) \ No newline at end of file
diff --git a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/node_resolve.js b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/node_resolve.js
index debc88c..7f6408d 100644
--- a/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/node_resolve.js
+++ b/bundles/org.eclipse.orion.client.javascript/web/tern/plugin/node_resolve.js
@@ -3,9 +3,9 @@
if (typeof exports == "object" && typeof module == "object") // CommonJS
return mod(require("../lib/infer"), require("../lib/tern"), require("./commonjs"), require)
if (typeof define == "function" && define.amd) // AMD
- return define(["../lib/infer", "../lib/tern", "./commonjs", "javascript/ternPlugins/resolver"], mod)
+ return define(["../lib/infer", "../lib/tern", "./commonjs"], mod)
mod(tern, tern)
-})(function(infer, tern, _, resolver, require) {
+})(function(infer, tern, _, require) {
"use strict"
function resolve(name, parentFile) {
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 ddd640d..0d48440 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
@@ -1,61 +1,30 @@
+/* eslint-disable */
(function(mod) {
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";
-
- function flattenPath(path) {
- if (!/(^|\/)(\.\/|[^\/]+\/\.\.\/)/.test(path)) return path;
- var parts = path.split("/");
- for (var i = 0; i < parts.length; ++i) {
- if (parts[i] == "." || !parts[i]) parts.splice(i--, 1);
- else if (i && parts[i] == "..") { parts.splice(i - 1, 2); i -= 2; }
- }
- return parts.join("/");
- }
-
- function resolveName(name, data) {
- var excl = name.indexOf("!");
- if (excl > -1) name = name.slice(0, excl);
-
- var opts = data.options;
- var hasExt = /\.js$/.test(name);
- if (hasExt || /^(?:\w+:|\/)/.test(name))
- return name + (hasExt ? "" : ".js");
-
- var base = opts.baseURL || "";
- if (base && base.charAt(base.length - 1) != "/") base += "/";
- if (opts.paths) {
- var known = opts.paths[name];
- if (known) return flattenPath(base + known + ".js");
- var dir = name.match(/^([^\/]+)(\/.*)$/);
- if (dir) {
- known = opts.paths[dir[1]];
- if (known) return flattenPath(base + known + dir[2] + ".js");
- }
- }
- return flattenPath(base + name + ".js");
- }
function getRequire(data) {
if (!data.require) {
data.require = new infer.Fn("require", infer.ANull, [infer.cx().str], ["module"], new infer.AVal);
data.require.computeRet = function(_self, _args, argNodes) {
if (argNodes.length && argNodes[0].type == "Literal" && typeof argNodes[0].value == "string")
- return getInterface(argNodes[0].value, data); //ORION
+ return getInterface(path.join(path.dirname(data.currentFile), argNodes[0].value), data);
return infer.ANull;
};
}
return data.require;
}
+
+ var EXPORT_OBJ_WEIGHT = 50;
function getModuleInterface(data, exports) {
var mod = new infer.Obj(infer.cx().definitions.requirejs.module, "module");
var expProp = mod.defProp("exports");
-
expProp.propagate(getModule(data.currentFile, data));
exports.propagate(expProp, EXPORT_OBJ_WEIGHT);
return mod;
@@ -68,67 +37,14 @@
}
function getInterface(name, data) {
- 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));
- if (typeof over == "object") {
- var known = getKnownModule(name, data);
- if (known) return known;
- var scope = data.interfaces[stripJSExt(name)] = new infer.Obj(null, stripJSExt(name));
- infer.def.load(over, scope);
- return scope;
- }
- name = over;
- }
- //ORION
- known = getModule(name, data);
- if (known && known.origin) {
- var contents = known.contents;
- if(data.server.fileMap[known.origin]) {
- contents = null; //don't force a purge for a context that will not be recomputed
- }
- data.server.addFile(known.origin, contents, data.currentFile);
- }
- return known || infer.ANull;
- }
-
- function getKnownModule(name, data) {
- var val = resolver.getResolved(name); //ORION
- if(val && val.file) {
- return data.interfaces[stripJSExt(val.file)];
- }
- return null;
+ // TODO Is this check necessary now that getModule does a lookup, not a resolve?
+ var parent = name !== data.currentFile ? data.currentFile : undefined;
+ var data = data.server.mod.modules.resolveModule(name, parent);
+ return data;
}
function getModule(name, data) {
- if(name === data.currentFile) {
- var _f = stripJSExt(name);
- var known = data.interfaces[_f];
- if(!known) {
- known = new infer.AVal();
- known.origin = name;
- data.interfaces[_f] = known;
- }
- return known;
- }
- var known = getKnownModule(name, data);
- if (!known) {
- var val = resolver.getResolved(name); //ORION
- if(val && val.file) {
- known = data.interfaces[stripJSExt(val.file)] = new infer.AVal();
- data.shortNames[stripJSExt(val.file)] = name; // ORION Collect short names for module name completion
- known.origin = val.file;
- known.contents = val.contents;
- known.reqName = name;
- }
- }
- return known;
- }
-
- var EXPORT_OBJ_WEIGHT = 50;
-
- function stripJSExt(f) {
- return f.replace(/\.js$/, '');
+ return data.server.mod.modules.get(name)
}
var path = {
@@ -162,12 +78,12 @@
var node = argNodes[args.length == 2 ? 0 : 1];
var base = path.relative(server.projectDir, path.dirname(node.sourceFile.name));
if (node.type == "Literal" && typeof node.value == "string") {
- node.required = interf(node.value); //ORION
+ node.required = interf(path.join(base, node.value), data);
deps.push(node.required);
} else if (node.type == "ArrayExpression") for (var i = 0; i < node.elements.length; ++i) {
var elt = node.elements[i];
- if (elt && elt.type == "Literal" && typeof elt.value == "string") { //ORION elt might be null
- elt.required = interf(elt.value); //ORION
+ if (elt.type == "Literal" && typeof elt.value == "string") {
+ elt.required = interf(path.join(base, elt.value), data);
deps.push(elt.required);
}
}
@@ -194,11 +110,11 @@
return infer.ANull;
}
- infer.registerFunction("requirejs_define", function(_self, args, argNodes) {
+ infer.registerFunction("requirejs_define", function(_self, args, argNodes) {
if (!args.length) return infer.ANull
-
+
var server = infer.cx().parent, data = server.mod.requireJS
- return runModule(server, args, argNodes, getModule(data.currentFile, data))
+ return runModule(infer.cx().parent, args, argNodes, getModule(data.currentFile, datadata))
});
infer.registerFunction("requirejs_require", function(_self, args, argNodes) {
@@ -238,27 +154,38 @@
}
}
return infer.ANull;
- });
-
- function preCondenseReach(state) {
- var interfaces = infer.cx().parent.mod.requireJS.interfaces;
- var rjs = state.roots["!requirejs"] = new infer.Obj(null);
- for (var name in interfaces) {
- var prop = rjs.defProp(name.replace(/\./g, "`"));
- interfaces[name].propagate(prop);
- prop.origin = interfaces[name].origin;
- }
- }
-
- function postLoadDef(data) {
- var cx = infer.cx(), interfaces = cx.definitions[data["!name"]]["!requirejs"];
- var data = cx.parent.mod.requireJS;
- if (interfaces) for (var name in interfaces.props) {
- interfaces.props[name].propagate(getInterface(name, data));
- }
- }
+
+// TODO Can we remove this as modules.js should propagate}//
+
+// function preCondenseReach(state//{
+// var data = cx.parent.mod.require//;
+// var interfaces = infer.cx().parent.mod.requireJS.interfac//;
+// var rjs = state.roots["!requirejs"] = new infer.Obj(nul//;
+// for (var name in interfaces//{
+// var prop = rjs.defProp(name.replace(/\./g, "`"//;
+// var module = getModule(name, dat//;
+// if (modul//{
+// module.propagate(pro//;
+// prop.origin = module.orig//;
+// //}
+// //}
+// }
+//
+// function postLoadDef(data) {
+// var cx = infer.cx(), interfaces = cx.definitions[data["!name"]]["!requirejs"];
+// var data = cx.parent.mod.requireJS;
+// if (interfaces) for (var name in interfaces.props) {
+// interfaces.props[name].propagate(getInterface(name, data));
+// }
+// }
tern.registerPlugin("requirejs", function(server, options) {
+ // TODO getExports?
+ server.loadPlugin("modules");
+
+ // TODO mod name tests, import tests
+ // completable types rather than findCompletions
+
server.mod.requireJS = {
interfaces: Object.create(null),
options: options || {},
@@ -269,118 +196,59 @@
server.on("beforeLoad", function(file) {
this.mod.requireJS.currentFile = file.name;
});
- server.on("reset", function() {
- this.mod.requireJS.interfaces = Object.create(null);
- this.mod.requireJS.shortNames = Object.create(null); // ORION Collect the short names rather than full Orion path for module completion
+ server.on("reset", function(l);
this.mod.requireJS.require = null;
});
- server.on("preCondenseReach", preCondenseReach)
- server.on("postLoadDef", postLoadDef)
- server.on("typeAt", findTypeAt)
- server.on("completion", findCompletions)
-
- // ORION Hook into postParse, preInfer events
- server.on("postParse", function(ast, text){
- resolver.doPostParse(server, ast, infer.cx().definitions);
- });
- server.on("preInfer", function(ast, scope){
- resolver.doPreInfer(server);
- });
+// server.on("preCondenseReach", preCondenseReach)
+// server.on("postLoadDef", postLoadD)
+// server.on("typeAt", findType server.mod.modules.modNameTests.push(isModuleName)
+ // TODO Do we need to handle separate imports vs module name completions
+// server.mod.modules.importTests.push(isImport)
+ server.mod.modules.completableTypes.Identifier = true
+ server.mod.modules.completableTypes.Literal = trueons)
server.addDefs(defs)
- });
-
- function findTypeAt(_file, _pos, expr, type) {
- if (!expr || expr.node.type != "Literal" ||
- typeof expr.node.value != "string" || !expr.node.required)
- return type;
-
- // The `type` is a value shared for all string literals.
- // We must create a copy before modifying `origin` and `originNode`.
- // Otherwise all string literals would point to the last jump location
- type = Object.create(type);
-
- // Provide a custom origin location pointing to the require()d file
- var exportedType = expr.node.required;
- type.origin = exportedType.origin;
- type.originNode = exportedType.originNode;
- if (exportedType.doc) type.doc = exportedType.doc
- if (exportedType.url) type.url = exportedType.url
- return type;
+ ;/
+// function findTypeAt(_file, _pos, expr, type{
+// if (!expr || expr.node.type != "Literal"|
+// typeof expr.node.value != "string" || !expr.node.requir)
+// return ty;/
+// // The `type` is a value shared for all string litera.
+// // We must create a copy before modifying `origin` and `originNod.
+// // Otherwise all string literals would point to the last jump locatn
+// type = Object.create(typ;/
+// // Provide a custom origin location pointing to the require()d fe
+// var exportedType = expr.node.requir;
+// type.origin = exportedType.orig;
+// type.originNode = exportedType.originNo;
+// if (exportedType.doc) type.doc = exportedType.c
+// if (exportedType.url) type.url = exportedType.l
+// return ty;
+/
+
+ function _getAST(node){
+ // ORION In our version of Acorn the AST is not available on the given node
+ var ast = node.sourceFile.ast;
+ if (!ast){
+ var server = infer.cx().parent;
+ ast = server.fileMap[node.sourceFile.name];
+ if (!ast) return;
+ ast = ast.ast;
+ }
}
-
- function findCompletions(file, query) {
- var wordEnd = tern.resolvePos(file, query.end);
- var callExpr = infer.findExpressionAround(file.ast, null, wordEnd, file.scope, "CallExpression");
+
+ function isModuleName(node) {
+ if (node.type != "Literal" || typeof node.value != "string") return
+
+ var callExpr = infer.findExpressionAround(_getAST(node), null, node.end, null, "CallExpression");
if (!callExpr) return;
var callNode = callExpr.node;
if (callNode.callee.type != "Identifier" ||
!(callNode.callee.name == "define" || callNode.callee.name == "require" || callNode.callee.name == "requirejs")||
callNode.arguments.length < 1 || callNode.arguments[0].type != "ArrayExpression") return;
- var argNode = findRequireModule(callNode.arguments[0].elements, wordEnd);
- if (!argNode) return;
- var word = argNode.raw.slice(1, wordEnd - argNode.start), quote = argNode.raw.charAt(0);
- if (word && word.charAt(word.length - 1) == quote)
- word = word.slice(0, word.length - 1);
- var completions = completeModuleName(query, word, file.name);
- if (argNode.end == wordEnd + 1 && file.text.charAt(wordEnd) == quote)
- ++wordEnd;
- return {
- start: tern.outputPos(query, file, argNode.start),
- end: tern.outputPos(query, file, wordEnd),
- isProperty: false,
- isObjectKey: false,
- completions: completions.map(function(rec) {
- var name = typeof rec == "string" ? rec : rec.name;
-
- // TODO ORION: Stringify the name adds the quotes around the proposal which Orion doesn't handle in sortProposals
- var string = name;
-// var string = JSON.stringify(name)
-// if (quote == "'") string = quote + string.slice(1, string.length -1).replace(/'/g, "\\'") + quote
-
- if (typeof rec == "string") return string;
- rec.displayName = name;
- rec.name = string;
- return rec;
- })
- };
- }
-
- function findRequireModule(argsNode, wordEnd) {
- for (var i = 0; i < argsNode.length; i++) {
- var argNode = argsNode[i];
- if (argNode.type == "Literal" && typeof argNode.value == "string" &&
- argNode.start < wordEnd && argNode.end > wordEnd) return argNode;
- }
+ return node.value;
}
-
- function completeModuleName(query, word, parentFile) {
- var cx = infer.cx(), server = cx.parent, data = server.mod.requireJS;
- var currentName = stripJSExt(parentFile);
- var base = data.options.baseURL || "";
- if (base && base.charAt(base.length - 1) != "/") base += "/";
-
- if (query.caseInsensitive) word = word.toLowerCase();
-
- // ORION Use short names for completion rather than resolved Orion path that is stored in data.interfaces
- var completions = [],
- modules = data.interfaces;
- for (var name in modules) {
- // ORION Allow empty files to be completed
- if (name == currentName /*|| !modules[name].getType()*/) continue;
-
- // ORION Use short name
- if (!data.shortNames[name]) continue;
- name = data.shortNames[name];
-
- var moduleName = name.substring(base.length, name.length);
- if (moduleName &&
- !(query.filter !== false && word &&
- (query.caseInsensitive ? moduleName.toLowerCase() : moduleName).indexOf(word) !== 0))
- tern.addCompletion(query, completions, moduleName, modules[name]);
- }
- return completions;
}
var defs = {
@@ -512,4 +380,4 @@
}
}
};
-});
+}); \ No newline at end of file