TypeScript Constant contexts (#9534)
* Add as const fixtures * parse constant context * parse constant context * quick check for literal * code review, better error message, check array elements * Removed unneeded test cases
This commit is contained in:
committed by
Nicolò Ribaudo
parent
0a69b45126
commit
25a3825a1d
@@ -321,6 +321,44 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
return this.finishNode(node, "TSTypeParameterDeclaration");
|
||||
}
|
||||
|
||||
tsTryNextParseConstantContext(): ?N.TsTypeReference {
|
||||
if (this.lookahead().type === tt._const) {
|
||||
this.next();
|
||||
return this.tsParseTypeReference();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
tsCheckLiteralForConstantContext(node: N.Node) {
|
||||
switch (node.type) {
|
||||
case "StringLiteral":
|
||||
case "TemplateLiteral":
|
||||
case "NumericLiteral":
|
||||
case "BooleanLiteral":
|
||||
case "SpreadElement":
|
||||
case "ObjectMethod":
|
||||
case "ObjectExpression":
|
||||
return;
|
||||
case "ArrayExpression":
|
||||
return (node: N.ArrayExpression).elements.forEach(element => {
|
||||
if (element) {
|
||||
this.tsCheckLiteralForConstantContext(element);
|
||||
}
|
||||
});
|
||||
case "ObjectProperty":
|
||||
return this.tsCheckLiteralForConstantContext(
|
||||
(node: N.ObjectProperty).value,
|
||||
);
|
||||
case "UnaryExpression":
|
||||
return this.tsCheckLiteralForConstantContext(node.argument);
|
||||
default:
|
||||
this.raise(
|
||||
node.start,
|
||||
"Only literal values are allowed in constant contexts",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: In TypeScript implementation we must provide `yieldContext` and `awaitContext`,
|
||||
// but here it's always false, because this is only used for types.
|
||||
tsFillSignature(
|
||||
@@ -937,12 +975,13 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
|
||||
tsParseTypeAssertion(): N.TsTypeAssertion {
|
||||
const node: N.TsTypeAssertion = this.startNode();
|
||||
this.next(); // <
|
||||
// Not actually necessary to set state.inType because we never reach here if JSX plugin is enabled,
|
||||
// but need `tsInType` to satisfy the assertion in `tsParseType`.
|
||||
node.typeAnnotation = this.tsInType(() => this.tsParseType());
|
||||
const _const = this.tsTryNextParseConstantContext();
|
||||
node.typeAnnotation = _const || this.tsNextThenParseType();
|
||||
this.expectRelational(">");
|
||||
node.expression = this.parseMaybeUnary();
|
||||
if (_const) {
|
||||
this.tsCheckLiteralForConstantContext(node.expression);
|
||||
}
|
||||
return this.finishNode(node, "TSTypeAssertion");
|
||||
}
|
||||
|
||||
@@ -1605,7 +1644,13 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
||||
leftStartLoc,
|
||||
);
|
||||
node.expression = left;
|
||||
node.typeAnnotation = this.tsNextThenParseType();
|
||||
const _const = this.tsTryNextParseConstantContext();
|
||||
if (_const) {
|
||||
this.tsCheckLiteralForConstantContext(node.expression);
|
||||
node.typeAnnotation = _const;
|
||||
} else {
|
||||
node.typeAnnotation = this.tsNextThenParseType();
|
||||
}
|
||||
this.finishNode(node, "TSAsExpression");
|
||||
return this.parseExprOp(
|
||||
node,
|
||||
|
||||
Reference in New Issue
Block a user