[flow] Add support for parsing _ as implicit instantiation in call/new (#8883)

* [flow] Add support for parsing  as implicit instantiation in call/new

* Update flow tests and fix underscore being a reserved type

* Rebase onto flow-test

* Fix flow commit hash
This commit is contained in:
Jordan Brown 2018-11-05 13:45:40 -05:00 committed by Daniel Tschinder
parent c6d2f45cab
commit f216a7b06f
18 changed files with 1328 additions and 4 deletions

View File

@ -1,5 +1,5 @@
MAKEFLAGS = -j1 MAKEFLAGS = -j1
FLOW_COMMIT = bea8b83f50f597454941d2a7ecef6e93a881e576 FLOW_COMMIT = e192e1a4793dd8e43415fbfe8046d832cb513c8b
TEST262_COMMIT = 72f1cfa2abd66a69b29e9b7d691a8ae8c5a7a00f TEST262_COMMIT = 72f1cfa2abd66a69b29e9b7d691a8ae8c5a7a00f
# Fix color output until TravisCI fixes https://github.com/travis-ci/travis-ci/issues/7967 # Fix color output until TravisCI fixes https://github.com/travis-ci/travis-ci/issues/7967
@ -82,7 +82,7 @@ test-ci-coverage:
bootstrap-flow: bootstrap-flow:
rm -rf ./build/flow rm -rf ./build/flow
mkdir -p ./build mkdir -p ./build
git clone --branch=master --single-branch --shallow-since=2017-01-01 https://github.com/facebook/flow.git ./build/flow git clone --branch=master --single-branch --shallow-since=2018-11-01 https://github.com/facebook/flow.git ./build/flow
cd build/flow && git checkout $(FLOW_COMMIT) cd build/flow && git checkout $(FLOW_COMMIT)
test-flow: test-flow:

View File

@ -23,6 +23,9 @@ const primitiveTypes = [
"true", "true",
"typeof", "typeof",
"void", "void",
"interface",
"extends",
"_",
]; ];
function isEsModuleType(bodyElement: N.Node): boolean { function isEsModuleType(bodyElement: N.Node): boolean {
@ -490,6 +493,15 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return this.finishNode(node, "InterfaceDeclaration"); return this.finishNode(node, "InterfaceDeclaration");
} }
checkNotUnderscore(word: string) {
if (word === "_") {
throw this.unexpected(
null,
"`_` is only allowed as a type argument to call or new",
);
}
}
checkReservedType(word: string, startLoc: number) { checkReservedType(word: string, startLoc: number) {
if (primitiveTypes.indexOf(word) > -1) { if (primitiveTypes.indexOf(word) > -1) {
this.raise(startLoc, `Cannot overwrite primitive type ${word}`); this.raise(startLoc, `Cannot overwrite primitive type ${word}`);
@ -654,6 +666,27 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return this.finishNode(node, "TypeParameterInstantiation"); return this.finishNode(node, "TypeParameterInstantiation");
} }
flowParseTypeParameterInstantiationCallOrNew(): N.TypeParameterInstantiation {
const node = this.startNode();
const oldInType = this.state.inType;
node.params = [];
this.state.inType = true;
this.expectRelational("<");
while (!this.isRelational(">")) {
node.params.push(this.flowParseTypeOrImplicitInstantiation());
if (!this.isRelational(">")) {
this.expect(tt.comma);
}
}
this.expectRelational(">");
this.state.inType = oldInType;
return this.finishNode(node, "TypeParameterInstantiation");
}
flowParseInterfaceType(): N.FlowInterfaceType { flowParseInterfaceType(): N.FlowInterfaceType {
const node = this.startNode(); const node = this.startNode();
this.expectContextual("interface"); this.expectContextual("interface");
@ -1176,6 +1209,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return this.finishNode(node, "StringTypeAnnotation"); return this.finishNode(node, "StringTypeAnnotation");
default: default:
this.checkNotUnderscore(id.name);
return this.flowParseGenericType(startPos, startLoc, id); return this.flowParseGenericType(startPos, startLoc, id);
} }
} }
@ -1431,6 +1465,17 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return type; return type;
} }
flowParseTypeOrImplicitInstantiation(): N.FlowTypeAnnotation {
if (this.state.type === tt.name && this.state.value === "_") {
const startPos = this.state.start;
const startLoc = this.state.startLoc;
const node = this.parseIdentifier();
return this.flowParseGenericType(startPos, startLoc, node);
} else {
return this.flowParseType();
}
}
flowParseTypeAnnotation(): N.FlowTypeAnnotation { flowParseTypeAnnotation(): N.FlowTypeAnnotation {
const node = this.startNode(); const node = this.startNode();
node.typeAnnotation = this.flowParseTypeInitialiser(); node.typeAnnotation = this.flowParseTypeInitialiser();
@ -2582,7 +2627,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
node.callee = base; node.callee = base;
const state = this.state.clone(); const state = this.state.clone();
try { try {
node.typeArguments = this.flowParseTypeParameterInstantiation(); node.typeArguments = this.flowParseTypeParameterInstantiationCallOrNew();
this.expect(tt.parenL); this.expect(tt.parenL);
node.arguments = this.parseCallExpressionArguments(tt.parenR, false); node.arguments = this.parseCallExpressionArguments(tt.parenR, false);
if (subscriptState.optionalChainMember) { if (subscriptState.optionalChainMember) {
@ -2613,7 +2658,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
if (this.shouldParseTypes() && this.isRelational("<")) { if (this.shouldParseTypes() && this.isRelational("<")) {
const state = this.state.clone(); const state = this.state.clone();
try { try {
targs = this.flowParseTypeParameterInstantiation(); targs = this.flowParseTypeParameterInstantiationCallOrNew();
} catch (e) { } catch (e) {
if (e instanceof SyntaxError) { if (e instanceof SyntaxError) {
this.state = state; this.state = state;

View File

@ -0,0 +1,8 @@
//@flow
test<
_,
_,
number,
_,
_,
>();

View File

@ -0,0 +1,283 @@
{
"type": "File",
"start": 0,
"end": 48,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 8,
"column": 4
}
},
"program": {
"type": "Program",
"start": 0,
"end": 48,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 8,
"column": 4
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start": 8,
"end": 48,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 8,
"column": 4
}
},
"expression": {
"type": "CallExpression",
"start": 8,
"end": 47,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 8,
"column": 3
}
},
"callee": {
"type": "Identifier",
"start": 8,
"end": 12,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 4
},
"identifierName": "test"
},
"name": "test"
},
"typeArguments": {
"type": "TypeParameterInstantiation",
"start": 12,
"end": 45,
"loc": {
"start": {
"line": 2,
"column": 4
},
"end": {
"line": 8,
"column": 1
}
},
"params": [
{
"type": "GenericTypeAnnotation",
"start": 16,
"end": 17,
"loc": {
"start": {
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 3
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 16,
"end": 17,
"loc": {
"start": {
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 3
},
"identifierName": "_"
},
"name": "_"
}
},
{
"type": "GenericTypeAnnotation",
"start": 21,
"end": 22,
"loc": {
"start": {
"line": 4,
"column": 2
},
"end": {
"line": 4,
"column": 3
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 21,
"end": 22,
"loc": {
"start": {
"line": 4,
"column": 2
},
"end": {
"line": 4,
"column": 3
},
"identifierName": "_"
},
"name": "_"
}
},
{
"type": "NumberTypeAnnotation",
"start": 26,
"end": 32,
"loc": {
"start": {
"line": 5,
"column": 2
},
"end": {
"line": 5,
"column": 8
}
}
},
{
"type": "GenericTypeAnnotation",
"start": 36,
"end": 37,
"loc": {
"start": {
"line": 6,
"column": 2
},
"end": {
"line": 6,
"column": 3
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 36,
"end": 37,
"loc": {
"start": {
"line": 6,
"column": 2
},
"end": {
"line": 6,
"column": 3
},
"identifierName": "_"
},
"name": "_"
}
},
{
"type": "GenericTypeAnnotation",
"start": 41,
"end": 42,
"loc": {
"start": {
"line": 7,
"column": 2
},
"end": {
"line": 7,
"column": 3
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 41,
"end": 42,
"loc": {
"start": {
"line": 7,
"column": 2
},
"end": {
"line": 7,
"column": 3
},
"identifierName": "_"
},
"name": "_"
}
}
]
},
"arguments": []
},
"leadingComments": [
{
"type": "CommentLine",
"value": "@flow",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
}
}
]
}
],
"directives": []
},
"comments": [
{
"type": "CommentLine",
"value": "@flow",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
}
}
]
}

View File

@ -0,0 +1,2 @@
//@flow
var x: Generic<_> = 3;

View File

@ -0,0 +1,5 @@
{
"sourceType": "module",
"plugins": ["jsx", "flow"],
"throws": "`_` is only allowed as a type argument to call or new (2:16)"
}

View File

@ -0,0 +1,2 @@
//@flow
type _ = number;

View File

@ -0,0 +1,8 @@
{
"sourceType": "module",
"plugins": [
"jsx",
"flow"
],
"throws": "Cannot overwrite primitive type _ (2:5)"
}

View File

@ -0,0 +1,2 @@
//@flow
type Generic<_> = _;

View File

@ -0,0 +1,8 @@
{
"sourceType": "module",
"plugins": [
"jsx",
"flow"
],
"throws": "Cannot overwrite primitive type _ (2:13)"
}

View File

@ -0,0 +1,2 @@
//@flow
test<number, _, string, _, _, _, Foo, Bar, Baz>();

View File

@ -0,0 +1,397 @@
{
"type": "File",
"start": 0,
"end": 58,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 50
}
},
"program": {
"type": "Program",
"start": 0,
"end": 58,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 50
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start": 8,
"end": 58,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 50
}
},
"expression": {
"type": "CallExpression",
"start": 8,
"end": 57,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 49
}
},
"callee": {
"type": "Identifier",
"start": 8,
"end": 12,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 4
},
"identifierName": "test"
},
"name": "test"
},
"typeArguments": {
"type": "TypeParameterInstantiation",
"start": 12,
"end": 55,
"loc": {
"start": {
"line": 2,
"column": 4
},
"end": {
"line": 2,
"column": 47
}
},
"params": [
{
"type": "NumberTypeAnnotation",
"start": 13,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 5
},
"end": {
"line": 2,
"column": 11
}
}
},
{
"type": "GenericTypeAnnotation",
"start": 21,
"end": 22,
"loc": {
"start": {
"line": 2,
"column": 13
},
"end": {
"line": 2,
"column": 14
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 21,
"end": 22,
"loc": {
"start": {
"line": 2,
"column": 13
},
"end": {
"line": 2,
"column": 14
},
"identifierName": "_"
},
"name": "_"
}
},
{
"type": "StringTypeAnnotation",
"start": 24,
"end": 30,
"loc": {
"start": {
"line": 2,
"column": 16
},
"end": {
"line": 2,
"column": 22
}
}
},
{
"type": "GenericTypeAnnotation",
"start": 32,
"end": 33,
"loc": {
"start": {
"line": 2,
"column": 24
},
"end": {
"line": 2,
"column": 25
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 32,
"end": 33,
"loc": {
"start": {
"line": 2,
"column": 24
},
"end": {
"line": 2,
"column": 25
},
"identifierName": "_"
},
"name": "_"
}
},
{
"type": "GenericTypeAnnotation",
"start": 35,
"end": 36,
"loc": {
"start": {
"line": 2,
"column": 27
},
"end": {
"line": 2,
"column": 28
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 35,
"end": 36,
"loc": {
"start": {
"line": 2,
"column": 27
},
"end": {
"line": 2,
"column": 28
},
"identifierName": "_"
},
"name": "_"
}
},
{
"type": "GenericTypeAnnotation",
"start": 38,
"end": 39,
"loc": {
"start": {
"line": 2,
"column": 30
},
"end": {
"line": 2,
"column": 31
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 38,
"end": 39,
"loc": {
"start": {
"line": 2,
"column": 30
},
"end": {
"line": 2,
"column": 31
},
"identifierName": "_"
},
"name": "_"
}
},
{
"type": "GenericTypeAnnotation",
"start": 41,
"end": 44,
"loc": {
"start": {
"line": 2,
"column": 33
},
"end": {
"line": 2,
"column": 36
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 41,
"end": 44,
"loc": {
"start": {
"line": 2,
"column": 33
},
"end": {
"line": 2,
"column": 36
},
"identifierName": "Foo"
},
"name": "Foo"
}
},
{
"type": "GenericTypeAnnotation",
"start": 46,
"end": 49,
"loc": {
"start": {
"line": 2,
"column": 38
},
"end": {
"line": 2,
"column": 41
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 46,
"end": 49,
"loc": {
"start": {
"line": 2,
"column": 38
},
"end": {
"line": 2,
"column": 41
},
"identifierName": "Bar"
},
"name": "Bar"
}
},
{
"type": "GenericTypeAnnotation",
"start": 51,
"end": 54,
"loc": {
"start": {
"line": 2,
"column": 43
},
"end": {
"line": 2,
"column": 46
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 51,
"end": 54,
"loc": {
"start": {
"line": 2,
"column": 43
},
"end": {
"line": 2,
"column": 46
},
"identifierName": "Baz"
},
"name": "Baz"
}
}
]
},
"arguments": []
},
"leadingComments": [
{
"type": "CommentLine",
"value": "@flow",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
}
}
]
}
],
"directives": []
},
"comments": [
{
"type": "CommentLine",
"value": "@flow",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
}
}
]
}

