Support Flow's inline interface syntax (#7973)

* Support Flow's inline interface syntax

* Fix babel-generator
This commit is contained in:
Sam Goldman
2018-05-18 14:11:27 +01:00
committed by Brian Ng
parent a40f54f847
commit 6baa36cdc5
11 changed files with 625 additions and 0 deletions

View File

@@ -262,6 +262,18 @@ function andSeparator() {
this.space();
}
export function InterfaceTypeAnnotation(node: Object) {
this.word("interface");
if (node.extends && node.extends.length) {
this.space();
this.word("extends");
this.space();
this.printList(node.extends, node);
}
this.space();
this.print(node.body, node);
}
export function IntersectionTypeAnnotation(node: Object) {
this.printJoin(node.types, node, { separator: andSeparator });
}

View File

@@ -0,0 +1,3 @@
type A = interface { p: string };
type B = interface extends X { p: string };
type C = interface extends X, Y { p: string };

View File

@@ -0,0 +1,9 @@
type A = interface {
p: string
};
type B = interface extends X {
p: string
};
type C = interface extends X, Y {
p: string
};

View File

@@ -211,6 +211,15 @@ defineType("InterfaceExtends", {
defineInterfaceishType("InterfaceDeclaration");
defineType("InterfaceTypeAnnotation", {
visitor: ["extends", "body"],
aliases: ["Flow", "FlowType"],
fields: {
extends: validateOptional(arrayOfType("InterfaceExtends")),
body: validateType("ObjectTypeAnnotation"),
},
});
defineType("IntersectionTypeAnnotation", {
visitor: ["types"],
aliases: ["Flow", "FlowType"],

View File

@@ -641,6 +641,22 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return this.finishNode(node, "TypeParameterInstantiation");
}
flowParseInterfaceType(): N.FlowInterfaceType {
const node = this.startNode();
this.expectContextual("interface");
node.extends = [];
if (this.eat(tt._extends)) {
do {
node.extends.push(this.flowParseInterfaceExtends());
} while (this.eat(tt.comma));
}
node.body = this.flowParseObjectType(true, false, false);
return this.finishNode(node, "InterfaceTypeAnnotation");
}
flowParseObjectPropertyKey(): N.Expression {
return this.match(tt.num) || this.match(tt.string)
? this.parseExprAtom()
@@ -1087,6 +1103,10 @@ export default (superClass: Class<Parser>): Class<Parser> =>
switch (this.state.type) {
case tt.name:
if (this.isContextual("interface")) {
return this.flowParseInterfaceType();
}
return this.flowIdentToTypeAnnotation(
startPos,
startLoc,

View File

@@ -0,0 +1 @@
type T = interface { p: string }

View File

@@ -0,0 +1,156 @@
{
"type": "File",
"start": 0,
"end": 32,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 32
}
},
"program": {
"type": "Program",
"start": 0,
"end": 32,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 32
}
},
"sourceType": "module",
"body": [
{
"type": "TypeAlias",
"start": 0,
"end": 32,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 32
}
},
"id": {
"type": "Identifier",
"start": 5,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 6
},
"identifierName": "T"
},
"name": "T"
},
"typeParameters": null,
"right": {
"type": "InterfaceTypeAnnotation",
"start": 9,
"end": 32,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 32
}
},
"extends": [],
"body": {
"type": "ObjectTypeAnnotation",
"start": 19,
"end": 32,
"loc": {
"start": {
"line": 1,
"column": 19
},
"end": {
"line": 1,
"column": 32
}
},
"callProperties": [],
"properties": [
{
"type": "ObjectTypeProperty",
"start": 21,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 21
},
"end": {
"line": 1,
"column": 30
}
},
"key": {
"type": "Identifier",
"start": 21,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 21
},
"end": {
"line": 1,
"column": 22
},
"identifierName": "p"
},
"name": "p"
},
"static": false,
"kind": "init",
"method": false,
"value": {
"type": "StringTypeAnnotation",
"start": 24,
"end": 30,
"loc": {
"start": {
"line": 1,
"column": 24
},
"end": {
"line": 1,
"column": 30
}
}
},
"variance": null,
"optional": false
}
],
"indexers": [],
"internalSlots": [],
"exact": false
}
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1 @@
type T = interface extends X, Y { p: string }

View File

