Flow Enums with unknown members support (#12193)

* Flow Enums with unknown members parsing

* Updates after rebase

Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
George Zahariev 2021-02-21 09:42:23 -08:00 committed by GitHub
parent d1d6ee6dc2
commit 5b99b8f221
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 168 additions and 34 deletions

View File

@ -195,6 +195,10 @@ function enumBody(context: any, node: any) {
context.print(member, node);
context.newline();
}
if (node.hasUnknownMembers) {
context.token("...");
context.newline();
}
context.dedent();
context.token("}");
}

View File

@ -34,3 +34,9 @@ enum E of symbol {
A,
B,
}
enum E {
A,
B,
...
}

View File

@ -34,3 +34,8 @@ enum E of symbol {
A,
B,
}
enum E {
A,
B,
...
}

View File

@ -3409,10 +3409,13 @@ export default (superClass: Class<Parser>): Class<Parser> =>
enumName: string,
explicitType: EnumExplicitType,
}): {|
booleanMembers: Array<N.Node>,
numberMembers: Array<N.Node>,
stringMembers: Array<N.Node>,
defaultedMembers: Array<N.Node>,
members: {|
booleanMembers: Array<N.Node>,
numberMembers: Array<N.Node>,
stringMembers: Array<N.Node>,
defaultedMembers: Array<N.Node>,
|},
hasUnknownMembers: boolean,
|} {
const seenNames = new Set();
const members = {
@ -3421,7 +3424,12 @@ export default (superClass: Class<Parser>): Class<Parser> =>
stringMembers: [],
defaultedMembers: [],
};
let hasUnknownMembers = false;
while (!this.match(tt.braceR)) {
if (this.eat(tt.ellipsis)) {
hasUnknownMembers = true;
break;
}
const memberNode = this.startNode();
const { id, init } = this.flowEnumMemberRaw();
const memberName = id.name;
@ -3498,7 +3506,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
this.expect(tt.comma);
}
}
return members;
return { members, hasUnknownMembers };
}
flowEnumStringMembers(
@ -3565,7 +3573,11 @@ export default (superClass: Class<Parser>): Class<Parser> =>
flowEnumBody(node: N.Node, { enumName, nameLoc }): N.Node {
const explicitType = this.flowEnumParseExplicitType({ enumName });
this.expect(tt.braceL);
const members = this.flowEnumMembers({ enumName, explicitType });
const { members, hasUnknownMembers } = this.flowEnumMembers({
enumName,
explicitType,
});
node.hasUnknownMembers = hasUnknownMembers;
switch (explicitType) {
case "boolean":

View File

@ -48,7 +48,8 @@
"value": false
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -19,6 +19,7 @@
"type": "EnumBooleanBody",
"start":7,"end":35,"loc":{"start":{"line":1,"column":7},"end":{"line":4,"column":1}},
"explicitType": false,
"hasUnknownMembers": false,
"members": [
{
"type": "EnumBooleanMember",

View File

@ -22,7 +22,8 @@
"type": "EnumBooleanBody",
"start":7,"end":26,"loc":{"start":{"line":1,"column":7},"end":{"line":3,"column":1}},
"explicitType": true,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -22,6 +22,7 @@
"type": "EnumBooleanBody",
"start":7,"end":27,"loc":{"start":{"line":1,"column":7},"end":{"line":4,"column":1}},
"explicitType": false,
"hasUnknownMembers": false,
"members": [
{
"type": "EnumBooleanMember",

View File

@ -41,7 +41,8 @@
"name": "A"
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -19,7 +19,8 @@
"type": "EnumStringBody",
"start":7,"end":10,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":10}},
"explicitType": false,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -19,7 +19,8 @@
"type": "EnumStringBody",
"start":10,"end":13,"loc":{"start":{"line":1,"column":10},"end":{"line":2,"column":1}},
"explicitType": false,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -25,7 +25,8 @@
"type": "EnumStringBody",
"start":14,"end":16,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":16}},
"explicitType": false,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
},
@ -44,7 +45,8 @@
"type": "EnumStringBody",
"start":40,"end":42,"loc":{"start":{"line":3,"column":22},"end":{"line":3,"column":24}},
"explicitType": false,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
}

View File

@ -22,7 +22,8 @@
"type": "EnumStringBody",
"start":7,"end":29,"loc":{"start":{"line":1,"column":7},"end":{"line":5,"column":1}},
"explicitType": false,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -22,7 +22,8 @@
"type": "EnumStringBody",
"start":7,"end":31,"loc":{"start":{"line":1,"column":7},"end":{"line":4,"column":1}},
"explicitType": false,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -22,7 +22,8 @@
"type": "EnumStringBody",
"start":7,"end":17,"loc":{"start":{"line":1,"column":7},"end":{"line":2,"column":1}},
"explicitType": false,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -22,7 +22,8 @@
"type": "EnumStringBody",
"start":7,"end":32,"loc":{"start":{"line":1,"column":7},"end":{"line":3,"column":1}},
"explicitType": true,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -21,7 +21,8 @@
"body": {
"type": "EnumSymbolBody",
"start":7,"end":29,"loc":{"start":{"line":1,"column":7},"end":{"line":3,"column":1}},
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -22,7 +22,8 @@
"type": "EnumBooleanBody",
"start":7,"end":30,"loc":{"start":{"line":1,"column":7},"end":{"line":3,"column":1}},
"explicitType": true,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -22,7 +22,8 @@
"type": "EnumStringBody",
"start":7,"end":29,"loc":{"start":{"line":1,"column":7},"end":{"line":3,"column":1}},
"explicitType": true,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -22,7 +22,8 @@
"type": "EnumBooleanBody",
"start":7,"end":33,"loc":{"start":{"line":1,"column":7},"end":{"line":3,"column":1}},
"explicitType": true,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -22,7 +22,8 @@
"type": "EnumNumberBody",
"start":7,"end":32,"loc":{"start":{"line":1,"column":7},"end":{"line":3,"column":1}},
"explicitType": true,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -42,7 +42,8 @@
"name": "bar"
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -29,7 +29,8 @@
"name": "A"
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -56,7 +56,8 @@
"value": 2
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -19,6 +19,7 @@
"type": "EnumNumberBody",
"start":7,"end":28,"loc":{"start":{"line":1,"column":7},"end":{"line":4,"column":1}},
"explicitType": false,
"hasUnknownMembers": false,
"members": [
{
"type": "EnumNumberMember",

View File

@ -22,7 +22,8 @@
"type": "EnumNumberBody",
"start":7,"end":25,"loc":{"start":{"line":1,"column":7},"end":{"line":3,"column":1}},
"explicitType": true,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -22,6 +22,7 @@
"type": "EnumNumberBody",
"start":7,"end":24,"loc":{"start":{"line":1,"column":7},"end":{"line":4,"column":1}},
"explicitType": false,
"hasUnknownMembers": false,
"members": [
{
"type": "EnumNumberMember",

View File

@ -22,7 +22,8 @@
"type": "EnumStringBody",
"start":11,"end":14,"loc":{"start":{"line":1,"column":11},"end":{"line":2,"column":1}},
"explicitType": false,
"members": []
"members": [],
"hasUnknownMembers": false
}
}
],

View File

@ -38,7 +38,8 @@
"name": "B"
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -56,7 +56,8 @@
"value": "b"
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -38,7 +38,8 @@
"name": "B"
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -56,7 +56,8 @@
"value": "b"
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -41,7 +41,8 @@
"name": "C"
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -59,7 +59,8 @@
"value": "c"
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -37,7 +37,8 @@
"name": "B"
}
}
]
],
"hasUnknownMembers": false
}
}
],

