Skip to content

Commit

Permalink
fix(ts): parse multiline declarations correctly (#12776)
Browse files Browse the repository at this point in the history
Co-authored-by: Nicol貌 Ribaudo <nicolo.ribaudo@gmail.com>
  • Loading branch information
fedeci and nicolo-ribaudo committed Feb 16, 2021
1 parent 4462eea commit 8e9143f
Show file tree
Hide file tree
Showing 15 changed files with 426 additions and 19 deletions.
36 changes: 19 additions & 17 deletions packages/babel-parser/src/plugins/typescript/index.js
Expand Up @@ -1624,14 +1624,13 @@ export default (superClass: Class<Parser>): Class<Parser> =>
value: string,
next: boolean,
): ?N.Declaration {
// no declaration apart from enum can be followed by a line break.
switch (value) {
case "abstract":
if (
this.tsCheckLineTerminatorAndMatch(tt._class, next) ||
// for interface
this.tsCheckLineTerminatorAndMatch(tt.name, next)
this.tsCheckLineTerminator(next) &&
(this.match(tt._class) || this.match(tt.name))
) {
if (next) this.next();
return this.tsParseAbstractDeclaration(node);
}
break;
Expand All @@ -1644,39 +1643,42 @@ export default (superClass: Class<Parser>): Class<Parser> =>
break;

case "interface":
if (this.tsCheckLineTerminatorAndMatch(tt.name, next)) {
if (next) this.next();
if (this.tsCheckLineTerminator(next) && this.match(tt.name)) {
return this.tsParseInterfaceDeclaration(node);
}
break;

case "module":
if (next) this.next();
if (this.match(tt.string)) {
return this.tsParseAmbientExternalModuleDeclaration(node);
} else if (this.tsCheckLineTerminatorAndMatch(tt.name, next)) {
return this.tsParseModuleOrNamespaceDeclaration(node);
if (this.tsCheckLineTerminator(next)) {
if (this.match(tt.string)) {
return this.tsParseAmbientExternalModuleDeclaration(node);
} else if (this.match(tt.name)) {
return this.tsParseModuleOrNamespaceDeclaration(node);
}
}
break;

case "namespace":
if (this.tsCheckLineTerminatorAndMatch(tt.name, next)) {
if (next) this.next();
if (this.tsCheckLineTerminator(next) && this.match(tt.name)) {
return this.tsParseModuleOrNamespaceDeclaration(node);
}
break;

case "type":
if (this.tsCheckLineTerminatorAndMatch(tt.name, next)) {
if (next) this.next();
if (this.tsCheckLineTerminator(next) && this.match(tt.name)) {
return this.tsParseTypeAliasDeclaration(node);
}
break;
}
}

tsCheckLineTerminatorAndMatch(tokenType: TokenType, next: boolean) {
return (next || this.match(tokenType)) && !this.isLineTerminator();
tsCheckLineTerminator(next: boolean) {
if (next) {
if (this.hasFollowingLineBreak()) return false;
this.next();
return true;
}
return !this.isLineTerminator();
}

tsTryParseGenericAsyncArrowFunction(
Expand Down
@@ -0,0 +1,2 @@
declare abstract
class A {}
@@ -0,0 +1,49 @@
{
"type": "File",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":10}},
"errors": [
"SyntaxError: Missing semicolon (1:7)"
],
"program": {
"type": "Program",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":2,"column":10}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":7,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":7}},
"expression": {
"type": "Identifier",
"start":0,"end":7,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":7},"identifierName":"declare"},
"name": "declare"
}
},
{
"type": "ExpressionStatement",
"start":8,"end":16,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":16}},
"expression": {
"type": "Identifier",
"start":8,"end":16,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":16},"identifierName":"abstract"},
"name": "abstract"
}
},
{
"type": "ClassDeclaration",
"start":17,"end":27,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":10}},
"id": {
"type": "Identifier",
"start":23,"end":24,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":7},"identifierName":"A"},
"name": "A"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":25,"end":27,"loc":{"start":{"line":2,"column":8},"end":{"line":2,"column":10}},
"body": []
}
}
],
"directives": []
}
}
@@ -0,0 +1,3 @@
declare enum
E
{}
@@ -0,0 +1,24 @@
{
"type": "File",
"start":0,"end":17,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":2}},
"program": {
"type": "Program",
"start":0,"end":17,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":2}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "TSEnumDeclaration",
"start":0,"end":17,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":2}},
"id": {
"type": "Identifier",
"start":13,"end":14,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":1},"identifierName":"E"},
"name": "E"
},
"members": [],
"declare": true
}
],
"directives": []
}
}
@@ -0,0 +1,3 @@
declare interface
I
{}
@@ -0,0 +1,49 @@
{
"type": "File",
"start":0,"end":22,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":2}},
"errors": [
"SyntaxError: Missing semicolon (1:7)"
],
"program": {
"type": "Program",
"start":0,"end":22,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":2}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":7,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":7}},
"expression": {
"type": "Identifier",
"start":0,"end":7,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":7},"identifierName":"declare"},
"name": "declare"
}
},
{
"type": "ExpressionStatement",
"start":8,"end":17,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":17}},
"expression": {
"type": "Identifier",
"start":8,"end":17,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":17},"identifierName":"interface"},
"name": "interface"
}
},
{
"type": "ExpressionStatement",
"start":18,"end":19,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":1}},
"expression": {
"type": "Identifier",
"start":18,"end":19,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":1},"identifierName":"I"},
"name": "I"
}
},
{
"type": "BlockStatement",
"start":20,"end":22,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":2}},
"body": [],
"directives": []
}
],
"directives": []
}
}
@@ -0,0 +1,8 @@
declare
module
'foo'
{}

