kopia lustrzana https://github.com/c9/core
107 wiersze
4.0 KiB
JavaScript
107 wiersze
4.0 KiB
JavaScript
(function(mod) {
|
|
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
return mod(require("../lib/infer"), require("../lib/tern"), require("acorn/dist/walk"), require("./modules"))
|
|
if (typeof define == "function" && define.amd) // AMD
|
|
return define(["../lib/infer", "../lib/tern", "acorn/dist/walk", "./modules"], mod)
|
|
mod(tern, tern, acorn.walk)
|
|
})(function(infer, tern, walk) {
|
|
"use strict"
|
|
|
|
var WG_IMPORT_DEFAULT_FALLBACK = 80
|
|
|
|
function connectModule(file, out) {
|
|
var modules = infer.cx().parent.mod.modules
|
|
var outObj = null
|
|
function exp(prop, type, originNode) {
|
|
if (!outObj) {
|
|
outObj = new infer.Obj(true)
|
|
outObj.origin = file.name
|
|
outObj.originNode = file.ast
|
|
out.addType(outObj)
|
|
}
|
|
type.propagate(outObj.defProp(prop, originNode))
|
|
}
|
|
|
|
walk.simple(file.ast, {
|
|
ImportDeclaration: function(node) {
|
|
var input = modules.resolveModule(node.source.value, file.name)
|
|
for (var i = 0; i < node.specifiers.length; i++) {
|
|
var spec = node.specifiers[i]
|
|
var aval = file.scope.getProp(spec.local.name)
|
|
if (spec.type == "ImportNamespaceSpecifier") {
|
|
input.propagate(aval)
|
|
} else if (spec.type == "ImportDefaultSpecifier") {
|
|
input.getProp("default").propagate(aval)
|
|
input.propagate(aval, WG_IMPORT_DEFAULT_FALLBACK)
|
|
} else {
|
|
input.getProp(spec.imported.name).propagate(aval)
|
|
}
|
|
}
|
|
},
|
|
ExportAllDeclaration: function(node) {
|
|
var input = modules.resolveModule(node.source.value, file.name)
|
|
input.forAllProps(function(prop, val, local) {
|
|
if (local) exp(prop, val, val.originNode)
|
|
})
|
|
},
|
|
ExportDefaultDeclaration: function(node) {
|
|
var decl = node.declaration.id || node.declaration
|
|
exp("default", infer.expressionType({node: decl, state: file.scope}), decl)
|
|
},
|
|
ExportNamedDeclaration: function(node) {
|
|
var decl = node.declaration
|
|
if (decl) {
|
|
if (decl.type == "VariableDeclaration") {
|
|
for (var i = 0; i < decl.declarations.length; ++i) {
|
|
var cur = decl.declarations[i]
|
|
if (cur.id.type == "Identifier")
|
|
exp(cur.id.name, file.scope.getProp(cur.id.name), cur.id)
|
|
}
|
|
} else {
|
|
exp(decl.id.name, file.scope.getProp(decl.id.name), decl.id)
|
|
}
|
|
}
|
|
if (node.specifiers.length) {
|
|
var src = node.source ? modules.resolveModule(node.source.value, file.name) : file.scope
|
|
for (var i = 0; i < node.specifiers.length; i++) {
|
|
var spec = node.specifiers[i]
|
|
exp(spec.exported.name, src.getProp(spec.local.name), spec.local)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
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) {
|
|
return node.type == "ImportDeclaration" || /Export(All|Named)Declaration/.test(node.type)
|
|
})
|
|
if (!decl || decl.node.source != node) return
|
|
return node.value
|
|
}
|
|
|
|
function isImport(node) {
|
|
if (node.type != "Identifier") return
|
|
var imp = infer.findExpressionAround(node.sourceFile.ast, null, node.end, null, "ImportDeclaration")
|
|
if (!imp) return
|
|
var specs = imp.node.specifiers
|
|
for (var i = 0; i < specs.length; i++) {
|
|
var spec = specs[i]
|
|
if (spec.local != node) continue
|
|
var result = {name: imp.node.source.value, prop: null}
|
|
if (spec.type == "ImportDefaultSpecifier") result.prop = "default"
|
|
else if (spec.type == "ImportSpecifier") result.prop = spec.imported.name
|
|
return result
|
|
}
|
|
}
|
|
|
|
tern.registerPlugin("es_modules", function(server) {
|
|
server.loadPlugin("modules")
|
|
server.mod.modules.on("getExports", connectModule)
|
|
server.mod.modules.modNameTests.push(isModuleName)
|
|
server.mod.modules.importTests.push(isImport)
|
|
})
|
|
})
|