Parse JSDoc ...T and T= only at top-level JSDoc (#22661)

* Parse JSDoc ...T and T= only at top-level JSDoc

...T and T= should only be legal at the top level of a type, and only in
JSDoc, since at least T= is ambiguous elsewhere. This PR changes parsing
to make that happen. The resulting parse tree is now simpler, allowing
me to get rid of some code I had to add in the checker.

* Extract JSDoc type parsing into its own function

* PR comments:return from parseJSDocType
This commit is contained in:
Nathan Shively-Sanders
2018-03-16 16:08:42 -07:00
committed by GitHub
parent 5fd3ed2c10
commit bb23e9601f
11 changed files with 56 additions and 114 deletions

View File

@@ -2204,11 +2204,18 @@ namespace ts {
}
function parseJSDocAllType(): JSDocAllType {
const result = <JSDocAllType>createNode(SyntaxKind.JSDocAllType);
const result = createNode(SyntaxKind.JSDocAllType) as JSDocAllType;
nextToken();
return finishNode(result);
}
function parseJSDocNonNullableType(): TypeNode {
const result = createNode(SyntaxKind.JSDocNonNullableType) as JSDocNonNullableType;
nextToken();
result.type = parseNonArrayType();
return finishNode(result);
}
function parseJSDocUnknownOrNullableType(): JSDocUnknownType | JSDocNullableType {
const pos = scanner.getStartPos();
// skip the ?
@@ -2259,15 +2266,22 @@ namespace ts {
parameter.name = parseIdentifierName();
parseExpected(SyntaxKind.ColonToken);
}
parameter.type = parseType();
parameter.type = parseJSDocType();
return finishNode(parameter);
}
function parseJSDocNodeWithType(kind: SyntaxKind.JSDocVariadicType | SyntaxKind.JSDocNonNullableType): TypeNode {
const result = createNode(kind) as JSDocVariadicType | JSDocNonNullableType;
nextToken();
result.type = parseNonArrayType();
return finishNode(result);
function parseJSDocType() {
const dotdotdot = parseOptionalToken(SyntaxKind.DotDotDotToken);
let type = parseType();
if (dotdotdot) {
const variadic = createNode(SyntaxKind.JSDocVariadicType, dotdotdot.pos) as JSDocVariadicType;
variadic.type = type;
type = finishNode(variadic);
}
if (token() === SyntaxKind.EqualsToken) {
return createJSDocPostfixType(SyntaxKind.JSDocOptionalType, type);
}
return type;
}
function parseTypeQuery(): TypeQueryNode {
@@ -2732,7 +2746,7 @@ namespace ts {
case SyntaxKind.FunctionKeyword:
return parseJSDocFunctionType();
case SyntaxKind.ExclamationToken:
return parseJSDocNodeWithType(SyntaxKind.JSDocNonNullableType);
return parseJSDocNonNullableType();
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:
@@ -2817,13 +2831,6 @@ namespace ts {
let type = parseNonArrayType();
while (!scanner.hasPrecedingLineBreak()) {
switch (token()) {
case SyntaxKind.EqualsToken:
// only parse postfix = inside jsdoc, because it's ambiguous elsewhere
if (!(contextFlags & NodeFlags.JSDoc)) {
return type;
}
type = createJSDocPostfixType(SyntaxKind.JSDocOptionalType, type);
break;
case SyntaxKind.ExclamationToken:
type = createJSDocPostfixType(SyntaxKind.JSDocNonNullableType, type);
break;
@@ -2889,12 +2896,6 @@ namespace ts {
return parseTypeOperator(operator);
case SyntaxKind.InferKeyword:
return parseInferType();
case SyntaxKind.DotDotDotToken: {
const result = createNode(SyntaxKind.JSDocVariadicType) as JSDocVariadicType;
nextToken();
result.type = parsePostfixTypeOrHigher();
return finishNode(result);
}
}
return parsePostfixTypeOrHigher();
}
@@ -6156,7 +6157,7 @@ namespace ts {
const result = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos());
const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken);
result.type = doInsideOfContext(NodeFlags.JSDoc, parseType);
result.type = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType);
if (!mayOmitBraces || hasBrace) {
parseExpected(SyntaxKind.CloseBraceToken);
}