[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:
committed by
Daniel Tschinder
parent
c6d2f45cab
commit
f216a7b06f
@@ -23,6 +23,9 @@ const primitiveTypes = [
|
||||
"true",
|
||||
"typeof",
|
||||
"void",
|
||||
"interface",
|
||||
"extends",
|
||||
"_",
|
||||
];
|
||||
|
||||
function isEsModuleType(bodyElement: N.Node): boolean {
|
||||
@@ -490,6 +493,15 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
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) {
|
||||
if (primitiveTypes.indexOf(word) > -1) {
|
||||
this.raise(startLoc, `Cannot overwrite primitive type ${word}`);
|
||||
@@ -654,6 +666,27 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
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 {
|
||||
const node = this.startNode();
|
||||
this.expectContextual("interface");
|
||||
@@ -1176,6 +1209,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
return this.finishNode(node, "StringTypeAnnotation");
|
||||
|
||||
default:
|
||||
this.checkNotUnderscore(id.name);
|
||||
return this.flowParseGenericType(startPos, startLoc, id);
|
||||
}
|
||||
}
|
||||
@@ -1431,6 +1465,17 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
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 {
|
||||
const node = this.startNode();
|
||||
node.typeAnnotation = this.flowParseTypeInitialiser();
|
||||
@@ -2582,7 +2627,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
node.callee = base;
|
||||
const state = this.state.clone();
|
||||
try {
|
||||
node.typeArguments = this.flowParseTypeParameterInstantiation();
|
||||
node.typeArguments = this.flowParseTypeParameterInstantiationCallOrNew();
|
||||
this.expect(tt.parenL);
|
||||
node.arguments = this.parseCallExpressionArguments(tt.parenR, false);
|
||||
if (subscriptState.optionalChainMember) {
|
||||
@@ -2613,7 +2658,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
if (this.shouldParseTypes() && this.isRelational("<")) {
|
||||
const state = this.state.clone();
|
||||
try {
|
||||
targs = this.flowParseTypeParameterInstantiation();
|
||||
targs = this.flowParseTypeParameterInstantiationCallOrNew();
|
||||
} catch (e) {
|
||||
if (e instanceof SyntaxError) {
|
||||
this.state = state;
|
||||
|
||||
Reference in New Issue
Block a user