Skip to content

Commit 76dcfb6

Browse files
committed
Merge pull request #2291 from Microsoft/letConstInSwitchStatements
introduce CaseBlock as a block-scoped container for switch statements
2 parents aa08300 + 59c71ac commit 76dcfb6

22 files changed

+392
-186
lines changed

src/compiler/binder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ module ts {
534534
case SyntaxKind.ForStatement:
535535
case SyntaxKind.ForInStatement:
536536
case SyntaxKind.ForOfStatement:
537-
case SyntaxKind.SwitchStatement:
537+
case SyntaxKind.CaseBlock:
538538
bindChildren(node, 0, /*isBlockScopeContainer*/ true);
539539
break;
540540
default:

src/compiler/checker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9049,7 +9049,7 @@ module ts {
90499049
var hasDuplicateDefaultClause = false;
90509050

90519051
var expressionType = checkExpression(node.expression);
9052-
forEach(node.clauses, clause => {
9052+
forEach(node.caseBlock.clauses, clause => {
90539053
// Grammar check for duplicate default clauses, skip if we already report duplicate default clause
90549054
if (clause.kind === SyntaxKind.DefaultClause && !hasDuplicateDefaultClause) {
90559055
if (firstDefaultClause === undefined) {
@@ -10165,6 +10165,7 @@ module ts {
1016510165
case SyntaxKind.BreakStatement:
1016610166
case SyntaxKind.ReturnStatement:
1016710167
case SyntaxKind.SwitchStatement:
10168+
case SyntaxKind.CaseBlock:
1016810169
case SyntaxKind.CaseClause:
1016910170
case SyntaxKind.DefaultClause:
1017010171
case SyntaxKind.LabeledStatement:

src/compiler/emitter.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3708,7 +3708,11 @@ module ts {
37083708
emit(node.expression);
37093709
endPos = emitToken(SyntaxKind.CloseParenToken, node.expression.end);
37103710
write(" ");
3711-
emitToken(SyntaxKind.OpenBraceToken, endPos);
3711+
emitCaseBlock(node.caseBlock, endPos)
3712+
}
3713+
3714+
function emitCaseBlock(node: CaseBlock, startPos: number): void {
3715+
emitToken(SyntaxKind.OpenBraceToken, startPos);
37123716
increaseIndent();
37133717
emitLines(node.clauses);
37143718
decreaseIndent();
@@ -4120,7 +4124,7 @@ module ts {
41204124
}
41214125
switch (current.kind) {
41224126
case SyntaxKind.SourceFile:
4123-
case SyntaxKind.SwitchKeyword:
4127+
case SyntaxKind.CaseBlock:
41244128
case SyntaxKind.CatchClause:
41254129
case SyntaxKind.ModuleDeclaration:
41264130
case SyntaxKind.ForStatement:

src/compiler/parser.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,9 @@ module ts {
209209
visitNode(cbNode, (<WithStatement>node).statement);
210210
case SyntaxKind.SwitchStatement:
211211
return visitNode(cbNode, (<SwitchStatement>node).expression) ||
212-
visitNodes(cbNodes, (<SwitchStatement>node).clauses);
212+
visitNode(cbNode, (<SwitchStatement>node).caseBlock);
213+
case SyntaxKind.CaseBlock:
214+
return visitNodes(cbNodes, (<CaseBlock>node).clauses);
213215
case SyntaxKind.CaseClause:
214216
return visitNode(cbNode, (<CaseClause>node).expression) ||
215217
visitNodes(cbNodes, (<CaseClause>node).statements);
@@ -3954,9 +3956,11 @@ module ts {
39543956
parseExpected(SyntaxKind.OpenParenToken);
39553957
node.expression = allowInAnd(parseExpression);
39563958
parseExpected(SyntaxKind.CloseParenToken);
3959+
var caseBlock = <CaseBlock>createNode(SyntaxKind.CaseBlock, scanner.getStartPos());
39573960
parseExpected(SyntaxKind.OpenBraceToken);
3958-
node.clauses = parseList(ParsingContext.SwitchClauses, /*checkForStrictMode*/ false, parseCaseOrDefaultClause);
3961+
caseBlock.clauses = parseList(ParsingContext.SwitchClauses, /*checkForStrictMode*/ false, parseCaseOrDefaultClause);
39593962
parseExpected(SyntaxKind.CloseBraceToken);
3963+
node.caseBlock = finishNode(caseBlock);
39603964
return finishNode(node);
39613965
}
39623966

src/compiler/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ module ts {
233233
EnumDeclaration,
234234
ModuleDeclaration,
235235
ModuleBlock,
236+
CaseBlock,
236237
ImportEqualsDeclaration,
237238
ImportDeclaration,
238239
ImportClause,
@@ -790,6 +791,10 @@ module ts {
790791

791792
export interface SwitchStatement extends Statement {
792793
expression: Expression;
794+
caseBlock: CaseBlock;
795+
}
796+
797+
export interface CaseBlock extends Node {
793798
clauses: NodeArray<CaseOrDefaultClause>;
794799
}
795800

src/compiler/utilities.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ module ts {
376376
switch (node.kind) {
377377
case SyntaxKind.ReturnStatement:
378378
return visitor(<ReturnStatement>node);
379+
case SyntaxKind.CaseBlock:
379380
case SyntaxKind.Block:
380381
case SyntaxKind.IfStatement:
381382
case SyntaxKind.DoStatement:

src/services/breakpoints.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,8 @@ module ts.BreakpointResolver {
416416
var classDeclaration = <ClassDeclaration>node.parent;
417417
return spanInNodeIfStartsOnSameLine(findPrecedingToken(node.pos, sourceFile, node.parent), classDeclaration.members.length ? classDeclaration.members[0] : classDeclaration.getLastToken(sourceFile));
418418

419-
case SyntaxKind.SwitchStatement:
420-
return spanInNodeIfStartsOnSameLine(node.parent, (<SwitchStatement>node.parent).clauses[0]);
419+
case SyntaxKind.CaseBlock:
420+
return spanInNodeIfStartsOnSameLine(node.parent.parent, (<CaseBlock>node.parent).clauses[0]);
421421
}
422422

423423
// Default to parent node
@@ -447,10 +447,10 @@ module ts.BreakpointResolver {
447447
case SyntaxKind.CatchClause:
448448
return spanInNode((<Block>node.parent).statements[(<Block>node.parent).statements.length - 1]);;
449449

450-
case SyntaxKind.SwitchStatement:
450+
case SyntaxKind.CaseBlock:
451451
// breakpoint in last statement of the last clause
452-
var switchStatement = <SwitchStatement>node.parent;
453-
var lastClause = switchStatement.clauses[switchStatement.clauses.length - 1];
452+
var caseBlock = <CaseBlock>node.parent;
453+
var lastClause = caseBlock.clauses[caseBlock.clauses.length - 1];
454454
if (lastClause) {
455455
return spanInNode(lastClause.statements[lastClause.statements.length - 1]);
456456
}

src/services/formatting/rules.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ module ts.formatting {
541541

542542
switch (node.kind) {
543543
case SyntaxKind.Block:
544-
case SyntaxKind.SwitchStatement:
544+
case SyntaxKind.CaseBlock:
545545
case SyntaxKind.ObjectLiteralExpression:
546546
case SyntaxKind.ModuleBlock:
547547
return true;

src/services/formatting/smartIndenter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ module ts.formatting {
357357
case SyntaxKind.ModuleBlock:
358358
case SyntaxKind.ObjectLiteralExpression:
359359
case SyntaxKind.TypeLiteral:
360-
case SyntaxKind.SwitchStatement:
360+
case SyntaxKind.CaseBlock:
361361
case SyntaxKind.DefaultClause:
362362
case SyntaxKind.CaseClause:
363363
case SyntaxKind.ParenthesizedExpression:
@@ -431,7 +431,7 @@ module ts.formatting {
431431
case SyntaxKind.ObjectLiteralExpression:
432432
case SyntaxKind.Block:
433433
case SyntaxKind.ModuleBlock:
434-
case SyntaxKind.SwitchStatement:
434+
case SyntaxKind.CaseBlock:
435435
return nodeEndsWith(n, SyntaxKind.CloseBraceToken, sourceFile);
436436
case SyntaxKind.CatchClause:
437437
return isCompletedNode((<CatchClause>n).block, sourceFile);

src/services/outliningElementsCollector.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ module ts {
104104
case SyntaxKind.InterfaceDeclaration:
105105
case SyntaxKind.EnumDeclaration:
106106
case SyntaxKind.ObjectLiteralExpression:
107-
case SyntaxKind.SwitchStatement:
107+
case SyntaxKind.CaseBlock:
108108
var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile);
109109
var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile);
110110
addOutliningSpan(n, openBrace, closeBrace, autoCollapse(n));

src/services/services.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3619,8 +3619,8 @@ module ts {
36193619
break;
36203620
case SyntaxKind.CaseKeyword:
36213621
case SyntaxKind.DefaultKeyword:
3622-
if (hasKind(parent(parent(node)), SyntaxKind.SwitchStatement)) {
3623-
return getSwitchCaseDefaultOccurrences(<SwitchStatement>node.parent.parent);
3622+
if (hasKind(parent(parent(parent(node))), SyntaxKind.SwitchStatement)) {
3623+
return getSwitchCaseDefaultOccurrences(<SwitchStatement>node.parent.parent.parent);
36243624
}
36253625
break;
36263626
case SyntaxKind.BreakKeyword:
@@ -3887,7 +3887,7 @@ module ts {
38873887
pushKeywordIf(keywords, switchStatement.getFirstToken(), SyntaxKind.SwitchKeyword);
38883888

38893889
// Go through each clause in the switch statement, collecting the 'case'/'default' keywords.
3890-
forEach(switchStatement.clauses, clause => {
3890+
forEach(switchStatement.caseBlock.clauses, clause => {
38913891
pushKeywordIf(keywords, clause.getFirstToken(), SyntaxKind.CaseKeyword, SyntaxKind.DefaultKeyword);
38923892

38933893
var breaksAndContinues = aggregateAllBreakAndContinueStatements(clause);

tests/baselines/reference/APISample_compile.js

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -261,27 +261,28 @@ declare module "typescript" {
261261
EnumDeclaration = 199,
262262
ModuleDeclaration = 200,
263263
ModuleBlock = 201,
264-
ImportEqualsDeclaration = 202,
265-
ImportDeclaration = 203,
266-
ImportClause = 204,
267-
NamespaceImport = 205,
268-
NamedImports = 206,
269-
ImportSpecifier = 207,
270-
ExportAssignment = 208,
271-
ExportDeclaration = 209,
272-
NamedExports = 210,
273-
ExportSpecifier = 211,
274-
ExternalModuleReference = 212,
275-
CaseClause = 213,
276-
DefaultClause = 214,
277-
HeritageClause = 215,
278-
CatchClause = 216,
279-
PropertyAssignment = 217,
280-
ShorthandPropertyAssignment = 218,
281-
EnumMember = 219,
282-
SourceFile = 220,
283-
SyntaxList = 221,
284-
Count = 222,
264+
CaseBlock = 202,
265+
ImportEqualsDeclaration = 203,
266+
ImportDeclaration = 204,
267+
ImportClause = 205,
268+
NamespaceImport = 206,
269+
NamedImports = 207,
270+
ImportSpecifier = 208,
271+
ExportAssignment = 209,
272+
ExportDeclaration = 210,
273+
NamedExports = 211,
274+
ExportSpecifier = 212,
275+
ExternalModuleReference = 213,
276+
CaseClause = 214,
277+
DefaultClause = 215,
278+
HeritageClause = 216,
279+
CatchClause = 217,
280+
PropertyAssignment = 218,
281+
ShorthandPropertyAssignment = 219,
282+
EnumMember = 220,
283+
SourceFile = 221,
284+
SyntaxList = 222,
285+
Count = 223,
285286
FirstAssignment = 52,
286287
LastAssignment = 63,
287288
FirstReservedWord = 65,
@@ -656,6 +657,9 @@ declare module "typescript" {
656657
}
657658
interface SwitchStatement extends Statement {
658659
expression: Expression;
660+
caseBlock: CaseBlock;
661+
}
662+
interface CaseBlock extends Node {
659663
clauses: NodeArray<CaseOrDefaultClause>;
660664
}
661665
interface CaseClause extends Node {

tests/baselines/reference/APISample_compile.types

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -801,67 +801,70 @@ declare module "typescript" {
801801
ModuleBlock = 201,
802802
>ModuleBlock : SyntaxKind
803803

804-
ImportEqualsDeclaration = 202,
804+
CaseBlock = 202,
805+
>CaseBlock : SyntaxKind
806+
807+
ImportEqualsDeclaration = 203,
805808
>ImportEqualsDeclaration : SyntaxKind
806809

807-
ImportDeclaration = 203,
810+
ImportDeclaration = 204,
808811
>ImportDeclaration : SyntaxKind
809812

810-
ImportClause = 204,
813+
ImportClause = 205,
811814
>ImportClause : SyntaxKind
812815

813-
NamespaceImport = 205,
816+
NamespaceImport = 206,
814817
>NamespaceImport : SyntaxKind
815818

816-
NamedImports = 206,
819+
NamedImports = 207,
817820
>NamedImports : SyntaxKind
818821

819-
ImportSpecifier = 207,
822+
ImportSpecifier = 208,
820823
>ImportSpecifier : SyntaxKind
821824

822-
ExportAssignment = 208,
825+
ExportAssignment = 209,
823826
>ExportAssignment : SyntaxKind
824827

825-
ExportDeclaration = 209,
828+
ExportDeclaration = 210,
826829
>ExportDeclaration : SyntaxKind
827830

828-
NamedExports = 210,
831+
NamedExports = 211,
829832
>NamedExports : SyntaxKind
830833

831-
ExportSpecifier = 211,
834+
ExportSpecifier = 212,
832835
>ExportSpecifier : SyntaxKind
833836

834-
ExternalModuleReference = 212,
837+
ExternalModuleReference = 213,
835838
>ExternalModuleReference : SyntaxKind
836839

837-
CaseClause = 213,
840+
CaseClause = 214,
838841
>CaseClause : SyntaxKind
839842

840-
DefaultClause = 214,
843+
DefaultClause = 215,
841844
>DefaultClause : SyntaxKind
842845

843-
HeritageClause = 215,
846+
HeritageClause = 216,
844847
>HeritageClause : SyntaxKind
845848

846-
CatchClause = 216,
849+
CatchClause = 217,
847850
>CatchClause : SyntaxKind
848851

849-
PropertyAssignment = 217,
852+
PropertyAssignment = 218,
850853
>PropertyAssignment : SyntaxKind
851854

852-
ShorthandPropertyAssignment = 218,
855+
ShorthandPropertyAssignment = 219,
853856
>ShorthandPropertyAssignment : SyntaxKind
854857

855-
EnumMember = 219,
858+
EnumMember = 220,
856859
>EnumMember : SyntaxKind
857860

858-
SourceFile = 220,
861+
SourceFile = 221,
859862
>SourceFile : SyntaxKind
860863

861-
SyntaxList = 221,
864+
SyntaxList = 222,
862865
>SyntaxList : SyntaxKind
863866

864-
Count = 222,
867+
Count = 223,
865868
>Count : SyntaxKind
866869

867870
FirstAssignment = 52,
@@ -1980,6 +1983,14 @@ declare module "typescript" {
19801983
>expression : Expression
19811984
>Expression : Expression
19821985

1986+
caseBlock: CaseBlock;
1987+
>caseBlock : CaseBlock
1988+
>CaseBlock : CaseBlock
1989+
}
1990+
interface CaseBlock extends Node {
1991+
>CaseBlock : CaseBlock
1992+
>Node : Node
1993+
19831994
clauses: NodeArray<CaseOrDefaultClause>;
19841995
>clauses : NodeArray<CaseClause | DefaultClause>
19851996
>NodeArray : NodeArray<T>

0 commit comments

Comments
 (0)