Improve syntax error for class fields in ambient context (#12108)
* Improve error messages for ambient context class fields * Modify switching state.isDeclareContext for class fields with declare
This commit is contained in:
parent
3d5da4c2b9
commit
39a12674b4
@ -68,7 +68,7 @@ const TSErrors = Object.freeze({
|
||||
ConstructorHasTypeParameters:
|
||||
"Type parameters cannot appear on a constructor declaration.",
|
||||
DeclareClassFieldHasInitializer:
|
||||
"'declare' class fields cannot have an initializer",
|
||||
"Initializers are not allowed in ambient contexts.",
|
||||
DeclareFunctionHasImplementation:
|
||||
"An implementation cannot be declared in ambient contexts.",
|
||||
DuplicateModifier: "Duplicate modifier: '%0'",
|
||||
@ -1478,10 +1478,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
kind = "let";
|
||||
}
|
||||
|
||||
const oldIsDeclareContext = this.state.isDeclareContext;
|
||||
this.state.isDeclareContext = true;
|
||||
|
||||
try {
|
||||
return this.tsInDeclareContext(() => {
|
||||
switch (starttype) {
|
||||
case tt._function:
|
||||
nany.declare = true;
|
||||
@ -1519,9 +1516,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.state.isDeclareContext = oldIsDeclareContext;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Note: this won't be called unless the keyword is allowed in `shouldParseExportDeclaration`.
|
||||
@ -2081,7 +2076,19 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
if (accessibility) member.accessibility = accessibility;
|
||||
this.tsParseModifiers(member, ["declare"]);
|
||||
|
||||
super.parseClassMember(classBody, member, state, constructorAllowsSuper);
|
||||
const callParseClassMember = () => {
|
||||
super.parseClassMember(
|
||||
classBody,
|
||||
member,
|
||||
state,
|
||||
constructorAllowsSuper,
|
||||
);
|
||||
};
|
||||
if (member.declare) {
|
||||
this.tsInDeclareContext(callParseClassMember);
|
||||
} else {
|
||||
callParseClassMember();
|
||||
}
|
||||
}
|
||||
|
||||
parseClassMemberWithIsStatic(
|
||||
@ -2294,7 +2301,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
parseClassProperty(node: N.ClassProperty): N.ClassProperty {
|
||||
this.parseClassPropertyAnnotation(node);
|
||||
|
||||
if (node.declare && this.match(tt.eq)) {
|
||||
if (this.state.isDeclareContext && this.match(tt.eq)) {
|
||||
this.raise(this.state.start, TSErrors.DeclareClassFieldHasInitializer);
|
||||
}
|
||||
|
||||
@ -2781,4 +2788,14 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
tsInDeclareContext<T>(cb: () => T): T {
|
||||
const oldIsDeclareContext = this.state.isDeclareContext;
|
||||
this.state.isDeclareContext = true;
|
||||
try {
|
||||
return cb();
|
||||
} finally {
|
||||
this.state.isDeclareContext = oldIsDeclareContext;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"type": "File",
|
||||
"start":0,"end":43,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
|
||||
"errors": [
|
||||
"SyntaxError: 'declare' class fields cannot have an initializer (2:22)"
|
||||
"SyntaxError: Initializers are not allowed in ambient contexts. (2:22)"
|
||||
],
|
||||
"program": {
|
||||
"type": "Program",
|
||||
|
||||
3
packages/babel-parser/test/fixtures/typescript/class/declare-initializer/input.ts
vendored
Normal file
3
packages/babel-parser/test/fixtures/typescript/class/declare-initializer/input.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
declare class C {
|
||||
field = "field";
|
||||
}
|
||||
53
packages/babel-parser/test/fixtures/typescript/class/declare-initializer/output.json
vendored
Normal file
53
packages/babel-parser/test/fixtures/typescript/class/declare-initializer/output.json
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start":0,"end":38,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
|
||||
"errors": [
|
||||
"SyntaxError: Initializers are not allowed in ambient contexts. (2:8)"
|
||||
],
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start":0,"end":38,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
|
||||
"sourceType": "module",
|
||||
"interpreter": null,
|
||||
"body": [
|
||||
{
|
||||
"type": "ClassDeclaration",
|
||||
"start":0,"end":38,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
|
||||
"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":38,"loc":{"start":{"line":1,"column":16},"end":{"line":3,"column":1}},
|
||||
"body": [
|
||||
{
|
||||
"type": "ClassProperty",
|
||||
"start":20,"end":36,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":18}},
|
||||
"static": false,
|
||||
"key": {
|
||||
"type": "Identifier",
|
||||
"start":20,"end":25,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":7},"identifierName":"field"},
|
||||
"name": "field"
|
||||
},
|
||||
"computed": false,
|
||||
"value": {
|
||||
"type": "StringLiteral",
|
||||
"start":28,"end":35,"loc":{"start":{"line":2,"column":10},"end":{"line":2,"column":17}},
|
||||
"extra": {
|
||||
"rawValue": "field",
|
||||
"raw": "\"field\""
|
||||
},
|
||||
"value": "field"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
5
packages/babel-parser/test/fixtures/typescript/declare/module-class/input.ts
vendored
Normal file
5
packages/babel-parser/test/fixtures/typescript/declare/module-class/input.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
declare module m {
|
||||
class C {
|
||||
field = "field";
|
||||
}
|
||||
}
|
||||
3
packages/babel-parser/test/fixtures/typescript/declare/module-class/options.json
vendored
Normal file
3
packages/babel-parser/test/fixtures/typescript/declare/module-class/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["typescript", "classProperties"]
|
||||
}
|
||||
68
packages/babel-parser/test/fixtures/typescript/declare/module-class/output.json
vendored
Normal file
68
packages/babel-parser/test/fixtures/typescript/declare/module-class/output.json
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
|
||||
"errors": [
|
||||
"SyntaxError: Initializers are not allowed in ambient contexts. (3:10)"
|
||||
],
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
|
||||
"sourceType": "module",
|
||||
"interpreter": null,
|
||||
"body": [
|
||||
{
|
||||
"type": "TSModuleDeclaration",
|
||||
"start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start":15,"end":16,"loc":{"start":{"line":1,"column":15},"end":{"line":1,"column":16},"identifierName":"m"},
|
||||
"name": "m"
|
||||
},
|
||||
"body": {
|
||||
"type": "TSModuleBlock",
|
||||
"start":17,"end":57,"loc":{"start":{"line":1,"column":17},"end":{"line":5,"column":1}},
|
||||
"body": [
|
||||
{
|
||||
"type": "ClassDeclaration",
|
||||
"start":21,"end":55,"loc":{"start":{"line":2,"column":2},"end":{"line":4,"column":3}},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start":27,"end":28,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":9},"identifierName":"C"},
|
||||
"name": "C"
|
||||
},
|
||||
"superClass": null,
|
||||
"body": {
|
||||
"type": "ClassBody",
|
||||
"start":29,"end":55,"loc":{"start":{"line":2,"column":10},"end":{"line":4,"column":3}},
|
||||
"body": [
|
||||
{
|
||||
"type": "ClassProperty",
|
||||
"start":35,"end":51,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":20}},
|
||||
"static": false,
|
||||
"key": {
|
||||
"type": "Identifier",
|
||||
"start":35,"end":40,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":9},"identifierName":"field"},
|
||||
"name": "field"
|
||||
},
|
||||
"computed": false,
|
||||
"value": {
|
||||
"type": "StringLiteral",
|
||||
"start":43,"end":50,"loc":{"start":{"line":3,"column":12},"end":{"line":3,"column":19}},
|
||||
"extra": {
|
||||
"rawValue": "field",
|
||||
"raw": "\"field\""
|
||||
},
|
||||
"value": "field"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"declare": true
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
6
packages/babel-parser/test/fixtures/typescript/declare/namespace-class/input.ts
vendored
Normal file
6
packages/babel-parser/test/fixtures/typescript/declare/namespace-class/input.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
declare namespace m {
|
||||
class C {
|
||||
field = "field";
|
||||
}
|
||||
}
|
||||
|
||||
3
packages/babel-parser/test/fixtures/typescript/declare/namespace-class/options.json
vendored
Normal file
3
packages/babel-parser/test/fixtures/typescript/declare/namespace-class/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["typescript", "classProperties"]
|
||||
}
|
||||
68
packages/babel-parser/test/fixtures/typescript/declare/namespace-class/output.json
vendored
Normal file
68
packages/babel-parser/test/fixtures/typescript/declare/namespace-class/output.json
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"type": "File",
|
||||
"start":0,"end":60,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
|
||||
"errors": [
|
||||
"SyntaxError: Initializers are not allowed in ambient contexts. (3:10)"
|
||||
],
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"start":0,"end":60,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
|
||||
"sourceType": "module",
|
||||
"interpreter": null,
|
||||
"body": [
|
||||
{
|
||||
"type": "TSModuleDeclaration",
|
||||
"start":0,"end":60,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start":18,"end":19,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":19},"identifierName":"m"},
|
||||
"name": "m"
|
||||
},
|
||||
"body": {
|
||||
"type": "TSModuleBlock",
|
||||
"start":20,"end":60,"loc":{"start":{"line":1,"column":20},"end":{"line":5,"column":1}},
|
||||
"body": [
|
||||
{
|
||||
"type": "ClassDeclaration",
|
||||
"start":24,"end":58,"loc":{"start":{"line":2,"column":2},"end":{"line":4,"column":3}},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"start":30,"end":31,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":9},"identifierName":"C"},
|
||||
"name": "C"
|
||||
},
|
||||
"superClass": null,
|
||||
"body": {
|
||||
"type": "ClassBody",
|
||||
"start":32,"end":58,"loc":{"start":{"line":2,"column":10},"end":{"line":4,"column":3}},
|
||||
"body": [
|
||||
{
|
||||
"type": "ClassProperty",
|
||||
"start":38,"end":54,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":20}},
|
||||
"static": false,
|
||||
"key": {
|
||||
"type": "Identifier",
|
||||
"start":38,"end":43,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":9},"identifierName":"field"},
|
||||
"name": "field"
|
||||
},
|
||||
"computed": false,
|
||||
"value": {
|
||||
"type": "StringLiteral",
|
||||
"start":46,"end":53,"loc":{"start":{"line":3,"column":12},"end":{"line":3,"column":19}},
|
||||
"extra": {
|
||||
"rawValue": "field",
|
||||
"raw": "\"field\""
|
||||
},
|
||||
"value": "field"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"declare": true
|
||||
}
|
||||
],
|
||||
"directives": []
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user