Handle pseudo-references in getFlowCacheKey (#49828)

* Handle pseudo-references in getFlowCacheKey

* Add tests

* Accept new baselines
This commit is contained in:
Anders Hejlsberg 2022-07-07 11:53:30 -10:00 committed by GitHub
parent 9dde56c6fc
commit 2eaf49f56e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 361 additions and 0 deletions

View File

@ -23348,6 +23348,15 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
const key = getFlowCacheKey((node as AccessExpression).expression, declaredType, initialType, flowContainer);
return key && key + "." + propName;
}
break;
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
case SyntaxKind.MethodDeclaration:
// Handle pseudo-references originating in getNarrowedTypeOfSymbol.
return `${getNodeId(node)}#${getTypeId(declaredType)}`;
}
return undefined;
}

View File

@ -331,4 +331,47 @@ tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts(314,5): er
test8 = value1.test8,
test9 = value1.test9
}) {}
// Repro from #49772
function fa1(x: [true, number] | [false, string]) {
const [guard, value] = x;
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
}
function fa2(x: { guard: true, value: number } | { guard: false, value: string }) {
const { guard, value } = x;
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
}
const fa3: (...args: [true, number] | [false, string]) => void = (guard, value) => {
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
}

View File

@ -323,6 +323,49 @@ function foo({
test8 = value1.test8,
test9 = value1.test9
}) {}
// Repro from #49772
function fa1(x: [true, number] | [false, string]) {
const [guard, value] = x;
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
}
function fa2(x: { guard: true, value: number } | { guard: false, value: string }) {
const { guard, value } = x;
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
}
const fa3: (...args: [true, number] | [false, string]) => void = (guard, value) => {
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
}
//// [dependentDestructuredVariables.js]
@ -567,6 +610,45 @@ const f60 = (kind, payload) => {
};
// Repro from #48902
function foo({ value1, test1 = value1.test1, test2 = value1.test2, test3 = value1.test3, test4 = value1.test4, test5 = value1.test5, test6 = value1.test6, test7 = value1.test7, test8 = value1.test8, test9 = value1.test9 }) { }
// Repro from #49772
function fa1(x) {
const [guard, value] = x;
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
}
function fa2(x) {
const { guard, value } = x;
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
}
const fa3 = (guard, value) => {
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
};
//// [dependentDestructuredVariables.d.ts]
@ -696,3 +778,12 @@ declare function foo({ value1, test1, test2, test3, test4, test5, test6, test7,
test8?: any;
test9?: any;
}): void;
declare function fa1(x: [true, number] | [false, string]): void;
declare function fa2(x: {
guard: true;
value: number;
} | {
guard: false;
value: string;
}): void;
declare const fa3: (...args: [true, number] | [false, string]) => void;

View File

@ -830,3 +830,81 @@ function foo({
}) {}
// Repro from #49772
function fa1(x: [true, number] | [false, string]) {
>fa1 : Symbol(fa1, Decl(dependentDestructuredVariables.ts, 323, 5))
>x : Symbol(x, Decl(dependentDestructuredVariables.ts, 327, 13))
const [guard, value] = x;
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 328, 11))
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 328, 17))
>x : Symbol(x, Decl(dependentDestructuredVariables.ts, 327, 13))
if (guard) {
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 328, 11))
for (;;) {
value; // number
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 328, 17))
}
}
else {
while (!!true) {
value; // string
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 328, 17))
}
}
}
function fa2(x: { guard: true, value: number } | { guard: false, value: string }) {
>fa2 : Symbol(fa2, Decl(dependentDestructuredVariables.ts, 339, 1))
>x : Symbol(x, Decl(dependentDestructuredVariables.ts, 341, 13))
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 341, 17))
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 341, 30))
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 341, 50))
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 341, 64))
const { guard, value } = x;
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 342, 11))
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 342, 18))
>x : Symbol(x, Decl(dependentDestructuredVariables.ts, 341, 13))
if (guard) {
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 342, 11))
for (;;) {
value; // number
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 342, 18))
}
}
else {
while (!!true) {
value; // string
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 342, 18))
}
}
}
const fa3: (...args: [true, number] | [false, string]) => void = (guard, value) => {
>fa3 : Symbol(fa3, Decl(dependentDestructuredVariables.ts, 355, 5))
>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 355, 12))
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 355, 66))
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 355, 72))
if (guard) {
>guard : Symbol(guard, Decl(dependentDestructuredVariables.ts, 355, 66))
for (;;) {
value; // number
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 355, 72))
}
}
else {
while (!!true) {
value; // string
>value : Symbol(value, Decl(dependentDestructuredVariables.ts, 355, 72))
}
}
}

View File

@ -955,3 +955,100 @@ function foo({
}) {}
// Repro from #49772
function fa1(x: [true, number] | [false, string]) {
>fa1 : (x: [true, number] | [false, string]) => void
>x : [true, number] | [false, string]
>true : true
>false : false
const [guard, value] = x;
>guard : boolean
>value : string | number
>x : [true, number] | [false, string]
if (guard) {
>guard : boolean
for (;;) {
value; // number
>value : number
}
}
else {
while (!!true) {
>!!true : true
>!true : false
>true : true
value; // string
>value : string
}
}
}
function fa2(x: { guard: true, value: number } | { guard: false, value: string }) {
>fa2 : (x: { guard: true; value: number;} | { guard: false; value: string;}) => void
>x : { guard: true; value: number; } | { guard: false; value: string; }
>guard : true
>true : true
>value : number
>guard : false
>false : false
>value : string
const { guard, value } = x;
>guard : boolean
>value : string | number
>x : { guard: true; value: number; } | { guard: false; value: string; }
if (guard) {
>guard : boolean
for (;;) {
value; // number
>value : number
}
}
else {
while (!!true) {
>!!true : true
>!true : false
>true : true
value; // string
>value : string
}
}
}
const fa3: (...args: [true, number] | [false, string]) => void = (guard, value) => {
>fa3 : (...args: [true, number] | [false, string]) => void
>args : [true, number] | [false, string]
>true : true
>false : false
>(guard, value) => { if (guard) { for (;;) { value; // number } } else { while (!!true) { value; // string } }} : (guard: boolean, value: string | number) => void
>guard : boolean
>value : string | number
if (guard) {
>guard : boolean
for (;;) {
value; // number
>value : number
}
}
else {
while (!!true) {
>!!true : true
>!true : false
>true : true
value; // string
>value : string
}
}
}

View File

@ -327,3 +327,46 @@ function foo({
test8 = value1.test8,
test9 = value1.test9
}) {}
// Repro from #49772
function fa1(x: [true, number] | [false, string]) {
const [guard, value] = x;
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
}
function fa2(x: { guard: true, value: number } | { guard: false, value: string }) {
const { guard, value } = x;
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
}
const fa3: (...args: [true, number] | [false, string]) => void = (guard, value) => {
if (guard) {
for (;;) {
value; // number
}
}
else {
while (!!true) {
value; // string
}
}
}