diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 17dbae83bf2..4520aaffc02 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -144,6 +144,7 @@ module ts { Array_element_destructuring_pattern_expected: { code: 1181, category: DiagnosticCategory.Error, key: "Array element destructuring pattern expected." }, A_destructuring_declaration_must_have_an_initializer: { code: 1182, category: DiagnosticCategory.Error, key: "A destructuring declaration must have an initializer." }, Destructuring_declarations_are_not_allowed_in_ambient_contexts: { code: 1183, category: DiagnosticCategory.Error, key: "Destructuring declarations are not allowed in ambient contexts." }, + Modifiers_cannot_appear_here: { code: 1184, category: DiagnosticCategory.Error, key: "Modifiers cannot appear here." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index a06b71d460e..7aacd21cea4 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -568,6 +568,10 @@ "category": "Error", "code": 1183 }, + "Modifiers cannot appear here.": { + "category": "Error", + "code": 1184 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3e8301ef7f7..9552e0f9cc9 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3866,12 +3866,45 @@ module ts { } // Else parse it like identifier - fall through default: + if (isModifier(token)) { + var result = tryParse(parseVariableStatementOrFunctionDeclarationWithModifiers); + if (result) { + return result; + } + } + return isLabel() ? parseLabeledStatement() : parseExpressionStatement(); } } + function parseVariableStatementOrFunctionDeclarationWithModifiers(): FunctionDeclaration | VariableStatement { + var start = scanner.getStartPos(); + var modifiers = parseModifiers(); + switch (token) { + case SyntaxKind.ConstKeyword: + var nextTokenIsEnum = lookAhead(nextTokenIsEnumKeyword) + if (nextTokenIsEnum) { + return undefined; + } + return parseVariableStatement(start, modifiers); + + case SyntaxKind.LetKeyword: + if (!isLetDeclaration()) { + return undefined; + } + return parseVariableStatement(start, modifiers); + + case SyntaxKind.VarKeyword: + return parseVariableStatement(start, modifiers); + case SyntaxKind.FunctionKeyword: + return parseFunctionDeclaration(start, modifiers); + } + + return undefined; + } + function parseFunctionBlockOrSemicolon(isGenerator: boolean): Block { if (token === SyntaxKind.OpenBraceToken) { return parseFunctionBlock(isGenerator, /*ignoreMissingOpenBrace:*/ false); @@ -4600,6 +4633,7 @@ module ts { // We're automatically in an ambient context if this is a .d.ts file. var inAmbientContext = fileExtensionIs(file.filename, ".d.ts"); var inFunctionBlock = false; + var inBlock = false; var parent: Node; visitNode(file); @@ -4614,6 +4648,10 @@ module ts { if (isFunctionBlock(node)) { inFunctionBlock = true; } + var savedInBlock = inBlock; + if (node.kind === SyntaxKind.Block || node.kind === SyntaxKind.TryBlock || node.kind === SyntaxKind.FinallyBlock) { + inBlock = true; + } var savedInAmbientContext = inAmbientContext if (node.flags & NodeFlags.Ambient) { @@ -4624,6 +4662,7 @@ module ts { inAmbientContext = savedInAmbientContext; inFunctionBlock = savedInFunctionBlock; + inBlock = savedInBlock; } parent = savedParent; @@ -5085,7 +5124,8 @@ module ts { } function checkFunctionDeclaration(node: FunctionLikeDeclaration) { - return checkAnySignatureDeclaration(node) || + return checkForDisallowedModifiersInBlock(node) || + checkAnySignatureDeclaration(node) || checkFunctionName(node.name) || checkForBodyInAmbientContext(node.body, /*isConstructor:*/ false) || checkForGenerator(node); @@ -5820,10 +5860,17 @@ module ts { } function checkVariableStatement(node: VariableStatement) { - return checkVariableDeclarations(node.declarations) || + return checkForDisallowedModifiersInBlock(node) || + checkVariableDeclarations(node.declarations) || checkForDisallowedLetOrConstStatement(node); } + function checkForDisallowedModifiersInBlock(node: Node) { + if (inBlock && node.modifiers) { + return grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here); + } + } + function checkForDisallowedLetOrConstStatement(node: VariableStatement) { if (!allowLetAndConstDeclarations(node.parent)) { if (isLet(node)) { diff --git a/tests/baselines/reference/parserModifierOnStatementInBlock2.errors.txt b/tests/baselines/reference/parserModifierOnStatementInBlock2.errors.txt index 7155d5cfe42..b07d7d9aad1 100644 --- a/tests/baselines/reference/parserModifierOnStatementInBlock2.errors.txt +++ b/tests/baselines/reference/parserModifierOnStatementInBlock2.errors.txt @@ -1,13 +1,10 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts(2,12): error TS1005: ';' expected. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts(2,4): error TS2304: Cannot find name 'declare'. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts(2,4): error TS1184: Modifiers cannot appear here. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts (1 errors) ==== { declare var x = this; - ~~~ -!!! error TS1005: ';' expected. ~~~~~~~ -!!! error TS2304: Cannot find name 'declare'. +!!! error TS1184: Modifiers cannot appear here. } \ No newline at end of file