View File

@ -0,0 +1,2 @@
//@flow
test<_>();

View File

@ -0,0 +1,169 @@
{
"type": "File",
"start": 0,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 10
}
},
"program": {
"type": "Program",
"start": 0,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 10
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start": 8,
"end": 18,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 10
}
},
"expression": {
"type": "CallExpression",
"start": 8,
"end": 17,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 9
}
},
"callee": {
"type": "Identifier",
"start": 8,
"end": 12,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 4
},
"identifierName": "test"
},
"name": "test"
},
"typeArguments": {
"type": "TypeParameterInstantiation",
"start": 12,
"end": 15,
"loc": {
"start": {
"line": 2,
"column": 4
},
"end": {
"line": 2,
"column": 7
}
},
"params": [
{
"type": "GenericTypeAnnotation",
"start": 13,
"end": 14,
"loc": {
"start": {
"line": 2,
"column": 5
},
"end": {
"line": 2,
"column": 6
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 13,
"end": 14,
"loc": {
"start": {
"line": 2,
"column": 5
},
"end": {
"line": 2,
"column": 6
},
"identifierName": "_"
},
"name": "_"
}
}
]
},
"arguments": []
},
"leadingComments": [
{
"type": "CommentLine",
"value": "@flow",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
}
}
]
}
],
"directives": []
},
"comments": [
{
"type": "CommentLine",
"value": "@flow",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
}
}
]
}

