diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b2d76eb8c1..b0264a108b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3699,7 +3699,6 @@ module ts { case SyntaxKind.OpenBraceToken: return parseBlock(SyntaxKind.Block, /* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: case SyntaxKind.ConstKeyword: // const here should always be parsed as const declaration because of check in 'isStatement' return parseVariableStatement(scanner.getStartPos(), /*modifiers:*/ undefined); @@ -3734,6 +3733,12 @@ module ts { return parseTryStatement(); case SyntaxKind.DebuggerKeyword: return parseDebuggerStatement(); + case SyntaxKind.LetKeyword: + // If let follows identifier on the same line, it is declaration parse it as variable statement + if (isLetDeclaration()) { + return parseVariableStatement(scanner.getStartPos(), /*modifiers:*/ undefined); + } + // Else parse it like identifier - fall through default: return isLabel() ? parseLabeledStatement() @@ -4166,14 +4171,21 @@ module ts { parseSemicolon(); return finishNode(node); } + + function isLetDeclaration() { + // It is let declaration if in strict mode or next token is identifier on same line. + // otherwise it needs to be treated like identifier + return inStrictModeContext() || lookAhead(nextTokenIsIdentifierOnSameLine); + } function isDeclarationStart(): boolean { switch (token) { case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: case SyntaxKind.ConstKeyword: case SyntaxKind.FunctionKeyword: return true; + case SyntaxKind.LetKeyword: + return isLetDeclaration(); case SyntaxKind.ClassKeyword: case SyntaxKind.InterfaceKeyword: case SyntaxKind.EnumKeyword: diff --git a/tests/baselines/reference/VariableDeclaration6_es6.errors.txt b/tests/baselines/reference/VariableDeclaration6_es6.errors.txt index 6217297336..fb2a41b873 100644 --- a/tests/baselines/reference/VariableDeclaration6_es6.errors.txt +++ b/tests/baselines/reference/VariableDeclaration6_es6.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/es6/variableDeclarations/VariableDeclaration6_es6.ts(1,4): error TS1123: Variable declaration list cannot be empty. +tests/cases/conformance/es6/variableDeclarations/VariableDeclaration6_es6.ts(1,1): error TS2304: Cannot find name 'let'. ==== tests/cases/conformance/es6/variableDeclarations/VariableDeclaration6_es6.ts (1 errors) ==== let - -!!! error TS1123: Variable declaration list cannot be empty. \ No newline at end of file + ~~~ +!!! error TS2304: Cannot find name 'let'. \ No newline at end of file diff --git a/tests/baselines/reference/VariableDeclaration6_es6.js b/tests/baselines/reference/VariableDeclaration6_es6.js new file mode 100644 index 0000000000..aee01ed527 --- /dev/null +++ b/tests/baselines/reference/VariableDeclaration6_es6.js @@ -0,0 +1,5 @@ +//// [VariableDeclaration6_es6.ts] +let + +//// [VariableDeclaration6_es6.js] +let; diff --git a/tests/baselines/reference/letAsIdentifier.js b/tests/baselines/reference/letAsIdentifier.js new file mode 100644 index 0000000000..ae45b4b491 --- /dev/null +++ b/tests/baselines/reference/letAsIdentifier.js @@ -0,0 +1,19 @@ +//// [letAsIdentifier.ts] + +var let = 10; +var a = 10; +let = 30; +let +a; + +//// [letAsIdentifier.js] +var let = 10; +var a = 10; +let = 30; +let; +a; + + +//// [letAsIdentifier.d.ts] +declare var let: number; +declare var a: number; diff --git a/tests/baselines/reference/letAsIdentifier.types b/tests/baselines/reference/letAsIdentifier.types new file mode 100644 index 0000000000..95fe2b11ac --- /dev/null +++ b/tests/baselines/reference/letAsIdentifier.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/letAsIdentifier.ts === + +var let = 10; +>let : number + +var a = 10; +>a : number + +let = 30; +>let = 30 : number +>let : number + +let +>let : number + +a; +>a : number + diff --git a/tests/baselines/reference/letAsIdentifierInStrictMode.errors.txt b/tests/baselines/reference/letAsIdentifierInStrictMode.errors.txt new file mode 100644 index 0000000000..e332535e23 --- /dev/null +++ b/tests/baselines/reference/letAsIdentifierInStrictMode.errors.txt @@ -0,0 +1,30 @@ +tests/cases/compiler/letAsIdentifierInStrictMode.ts(2,5): error TS1134: Variable declaration expected. +tests/cases/compiler/letAsIdentifierInStrictMode.ts(2,9): error TS1134: Variable declaration expected. +tests/cases/compiler/letAsIdentifierInStrictMode.ts(2,11): error TS1134: Variable declaration expected. +tests/cases/compiler/letAsIdentifierInStrictMode.ts(4,5): error TS1134: Variable declaration expected. +tests/cases/compiler/letAsIdentifierInStrictMode.ts(4,7): error TS1134: Variable declaration expected. +tests/cases/compiler/letAsIdentifierInStrictMode.ts(3,5): error TS2300: Duplicate identifier 'a'. +tests/cases/compiler/letAsIdentifierInStrictMode.ts(6,1): error TS2300: Duplicate identifier 'a'. + + +==== tests/cases/compiler/letAsIdentifierInStrictMode.ts (7 errors) ==== + "use strict"; + var let = 10; + ~~~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS1134: Variable declaration expected. + ~~ +!!! error TS1134: Variable declaration expected. + var a = 10; + ~ +!!! error TS2300: Duplicate identifier 'a'. + let = 30; + ~ +!!! error TS1134: Variable declaration expected. + ~~ +!!! error TS1134: Variable declaration expected. + let + a; + ~ +!!! error TS2300: Duplicate identifier 'a'. \ No newline at end of file diff --git a/tests/cases/compiler/letAsIdentifier.ts b/tests/cases/compiler/letAsIdentifier.ts new file mode 100644 index 0000000000..d4473aa99c --- /dev/null +++ b/tests/cases/compiler/letAsIdentifier.ts @@ -0,0 +1,7 @@ +// @declaration: true + +var let = 10; +var a = 10; +let = 30; +let +a; \ No newline at end of file diff --git a/tests/cases/compiler/letAsIdentifierInStrictMode.ts b/tests/cases/compiler/letAsIdentifierInStrictMode.ts new file mode 100644 index 0000000000..59a9d7da88 --- /dev/null +++ b/tests/cases/compiler/letAsIdentifierInStrictMode.ts @@ -0,0 +1,6 @@ +"use strict"; +var let = 10; +var a = 10; +let = 30; +let +a; \ No newline at end of file