Merge pull request #23253 from Kingwl/definite-assignment-assertion-improve
improve parser and error message if definite assignment assertions in…
This commit is contained in:
commit
5d65e86756
|
@ -29024,10 +29024,14 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function checkGrammarForInvalidQuestionMark(questionToken: Node | undefined, message: DiagnosticMessage): boolean {
|
||||
function checkGrammarForInvalidQuestionMark(questionToken: QuestionToken | undefined, message: DiagnosticMessage): boolean {
|
||||
return !!questionToken && grammarErrorOnNode(questionToken, message);
|
||||
}
|
||||
|
||||
function checkGrammarForInvalidExclamationToken(exclamationToken: ExclamationToken | undefined, message: DiagnosticMessage): boolean {
|
||||
return !!exclamationToken && grammarErrorOnNode(exclamationToken, message);
|
||||
}
|
||||
|
||||
function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression, inDestructuring: boolean) {
|
||||
const enum Flags {
|
||||
Property = 1,
|
||||
|
@ -29072,8 +29076,10 @@ namespace ts {
|
|||
// and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
|
||||
let currentKind: Flags;
|
||||
switch (prop.kind) {
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
checkGrammarForInvalidExclamationToken(prop.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
|
||||
/* tslint:disable:no-switch-case-fall-through */
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
// Grammar checking for computedPropertyName and shorthandPropertyAssignment
|
||||
checkGrammarForInvalidQuestionMark(prop.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional);
|
||||
if (name.kind === SyntaxKind.NumericLiteral) {
|
||||
|
@ -29314,6 +29320,9 @@ namespace ts {
|
|||
else if (checkGrammarForInvalidQuestionMark(node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional)) {
|
||||
return true;
|
||||
}
|
||||
else if (checkGrammarForInvalidExclamationToken(node.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context)) {
|
||||
return true;
|
||||
}
|
||||
else if (node.body === undefined) {
|
||||
return grammarErrorAtPos(node, node.end - 1, ";".length, Diagnostics._0_expected, "{");
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ namespace ts {
|
|||
visitNodes(cbNode, cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).name) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).questionToken) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).exclamationToken) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).equalsToken) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).objectAssignmentInitializer);
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
|
@ -156,6 +157,7 @@ namespace ts {
|
|||
visitNode(cbNode, (<FunctionLikeDeclaration>node).asteriskToken) ||
|
||||
visitNode(cbNode, (<FunctionLikeDeclaration>node).name) ||
|
||||
visitNode(cbNode, (<FunctionLikeDeclaration>node).questionToken) ||
|
||||
visitNode(cbNode, (<FunctionLikeDeclaration>node).exclamationToken) ||
|
||||
visitNodes(cbNode, cbNodes, (<FunctionLikeDeclaration>node).typeParameters) ||
|
||||
visitNodes(cbNode, cbNodes, (<FunctionLikeDeclaration>node).parameters) ||
|
||||
visitNode(cbNode, (<FunctionLikeDeclaration>node).type) ||
|
||||
|
@ -4713,8 +4715,10 @@ namespace ts {
|
|||
const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
|
||||
const tokenIsIdentifier = isIdentifier();
|
||||
node.name = parsePropertyName();
|
||||
// Disallowing of optional property assignments happens in the grammar checker.
|
||||
// Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker.
|
||||
(<MethodDeclaration>node).questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
|
||||
(<MethodDeclaration>node).exclamationToken = parseOptionalToken(SyntaxKind.ExclamationToken);
|
||||
|
||||
if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) {
|
||||
return parseMethodDeclaration(<MethodDeclaration>node, asteriskToken);
|
||||
}
|
||||
|
|
|
@ -883,6 +883,7 @@ namespace ts {
|
|||
kind: SyntaxKind.ShorthandPropertyAssignment;
|
||||
name: Identifier;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
// used when ObjectLiteralExpression is used in ObjectAssignmentPattern
|
||||
// it is grammar error to appear in actual object initializer
|
||||
equalsToken?: Token<SyntaxKind.EqualsToken>;
|
||||
|
@ -941,6 +942,7 @@ namespace ts {
|
|||
|
||||
asteriskToken?: AsteriskToken;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
body?: Block | Expression;
|
||||
}
|
||||
|
||||
|
|
|
@ -632,6 +632,7 @@ declare namespace ts {
|
|||
kind: SyntaxKind.ShorthandPropertyAssignment;
|
||||
name: Identifier;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
equalsToken?: Token<SyntaxKind.EqualsToken>;
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
|
@ -668,6 +669,7 @@ declare namespace ts {
|
|||
_functionLikeDeclarationBrand: any;
|
||||
asteriskToken?: AsteriskToken;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
body?: Block | Expression;
|
||||
}
|
||||
type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction;
|
||||
|
|
|
@ -632,6 +632,7 @@ declare namespace ts {
|
|||
kind: SyntaxKind.ShorthandPropertyAssignment;
|
||||
name: Identifier;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
equalsToken?: Token<SyntaxKind.EqualsToken>;
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
|
@ -668,6 +669,7 @@ declare namespace ts {
|
|||
_functionLikeDeclarationBrand: any;
|
||||
asteriskToken?: AsteriskToken;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
body?: Block | Expression;
|
||||
}
|
||||
type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction;
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts(2,16): error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts(5,7): error TS1162: An object member cannot be declared optional.
|
||||
|
||||
|
||||
==== tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts (2 errors) ====
|
||||
const a: string | undefined = 'ff';
|
||||
const foo = { a! }
|
||||
~
|
||||
!!! error TS1255: A definite assignment assertion '!' is not permitted in this context.
|
||||
|
||||
const bar = {
|
||||
a ? () { }
|
||||
~
|
||||
!!! error TS1162: An object member cannot be declared optional.
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
//// [definiteAssignmentAssertionsWithObjectShortHand.ts]
|
||||
const a: string | undefined = 'ff';
|
||||
const foo = { a! }
|
||||
|
||||
const bar = {
|
||||
a ? () { }
|
||||
}
|
||||
|
||||
//// [definiteAssignmentAssertionsWithObjectShortHand.js]
|
||||
"use strict";
|
||||
var a = 'ff';
|
||||
var foo = { a: a };
|
||||
var bar = {
|
||||
a: function () { }
|
||||
};
|
||||
|
||||
|
||||
//// [definiteAssignmentAssertionsWithObjectShortHand.d.ts]
|
||||
declare const a: string | undefined;
|
||||
declare const foo: {
|
||||
a: string;
|
||||
};
|
||||
declare const bar: {};
|
|
@ -0,0 +1,14 @@
|
|||
=== tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts ===
|
||||
const a: string | undefined = 'ff';
|
||||
>a : Symbol(a, Decl(definiteAssignmentAssertionsWithObjectShortHand.ts, 0, 5))
|
||||
|
||||
const foo = { a! }
|
||||
>foo : Symbol(foo, Decl(definiteAssignmentAssertionsWithObjectShortHand.ts, 1, 5))
|
||||
>a : Symbol(a, Decl(definiteAssignmentAssertionsWithObjectShortHand.ts, 1, 13))
|
||||
|
||||
const bar = {
|
||||
>bar : Symbol(bar, Decl(definiteAssignmentAssertionsWithObjectShortHand.ts, 3, 5))
|
||||
|
||||
a ? () { }
|
||||
>a : Symbol(a, Decl(definiteAssignmentAssertionsWithObjectShortHand.ts, 3, 13))
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
=== tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts ===
|
||||
const a: string | undefined = 'ff';
|
||||
>a : string | undefined
|
||||
>'ff' : "ff"
|
||||
|
||||
const foo = { a! }
|
||||
>foo : { a: string; }
|
||||
>{ a! } : { a: string; }
|
||||
>a : string
|
||||
|
||||
const bar = {
|
||||
>bar : {}
|
||||
>{ a ? () { }} : {}
|
||||
|
||||
a ? () { }
|
||||
>a : (() => void) | undefined
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
const a: string | undefined = 'ff';
|
||||
const foo = { a! }
|
||||
|
||||
const bar = {
|
||||
a ? () { }
|
||||
}
|
Loading…
Reference in a new issue