Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not register ambient classes to the TS scope #10352

Merged
merged 2 commits into from Aug 20, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/babel-parser/src/parser/statement.js
Expand Up @@ -20,6 +20,7 @@ import {
SCOPE_OTHER,
SCOPE_SIMPLE_CATCH,
SCOPE_SUPER,
type BindingTypes,
} from "../util/scopeflags";

const loopLabel = { kind: "loop" },
Expand Down Expand Up @@ -1611,11 +1612,12 @@ export default class StatementParser extends ExpressionParser {
node: N.Class,
isStatement: boolean,
optionalId: ?boolean,
bindingType: BindingTypes = BIND_CLASS,
): void {
if (this.match(tt.name)) {
node.id = this.parseIdentifier();
if (isStatement) {
this.checkLVal(node.id, BIND_CLASS, undefined, "class name");
this.checkLVal(node.id, bindingType, undefined, "class name");
}
} else {
if (optionalId || !isStatement) {
Expand Down
15 changes: 12 additions & 3 deletions packages/babel-parser/src/plugins/typescript/index.js
Expand Up @@ -14,8 +14,9 @@ import {
BIND_TS_CONST_ENUM,
BIND_TS_TYPE,
BIND_TS_INTERFACE,
BIND_TS_FN_TYPE,
BIND_TS_AMBIENT,
BIND_TS_NAMESPACE,
BIND_CLASS,
} from "../../util/scopeflags";
import TypeScriptScopeHandler from "./scope";

Expand Down Expand Up @@ -1278,6 +1279,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
/* 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,
Expand Down Expand Up @@ -1552,7 +1556,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>

checkFunctionStatementId(node: N.Function): void {
if (!node.body && node.id) {
this.checkLVal(node.id, BIND_TS_FN_TYPE, null, "function name");
this.checkLVal(node.id, BIND_TS_AMBIENT, null, "function name");
} else {
super.checkFunctionStatementId(...arguments);
}
Expand Down Expand Up @@ -1988,7 +1992,12 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return;
}

super.parseClassId(...arguments);
super.parseClassId(
node,
isStatement,
optionalId,
(node: any).declare ? BIND_TS_AMBIENT : BIND_CLASS,
);
const typeParameters = this.tsTryParseTypeParameters();
if (typeParameters) node.typeParameters = typeParameters;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-parser/src/plugins/typescript/scope.js
Expand Up @@ -25,7 +25,7 @@ class TypeScriptScope extends Scope {
// classes (which are also in .lexical) and interface (which are also in .types)
classes: string[] = [];

// namespaces and bodyless-functions are too difficult to track,
// namespaces and ambient functions (or classes) are too difficult to track,
// especially without type analysis.
// We need to track them anyway, to avoid "X is not defined" errors
// when exporting them.
Expand Down
6 changes: 3 additions & 3 deletions packages/babel-parser/src/util/scopeflags.js
Expand Up @@ -62,14 +62,14 @@ export const BIND_CLASS = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_
BIND_TS_INTERFACE = 0 | BIND_KIND_TYPE | 0 | BIND_FLAGS_CLASS ,
BIND_TS_TYPE = 0 | BIND_KIND_TYPE | 0 | 0 ,
BIND_TS_ENUM = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_LEXICAL | BIND_FLAGS_TS_ENUM,
BIND_TS_FN_TYPE = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY,
BIND_TS_AMBIENT = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY,
// These bindings don't introduce anything in the scope. They are used for assignments and
// function expressions IDs.
BIND_NONE = 0 | 0 | 0 | BIND_FLAGS_NONE ,
BIND_OUTSIDE = BIND_KIND_VALUE | 0 | 0 | BIND_FLAGS_NONE ,

BIND_TS_CONST_ENUM = BIND_TS_ENUM | BIND_FLAGS_TS_CONST_ENUM,
BIND_TS_NAMESPACE = BIND_TS_FN_TYPE;
BIND_TS_NAMESPACE = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY;

export type BindingTypes =
| typeof BIND_NONE
Expand All @@ -81,5 +81,5 @@ export type BindingTypes =
| typeof BIND_TS_INTERFACE
| typeof BIND_TS_TYPE
| typeof BIND_TS_ENUM
| typeof BIND_TS_FN_TYPE
| typeof BIND_TS_AMBIENT
| typeof BIND_TS_NAMESPACE;
@@ -0,0 +1,2 @@
declare class C { }
declare function C(): void;
@@ -0,0 +1,151 @@
{
"type": "File",
"start": 0,
"end": 47,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 27
}
},
"program": {
"type": "Program",
"start": 0,
"end": 47,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 27
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 19,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 19
}
},
"id": {
"type": "Identifier",
"start": 14,
"end": 15,
"loc": {
"start": {
"line": 1,
"column": 14
},
"end": {
"line": 1,
"column": 15
},
"identifierName": "C"
},
"name": "C"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 16,
"end": 19,
"loc": {
"start": {
"line": 1,
"column": 16
},
"end": {
"line": 1,
"column": 19
}
},
"body": []
},
"declare": true
},
{
"type": "TSDeclareFunction",
"start": 20,
"end": 47,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 27
}
},
"id": {
"type": "Identifier",
"start": 37,
"end": 38,
"loc": {
"start": {
"line": 2,
"column": 17
},
"end": {
"line": 2,
"column": 18
},
"identifierName": "C"
},
"name": "C"
},
"generator": false,
"async": false,
"params": [],
"returnType": {
"type": "TSTypeAnnotation",
"start": 40,
"end": 46,
"loc": {
"start": {
"line": 2,
"column": 20
},
"end": {
"line": 2,
"column": 26
}
},
"typeAnnotation": {
"type": "TSVoidKeyword",
"start": 42,
"end": 46,
"loc": {
"start": {
"line": 2,
"column": 22
},
"end": {
"line": 2,
"column": 26
}
}
}
},
"declare": true
}
],
"directives": []
}
}
@@ -0,0 +1,2 @@
declare class C { }
function C() { }
@@ -0,0 +1,137 @@
{
"type": "File",
"start": 0,
"end": 36,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 16
}
},
"program": {
"type": "Program",
"start": 0,
"end": 36,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 16
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 19,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 19
}
},
"declare": true,
"id": {
"type": "Identifier",
"start": 14,
"end": 15,
"loc": {
"start": {
"line": 1,
"column": 14
},
"end": {
"line": 1,
"column": 15
},
"identifierName": "C"
},
"name": "C"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 16,
"end": 19,
"loc": {
"start": {
"line": 1,
"column": 16
},
"end": {
"line": 1,
"column": 19
}
},
"body": []
}
},
{
"type": "FunctionDeclaration",
"start": 20,
"end": 36,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 16
}
},
"id": {
"type": "Identifier",
"start": 29,
"end": 30,
"loc": {
"start": {
"line": 2,
"column": 9
},
"end": {
"line": 2,
"column": 10
},
"identifierName": "C"
},
"name": "C"
},
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 33,
"end": 36,
"loc": {
"start": {
"line": 2,
"column": 13
},
"end": {
"line": 2,
"column": 16
}
},
"body": [],
"directives": []
}
}
],
"directives": []
}
}