From 55beb14bca0b9ffebd1df839a21b7715961d41c1 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Jun 2017 14:40:01 -0700 Subject: [PATCH 1/2] Checking references skips assertions+parentheses --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bbd38ddbc5d..46e60427468 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16880,7 +16880,7 @@ namespace ts { function checkReferenceExpression(expr: Expression, invalidReferenceMessage: DiagnosticMessage): boolean { // References are combinations of identifiers, parentheses, and property accesses. - const node = skipParentheses(expr); + const node = skipOuterExpressions(expr, OuterExpressionKinds.Assertions | OuterExpressionKinds.Parentheses); if (node.kind !== SyntaxKind.Identifier && node.kind !== SyntaxKind.PropertyAccessExpression && node.kind !== SyntaxKind.ElementAccessExpression) { error(expr, invalidReferenceMessage); return false; From 497d627a027236b5ef69d3bda9d63f55b4578932 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 12 Jun 2017 14:41:10 -0700 Subject: [PATCH 2/2] Test: Allow ++ after non-null assertion --- .../reference/incrementOnNullAssertion.js | 28 ++++++++++ .../incrementOnNullAssertion.symbols | 41 ++++++++++++++ .../reference/incrementOnNullAssertion.types | 53 +++++++++++++++++++ .../compiler/incrementOnNullAssertion.ts | 14 +++++ 4 files changed, 136 insertions(+) create mode 100644 tests/baselines/reference/incrementOnNullAssertion.js create mode 100644 tests/baselines/reference/incrementOnNullAssertion.symbols create mode 100644 tests/baselines/reference/incrementOnNullAssertion.types create mode 100644 tests/cases/compiler/incrementOnNullAssertion.ts diff --git a/tests/baselines/reference/incrementOnNullAssertion.js b/tests/baselines/reference/incrementOnNullAssertion.js new file mode 100644 index 00000000000..1f56fa00f56 --- /dev/null +++ b/tests/baselines/reference/incrementOnNullAssertion.js @@ -0,0 +1,28 @@ +//// [incrementOnNullAssertion.ts] +interface Dictionary { + [myFavouriteType: string]: T | undefined +} +const x = 'bar' +let foo: Dictionary = {} +if (foo[x] === undefined) { + foo[x] = 1 +} +else { + let nu = foo[x] + let n = foo[x] + foo[x]!++ +} + + +//// [incrementOnNullAssertion.js] +"use strict"; +var x = 'bar'; +var foo = {}; +if (foo[x] === undefined) { + foo[x] = 1; +} +else { + var nu = foo[x]; + var n = foo[x]; + foo[x]++; +} diff --git a/tests/baselines/reference/incrementOnNullAssertion.symbols b/tests/baselines/reference/incrementOnNullAssertion.symbols new file mode 100644 index 00000000000..07f37e4aaa7 --- /dev/null +++ b/tests/baselines/reference/incrementOnNullAssertion.symbols @@ -0,0 +1,41 @@ +=== tests/cases/compiler/incrementOnNullAssertion.ts === +interface Dictionary { +>Dictionary : Symbol(Dictionary, Decl(incrementOnNullAssertion.ts, 0, 0)) +>T : Symbol(T, Decl(incrementOnNullAssertion.ts, 0, 21)) + + [myFavouriteType: string]: T | undefined +>myFavouriteType : Symbol(myFavouriteType, Decl(incrementOnNullAssertion.ts, 1, 5)) +>T : Symbol(T, Decl(incrementOnNullAssertion.ts, 0, 21)) +} +const x = 'bar' +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) + +let foo: Dictionary = {} +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>Dictionary : Symbol(Dictionary, Decl(incrementOnNullAssertion.ts, 0, 0)) + +if (foo[x] === undefined) { +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) +>undefined : Symbol(undefined) + + foo[x] = 1 +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) +} +else { + let nu = foo[x] +>nu : Symbol(nu, Decl(incrementOnNullAssertion.ts, 9, 7)) +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) + + let n = foo[x] +>n : Symbol(n, Decl(incrementOnNullAssertion.ts, 10, 7)) +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) + + foo[x]!++ +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) +} + diff --git a/tests/baselines/reference/incrementOnNullAssertion.types b/tests/baselines/reference/incrementOnNullAssertion.types new file mode 100644 index 00000000000..f6acdda65bc --- /dev/null +++ b/tests/baselines/reference/incrementOnNullAssertion.types @@ -0,0 +1,53 @@ +=== tests/cases/compiler/incrementOnNullAssertion.ts === +interface Dictionary { +>Dictionary : Dictionary +>T : T + + [myFavouriteType: string]: T | undefined +>myFavouriteType : string +>T : T +} +const x = 'bar' +>x : "bar" +>'bar' : "bar" + +let foo: Dictionary = {} +>foo : Dictionary +>Dictionary : Dictionary +>{} : {} + +if (foo[x] === undefined) { +>foo[x] === undefined : boolean +>foo[x] : number | undefined +>foo : Dictionary +>x : "bar" +>undefined : undefined + + foo[x] = 1 +>foo[x] = 1 : 1 +>foo[x] : number | undefined +>foo : Dictionary +>x : "bar" +>1 : 1 +} +else { + let nu = foo[x] +>nu : number | undefined +>foo[x] : number | undefined +>foo : Dictionary +>x : "bar" + + let n = foo[x] +>n : number | undefined +>foo[x] : number | undefined +>foo : Dictionary +>x : "bar" + + foo[x]!++ +>foo[x]!++ : number +>foo[x]! : number +>foo[x] : number | undefined +>foo : Dictionary +>x : "bar" +} + diff --git a/tests/cases/compiler/incrementOnNullAssertion.ts b/tests/cases/compiler/incrementOnNullAssertion.ts new file mode 100644 index 00000000000..4521b8a4455 --- /dev/null +++ b/tests/cases/compiler/incrementOnNullAssertion.ts @@ -0,0 +1,14 @@ +// @strict: true +interface Dictionary { + [myFavouriteType: string]: T | undefined +} +const x = 'bar' +let foo: Dictionary = {} +if (foo[x] === undefined) { + foo[x] = 1 +} +else { + let nu = foo[x] + let n = foo[x] + foo[x]!++ +}