View File

@ -0,0 +1,3 @@
enum E {
...,
}

View File

@ -0,0 +1,11 @@
{
"plugins": [
[
"flow",
{
"enums": true
}
]
],
"throws": "Unexpected token, expected \"}\" (2:5)"
}

View File

@ -0,0 +1,5 @@
enum E {
A,
B,
...
}

View File

@ -0,0 +1,48 @@
{
"type": "File",
"start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
"program": {
"type": "Program",
"start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "EnumDeclaration",
"start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
"id": {
"type": "Identifier",
"start":5,"end":6,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":6},"identifierName":"E"},
"name": "E"
},
"body": {
"type": "EnumStringBody",
"start":7,"end":26,"loc":{"start":{"line":1,"column":7},"end":{"line":5,"column":1}},
"explicitType": false,
"members": [
{
"type": "EnumDefaultedMember",
"start":11,"end":12,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":3}},
"id": {
"type": "Identifier",
"start":11,"end":12,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":3},"identifierName":"A"},
"name": "A"
}
},
{
"type": "EnumDefaultedMember",
"start":16,"end":17,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":3}},
"id": {
"type": "Identifier",
"start":16,"end":17,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":3},"identifierName":"B"},
"name": "B"
}
}
],
"hasUnknownMembers": true
}
}
],
"directives": []
}
}

View File

@ -1339,23 +1339,27 @@ export interface EnumBooleanBody extends BaseNode {
type: "EnumBooleanBody";
members: Array<EnumBooleanMember>;
explicitType: boolean;
hasUnknownMembers: boolean;
}
export interface EnumNumberBody extends BaseNode {
type: "EnumNumberBody";
members: Array<EnumNumberMember>;
explicitType: boolean;
hasUnknownMembers: boolean;
}
export interface EnumStringBody extends BaseNode {
type: "EnumStringBody";
members: Array<EnumStringMember | EnumDefaultedMember>;
explicitType: boolean;
hasUnknownMembers: boolean;
}
export interface EnumSymbolBody extends BaseNode {
type: "EnumSymbolBody";
members: Array<EnumDefaultedMember>;
hasUnknownMembers: boolean;
}
export interface EnumBooleanMember extends BaseNode {

View File

@ -492,6 +492,7 @@ defineType("EnumBooleanBody", {
fields: {
explicitType: validate(assertValueType("boolean")),
members: validateArrayOfType("EnumBooleanMember"),
hasUnknownMembers: validate(assertValueType("boolean")),
},
});
@ -501,6 +502,7 @@ defineType("EnumNumberBody", {
fields: {
explicitType: validate(assertValueType("boolean")),
members: validateArrayOfType("EnumNumberMember"),
hasUnknownMembers: validate(assertValueType("boolean")),
},
});
@ -510,6 +512,7 @@ defineType("EnumStringBody", {
fields: {
explicitType: validate(assertValueType("boolean")),
members: validateArrayOfType(["EnumStringMember", "EnumDefaultedMember"]),
hasUnknownMembers: validate(assertValueType("boolean")),
},
});
@ -518,6 +521,7 @@ defineType("EnumSymbolBody", {
visitor: ["members"],
fields: {
members: validateArrayOfType("EnumDefaultedMember"),
hasUnknownMembers: validate(assertValueType("boolean")),
},
});