switch scope tracking to a path based system
This commit is contained in:
parent
3cd110a7c9
commit
9cff51915d
@ -1,6 +1,7 @@
|
||||
import convertSourceMap from "convert-source-map";
|
||||
import shebangRegex from "shebang-regex";
|
||||
import isFunction from "lodash/lang/isFunction";
|
||||
import TraversalPath from "../traversal/path";
|
||||
import sourceMap from "source-map";
|
||||
import transform from "./index";
|
||||
import generate from "../generation";
|
||||
@ -375,7 +376,7 @@ export default class File {
|
||||
this.usedHelpers[name] = true;
|
||||
|
||||
var generator = this.get("helperGenerator");
|
||||
var runtime = this.get("helpersNamespace");
|
||||
var runtime = this.get("helpersNamespace");
|
||||
if (generator) {
|
||||
return generator(name);
|
||||
} else if (runtime) {
|
||||
@ -425,9 +426,11 @@ export default class File {
|
||||
transform(ast) {
|
||||
this.log.debug();
|
||||
|
||||
this.ast = ast;
|
||||
this.path = TraversalPath.get(null, null, ast, ast, "program", this);
|
||||
this.scope = this.path.scope;
|
||||
this.ast = ast;
|
||||
|
||||
this.lastStatements = t.getLastStatements(ast.program);
|
||||
this.scope = new Scope(ast.program, ast, null, this);
|
||||
|
||||
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
|
||||
if (modFormatter.init && this.transformers["es6.modules"].canRun()) {
|
||||
@ -481,14 +484,14 @@ export default class File {
|
||||
if (inputMap) {
|
||||
map.sources[0] = inputMap.file;
|
||||
|
||||
var inputMapConsumer = new sourceMap.SourceMapConsumer(inputMap);
|
||||
var outputMapConsumer = new sourceMap.SourceMapConsumer(map);
|
||||
var inputMapConsumer = new sourceMap.SourceMapConsumer(inputMap);
|
||||
var outputMapConsumer = new sourceMap.SourceMapConsumer(map);
|
||||
var outputMapGenerator = sourceMap.SourceMapGenerator.fromSourceMap(outputMapConsumer);
|
||||
outputMapGenerator.applySourceMap(inputMapConsumer);
|
||||
|
||||
var mergedMap = outputMapGenerator.toJSON();
|
||||
mergedMap.sources = inputMap.sources
|
||||
mergedMap.file = inputMap.file;
|
||||
mergedMap.file = inputMap.file;
|
||||
return mergedMap;
|
||||
}
|
||||
|
||||
|
||||
@ -29,9 +29,6 @@ export function ForOfStatement(node, parent, scope, file) {
|
||||
|
||||
t.inherits(loop, node);
|
||||
|
||||
// todo: find out why this is necessary? #538
|
||||
loop._scopeInfo = node._scopeInfo;
|
||||
|
||||
if (build.replaceParent) {
|
||||
this.parentPath.node = build.node;
|
||||
} else {
|
||||
|
||||
@ -10,7 +10,7 @@ export default class TraversalPath {
|
||||
this.data = {};
|
||||
}
|
||||
|
||||
static get(parentPath, context, parent, container, key) {
|
||||
static get(parentPath: TraversalPath, context?: TraversalContext, parent, container, key, file?: File) {
|
||||
var targetNode = container[key];
|
||||
var paths = container._paths ||= [];
|
||||
var path;
|
||||
@ -28,17 +28,17 @@ export default class TraversalPath {
|
||||
paths.push(path);
|
||||
}
|
||||
|
||||
path.setContext(parentPath, context, key);
|
||||
path.setContext(parentPath, context, key, file);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static getScope(node, parent, scope) {
|
||||
static getScope(path: TraversalPath, scope: Scope, file?: File) {
|
||||
var ourScope = scope;
|
||||
|
||||
// we're entering a new scope so let's construct it!
|
||||
if (t.isScope(node, parent)) {
|
||||
ourScope = new Scope(node, parent, scope);
|
||||
if (path.isScope()) {
|
||||
ourScope = new Scope(path, scope, file);
|
||||
}
|
||||
|
||||
return ourScope;
|
||||
@ -60,21 +60,24 @@ export default class TraversalPath {
|
||||
return this.data[key];
|
||||
}
|
||||
|
||||
setScope() {
|
||||
this.scope = TraversalPath.getScope(this.node, this.parent, this.context.scope);
|
||||
setScope(file?) {
|
||||
this.scope = TraversalPath.getScope(this, this.context && this.context.scope, file);
|
||||
}
|
||||
|
||||
setContext(parentPath, context, key) {
|
||||
setContext(parentPath, context, key, file?) {
|
||||
this.shouldSkip = false;
|
||||
this.shouldStop = false;
|
||||
|
||||
this.parentPath = parentPath || this.parentPath;
|
||||
this.context = context;
|
||||
this.state = context.state;
|
||||
this.opts = context.opts;
|
||||
this.key = key;
|
||||
|
||||
this.setScope();
|
||||
if (context) {
|
||||
this.context = context;
|
||||
this.state = context.state;
|
||||
this.opts = context.opts;
|
||||
}
|
||||
|
||||
this.setScope(file);
|
||||
}
|
||||
|
||||
remove() {
|
||||
@ -200,6 +203,10 @@ export default class TraversalPath {
|
||||
return TraversalPath.get(this, this.context, this.node, this.node, key);
|
||||
}
|
||||
|
||||
isScope() {
|
||||
return t.isScope(this.node, this.parent);
|
||||
}
|
||||
|
||||
isReferencedIdentifier(opts) {
|
||||
return t.isReferencedIdentifier(this.node, this.parent, opts);
|
||||
}
|
||||
|
||||
@ -65,12 +65,20 @@ export default class Scope {
|
||||
* within.
|
||||
*/
|
||||
|
||||
constructor(block: Object, parentBlock: Object, parent?: Scope, file?: File) {
|
||||
constructor(path: TraversalPath, parent?: Scope, file?: File) {
|
||||
var cached = path.getData("scope");
|
||||
if (cached) {
|
||||
return cached;
|
||||
} else {
|
||||
path.setData("scope", this);
|
||||
}
|
||||
|
||||
this.parent = parent;
|
||||
this.file = parent ? parent.file : file;
|
||||
|
||||
this.parentBlock = parentBlock;
|
||||
this.block = block;
|
||||
this.parentBlock = path.parent;
|
||||
this.block = path.node;
|
||||
this.path = path;
|
||||
|
||||
this.crawl();
|
||||
}
|
||||
@ -472,7 +480,7 @@ export default class Scope {
|
||||
*/
|
||||
|
||||
recrawl() {
|
||||
this.block._scopeInfo = null;
|
||||
this.path.setData("scopeInfo", null);
|
||||
this.crawl();
|
||||
}
|
||||
|
||||
@ -481,21 +489,21 @@ export default class Scope {
|
||||
*/
|
||||
|
||||
crawl() {
|
||||
var block = this.block;
|
||||
var block = this.block;
|
||||
var i;
|
||||
|
||||
//
|
||||
|
||||
var info = block._scopeInfo;
|
||||
var info = this.path.getData("scopeInfo");
|
||||
if (info) {
|
||||
extend(this, info);
|
||||
return;
|
||||
}
|
||||
|
||||
info = block._scopeInfo = {
|
||||
info = this.path.setData("scopeInfo", {
|
||||
bindings: object(),
|
||||
globals: object()
|
||||
};
|
||||
});
|
||||
|
||||
extend(this, info);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user