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:
|
ConstructorHasTypeParameters:
|
||||||
"Type parameters cannot appear on a constructor declaration.",
|
"Type parameters cannot appear on a constructor declaration.",
|
||||||
DeclareClassFieldHasInitializer:
|
DeclareClassFieldHasInitializer:
|
||||||
"'declare' class fields cannot have an initializer",
|
"Initializers are not allowed in ambient contexts.",
|
||||||
DeclareFunctionHasImplementation:
|
DeclareFunctionHasImplementation:
|
||||||
"An implementation cannot be declared in ambient contexts.",
|
"An implementation cannot be declared in ambient contexts.",
|
||||||
DuplicateModifier: "Duplicate modifier: '%0'",
|
DuplicateModifier: "Duplicate modifier: '%0'",
|
||||||
@ -1478,10 +1478,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
kind = "let";
|
kind = "let";
|
||||||
}
|
}
|
||||||
|
|
||||||
const oldIsDeclareContext = this.state.isDeclareContext;
|
return this.tsInDeclareContext(() => {
|
||||||
this.state.isDeclareContext = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
switch (starttype) {
|
switch (starttype) {
|
||||||
case tt._function:
|
case tt._function:
|
||||||
nany.declare = true;
|
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`.
|
// 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;
|
if (accessibility) member.accessibility = accessibility;
|
||||||
this.tsParseModifiers(member, ["declare"]);
|
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(
|
parseClassMemberWithIsStatic(
|
||||||
@ -2294,7 +2301,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
parseClassProperty(node: N.ClassProperty): N.ClassProperty {
|
parseClassProperty(node: N.ClassProperty): N.ClassProperty {
|
||||||
this.parseClassPropertyAnnotation(node);
|
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);
|
this.raise(this.state.start, TSErrors.DeclareClassFieldHasInitializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2781,4 +2788,14 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
|
|
||||||
return param;
|
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",
|
"type": "File",
|
||||||
"start":0,"end":43,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
|
"start":0,"end":43,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},
|
||||||
"errors": [
|
"errors": [
|
||||||
"SyntaxError: 'declare' class fields cannot have an initializer (2:22)"
|
"SyntaxError: Initializers are not allowed in ambient contexts. (2:22)"
|
||||||
],
|
],
|
||||||
"program": {
|
"program": {
|
||||||
"type": "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