Skip to content

Commit

Permalink
Add isDeclareContext to state
Browse files Browse the repository at this point in the history
  • Loading branch information
sosukesuzuki committed Sep 18, 2020
1 parent a472fcd commit 3471de1
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 78 deletions.
2 changes: 0 additions & 2 deletions packages/babel-parser/src/parser/expression.js
Expand Up @@ -2101,8 +2101,6 @@ export default class ExpressionParser extends LValParser {
node: N.BodilessFunctionOrMethodBase,
type: string,
isMethod?: boolean = false,
// eslint-disable-next-line no-unused-vars -- this is used in /plugins/typescript
isDeclare?: boolean = false,
): void {
// $FlowIgnore (node is not bodiless if we get here)
this.parseFunctionBody(node, false, isMethod);
Expand Down
24 changes: 5 additions & 19 deletions packages/babel-parser/src/parser/statement.js
Expand Up @@ -144,22 +144,14 @@ export default class StatementParser extends ExpressionParser {
// https://tc39.es/ecma262/#prod-Statement
// ImportDeclaration and ExportDeclaration are also handled here so we can throw recoverable errors
// when they are not at the top level
parseStatement(
context: ?string,
topLevel?: boolean,
isDeclare?: boolean = false,
): N.Statement {
parseStatement(context: ?string, topLevel?: boolean): N.Statement {
if (this.match(tt.at)) {
this.parseDecorators(true);
}
return this.parseStatementContent(context, topLevel, isDeclare);
return this.parseStatementContent(context, topLevel);
}

parseStatementContent(
context: ?string,
topLevel: ?boolean,
isDeclare?: boolean = false,
): N.Statement {
parseStatementContent(context: ?string, topLevel: ?boolean): N.Statement {
let starttype = this.state.type;
const node = this.startNode();
let kind;
Expand Down Expand Up @@ -193,7 +185,7 @@ export default class StatementParser extends ExpressionParser {
this.raise(this.state.start, Errors.SloppyFunction);
}
}
return this.parseFunctionStatement(node, false, !context, isDeclare);
return this.parseFunctionStatement(node, false, !context);

case tt._class:
if (context) this.unexpected();
Expand Down Expand Up @@ -549,14 +541,12 @@ export default class StatementParser extends ExpressionParser {
node: N.FunctionDeclaration,
isAsync?: boolean,
declarationPosition?: boolean,
isDeclare?: boolean = false,
): N.FunctionDeclaration {
this.next();
return this.parseFunction(
node,
FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT),
isAsync,
isDeclare,
);
}

Expand Down Expand Up @@ -866,7 +856,6 @@ export default class StatementParser extends ExpressionParser {
topLevel: boolean,
end: TokenType,
afterBlockParse?: (hasStrictModeDirective: boolean) => void,
isDeclare?: boolean = false,
): void {
const octalPositions = [];
const oldStrict = this.state.strict;
Expand All @@ -879,7 +868,7 @@ export default class StatementParser extends ExpressionParser {
octalPositions.push(...this.state.octalPositions);
}

const stmt = this.parseStatement(null, topLevel, isDeclare);
const stmt = this.parseStatement(null, topLevel);

if (directives && !parsedNonDirective && this.isValidDirective(stmt)) {
const directive = this.stmtToDirective(stmt);
Expand Down Expand Up @@ -1065,7 +1054,6 @@ export default class StatementParser extends ExpressionParser {
node: T,
statement?: number = FUNC_NO_FLAGS,
isAsync?: boolean = false,
isDeclare?: boolean = false,
): T {
const isStatement = statement & FUNC_STATEMENT;
const isHangingStatement = statement & FUNC_HANGING_STATEMENT;
Expand Down Expand Up @@ -1105,8 +1093,6 @@ export default class StatementParser extends ExpressionParser {
this.parseFunctionBodyAndFinish(
node,
isStatement ? "FunctionDeclaration" : "FunctionExpression",
/* method */ false,
isDeclare,
);
});
Expand Down
102 changes: 45 additions & 57 deletions packages/babel-parser/src/plugins/typescript/index.js
Expand Up @@ -1318,7 +1318,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return this.finishNode(node, "TSEnumDeclaration");
}

tsParseModuleBlock(isDeclare?: boolean = false): N.TsModuleBlock {
tsParseModuleBlock(): N.TsModuleBlock {
const node: N.TsModuleBlock = this.startNode();
this.scope.enter(SCOPE_OTHER);

Expand All @@ -1329,8 +1329,6 @@ export default (superClass: Class<Parser>): Class<Parser> =>
/* directives */ undefined,
/* topLevel */ true,
/* end */ tt.braceR,
/* afterBlockParse */ undefined,
/* declare */ isDeclare,
);
this.scope.exit();
return this.finishNode(node, "TSModuleBlock");
Expand All @@ -1339,7 +1337,6 @@ export default (superClass: Class<Parser>): Class<Parser> =>
tsParseModuleOrNamespaceDeclaration(
node: N.TsModuleDeclaration,
nested?: boolean = false,
isDeclare?: boolean = false,
): N.TsModuleDeclaration {
node.id = this.parseIdentifier();

Expand All @@ -1359,7 +1356,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
} else {
this.scope.enter(SCOPE_TS_MODULE);
this.prodParam.enter(PARAM);
node.body = this.tsParseModuleBlock(isDeclare);
node.body = this.tsParseModuleBlock();
this.prodParam.exit();
this.scope.exit();
}
Expand Down Expand Up @@ -1474,48 +1471,49 @@ export default (superClass: Class<Parser>): Class<Parser> =>
kind = "let";
}

switch (starttype) {
case tt._function:
nany.declare = true;
return this.parseFunctionStatement(
nany,
/* async */ false,
/* declarationPosition */ true,
/* declare */ true,
);
case tt._class:
// While this is also set by tsParseExpressionStatement, we need to set it
// before parsing the class declaration to now how to register it in the scope.
nany.declare = true;
return this.parseClass(
nany,
/* isStatement */ true,
/* optionalId */ false,
);
case tt._const:
if (this.match(tt._const) && this.isLookaheadContextual("enum")) {
// `const enum = 0;` not allowed because "enum" is a strict mode reserved word.
this.expect(tt._const);
this.expectContextual("enum");
return this.tsParseEnumDeclaration(nany, /* isConst */ true);
}
// falls through
case tt._var:
kind = kind || this.state.value;
return this.parseVarStatement(nany, kind);
case tt.name: {
const value = this.state.value;
if (value === "global") {
return this.tsParseAmbientExternalModuleDeclaration(nany);
} else {
return this.tsParseDeclaration(
const oldIsDeclareContext = this.state.isDeclareContext;
this.state.isDeclareContext = true;

try {
switch (starttype) {
case tt._function:
nany.declare = true;
return this.parseFunctionStatement(
nany,
value,
/* next */ true,
/* declare */ true,
/* async */ false,
/* declarationPosition */ true,
);
case tt._class:
// While this is also set by tsParseExpressionStatement, we need to set it
// before parsing the class declaration to now how to register it in the scope.
nany.declare = true;
return this.parseClass(
nany,
/* isStatement */ true,
/* optionalId */ false,
);
case tt._const:
if (this.match(tt._const) && this.isLookaheadContextual("enum")) {
// `const enum = 0;` not allowed because "enum" is a strict mode reserved word.
this.expect(tt._const);
this.expectContextual("enum");
return this.tsParseEnumDeclaration(nany, /* isConst */ true);
}
// falls through
case tt._var:
kind = kind || this.state.value;
return this.parseVarStatement(nany, kind);
case tt.name: {
const value = this.state.value;
if (value === "global") {
return this.tsParseAmbientExternalModuleDeclaration(nany);
} else {
return this.tsParseDeclaration(nany, value, /* next */ true);
}
}
}
} finally {
this.state.isDeclareContext = oldIsDeclareContext;
}
}

Expand Down Expand Up @@ -1564,7 +1562,6 @@ export default (superClass: Class<Parser>): Class<Parser> =>
node: any,
value: string,
next: boolean,
isDeclare?: boolean = false,
): ?N.Declaration {
switch (value) {
case "abstract":
Expand Down Expand Up @@ -1611,11 +1608,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
case "namespace":
if (this.tsCheckLineTerminatorAndMatch(tt.name, next)) {
if (next) this.next();
return this.tsParseModuleOrNamespaceDeclaration(
node,
/* nested */ false,
isDeclare,
);
return this.tsParseModuleOrNamespaceDeclaration(node);
}
break;

Expand Down Expand Up @@ -1766,7 +1759,6 @@ export default (superClass: Class<Parser>): Class<Parser> =>
node: N.BodilessFunctionOrMethodBase,
type: string,
isMethod?: boolean = false,
isDeclare?: boolean = false,
): void {
if (this.match(tt.colon)) {
node.returnType = this.tsParseTypeOrTypePredicateAnnotation(tt.colon);
Expand All @@ -1782,7 +1774,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
this.finishNode(node, bodilessType);
return;
}
if (bodilessType === "TSDeclareFunction" && isDeclare) {
if (bodilessType === "TSDeclareFunction" && this.state.isDeclareContext) {
this.raise(node.start, TSErrors.DeclareFunctionHasImplementation);
if (
// $FlowIgnore
Expand Down Expand Up @@ -2051,11 +2043,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return super.parseExportDefaultExpression();
}

parseStatementContent(
context: ?string,
topLevel: ?boolean,
isDeclare?: boolean = false,
): N.Statement {
parseStatementContent(context: ?string, topLevel: ?boolean): N.Statement {
if (this.state.type === tt._const) {
const ahead = this.lookahead();
if (ahead.type === tt.name && ahead.value === "enum") {
Expand All @@ -2065,7 +2053,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return this.tsParseEnumDeclaration(node, /* isConst */ true);
}
}
return super.parseStatementContent(context, topLevel, isDeclare);
return super.parseStatementContent(context, topLevel);
}

parseAccessModifier(): ?N.Accessibility {
Expand Down
1 change: 1 addition & 0 deletions packages/babel-parser/src/tokenizer/state.js
Expand Up @@ -70,6 +70,7 @@ export default class State {
inPropertyName: boolean = false;
hasFlowComment: boolean = false;
isIterator: boolean = false;
isDeclareContext: boolean = false;

// For the smartPipelines plugin:
topicContext: TopicContextState = {
Expand Down

0 comments on commit 3471de1

Please sign in to comment.