View File

@ -0,0 +1,2 @@
//@flow
instance.method()<_>();

View File

@ -0,0 +1,218 @@
{
"type": "File",
"start": 0,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 23
}
},
"program": {
"type": "Program",
"start": 0,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 23
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start": 8,
"end": 31,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 23
}
},
"expression": {
"type": "CallExpression",
"start": 8,
"end": 30,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 22
}
},
"callee": {
"type": "CallExpression",
"start": 8,
"end": 25,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 17
}
},
"callee": {
"type": "MemberExpression",
"start": 8,
"end": 23,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 15
}
},
"object": {
"type": "Identifier",
"start": 8,
"end": 16,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 8
},
"identifierName": "instance"
},
"name": "instance"
},
"property": {
"type": "Identifier",
"start": 17,
"end": 23,
"loc": {
"start": {
"line": 2,
"column": 9
},
"end": {
"line": 2,
"column": 15
},
"identifierName": "method"
},
"name": "method"
},
"computed": false
},
"arguments": []
},
"typeArguments": {
"type": "TypeParameterInstantiation",
"start": 25,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 17
},
"end": {
"line": 2,
"column": 20
}
},
"params": [
{
"type": "GenericTypeAnnotation",
"start": 26,
"end": 27,
"loc": {
"start": {
"line": 2,
"column": 18
},
"end": {
"line": 2,
"column": 19
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 26,
"end": 27,
"loc": {
"start": {
"line": 2,
"column": 18
},
"end": {
"line": 2,
"column": 19
},
"identifierName": "_"
},
"name": "_"
}
}
]
},
"arguments": []
},
"leadingComments": [
{
"type": "CommentLine",
"value": "@flow",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
}
}
]
}
],
"directives": []
},
"comments": [
{
"type": "CommentLine",
"value": "@flow",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
}
}
]
}