@@ -0,0 +1,223 @@
{
"type": "File",
"start": 0,
"end": 45,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 45
}
},
"program": {
"type": "Program",
"start": 0,
"end": 45,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 45
}
},
"sourceType": "module",
"body": [
{
"type": "TypeAlias",
"start": 0,
"end": 45,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 45
}
},
"id": {
"type": "Identifier",
"start": 5,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 6
},
"identifierName": "T"
},
"name": "T"
},
"typeParameters": null,
"right": {
"type": "InterfaceTypeAnnotation",
"start": 9,
"end": 45,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 45
}
},
"extends": [
{
"type": "InterfaceExtends",
"start": 27,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 27
},
"end": {
"line": 1,
"column": 28
}
},
"id": {
"type": "Identifier",
"start": 27,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 27
},
"end": {
"line": 1,
"column": 28
},
"identifierName": "X"
},
"name": "X"
},
"typeParameters": null
},
{
"type": "InterfaceExtends",
"start": 30,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 30
},
"end": {
"line": 1,
"column": 31
}
},
"id": {
"type": "Identifier",
"start": 30,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 30
},
"end": {
"line": 1,
"column": 31
},
"identifierName": "Y"
},
"name": "Y"
},
"typeParameters": null
}
],
"body": {
"type": "ObjectTypeAnnotation",
"start": 32,
"end": 45,
"loc": {
"start": {
"line": 1,
"column": 32
},
"end": {
"line": 1,
"column": 45
}
},
"callProperties": [],
"properties": [
{
"type": "ObjectTypeProperty",
"start": 34,
"end": 43,
"loc": {
"start": {
"line": 1,
"column": 34
},
"end": {
"line": 1,
"column": 43
}
},
"key": {
"type": "Identifier",
"start": 34,
"end": 35,
"loc": {
"start": {
"line": 1,
"column": 34
},
"end": {
"line": 1,
"column": 35
},
"identifierName": "p"
},
"name": "p"
},
"static": false,
"kind": "init",
"method": false,
"value": {
"type": "StringTypeAnnotation",
"start": 37,
"end": 43,
"loc": {
"start": {
"line": 1,
"column": 37
},
"end": {
"line": 1,
"column": 43
}
}
},
"variance": null,
"optional": false
}
],
"indexers": [],
"internalSlots": [],
"exact": false
}
}
}
],
"directives": []
}
}

View File

@@ -0,0 +1 @@
type T = interface extends X { p: string }

View File

@@ -0,0 +1,190 @@
{
"type": "File",
"start": 0,
"end": 42,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 42
}
},
"program": {
"type": "Program",
"start": 0,
"end": 42,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 42
}
},
"sourceType": "module",
"body": [
{
"type": "TypeAlias",
"start": 0,
"end": 42,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 42
}
},
"id": {
"type": "Identifier",
"start": 5,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 6
},
"identifierName": "T"
},
"name": "T"
},
"typeParameters": null,
"right": {
"type": "InterfaceTypeAnnotation",
"start": 9,
"end": 42,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 42
}
},
"extends": [
{
"type": "InterfaceExtends",
"start": 27,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 27
},
"end": {
"line": 1,
"column": 28
}
},
"id": {
"type": "Identifier",
"start": 27,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 27
},
"end": {
"line": 1,
"column": 28
},
"identifierName": "X"
},
"name": "X"
},
"typeParameters": null
}
],
"body": {
"type": "ObjectTypeAnnotation",
"start": 29,
"end": 42,
"loc": {
"start": {
"line": 1,
"column": 29
},
"end": {
"line": 1,
"column": 42
}
},
"callProperties": [],
"properties": [
{
"type": "ObjectTypeProperty",
"start": 31,
"end": 40,
"loc": {
"start": {
"line": 1,
"column": 31
},
"end": {
"line": 1,
"column": 40
}
},
"key": {
"type": "Identifier",
"start": 31,
"end": 32,
"loc": {
"start": {
"line": 1,
"column": 31
},
"end": {
"line": 1,
"column": 32
},
"identifierName": "p"
},
"name": "p"
},
"static": false,
"kind": "init",
"method": false,
"value": {
"type": "StringTypeAnnotation",
"start": 34,
"end": 40,
"loc": {
"start": {
"line": 1,
"column": 34
},
"end": {
"line": 1,
"column": 40
}
}
},
"variance": null,
"optional": false
}
],
"indexers": [],
"internalSlots": [],
"exact": false
}
}
}
],
"directives": []
}
}