From 2748b3b334d705b3fcc18e2c4c4fd71af620584f Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 12 Jun 2017 11:08:41 -0700 Subject: [PATCH] Add isForInOrOfStatement utility (#16455) --- src/compiler/binder.ts | 6 +++--- src/compiler/checker.ts | 20 +++++--------------- src/compiler/types.ts | 2 ++ src/compiler/utilities.ts | 7 ++++++- src/compiler/visitor.ts | 6 +++--- src/harness/harness.ts | 2 +- src/services/breakpoints.ts | 2 +- 7 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 80ab042ba6d..38d526dac02 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -612,7 +612,7 @@ namespace ts { break; case SyntaxKind.ForInStatement: case SyntaxKind.ForOfStatement: - bindForInOrForOfStatement(node); + bindForInOrForOfStatement(node); break; case SyntaxKind.IfStatement: bindIfStatement(node); @@ -950,7 +950,7 @@ namespace ts { currentFlow = finishFlowLabel(postLoopLabel); } - function bindForInOrForOfStatement(node: ForInStatement | ForOfStatement): void { + function bindForInOrForOfStatement(node: ForInOrOfStatement): void { const preLoopLabel = createLoopLabel(); const postLoopLabel = createBranchLabel(); addAntecedent(preLoopLabel, currentFlow); @@ -1328,7 +1328,7 @@ namespace ts { function bindVariableDeclarationFlow(node: VariableDeclaration) { bindEachChild(node); - if (node.initializer || node.parent.parent.kind === SyntaxKind.ForInStatement || node.parent.parent.kind === SyntaxKind.ForOfStatement) { + if (node.initializer || isForInOrOfStatement(node.parent.parent)) { bindInitializedVariableFlow(node); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f5aa57777da..8053b7bb438 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -804,16 +804,8 @@ namespace ts { break; } - switch (declaration.parent.parent.kind) { - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - // ForIn/ForOf case - use site should not be used in expression part - if (isSameScopeDescendentOf(usage, (declaration.parent.parent).expression, container)) { - return true; - } - } - - return false; + // ForIn/ForOf case - use site should not be used in expression part + return isForInOrOfStatement(declaration.parent.parent) && isSameScopeDescendentOf(usage, declaration.parent.parent.expression, container); } function isUsedInFunctionOrInstanceProperty(usage: Node, declaration: Node, container?: Node): boolean { @@ -19588,9 +19580,7 @@ namespace ts { function errorUnusedLocal(node: Node, name: string) { if (isIdentifierThatStartsWithUnderScore(node)) { const declaration = getRootDeclaration(node.parent); - if (declaration.kind === SyntaxKind.VariableDeclaration && - (declaration.parent.parent.kind === SyntaxKind.ForInStatement || - declaration.parent.parent.kind === SyntaxKind.ForOfStatement)) { + if (declaration.kind === SyntaxKind.VariableDeclaration && isForInOrOfStatement(declaration.parent.parent)) { return; } } @@ -20283,7 +20273,7 @@ namespace ts { } } - function checkForInOrForOfVariableDeclaration(iterationStatement: ForInStatement | ForOfStatement): void { + function checkForInOrForOfVariableDeclaration(iterationStatement: ForInOrOfStatement): void { const variableDeclarationList = iterationStatement.initializer; // checkGrammarForInOrForOfStatement will check that there is exactly one declaration. if (variableDeclarationList.declarations.length >= 1) { @@ -24263,7 +24253,7 @@ namespace ts { } } - function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInStatement | ForOfStatement): boolean { + function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInOrOfStatement): boolean { if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) { return true; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d9afbff6ea6..5632299b396 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1708,6 +1708,8 @@ namespace ts { incrementor?: Expression; } + export type ForInOrOfStatement = ForInStatement | ForOfStatement; + export interface ForInStatement extends IterationStatement { kind: SyntaxKind.ForInStatement; initializer: ForInitializer; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 7399399160b..b8efcdff9fd 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1627,7 +1627,7 @@ namespace ts { return unaryOperator === SyntaxKind.PlusPlusToken || unaryOperator === SyntaxKind.MinusMinusToken ? AssignmentKind.Compound : AssignmentKind.None; case SyntaxKind.ForInStatement: case SyntaxKind.ForOfStatement: - return (parent).initializer === node ? AssignmentKind.Definite : AssignmentKind.None; + return (parent).initializer === node ? AssignmentKind.Definite : AssignmentKind.None; case SyntaxKind.ParenthesizedExpression: case SyntaxKind.ArrayLiteralExpression: case SyntaxKind.SpreadElement: @@ -5152,6 +5152,11 @@ namespace ts { return false; } + /* @internal */ + export function isForInOrOfStatement(node: Node): node is ForInOrOfStatement { + return node.kind === SyntaxKind.ForInStatement || node.kind === SyntaxKind.ForOfStatement; + } + // Element /* @internal */ diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index c4023c0a3bd..12357121573 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -1198,9 +1198,9 @@ namespace ts { case SyntaxKind.ForInStatement: case SyntaxKind.ForOfStatement: - result = reduceNode((node).initializer, cbNode, result); - result = reduceNode((node).expression, cbNode, result); - result = reduceNode((node).statement, cbNode, result); + result = reduceNode((node).initializer, cbNode, result); + result = reduceNode((node).expression, cbNode, result); + result = reduceNode((node).statement, cbNode, result); break; case SyntaxKind.ReturnStatement: diff --git a/src/harness/harness.ts b/src/harness/harness.ts index ce264a01e23..e944e68f11e 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1053,7 +1053,7 @@ namespace Harness { ]; let optionsIndex: ts.Map; - function getCommandLineOption(name: string): ts.CommandLineOption { + function getCommandLineOption(name: string): ts.CommandLineOption | undefined { if (!optionsIndex) { optionsIndex = ts.createMap(); const optionDeclarations = harnessOptionDeclarations.concat(ts.optionDeclarations); diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 38da43bdee8..37aa8df0ca1 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -146,7 +146,7 @@ namespace ts.BreakpointResolver { case SyntaxKind.ForOfStatement: // span in initializer - return spanInInitializerOfForLike(node); + return spanInInitializerOfForLike(node); case SyntaxKind.SwitchStatement: // span on switch(...)