View File

@ -0,0 +1,2 @@
//@flow
new test<_>();

View File

@ -0,0 +1,169 @@
{
"type": "File",
"start": 0,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 14
}
},
"program": {
"type": "Program",
"start": 0,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 14
}
},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start": 8,
"end": 22,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 14
}
},
"expression": {
"type": "NewExpression",
"start": 8,
"end": 21,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 13
}
},
"callee": {
"type": "Identifier",
"start": 12,
"end": 16,
"loc": {
"start": {
"line": 2,
"column": 4
},
"end": {
"line": 2,
"column": 8
},
"identifierName": "test"
},
"name": "test"
},
"typeArguments": {
"type": "TypeParameterInstantiation",
"start": 16,
"end": 19,
"loc": {
"start": {
"line": 2,
"column": 8
},
"end": {
"line": 2,
"column": 11
}
},
"params": [
{
"type": "GenericTypeAnnotation",
"start": 17,
"end": 18,
"loc": {
"start": {
"line": 2,
"column": 9
},
"end": {
"line": 2,
"column": 10
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 17,
"end": 18,
"loc": {
"start": {
"line": 2,
"column": 9
},
"end": {
"line": 2,
"column": 10
},
"identifierName": "_"
},
"name": "_"
}
}
]
},
"arguments": []
},
"leadingComments": [
{
"type": "CommentLine",
"value": "@flow",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
}
}
]
}
],
"directives": []
},
"comments": [
{
"type": "CommentLine",
"value": "@flow",
"start": 0,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 7
}
}
}
]
}