Skip to content

Commit f73af3a

Browse files
committed
Merge pull request #3461 from Microsoft/parsingModuleElements
Parse module elements in a block context
2 parents d49fe6a + 380918c commit f73af3a

35 files changed

+756
-166
lines changed

src/compiler/binder.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,11 @@ module ts {
661661
}
662662

663663
function bindExportAssignment(node: ExportAssignment) {
664-
if (node.expression.kind === SyntaxKind.Identifier) {
664+
if (!container.symbol || !container.symbol.exports) {
665+
// Export assignment in some sort of block construct
666+
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
667+
}
668+
else if (node.expression.kind === SyntaxKind.Identifier) {
665669
// An export default clause with an identifier exports all meanings of that identifier
666670
declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes);
667671
}
@@ -672,7 +676,11 @@ module ts {
672676
}
673677

674678
function bindExportDeclaration(node: ExportDeclaration) {
675-
if (!node.exportClause) {
679+
if (!container.symbol || !container.symbol.exports) {
680+
// Export * in some sort of block construct
681+
bindAnonymousDeclaration(node, SymbolFlags.ExportStar, getDeclarationName(node));
682+
}
683+
else if (!node.exportClause) {
676684
// All export * declarations are collected in an __export symbol
677685
declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, SymbolFlags.None);
678686
}

src/compiler/checker.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11114,6 +11114,15 @@ module ts {
1111411114
function checkModuleDeclaration(node: ModuleDeclaration) {
1111511115
if (produceDiagnostics) {
1111611116
// Grammar checking
11117+
let isAmbientExternalModule = node.name.kind === SyntaxKind.StringLiteral;
11118+
let contextErrorMessage = isAmbientExternalModule
11119+
? Diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file
11120+
: Diagnostics.A_namespace_declaration_is_only_allowed_in_a_namespace_or_module;
11121+
if (checkGrammarModuleElementContext(node, contextErrorMessage)) {
11122+
// If we hit a module declaration in an illegal context, just bail out to avoid cascading errors.
11123+
return;
11124+
}
11125+
1111711126
if (!checkGrammarDeclarationNameInStrictMode(node) && !checkGrammarDecorators(node) && !checkGrammarModifiers(node)) {
1111811127
if (!isInAmbientContext(node) && node.name.kind === SyntaxKind.StringLiteral) {
1111911128
grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names);
@@ -11150,7 +11159,7 @@ module ts {
1115011159
}
1115111160

1115211161
// Checks for ambient external modules.
11153-
if (node.name.kind === SyntaxKind.StringLiteral) {
11162+
if (isAmbientExternalModule) {
1115411163
if (!isGlobalSourceFile(node.parent)) {
1115511164
error(node.name, Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules);
1115611165
}
@@ -11226,6 +11235,10 @@ module ts {
1122611235
}
1122711236

1122811237
function checkImportDeclaration(node: ImportDeclaration) {
11238+
if (checkGrammarModuleElementContext(node, Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
11239+
// If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
11240+
return;
11241+
}
1122911242
if (!checkGrammarImportDeclarationNameInStrictMode(node) && !checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
1123011243
grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers);
1123111244
}
@@ -11248,6 +11261,11 @@ module ts {
1124811261
}
1124911262

1125011263
function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) {
11264+
if (checkGrammarModuleElementContext(node, Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
11265+
// If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
11266+
return;
11267+
}
11268+
1125111269
checkGrammarDeclarationNameInStrictMode(node) || checkGrammarDecorators(node) || checkGrammarModifiers(node);
1125211270
if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) {
1125311271
checkImportBinding(node);
@@ -11279,9 +11297,15 @@ module ts {
1127911297
}
1128011298

1128111299
function checkExportDeclaration(node: ExportDeclaration) {
11300+
if (checkGrammarModuleElementContext(node, Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) {
11301+
// If we hit an export in an illegal context, just bail out to avoid cascading errors.
11302+
return;
11303+
}
11304+
1128211305
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
1128311306
grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers);
1128411307
}
11308+
1128511309
if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
1128611310
if (node.exportClause) {
1128711311
// export { x, y }
@@ -11303,6 +11327,12 @@ module ts {
1130311327
}
1130411328
}
1130511329

11330+
function checkGrammarModuleElementContext(node: Statement, errorMessage: DiagnosticMessage): boolean {
11331+
if (node.parent.kind !== SyntaxKind.SourceFile && node.parent.kind !== SyntaxKind.ModuleBlock && node.parent.kind !== SyntaxKind.ModuleDeclaration) {
11332+
return grammarErrorOnFirstToken(node, errorMessage);
11333+
}
11334+
}
11335+
1130611336
function checkExportSpecifier(node: ExportSpecifier) {
1130711337
checkAliasSymbol(node);
1130811338
if (!(<ExportDeclaration>node.parent.parent).moduleSpecifier) {
@@ -11311,6 +11341,11 @@ module ts {
1131111341
}
1131211342

1131311343
function checkExportAssignment(node: ExportAssignment) {
11344+
if (checkGrammarModuleElementContext(node, Diagnostics.An_export_assignment_can_only_be_used_in_a_module)) {
11345+
// If we hit an export assignment in an illegal context, just bail out to avoid cascading errors.
11346+
return;
11347+
}
11348+
1131411349
let container = node.parent.kind === SyntaxKind.SourceFile ? <SourceFile>node.parent : <ModuleDeclaration>node.parent.parent;
1131511350
if (container.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>container).name.kind === SyntaxKind.Identifier) {
1131611351
error(node, Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace);
@@ -11326,7 +11361,8 @@ module ts {
1132611361
else {
1132711362
checkExpressionCached(node.expression);
1132811363
}
11329-
checkExternalModuleExports(container);
11364+
11365+
checkExternalModuleExports(<SourceFile | ModuleDeclaration>container);
1133011366

1133111367
if (node.isExportEquals && !isInAmbientContext(node)) {
1133211368
if (languageVersion >= ScriptTarget.ES6) {
@@ -11340,7 +11376,7 @@ module ts {
1134011376
}
1134111377
}
1134211378

11343-
function getModuleStatements(node: Declaration): ModuleElement[] {
11379+
function getModuleStatements(node: Declaration): Statement[] {
1134411380
if (node.kind === SyntaxKind.SourceFile) {
1134511381
return (<SourceFile>node).statements;
1134611382
}

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ module ts {
186186
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." },
187187
A_type_predicate_cannot_reference_a_rest_parameter: { code: 1229, category: DiagnosticCategory.Error, key: "A type predicate cannot reference a rest parameter." },
188188
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." },
189+
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." },
190+
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." },
191+
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." },
192+
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." },
193+
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." },
189194
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
190195
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." },
191196
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },

src/compiler/diagnosticMessages.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,26 @@
731731
"category": "Error",
732732
"code": 1230
733733
},
734+
"An export assignment can only be used in a module.": {
735+
"category": "Error",
736+
"code": 1231
737+
},
738+
"An import declaration can only be used in a namespace or module.": {
739+
"category": "Error",
740+
"code": 1232
741+
},
742+
"An export declaration can only be used in a module.": {
743+
"category": "Error",
744+
"code": 1233
745+
},
746+
"An ambient module declaration is only allowed at the top level in a file.": {
747+
"category": "Error",
748+
"code": 1234
749+
},
750+
"A namespace declaration is only allowed in a namespace or module.": {
751+
"category": "Error",
752+
"code": 1235
753+
},
734754

735755

736756
"Duplicate identifier '{0}'.": {

0 commit comments

Comments
 (0)