diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1ad31795beb..828ddb0dec0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11114,6 +11114,14 @@ module ts { function checkModuleDeclaration(node: ModuleDeclaration) { if (produceDiagnostics) { // Grammar checking + let isAmbientExternalModule = node.name.kind === SyntaxKind.StringLiteral; + let contextErrorMessage = isAmbientExternalModule + ? Diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file + : Diagnostics.A_namespace_declaration_is_only_allowed_in_a_namespace_or_module; + if (!checkGrammarModuleElementContext(node, contextErrorMessage)) { + return; + } + if (!checkGrammarDeclarationNameInStrictMode(node) && !checkGrammarDecorators(node) && !checkGrammarModifiers(node)) { if (!isInAmbientContext(node) && node.name.kind === SyntaxKind.StringLiteral) { grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names); @@ -11150,7 +11158,7 @@ module ts { } // Checks for ambient external modules. - if (node.name.kind === SyntaxKind.StringLiteral) { + if (isAmbientExternalModule) { if (!isGlobalSourceFile(node.parent)) { error(node.name, Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules); } @@ -11227,6 +11235,9 @@ module ts { } function checkImportDeclaration(node: ImportDeclaration) { + if (!checkGrammarModuleElementContext(node, Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) { + return; + } if (!checkGrammarImportDeclarationNameInStrictMode(node) && !checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers); } @@ -11249,6 +11260,10 @@ module ts { } function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) { + if (!checkGrammarModuleElementContext(node, Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) { + return; + } + checkGrammarDeclarationNameInStrictMode(node) || checkGrammarDecorators(node) || checkGrammarModifiers(node); if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); @@ -11280,9 +11295,14 @@ module ts { } function checkExportDeclaration(node: ExportDeclaration) { + if (!checkGrammarModuleElementContext(node, Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) { + return; + } + if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) { grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers); } + if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) { if (node.exportClause) { // export { x, y } @@ -11304,6 +11324,15 @@ module ts { } } + function checkGrammarModuleElementContext(node: ModuleElement, errorMessage: DiagnosticMessage): boolean { + if (node.parent.kind !== SyntaxKind.SourceFile && node.parent.kind !== SyntaxKind.ModuleBlock && node.parent.kind !== SyntaxKind.ModuleDeclaration) { + grammarErrorOnFirstToken(node, errorMessage); + return false; + } + + return true; + } + function checkExportSpecifier(node: ExportSpecifier) { checkAliasSymbol(node); if (!(node.parent.parent).moduleSpecifier) { @@ -11312,8 +11341,7 @@ module ts { } function checkExportAssignment(node: ExportAssignment) { - if (node.parent.kind !== SyntaxKind.SourceFile && node.parent.kind !== SyntaxKind.ModuleBlock) { - // TODO: StatementFlags + if (!checkGrammarModuleElementContext(node, Diagnostics.An_export_assignment_can_only_be_used_in_a_module)) { return; } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 0c8be2d3c54..9f6190ead11 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -186,6 +186,11 @@ module ts { A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods: { code: 1228, category: DiagnosticCategory.Error, key: "A type predicate is only allowed in return type position for functions and methods." }, A_type_predicate_cannot_reference_a_rest_parameter: { code: 1229, category: DiagnosticCategory.Error, key: "A type predicate cannot reference a rest parameter." }, A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: { code: 1230, category: DiagnosticCategory.Error, key: "A type predicate cannot reference element '{0}' in a binding pattern." }, + An_export_assignment_can_only_be_used_in_a_module: { code: 1231, category: DiagnosticCategory.Error, key: "An export assignment can only be used in a module." }, + An_import_declaration_can_only_be_used_in_a_namespace_or_module: { code: 1232, category: DiagnosticCategory.Error, key: "An import declaration can only be used in a namespace or module." }, + An_export_declaration_can_only_be_used_in_a_module: { code: 1233, category: DiagnosticCategory.Error, key: "An export declaration can only be used in a module." }, + An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: { code: 1234, category: DiagnosticCategory.Error, key: "An ambient module declaration is only allowed at the top level in a file." }, + A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: { code: 1235, category: DiagnosticCategory.Error, key: "A namespace declaration is only allowed in a namespace or module." }, 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 08273011745..d78ea07f91a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -731,6 +731,26 @@ "category": "Error", "code": 1230 }, + "An export assignment can only be used in a module.": { + "category": "Error", + "code": 1231 + }, + "An import declaration can only be used in a namespace or module.": { + "category": "Error", + "code": 1232 + }, + "An export declaration can only be used in a module.": { + "category": "Error", + "code": 1233 + }, + "An ambient module declaration is only allowed at the top level in a file.": { + "category": "Error", + "code": 1234 + }, + "A namespace declaration is only allowed in a namespace or module.": { + "category": "Error", + "code": 1235 + }, "Duplicate identifier '{0}'.": {