From 90e19551bc71f25473eaf559f27611ccb89b8474 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 2 Jun 2015 15:03:01 -0700 Subject: [PATCH] merge compatiblity now performed in checker.ts --- src/compiler/binder.ts | 12 +------- src/compiler/checker.ts | 28 +++++++++++++++++++ .../diagnosticInformationMap.generated.ts | 2 ++ src/compiler/diagnosticMessages.json | 17 +++++++---- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 60b5a622ac6..42c22eda571 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -135,15 +135,6 @@ module ts { return node.name ? declarationNameToString(node.name) : getDeclarationName(node); } - // /** - // * Checks if the symbol contains a class declaration that is non-ambient. - // */ - // function hasNonAmbientClass(symbol: Symbol): boolean { - // return symbol && forEach(symbol.declarations, (element: Declaration) => { - // return element.kind === SyntaxKind.ClassDeclaration && !(element.flags & NodeFlags.Ambient); - // }); - // } - /** * Declares a Symbol for the Node and add it to symbols. Reports errors for conflicting identifier names. * @param symbols - The symbolTable which node will be added to. @@ -162,8 +153,7 @@ module ts { if (name !== undefined) { symbol = hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(0, name)); - // Check for declarations 'node' cannot be merged with. - // Interfaces declarations cannot be merged with non-ambient class declarations, which isn't encoded in SymbolFlags. + // Check for declarations 'node' cannot be merged with. if (symbol.flags & excludes) { if (node.name) { node.name.parent = node; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 759b235ad0a..20b0fc6d68e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10393,6 +10393,15 @@ module ts { }); } + // Non-ambient classes cannot merge with interfaces. + if (!(node.flags & NodeFlags.Ambient)) { + if (forEach(symbol.declarations, (element: Declaration) => { + return element.kind === SyntaxKind.InterfaceDeclaration; + })) { + error(node, Diagnostics.A_non_ambient_class_cannot_be_merged_with_an_interface) + } + } + forEach(node.members, checkSourceElement); if (produceDiagnostics) { checkIndexConstraints(type); @@ -10544,6 +10553,15 @@ module ts { return ok; } + /** + * Checks if the symbol contains a class declaration that is non-ambient. + */ + function hasNonAmbientClass(symbol: Symbol): boolean { + return symbol && forEach(symbol.declarations, (element: Declaration) => { + return element.kind === SyntaxKind.ClassDeclaration && !(element.flags & NodeFlags.Ambient); + }); + } + function checkInterfaceDeclaration(node: InterfaceDeclaration) { // Grammar checking checkGrammarDeclarationNameInStrictMode(node) || checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node); @@ -10572,6 +10590,13 @@ module ts { checkIndexConstraints(type); } } + + // Interfaces cannot merge with non-ambient classes. + if (!(node.flags & NodeFlags.Ambient)) { + if (hasNonAmbientClass(symbol)) { + error(node, Diagnostics.An_interface_cannot_merge_with_a_non_ambient_class); + } + } } forEach(getInterfaceBaseTypeNodes(node), heritageElement => { if (!isSupportedExpressionWithTypeArguments(heritageElement)) { @@ -10580,6 +10605,9 @@ module ts { checkExpressionWithTypeArguments(heritageElement); }); + + + forEach(node.members, checkSourceElement); if (produceDiagnostics) { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 6e73d28bddd..2d7fd358f70 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -371,6 +371,8 @@ module ts { Cannot_find_namespace_0: { code: 2503, category: DiagnosticCategory.Error, key: "Cannot find namespace '{0}'." }, No_best_common_type_exists_among_yield_expressions: { code: 2504, category: DiagnosticCategory.Error, key: "No best common type exists among yield expressions." }, A_generator_cannot_have_a_void_type_annotation: { code: 2505, category: DiagnosticCategory.Error, key: "A generator cannot have a 'void' type annotation." }, + A_non_ambient_class_cannot_be_merged_with_an_interface: { code: 2506, category: DiagnosticCategory.Error, key: "A non-ambient class cannot be merged with an interface." }, + An_interface_cannot_merge_with_a_non_ambient_class: { code: 2507, category: DiagnosticCategory.Error, key: "An interface cannot merge with a non-ambient class." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d5764605d51..fdf35985189 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1456,15 +1456,15 @@ "A rest element cannot contain a binding pattern.": { "category": "Error", "code": 2501 - }, + }, "'{0}' is referenced directly or indirectly in its own type annotation.": { "category": "Error", "code": 2502 - }, + }, "Cannot find namespace '{0}'.": { "category": "Error", "code": 2503 - }, + }, "No best common type exists among yield expressions.": { "category": "Error", "code": 2504 @@ -1472,8 +1472,15 @@ "A generator cannot have a 'void' type annotation.": { "category": "Error", "code": 2505 - }, - + }, + "A non-ambient class cannot be merged with an interface.": { + "category": "Error", + "code": 2506 + }, + "An interface cannot merge with a non-ambient class.": { + "category": "Error", + "code": 2507 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000