-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2542,11 +2542,14 @@ module ts { | |
} | ||
|
||
// STATEMENTS | ||
function parseStatementAllowingLetDeclaration() { | ||
return parseStatement(/*allowLetDeclarations*/ true); | ||
} | ||
|
||
function parseBlock(ignoreMissingOpenBrace: boolean, checkForStrictMode: boolean): Block { | ||
var node = <Block>createNode(SyntaxKind.Block); | ||
if (parseExpected(SyntaxKind.OpenBraceToken) || ignoreMissingOpenBrace) { | ||
node.statements = parseList(ParsingContext.BlockStatements,checkForStrictMode, parseStatement); | ||
node.statements = parseList(ParsingContext.BlockStatements, checkForStrictMode, parseStatementAllowingLetDeclaration); | ||
parseExpected(SyntaxKind.CloseBraceToken); | ||
} | ||
else { | ||
|
@@ -2592,8 +2595,8 @@ module ts { | |
parseExpected(SyntaxKind.OpenParenToken); | ||
node.expression = parseExpression(); | ||
parseExpected(SyntaxKind.CloseParenToken); | ||
node.thenStatement = parseStatement(); | ||
node.elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined; | ||
node.thenStatement = parseStatement(/*allowLetDeclarations*/ false); | ||
node.elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement(/*allowLetDeclarations*/ false) : undefined; | ||
return finishNode(node); | ||
} | ||
|
||
|
@@ -2603,7 +2606,7 @@ module ts { | |
|
||
var saveInIterationStatement = inIterationStatement; | ||
inIterationStatement = ControlBlockContext.Nested; | ||
node.statement = parseStatement(); | ||
node.statement = parseStatement(/*allowLetDeclarations*/ false); | ||
inIterationStatement = saveInIterationStatement; | ||
|
||
parseExpected(SyntaxKind.WhileKeyword); | ||
|
@@ -2628,7 +2631,7 @@ module ts { | |
|
||
var saveInIterationStatement = inIterationStatement; | ||
inIterationStatement = ControlBlockContext.Nested; | ||
node.statement = parseStatement(); | ||
node.statement = parseStatement(/*allowLetDeclarations*/ false); | ||
inIterationStatement = saveInIterationStatement; | ||
|
||
return finishNode(node); | ||
|
@@ -2692,7 +2695,7 @@ module ts { | |
|
||
var saveInIterationStatement = inIterationStatement; | ||
inIterationStatement = ControlBlockContext.Nested; | ||
forOrForInStatement.statement = parseStatement(); | ||
forOrForInStatement.statement = parseStatement(/*allowLetDeclarations*/ false); | ||
inIterationStatement = saveInIterationStatement; | ||
|
||
return finishNode(forOrForInStatement); | ||
|
@@ -2803,7 +2806,7 @@ module ts { | |
parseExpected(SyntaxKind.OpenParenToken); | ||
node.expression = parseExpression(); | ||
parseExpected(SyntaxKind.CloseParenToken); | ||
node.statement = parseStatement(); | ||
node.statement = parseStatement(/*allowLetDeclarations*/ false); | ||
node = finishNode(node); | ||
if (isInStrictMode) { | ||
// Strict mode code may not include a WithStatement. The occurrence of a WithStatement in such | ||
|
@@ -2818,15 +2821,15 @@ module ts { | |
parseExpected(SyntaxKind.CaseKeyword); | ||
node.expression = parseExpression(); | ||
parseExpected(SyntaxKind.ColonToken); | ||
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement); | ||
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatementAllowingLetDeclaration); | ||
return finishNode(node); | ||
} | ||
|
||
function parseDefaultClause(): CaseOrDefaultClause { | ||
var node = <CaseOrDefaultClause>createNode(SyntaxKind.DefaultClause); | ||
parseExpected(SyntaxKind.DefaultKeyword); | ||
parseExpected(SyntaxKind.ColonToken); | ||
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement); | ||
node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatementAllowingLetDeclaration); | ||
return finishNode(node); | ||
} | ||
|
||
|
@@ -2933,9 +2936,9 @@ module ts { | |
return token === SyntaxKind.WhileKeyword || token === SyntaxKind.DoKeyword || token === SyntaxKind.ForKeyword; | ||
} | ||
|
||
function parseStatementWithLabelSet(): Statement { | ||
function parseStatementWithLabelSet(allowLetDeclarations: boolean): Statement { | ||
labelledStatementInfo.pushCurrentLabelSet(isIterationStatementStart()); | ||
var statement = parseStatement(); | ||
var statement = parseStatement(allowLetDeclarations); | ||
labelledStatementInfo.pop(); | ||
return statement; | ||
} | ||
|
@@ -2944,7 +2947,7 @@ module ts { | |
return isIdentifier() && lookAhead(() => nextToken() === SyntaxKind.ColonToken); | ||
} | ||
|
||
function parseLabelledStatement(): LabeledStatement { | ||
function parseLabelledStatement(allowLetDeclarations: boolean): LabeledStatement { | ||
var node = <LabeledStatement>createNode(SyntaxKind.LabeledStatement); | ||
node.label = parseIdentifier(); | ||
parseExpected(SyntaxKind.ColonToken); | ||
|
@@ -2956,7 +2959,7 @@ module ts { | |
|
||
// We only want to call parseStatementWithLabelSet when the label set is complete | ||
// Therefore, keep parsing labels until we know we're done. | ||
node.statement = isLabel() ? parseLabelledStatement() : parseStatementWithLabelSet(); | ||
node.statement = isLabel() ? parseLabelledStatement(allowLetDeclarations) : parseStatementWithLabelSet(allowLetDeclarations); | ||
return finishNode(node); | ||
} | ||
|
||
|
@@ -3022,14 +3025,14 @@ module ts { | |
} | ||
} | ||
|
||
function parseStatement(): Statement { | ||
function parseStatement(allowLetDeclarations: boolean): Statement { | ||
switch (token) { | ||
case SyntaxKind.OpenBraceToken: | ||
return parseBlock(/* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); | ||
case SyntaxKind.VarKeyword: | ||
case SyntaxKind.LetKeyword: | ||
case SyntaxKind.ConstKeyword: | ||
return parseVariableStatement(); | ||
return parseVariableStatement(allowLetDeclarations); | ||
case SyntaxKind.FunctionKeyword: | ||
return parseFunctionDeclaration(); | ||
case SyntaxKind.SemicolonToken: | ||
|
@@ -3063,16 +3066,12 @@ module ts { | |
return parseDebuggerStatement(); | ||
default: | ||
if (isLabel()) { | ||
return parseLabelledStatement(); | ||
return parseLabelledStatement(allowLetDeclarations); | ||
} | ||
return parseExpressionStatement(); | ||
} | ||
} | ||
|
||
function parseStatementOrFunction(): Statement { | ||
return token === SyntaxKind.FunctionKeyword ? parseFunctionDeclaration() : parseStatement(); | ||
} | ||
|
||
function parseAndCheckFunctionBody(isConstructor: boolean): Block { | ||
var initialPosition = scanner.getTokenPos(); | ||
var errorCountBeforeBody = file.syntacticErrors.length; | ||
|
@@ -3109,7 +3108,7 @@ module ts { | |
grammarErrorAtPos(initializerStart, initializerFirstTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); | ||
} | ||
if (!inAmbientContext && !node.initializer && flags & NodeFlags.Const) { | ||
grammarErrorOnNode(node, Diagnostics.Const_must_be_intialized); | ||
grammarErrorOnNode(node, Diagnostics.const_must_be_intialized); | ||
} | ||
if (isInStrictMode && isEvalOrArgumentsIdentifier(node.name)) { | ||
// It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code | ||
|
@@ -3124,7 +3123,7 @@ module ts { | |
() => parseVariableDeclaration(flags, noIn), /*allowTrailingComma*/ false); | ||
} | ||
|
||
function parseVariableStatement(pos?: number, flags?: NodeFlags): VariableStatement { | ||
function parseVariableStatement(allowLetDeclarations: boolean, pos?: number, flags?: NodeFlags): VariableStatement { | ||
var node = <VariableStatement>createNode(SyntaxKind.VariableStatement, pos); | ||
if (flags) node.flags = flags; | ||
var errorCountBeforeVarStatement = file.syntacticErrors.length; | ||
|
@@ -3152,6 +3151,14 @@ module ts { | |
grammarErrorOnNode(node, Diagnostics.const_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); | ||
} | ||
} | ||
else if (!allowLetDeclarations){ | ||
This comment has been minimized.
Sorry, something went wrong. |
||
if (node.flags & NodeFlags.Let) { | ||
grammarErrorOnNode(node, Diagnostics.let_must_be_declared_inside_a_block); | ||
} | ||
else if (node.flags & NodeFlags.Const) { | ||
grammarErrorOnNode(node, Diagnostics.const_must_be_declared_inside_a_block); | ||
} | ||
} | ||
return node; | ||
} | ||
|
||
|
@@ -3784,7 +3791,7 @@ module ts { | |
case SyntaxKind.VarKeyword: | ||
case SyntaxKind.LetKeyword: | ||
case SyntaxKind.ConstKeyword: | ||
result = parseVariableStatement(pos, flags); | ||
result = parseVariableStatement(/*allowLetDeclarations*/ true, pos, flags); | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
Contributor
|
||
break; | ||
case SyntaxKind.FunctionKeyword: | ||
result = parseFunctionDeclaration(pos, flags); | ||
|
@@ -3832,7 +3839,7 @@ module ts { | |
var statementStart = scanner.getTokenPos(); | ||
var statementFirstTokenLength = scanner.getTextPos() - statementStart; | ||
var errorCountBeforeStatement = file.syntacticErrors.length; | ||
var statement = parseStatement(); | ||
var statement = parseStatement(/*allowLetDeclarations*/ false); | ||
This comment has been minimized.
Sorry, something went wrong.
JsonFreeman
Contributor
|
||
|
||
if (inAmbientContext && file.syntacticErrors.length === errorCountBeforeStatement) { | ||
grammarErrorAtPos(statementStart, statementFirstTokenLength, Diagnostics.Statements_are_not_allowed_in_ambient_contexts); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
tests/cases/compiler/constDeclarations-invalidContexts.ts(4,5): error TS1156: const must be declared inside a block. | ||
tests/cases/compiler/constDeclarations-invalidContexts.ts(6,5): error TS1156: const must be declared inside a block. | ||
tests/cases/compiler/constDeclarations-invalidContexts.ts(9,5): error TS1156: const must be declared inside a block. | ||
tests/cases/compiler/constDeclarations-invalidContexts.ts(12,5): error TS1156: const must be declared inside a block. | ||
tests/cases/compiler/constDeclarations-invalidContexts.ts(17,5): error TS1156: const must be declared inside a block. | ||
tests/cases/compiler/constDeclarations-invalidContexts.ts(20,5): error TS1156: const must be declared inside a block. | ||
tests/cases/compiler/constDeclarations-invalidContexts.ts(23,5): error TS1156: const must be declared inside a block. | ||
tests/cases/compiler/constDeclarations-invalidContexts.ts(26,12): error TS1156: const must be declared inside a block. | ||
tests/cases/compiler/constDeclarations-invalidContexts.ts(29,29): error TS1156: const must be declared inside a block. | ||
tests/cases/compiler/constDeclarations-invalidContexts.ts(16,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'. | ||
|
||
|
||
==== tests/cases/compiler/constDeclarations-invalidContexts.ts (10 errors) ==== | ||
|
||
// Errors, const must be defined inside a block | ||
if (true) | ||
const c1 = 0; | ||
~~~~~~~~~~~~~ | ||
!!! error TS1156: const must be declared inside a block. | ||
else | ||
const c2 = 0; | ||
~~~~~~~~~~~~~ | ||
!!! error TS1156: const must be declared inside a block. | ||
|
||
while (true) | ||
const c3 = 0; | ||
~~~~~~~~~~~~~ | ||
!!! error TS1156: const must be declared inside a block. | ||
|
||
do | ||
const c4 = 0; | ||
~~~~~~~~~~~~~ | ||
!!! error TS1156: const must be declared inside a block. | ||
while (true); | ||
|
||
var obj; | ||
with (obj) | ||
~~~ | ||
!!! error TS2410: All symbols within a 'with' block will be resolved to 'any'. | ||
const c5 = 0; | ||
~~~~~~~~~~~~~ | ||
!!! error TS1156: const must be declared inside a block. | ||
|
||
for (var i = 0; i < 10; i++) | ||
const c6 = 0; | ||
~~~~~~~~~~~~~ | ||
!!! error TS1156: const must be declared inside a block. | ||
|
||
for (var i2 in {}) | ||
const c7 = 0; | ||
~~~~~~~~~~~~~ | ||
!!! error TS1156: const must be declared inside a block. | ||
|
||
if (true) | ||
label: const c8 = 0; | ||
~~~~~~~~~~~~~ | ||
!!! error TS1156: const must be declared inside a block. | ||
|
||
while (false) | ||
label2: label3: label4: const c9 = 0; | ||
~~~~~~~~~~~~~ | ||
!!! error TS1156: const must be declared inside a block. | ||
|
||
|
||
|
||
|
Please put single quotes around these, and consider hard coding the names 'let' and 'const'