Skip to content

Commit

Permalink
Reuse initializeScopes
Browse files Browse the repository at this point in the history
  • Loading branch information
sosukesuzuki committed Feb 13, 2021
1 parent 8fb5520 commit 96c07c5
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 36 deletions.
5 changes: 4 additions & 1 deletion packages/babel-parser/src/parser/expression.js
Expand Up @@ -2657,7 +2657,10 @@ export default class ExpressionParser extends LValParser {
const node = this.startNode<N.ModuleExpression>();
this.next(); // eat "module"
this.expect(tt.braceL);
const revertScopes = this.initializeScopes();

const revertScopes = this.initializeScopes(/** inModule */ true);
this.enterInitialScopes();

const program = this.startNode<N.Program>();
try {
node.body = this.parseProgram(program, tt.braceR, "module");
Expand Down
22 changes: 2 additions & 20 deletions packages/babel-parser/src/parser/index.js
Expand Up @@ -5,14 +5,7 @@ import type { File /*::, JSXOpeningElement */ } from "../types";
import type { PluginList } from "../plugin-utils";
import { getOptions } from "../options";
import StatementParser from "./statement";
import { SCOPE_PROGRAM } from "../util/scopeflags";
import ScopeHandler from "../util/scope";
import ClassScopeHandler from "../util/class-scope";
import ExpressionScopeHandler from "../util/expression-scope";
import ProductionParameterHandler, {
PARAM_AWAIT,
PARAM,
} from "../util/production-parameter";

export type PluginsMap = Map<string, { [string]: any }>;

Expand All @@ -28,14 +21,8 @@ export default class Parser extends StatementParser {
options = getOptions(options);
super(options, input);

const ScopeHandler = this.getScopeHandler();

this.options = options;
this.inModule = this.options.sourceType === "module";
this.scope = new ScopeHandler(this.raise.bind(this), this.inModule);
this.prodParam = new ProductionParameterHandler();
this.classScope = new ClassScopeHandler(this.raise.bind(this));
this.expressionScope = new ExpressionScopeHandler(this.raise.bind(this));
this.initializeScopes();
this.plugins = pluginsMap(this.options.plugins);
this.filename = options.sourceFilename;
}
Expand All @@ -46,12 +33,7 @@ export default class Parser extends StatementParser {
}

parse(): File {
let paramFlags = PARAM;
if (this.hasPlugin("topLevelAwait") && this.inModule) {
paramFlags |= PARAM_AWAIT;
}
this.scope.enter(SCOPE_PROGRAM);
this.prodParam.enter(paramFlags);
this.enterInitialScopes();
const file = this.startNode();
const program = this.startNode();
this.nextToken();
Expand Down
54 changes: 39 additions & 15 deletions packages/babel-parser/src/parser/util.js
Expand Up @@ -7,8 +7,12 @@ import type { Node } from "../types";
import { lineBreak } from "../util/whitespace";
import { isIdentifierChar } from "../util/identifier";
import ClassScopeHandler from "../util/class-scope";
import ExpressionScopeHandler from "../util/expression-scope";
import { SCOPE_PROGRAM } from "../util/scopeflags";
import { PARAM_AWAIT, PARAM } from "../util/production-parameter";
import ProductionParameterHandler, {
PARAM_AWAIT,
PARAM,
} from "../util/production-parameter";
import { Errors } from "./error";

type TryParse<Node, Error, Thrown, Aborted, FailState> = {
Expand Down Expand Up @@ -308,33 +312,53 @@ export default class UtilParser extends Tokenizer {
return node.type === "ObjectMethod";
}

initializeScopes() {
initializeScopes(inModule: boolean = this.options.sourceType === "module") {
// Initialize state
const oldLabels = this.state.labels;
this.state.labels = [];

const oldExportedIdentifiers = this.state.exportedIdentifiers;
this.state.exportedIdentifiers = [];
this.scope.enter(SCOPE_PROGRAM);
const oldUndefinedExports = this.scope.undefinedExports;
this.scope.undefinedExports = new Map();
let paramFlags = PARAM;
if (this.hasPlugin("topLevelAwait")) {
paramFlags |= PARAM_AWAIT;
}
this.prodParam.enter(paramFlags);

// initialize scopes
const oldInModule = this.inModule;
this.inModule = true;
this.inModule = inModule;

const oldScope = this.scope;
const ScopeHandler = this.getScopeHandler();
this.scope = new ScopeHandler(this.raise.bind(this), this.inModule);

const oldProdParam = this.prodParam;
this.prodParam = new ProductionParameterHandler();

const oldClassScope = this.classScope;
this.classScope = new ClassScopeHandler(this.raise.bind(this));

const oldExpressionScope = this.expressionScope;
this.expressionScope = new ExpressionScopeHandler(this.raise.bind(this));

return () => {
this.scope.exit();
this.scope.undefinedExports = oldUndefinedExports;
this.prodParam.exit();
this.inModule = oldInModule;
// Revert state
this.state.labels = oldLabels;
this.state.exportedIdentifiers = oldExportedIdentifiers;

// Revert scopes
this.inModule = oldInModule;
this.scope = oldScope;
this.prodParam = oldProdParam;
this.classScope = oldClassScope;
this.expressionScope = oldExpressionScope;
};
}

enterInitialScopes() {
let paramFlags = PARAM;
if (this.hasPlugin("topLevelAwait") && this.inModule) {
paramFlags |= PARAM_AWAIT;
}
this.scope.enter(SCOPE_PROGRAM);
this.prodParam.enter(paramFlags);
}
}

/**
Expand Down

0 comments on commit 96c07c5

Please sign in to comment.