declare module
'bar'
{}
@@ -0,0 +1,90 @@
{
"type": "File",
"start":0,"end":48,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":2}},
"errors": [
"SyntaxError: Missing semicolon (6:7)"
],
"program": {
"type": "Program",
"start":0,"end":48,"loc":{"start":{"line":1,"column":0},"end":{"line":8,"column":2}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":7,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":7}},
"expression": {
"type": "Identifier",
"start":0,"end":7,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":7},"identifierName":"declare"},
"name": "declare"
}
},
{
"type": "ExpressionStatement",
"start":8,"end":14,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":6}},
"expression": {
"type": "Identifier",
"start":8,"end":14,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":6},"identifierName":"module"},
"name": "module"
}
},
{
"type": "ExpressionStatement",
"start":15,"end":20,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":5}},
"expression": {
"type": "StringLiteral",
"start":15,"end":20,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":5}},
"extra": {
"rawValue": "foo",
"raw": "'foo'"
},
"value": "foo"
}
},
{
"type": "BlockStatement",
"start":21,"end":23,"loc":{"start":{"line":4,"column":0},"end":{"line":4,"column":2}},
"body": [],
"directives": []
},
{
"type": "ExpressionStatement",
"start":25,"end":32,"loc":{"start":{"line":6,"column":0},"end":{"line":6,"column":7}},
"expression": {
"type": "Identifier",
"start":25,"end":32,"loc":{"start":{"line":6,"column":0},"end":{"line":6,"column":7},"identifierName":"declare"},
"name": "declare"
}
},
{
"type": "ExpressionStatement",
"start":33,"end":39,"loc":{"start":{"line":6,"column":8},"end":{"line":6,"column":14}},
"expression": {
"type": "Identifier",
"start":33,"end":39,"loc":{"start":{"line":6,"column":8},"end":{"line":6,"column":14},"identifierName":"module"},
"name": "module"
}
},
{
"type": "ExpressionStatement",
"start":40,"end":45,"loc":{"start":{"line":7,"column":0},"end":{"line":7,"column":5}},
"expression": {
"type": "StringLiteral",
"start":40,"end":45,"loc":{"start":{"line":7,"column":0},"end":{"line":7,"column":5}},
"extra": {
"rawValue": "bar",
"raw": "'bar'"
},
"value": "bar"
}
},
{
"type": "BlockStatement",
"start":46,"end":48,"loc":{"start":{"line":8,"column":0},"end":{"line":8,"column":2}},
"body": [],
"directives": []
}
],
"directives": []
}
}
@@ -1,3 +1,7 @@
module
Foo
{}

module
'm'
{}
@@ -1,9 +1,9 @@
{
"type": "File",
"start":0,"end":13,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":2}},
"start":0,"end":28,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":2}},
"program": {
"type": "Program",
"start":0,"end":13,"loc":{"start":{"line":1,"column":0},"end":{"line":3,"column":2}},
"start":0,"end":28,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":2}},
"sourceType": "module",
"interpreter": null,
"body": [
Expand All @@ -30,6 +30,34 @@
"start":11,"end":13,"loc":{"start":{"line":3,"column":0},"end":{"line":3,"column":2}},
"body": [],
"directives": []
},
{
"type": "ExpressionStatement",
"start":15,"end":21,"loc":{"start":{"line":5,"column":0},"end":{"line":5,"column":6}},
"expression": {
"type": "Identifier",
"start":15,"end":21,"loc":{"start":{"line":5,"column":0},"end":{"line":5,"column":6},"identifierName":"module"},
"name": "module"
}
},
{
"type": "ExpressionStatement",
"start":22,"end":25,"loc":{"start":{"line":6,"column":0},"end":{"line":6,"column":3}},
"expression": {
"type": "StringLiteral",
"start":22,"end":25,"loc":{"start":{"line":6,"column":0},"end":{"line":6,"column":3}},
"extra": {
"rawValue": "m",
"raw": "'m'"
},
"value": "m"
}
},
{
"type": "BlockStatement",
"start":26,"end":28,"loc":{"start":{"line":7,"column":0},"end":{"line":7,"column":2}},
"body": [],
"directives": []
}
],
"directives": []
Expand Down
@@ -0,0 +1,8 @@
declare
namespace
foofoo
{}

declare namespace
barbar
{}

0 comments on commit 8e9143f

Please sign in to comment.