mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Add '!' non-null assertion postfix operator
This commit is contained in:
@@ -6878,6 +6878,7 @@ namespace ts {
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
case SyntaxKind.AsExpression:
|
||||
case SyntaxKind.NonNullExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
case SyntaxKind.DeleteExpression:
|
||||
@@ -10383,6 +10384,10 @@ namespace ts {
|
||||
return targetType;
|
||||
}
|
||||
|
||||
function checkNonNullExpression(node: NonNullExpression) {
|
||||
return getNonNullableType(checkExpression(node.expression));
|
||||
}
|
||||
|
||||
function getTypeAtPosition(signature: Signature, pos: number): Type {
|
||||
return signature.hasRestParameter ?
|
||||
pos < signature.parameters.length - 1 ? getTypeOfSymbol(signature.parameters[pos]) : getRestTypeOfSignature(signature) :
|
||||
@@ -11555,6 +11560,8 @@ namespace ts {
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
case SyntaxKind.AsExpression:
|
||||
return checkAssertion(<AssertionExpression>node);
|
||||
case SyntaxKind.NonNullExpression:
|
||||
return checkNonNullExpression(<NonNullExpression>node);
|
||||
case SyntaxKind.DeleteExpression:
|
||||
return checkDeleteExpression(<DeleteExpression>node);
|
||||
case SyntaxKind.VoidExpression:
|
||||
|
||||
+20
-10
@@ -1533,6 +1533,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
case SyntaxKind.JsxExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.NonNullExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
@@ -2077,8 +2078,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
function parenthesizeForAccess(expr: Expression): LeftHandSideExpression {
|
||||
// When diagnosing whether the expression needs parentheses, the decision should be based
|
||||
// on the innermost expression in a chain of nested type assertions.
|
||||
while (expr.kind === SyntaxKind.TypeAssertionExpression || expr.kind === SyntaxKind.AsExpression) {
|
||||
expr = (<AssertionExpression>expr).expression;
|
||||
while (expr.kind === SyntaxKind.TypeAssertionExpression ||
|
||||
expr.kind === SyntaxKind.AsExpression ||
|
||||
expr.kind === SyntaxKind.NonNullExpression) {
|
||||
expr = (<AssertionExpression | NonNullExpression>expr).expression;
|
||||
}
|
||||
|
||||
// isLeftHandSideExpression is almost the correct criterion for when it is not necessary
|
||||
@@ -2326,8 +2329,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
}
|
||||
|
||||
function skipParentheses(node: Expression): Expression {
|
||||
while (node.kind === SyntaxKind.ParenthesizedExpression || node.kind === SyntaxKind.TypeAssertionExpression || node.kind === SyntaxKind.AsExpression) {
|
||||
node = (<ParenthesizedExpression | AssertionExpression>node).expression;
|
||||
while (node.kind === SyntaxKind.ParenthesizedExpression ||
|
||||
node.kind === SyntaxKind.TypeAssertionExpression ||
|
||||
node.kind === SyntaxKind.AsExpression ||
|
||||
node.kind === SyntaxKind.NonNullExpression) {
|
||||
node = (<ParenthesizedExpression | AssertionExpression | NonNullExpression>node).expression;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -2501,13 +2507,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
// not the user. If we didn't want them, the emitter would not have put them
|
||||
// there.
|
||||
if (!nodeIsSynthesized(node) && node.parent.kind !== SyntaxKind.ArrowFunction) {
|
||||
if (node.expression.kind === SyntaxKind.TypeAssertionExpression || node.expression.kind === SyntaxKind.AsExpression) {
|
||||
let operand = (<TypeAssertion>node.expression).expression;
|
||||
if (node.expression.kind === SyntaxKind.TypeAssertionExpression ||
|
||||
node.expression.kind === SyntaxKind.AsExpression ||
|
||||
node.expression.kind === SyntaxKind.NonNullExpression) {
|
||||
let operand = (<TypeAssertion | NonNullExpression>node.expression).expression;
|
||||
|
||||
// Make sure we consider all nested cast expressions, e.g.:
|
||||
// (<any><number><any>-A).x;
|
||||
while (operand.kind === SyntaxKind.TypeAssertionExpression || operand.kind === SyntaxKind.AsExpression) {
|
||||
operand = (<TypeAssertion>operand).expression;
|
||||
while (operand.kind === SyntaxKind.TypeAssertionExpression ||
|
||||
operand.kind === SyntaxKind.AsExpression ||
|
||||
operand.kind === SyntaxKind.NonNullExpression) {
|
||||
operand = (<TypeAssertion | NonNullExpression>operand).expression;
|
||||
}
|
||||
|
||||
// We have an expression of the form: (<Type>SubExpr)
|
||||
@@ -7887,9 +7897,9 @@ const _super = (function (geti, seti) {
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
return emitTaggedTemplateExpression(<TaggedTemplateExpression>node);
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
return emit((<TypeAssertion>node).expression);
|
||||
case SyntaxKind.AsExpression:
|
||||
return emit((<AsExpression>node).expression);
|
||||
case SyntaxKind.NonNullExpression:
|
||||
return emit((<AssertionExpression | NonNullExpression>node).expression);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return emitParenExpression(<ParenthesizedExpression>node);
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
|
||||
@@ -178,6 +178,8 @@ namespace ts {
|
||||
case SyntaxKind.AsExpression:
|
||||
return visitNode(cbNode, (<AsExpression>node).expression) ||
|
||||
visitNode(cbNode, (<AsExpression>node).type);
|
||||
case SyntaxKind.NonNullExpression:
|
||||
return visitNode(cbNode, (<NonNullExpression>node).expression);
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
return visitNode(cbNode, (<ConditionalExpression>node).condition) ||
|
||||
visitNode(cbNode, (<ConditionalExpression>node).questionToken) ||
|
||||
@@ -3726,6 +3728,13 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parseOptional(SyntaxKind.ExclamationToken)) {
|
||||
const nonNullExpression = <NonNullExpression>createNode(SyntaxKind.NonNullExpression, expression.pos);
|
||||
nonNullExpression.expression = expression;
|
||||
expression = finishNode(nonNullExpression);
|
||||
continue;
|
||||
}
|
||||
|
||||
// when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName
|
||||
if (!inDecoratorContext() && parseOptional(SyntaxKind.OpenBracketToken)) {
|
||||
const indexedAccess = <ElementAccessExpression>createNode(SyntaxKind.ElementAccessExpression, expression.pos);
|
||||
|
||||
@@ -240,6 +240,7 @@ namespace ts {
|
||||
OmittedExpression,
|
||||
ExpressionWithTypeArguments,
|
||||
AsExpression,
|
||||
NonNullExpression,
|
||||
|
||||
// Misc
|
||||
TemplateSpan,
|
||||
@@ -1017,6 +1018,11 @@ namespace ts {
|
||||
|
||||
export type AssertionExpression = TypeAssertion | AsExpression;
|
||||
|
||||
// @kind(SyntaxKind.NonNullExpression)
|
||||
export interface NonNullExpression extends LeftHandSideExpression {
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
/// A JSX expression of the form <TagName attrs>...</TagName>
|
||||
// @kind(SyntaxKind.JsxElement)
|
||||
export interface JsxElement extends PrimaryExpression {
|
||||
|
||||
@@ -968,6 +968,7 @@ namespace ts {
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.AsExpression:
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
case SyntaxKind.NonNullExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ClassExpression:
|
||||
@@ -2394,6 +2395,7 @@ namespace ts {
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NonNullExpression:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
|
||||
Reference in New Issue
Block a user