@@ -27393,7 +27393,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
27393
27393
case SyntaxKind.Identifier:
27394
27394
if (!isThisInTypeQuery(node)) {
27395
27395
const symbol = getResolvedSymbol(node as Identifier);
27396
- return isConstantVariable(symbol) || isParameterOrCatchClauseVariable(symbol) && !isSomeSymbolAssigned(getRootDeclaration( symbol.valueDeclaration!) );
27396
+ return isConstantVariable(symbol) || isParameterOrCatchClauseVariable(symbol) && !isSymbolAssigned( symbol);
27397
27397
}
27398
27398
break;
27399
27399
case SyntaxKind.PropertyAccessExpression:
@@ -28668,34 +28668,51 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
28668
28668
node.kind === SyntaxKind.PropertyDeclaration)!;
28669
28669
}
28670
28670
28671
- // Check if a parameter or catch variable (or their bindings elements) is assigned anywhere
28672
- function isSomeSymbolAssigned(rootDeclaration: Node) {
28673
- const parent = rootDeclaration.parent;
28671
+ // Check if a parameter or catch variable is assigned anywhere
28672
+ function isSymbolAssigned(symbol: Symbol) {
28673
+ if (!symbol.valueDeclaration) {
28674
+ return false;
28675
+ }
28676
+ const parent = getRootDeclaration(symbol.valueDeclaration).parent;
28674
28677
const links = getNodeLinks(parent);
28675
28678
if (!(links.flags & NodeCheckFlags.AssignmentsMarked)) {
28676
28679
links.flags |= NodeCheckFlags.AssignmentsMarked;
28677
28680
if (!hasParentWithAssignmentsMarked(parent)) {
28678
28681
markNodeAssignments(parent);
28679
28682
}
28680
28683
}
28681
- return !!getNodeLinks(rootDeclaration).someSymbolAssigned;
28684
+ return symbol.isAssigned || false;
28685
+ }
28686
+
28687
+ // Check if a parameter or catch variable (or their bindings elements) is assigned anywhere
28688
+ function isSomeSymbolAssigned(rootDeclaration: Node) {
28689
+ Debug.assert(isVariableDeclaration(rootDeclaration) || isParameter(rootDeclaration));
28690
+ return isSomeSymbolAssignedWorker(rootDeclaration.name);
28691
+ }
28692
+
28693
+ function isSomeSymbolAssignedWorker(node: BindingName): boolean {
28694
+ if (node.kind === SyntaxKind.Identifier) {
28695
+ return isSymbolAssigned(getSymbolOfDeclaration(node.parent as Declaration));
28696
+ }
28697
+
28698
+ return some(node.elements, e => e.kind !== SyntaxKind.OmittedExpression && isSomeSymbolAssignedWorker(e.name));
28682
28699
}
28683
28700
28684
28701
function hasParentWithAssignmentsMarked(node: Node) {
28685
28702
return !!findAncestor(node.parent, node => (isFunctionLike(node) || isCatchClause(node)) && !!(getNodeLinks(node).flags & NodeCheckFlags.AssignmentsMarked));
28686
28703
}
28687
28704
28688
- function markNodeAssignments(node: Node): true | undefined {
28705
+ function markNodeAssignments(node: Node) {
28689
28706
if (node.kind === SyntaxKind.Identifier) {
28690
28707
if (isAssignmentTarget(node)) {
28691
28708
const symbol = getResolvedSymbol(node as Identifier);
28692
28709
if (isParameterOrCatchClauseVariable(symbol)) {
28693
- return getNodeLinks(getRootDeclaration( symbol.valueDeclaration!)).someSymbolAssigned = true;
28710
+ symbol.isAssigned = true;
28694
28711
}
28695
28712
}
28696
28713
}
28697
28714
else {
28698
- return forEachChild(node, markNodeAssignments);
28715
+ forEachChild(node, markNodeAssignments);
28699
28716
}
28700
28717
}
28701
28718
@@ -29045,8 +29062,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
29045
29062
// The declaration container is the innermost function that encloses the declaration of the variable
29046
29063
// or parameter. The flow container is the innermost function starting with which we analyze the control
29047
29064
// flow graph to determine the control flow based type.
29048
- const rootDeclaration = getRootDeclaration(declaration);
29049
- const isParameter = rootDeclaration.kind === SyntaxKind.Parameter;
29065
+ const isParameter = getRootDeclaration(declaration).kind === SyntaxKind.Parameter;
29050
29066
const declarationContainer = getControlFlowContainer(declaration);
29051
29067
let flowContainer = getControlFlowContainer(node);
29052
29068
const isOuterVariable = flowContainer !== declarationContainer;
@@ -29060,7 +29076,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
29060
29076
while (
29061
29077
flowContainer !== declarationContainer && (flowContainer.kind === SyntaxKind.FunctionExpression ||
29062
29078
flowContainer.kind === SyntaxKind.ArrowFunction || isObjectLiteralOrClassExpressionMethodOrAccessor(flowContainer)) &&
29063
- (isConstantVariable(localOrExportSymbol) && type !== autoArrayType || isParameter && !isSomeSymbolAssigned(rootDeclaration ))
29079
+ (isConstantVariable(localOrExportSymbol) && type !== autoArrayType || isParameter && !isSymbolAssigned(localOrExportSymbol ))
29064
29080
) {
29065
29081
flowContainer = getControlFlowContainer(flowContainer);
29066
29082
}
0 commit comments