From ee0b57867f04ee0454fbb347cbc600ebf12740ca Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 18 Jul 2022 15:51:37 -0700 Subject: [PATCH 1/3] Don't leak EvolvingArray out of code flow --- src/compiler/checker.ts | 8 +- .../quickInfoEvolvingArrayType.baseline | 108 ++++++++++++++++++ .../fourslash/quickInfoEvolvingArrayType.ts | 15 +++ 3 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/quickInfoEvolvingArrayType.baseline create mode 100644 tests/cases/fourslash/quickInfoEvolvingArrayType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ce644034b9c3b..82d1ab321f2b9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11896,6 +11896,9 @@ namespace ts { else if ((type as MappedType).objectFlags & ObjectFlags.Mapped) { resolveMappedTypeMembers(type as MappedType); } + else { + Debug.fail("Unhandled object type " + Debug.formatObjectFlags(type.objectFlags)); + } } else if (type.flags & TypeFlags.Union) { resolveUnionTypeMembers(type as UnionType); @@ -11903,6 +11906,9 @@ namespace ts { else if (type.flags & TypeFlags.Intersection) { resolveIntersectionTypeMembers(type as IntersectionType); } + else { + Debug.fail("Unhandled type " + Debug.formatTypeFlags(type.flags)); + } } return type as ResolvedType; } @@ -24613,7 +24619,7 @@ namespace ts { } // for (const _ in ref) acts as a nonnull on ref if (isVariableDeclaration(node) && node.parent.parent.kind === SyntaxKind.ForInStatement && isMatchingReference(reference, node.parent.parent.expression)) { - return getNonNullableTypeIfNeeded(getTypeFromFlowType(getTypeAtFlowNode(flow.antecedent))); + return getNonNullableTypeIfNeeded(finalizeEvolvingArrayType(getTypeFromFlowType(getTypeAtFlowNode(flow.antecedent)))); } // Assignment doesn't affect reference return undefined; diff --git a/tests/baselines/reference/quickInfoEvolvingArrayType.baseline b/tests/baselines/reference/quickInfoEvolvingArrayType.baseline new file mode 100644 index 0000000000000..3171d065aa957 --- /dev/null +++ b/tests/baselines/reference/quickInfoEvolvingArrayType.baseline @@ -0,0 +1,108 @@ +[ + { + "marker": { + "fileName": "/tests/cases/fourslash/quickInfoEvolvingArrayType.ts", + "position": 45, + "name": "1" + }, + "quickInfo": { + "kind": "method", + "kindModifiers": "declare", + "textSpan": { + "start": 39, + "length": 14 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "method", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Object", + "kind": "localName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "hasOwnProperty", + "kind": "methodName" + }, + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "v", + "kind": "parameterName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "PropertyKey", + "kind": "aliasName" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "boolean", + "kind": "keyword" + } + ], + "documentation": [ + { + "text": "Determines whether an object has a property with the specified name.", + "kind": "text" + } + ], + "tags": [ + { + "name": "param", + "text": [ + { + "text": "v", + "kind": "parameterName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "A property name.", + "kind": "text" + } + ] + } + ] + } + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoEvolvingArrayType.ts b/tests/cases/fourslash/quickInfoEvolvingArrayType.ts new file mode 100644 index 0000000000000..c16d905b4a0a5 --- /dev/null +++ b/tests/cases/fourslash/quickInfoEvolvingArrayType.ts @@ -0,0 +1,15 @@ +/// + +// @strict: true +// @checkJs: true +// @allowJs: true +// @outDir: ./dist + +// filename: index.js +//// var C = []; +//// for (var a in C) +//// if (C.hasOwn/*1*/Property(a)) { +//// } +//// } + +verify.baselineQuickInfo(); From 9a5ef9b8d93fe4910a5cc75cc17a2a4279f3c6e9 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 18 Jul 2022 16:34:25 -0700 Subject: [PATCH 2/3] Switch to compiler test --- .../evolvingArrayResolvedAssert.errors.txt | 18 +++ .../reference/evolvingArrayResolvedAssert.js | 15 +++ .../evolvingArrayResolvedAssert.symbols | 16 +++ .../evolvingArrayResolvedAssert.types | 18 +++ .../quickInfoEvolvingArrayType.baseline | 108 ------------------ .../compiler/evolvingArrayResolvedAssert.ts | 11 ++ .../fourslash/quickInfoEvolvingArrayType.ts | 15 --- 7 files changed, 78 insertions(+), 123 deletions(-) create mode 100644 tests/baselines/reference/evolvingArrayResolvedAssert.errors.txt create mode 100644 tests/baselines/reference/evolvingArrayResolvedAssert.js create mode 100644 tests/baselines/reference/evolvingArrayResolvedAssert.symbols create mode 100644 tests/baselines/reference/evolvingArrayResolvedAssert.types delete mode 100644 tests/baselines/reference/quickInfoEvolvingArrayType.baseline create mode 100644 tests/cases/compiler/evolvingArrayResolvedAssert.ts delete mode 100644 tests/cases/fourslash/quickInfoEvolvingArrayType.ts diff --git a/tests/baselines/reference/evolvingArrayResolvedAssert.errors.txt b/tests/baselines/reference/evolvingArrayResolvedAssert.errors.txt new file mode 100644 index 0000000000000..9c21c78820279 --- /dev/null +++ b/tests/baselines/reference/evolvingArrayResolvedAssert.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/index.js(1,5): error TS7034: Variable 'C' implicitly has type 'any[]' in some locations where its type cannot be determined. +tests/cases/compiler/index.js(2,15): error TS7005: Variable 'C' implicitly has an 'any[]' type. +tests/cases/compiler/index.js(3,9): error TS7005: Variable 'C' implicitly has an 'any[]' type. + + +==== tests/cases/compiler/index.js (3 errors) ==== + var C = []; + ~ +!!! error TS7034: Variable 'C' implicitly has type 'any[]' in some locations where its type cannot be determined. + for (var a in C) { + ~ +!!! error TS7005: Variable 'C' implicitly has an 'any[]' type. + if (C.hasOwnProperty(a)) { + ~ +!!! error TS7005: Variable 'C' implicitly has an 'any[]' type. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/evolvingArrayResolvedAssert.js b/tests/baselines/reference/evolvingArrayResolvedAssert.js new file mode 100644 index 0000000000000..0ffb6e71de6b9 --- /dev/null +++ b/tests/baselines/reference/evolvingArrayResolvedAssert.js @@ -0,0 +1,15 @@ +//// [index.js] +var C = []; +for (var a in C) { + if (C.hasOwnProperty(a)) { + } +} + + +//// [index.js] +"use strict"; +var C = []; +for (var a in C) { + if (C.hasOwnProperty(a)) { + } +} diff --git a/tests/baselines/reference/evolvingArrayResolvedAssert.symbols b/tests/baselines/reference/evolvingArrayResolvedAssert.symbols new file mode 100644 index 0000000000000..8afcfab09152c --- /dev/null +++ b/tests/baselines/reference/evolvingArrayResolvedAssert.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/index.js === +var C = []; +>C : Symbol(C, Decl(index.js, 0, 3)) + +for (var a in C) { +>a : Symbol(a, Decl(index.js, 1, 8)) +>C : Symbol(C, Decl(index.js, 0, 3)) + + if (C.hasOwnProperty(a)) { +>C.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) +>C : Symbol(C, Decl(index.js, 0, 3)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(index.js, 1, 8)) + } +} + diff --git a/tests/baselines/reference/evolvingArrayResolvedAssert.types b/tests/baselines/reference/evolvingArrayResolvedAssert.types new file mode 100644 index 0000000000000..91e5d706fb29c --- /dev/null +++ b/tests/baselines/reference/evolvingArrayResolvedAssert.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/index.js === +var C = []; +>C : any[] +>[] : never[] + +for (var a in C) { +>a : string +>C : any[] + + if (C.hasOwnProperty(a)) { +>C.hasOwnProperty(a) : boolean +>C.hasOwnProperty : (v: PropertyKey) => boolean +>C : any[] +>hasOwnProperty : (v: PropertyKey) => boolean +>a : string + } +} + diff --git a/tests/baselines/reference/quickInfoEvolvingArrayType.baseline b/tests/baselines/reference/quickInfoEvolvingArrayType.baseline deleted file mode 100644 index 3171d065aa957..0000000000000 --- a/tests/baselines/reference/quickInfoEvolvingArrayType.baseline +++ /dev/null @@ -1,108 +0,0 @@ -[ - { - "marker": { - "fileName": "/tests/cases/fourslash/quickInfoEvolvingArrayType.ts", - "position": 45, - "name": "1" - }, - "quickInfo": { - "kind": "method", - "kindModifiers": "declare", - "textSpan": { - "start": 39, - "length": 14 - }, - "displayParts": [ - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "method", - "kind": "text" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "Object", - "kind": "localName" - }, - { - "text": ".", - "kind": "punctuation" - }, - { - "text": "hasOwnProperty", - "kind": "methodName" - }, - { - "text": "(", - "kind": "punctuation" - }, - { - "text": "v", - "kind": "parameterName" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "PropertyKey", - "kind": "aliasName" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": ":", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "boolean", - "kind": "keyword" - } - ], - "documentation": [ - { - "text": "Determines whether an object has a property with the specified name.", - "kind": "text" - } - ], - "tags": [ - { - "name": "param", - "text": [ - { - "text": "v", - "kind": "parameterName" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "A property name.", - "kind": "text" - } - ] - } - ] - } - } -] \ No newline at end of file diff --git a/tests/cases/compiler/evolvingArrayResolvedAssert.ts b/tests/cases/compiler/evolvingArrayResolvedAssert.ts new file mode 100644 index 0000000000000..0a08459eb068d --- /dev/null +++ b/tests/cases/compiler/evolvingArrayResolvedAssert.ts @@ -0,0 +1,11 @@ +// @strict: true +// @checkJs: true +// @allowJs: true +// @outDir: ./out + +// @filename: index.js +var C = []; +for (var a in C) { + if (C.hasOwnProperty(a)) { + } +} diff --git a/tests/cases/fourslash/quickInfoEvolvingArrayType.ts b/tests/cases/fourslash/quickInfoEvolvingArrayType.ts deleted file mode 100644 index c16d905b4a0a5..0000000000000 --- a/tests/cases/fourslash/quickInfoEvolvingArrayType.ts +++ /dev/null @@ -1,15 +0,0 @@ -/// - -// @strict: true -// @checkJs: true -// @allowJs: true -// @outDir: ./dist - -// filename: index.js -//// var C = []; -//// for (var a in C) -//// if (C.hasOwn/*1*/Property(a)) { -//// } -//// } - -verify.baselineQuickInfo(); From 7d14f8849b9b9444a42b8b5492d5db483f040a2e Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 18 Jul 2022 18:10:09 -0700 Subject: [PATCH 3/3] Just use TS --- .../reference/evolvingArrayResolvedAssert.errors.txt | 8 ++++---- .../reference/evolvingArrayResolvedAssert.js | 4 ++-- .../reference/evolvingArrayResolvedAssert.symbols | 12 ++++++------ .../reference/evolvingArrayResolvedAssert.types | 2 +- tests/cases/compiler/evolvingArrayResolvedAssert.ts | 4 ---- 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/tests/baselines/reference/evolvingArrayResolvedAssert.errors.txt b/tests/baselines/reference/evolvingArrayResolvedAssert.errors.txt index 9c21c78820279..487ffa3a82a12 100644 --- a/tests/baselines/reference/evolvingArrayResolvedAssert.errors.txt +++ b/tests/baselines/reference/evolvingArrayResolvedAssert.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/index.js(1,5): error TS7034: Variable 'C' implicitly has type 'any[]' in some locations where its type cannot be determined. -tests/cases/compiler/index.js(2,15): error TS7005: Variable 'C' implicitly has an 'any[]' type. -tests/cases/compiler/index.js(3,9): error TS7005: Variable 'C' implicitly has an 'any[]' type. +tests/cases/compiler/evolvingArrayResolvedAssert.ts(1,5): error TS7034: Variable 'C' implicitly has type 'any[]' in some locations where its type cannot be determined. +tests/cases/compiler/evolvingArrayResolvedAssert.ts(2,15): error TS7005: Variable 'C' implicitly has an 'any[]' type. +tests/cases/compiler/evolvingArrayResolvedAssert.ts(3,9): error TS7005: Variable 'C' implicitly has an 'any[]' type. -==== tests/cases/compiler/index.js (3 errors) ==== +==== tests/cases/compiler/evolvingArrayResolvedAssert.ts (3 errors) ==== var C = []; ~ !!! error TS7034: Variable 'C' implicitly has type 'any[]' in some locations where its type cannot be determined. diff --git a/tests/baselines/reference/evolvingArrayResolvedAssert.js b/tests/baselines/reference/evolvingArrayResolvedAssert.js index 0ffb6e71de6b9..4cae93bbb8645 100644 --- a/tests/baselines/reference/evolvingArrayResolvedAssert.js +++ b/tests/baselines/reference/evolvingArrayResolvedAssert.js @@ -1,4 +1,4 @@ -//// [index.js] +//// [evolvingArrayResolvedAssert.ts] var C = []; for (var a in C) { if (C.hasOwnProperty(a)) { @@ -6,7 +6,7 @@ for (var a in C) { } -//// [index.js] +//// [evolvingArrayResolvedAssert.js] "use strict"; var C = []; for (var a in C) { diff --git a/tests/baselines/reference/evolvingArrayResolvedAssert.symbols b/tests/baselines/reference/evolvingArrayResolvedAssert.symbols index 8afcfab09152c..8d52f9e5d0266 100644 --- a/tests/baselines/reference/evolvingArrayResolvedAssert.symbols +++ b/tests/baselines/reference/evolvingArrayResolvedAssert.symbols @@ -1,16 +1,16 @@ -=== tests/cases/compiler/index.js === +=== tests/cases/compiler/evolvingArrayResolvedAssert.ts === var C = []; ->C : Symbol(C, Decl(index.js, 0, 3)) +>C : Symbol(C, Decl(evolvingArrayResolvedAssert.ts, 0, 3)) for (var a in C) { ->a : Symbol(a, Decl(index.js, 1, 8)) ->C : Symbol(C, Decl(index.js, 0, 3)) +>a : Symbol(a, Decl(evolvingArrayResolvedAssert.ts, 1, 8)) +>C : Symbol(C, Decl(evolvingArrayResolvedAssert.ts, 0, 3)) if (C.hasOwnProperty(a)) { >C.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) ->C : Symbol(C, Decl(index.js, 0, 3)) +>C : Symbol(C, Decl(evolvingArrayResolvedAssert.ts, 0, 3)) >hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) ->a : Symbol(a, Decl(index.js, 1, 8)) +>a : Symbol(a, Decl(evolvingArrayResolvedAssert.ts, 1, 8)) } } diff --git a/tests/baselines/reference/evolvingArrayResolvedAssert.types b/tests/baselines/reference/evolvingArrayResolvedAssert.types index 91e5d706fb29c..b0524c275c117 100644 --- a/tests/baselines/reference/evolvingArrayResolvedAssert.types +++ b/tests/baselines/reference/evolvingArrayResolvedAssert.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/index.js === +=== tests/cases/compiler/evolvingArrayResolvedAssert.ts === var C = []; >C : any[] >[] : never[] diff --git a/tests/cases/compiler/evolvingArrayResolvedAssert.ts b/tests/cases/compiler/evolvingArrayResolvedAssert.ts index 0a08459eb068d..7ba37947b0414 100644 --- a/tests/cases/compiler/evolvingArrayResolvedAssert.ts +++ b/tests/cases/compiler/evolvingArrayResolvedAssert.ts @@ -1,9 +1,5 @@ // @strict: true -// @checkJs: true -// @allowJs: true -// @outDir: ./out -// @filename: index.js var C = []; for (var a in C) { if (C.hasOwnProperty(a)) {