Skip to content

Commit f837fa6

Browse files
Copilotjakebailey
andcommitted
Port TypeScript PR #61788: Fix control flow analysis of aliased discriminants with parenthesized initializers
Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
1 parent 4646d45 commit f837fa6

File tree

7 files changed

+55
-431
lines changed

7 files changed

+55
-431
lines changed

internal/checker/flow.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,26 +1442,32 @@ func (c *Checker) getCandidateDiscriminantPropertyAccess(f *FlowState, expr *ast
14421442
symbol := c.getResolvedSymbol(expr)
14431443
if c.isConstantVariable(symbol) {
14441444
declaration := symbol.ValueDeclaration
1445+
initializer := getCandidateVariableDeclarationInitializer(declaration)
14451446
// Given 'const x = obj.kind', allow 'x' as an alias for 'obj.kind'
1446-
if ast.IsVariableDeclaration(declaration) && declaration.Type() == nil {
1447-
if initializer := declaration.Initializer(); initializer != nil && ast.IsAccessExpression(initializer) && c.isMatchingReference(f.reference, initializer.Expression()) {
1448-
return initializer
1449-
}
1447+
if initializer != nil && ast.IsAccessExpression(initializer) && c.isMatchingReference(f.reference, initializer.Expression()) {
1448+
return initializer
14501449
}
14511450
// Given 'const { kind: x } = obj', allow 'x' as an alias for 'obj.kind'
14521451
if ast.IsBindingElement(declaration) && declaration.Initializer() == nil {
1453-
parent := declaration.Parent.Parent
1454-
if ast.IsVariableDeclaration(parent) && parent.Type() == nil {
1455-
if initializer := parent.Initializer(); initializer != nil && (ast.IsIdentifier(initializer) || ast.IsAccessExpression(initializer)) && c.isMatchingReference(f.reference, initializer) {
1456-
return declaration
1457-
}
1452+
initializer = getCandidateVariableDeclarationInitializer(declaration.Parent.Parent)
1453+
if initializer != nil && (ast.IsIdentifier(initializer) || ast.IsAccessExpression(initializer)) && c.isMatchingReference(f.reference, initializer) {
1454+
return declaration
14581455
}
14591456
}
14601457
}
14611458
}
14621459
return nil
14631460
}
14641461

1462+
func getCandidateVariableDeclarationInitializer(node *ast.Node) *ast.Node {
1463+
if ast.IsVariableDeclaration(node) && node.Type() == nil {
1464+
if initializer := node.Initializer(); initializer != nil {
1465+
return ast.SkipParentheses(initializer)
1466+
}
1467+
}
1468+
return nil
1469+
}
1470+
14651471
// An evolving array type tracks the element types that have so far been seen in an
14661472
// 'x.push(value)' or 'x[n] = value' operation along the control flow graph. Evolving
14671473
// array types are ultimately converted into manifest array types (using getFinalArrayType)

testdata/baselines/reference/submodule/conformance/controlFlowAliasing2.errors.txt

Lines changed: 0 additions & 117 deletions
This file was deleted.

testdata/baselines/reference/submodule/conformance/controlFlowAliasing2.errors.txt.diff

Lines changed: 0 additions & 121 deletions
This file was deleted.

testdata/baselines/reference/submodule/conformance/controlFlowAliasing2.symbols

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ function _tcb1(this: { test: Test }) {
4747
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 16, 7))
4848

4949
(((((this).test)).name));
50+
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
5051
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
5152
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 14, 15))
5253
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 14, 22))
54+
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
5355
}
5456

5557
// Same as above, without the parenthesis
@@ -112,9 +114,11 @@ function _tcb2(this: { test: Test }) {
112114
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 36, 7))
113115

114116
(((((this).test)).name));
117+
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
115118
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
116119
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 34, 15))
117120
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 34, 22))
121+
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
118122
}
119123

120124
// Same as above, without the parenthesis
@@ -175,9 +179,11 @@ function _tcb3(this: { test: Test }) {
175179
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 55, 9))
176180

177181
(((((this).test)).name));
182+
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
178183
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
179184
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 54, 15))
180185
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 54, 22))
186+
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
181187
}
182188

183189
// Same as above, without the parenthesis
@@ -236,9 +242,11 @@ function _tcb4(this: { test: Test }) {
236242
>_t1 : Symbol(_t1, Decl(controlFlowAliasing2.ts, 74, 9))
237243

238244
(((((this).test)).name));
245+
>(((this).test)).name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
239246
>(this).test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
240247
>this : Symbol(this, Decl(controlFlowAliasing2.ts, 73, 15))
241248
>test : Symbol(test, Decl(controlFlowAliasing2.ts, 73, 22))
249+
>name : Symbol(TestA.name, Decl(controlFlowAliasing2.ts, 5, 12))
242250
}
243251

244252
// Same as above, without the parenthesis

testdata/baselines/reference/submodule/conformance/controlFlowAliasing2.symbols.diff

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)