Skip to content

Commit 98f631e

Browse files
committed
Make changes to report error if the type used from external module cannot be named
Adds test cases too
1 parent e27e6b2 commit 98f631e

16 files changed

+2831
-39
lines changed

src/compiler/checker.ts

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -681,9 +681,11 @@ module ts {
681681

682682
function isAccessible(symbolFromSymbolTable: Symbol, resolvedAliasSymbol?: Symbol) {
683683
if (symbol === (resolvedAliasSymbol || symbolFromSymbolTable)) {
684-
// if symbolfrom symbolTable or alias resolution matches the symbol,
684+
// if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
685+
// and if symbolfrom symbolTable or alias resolution matches the symbol,
685686
// check the symbol can be qualified, it is only then this symbol is accessible
686-
return canQualifySymbol(symbolFromSymbolTable, meaning);
687+
return !forEach(symbolFromSymbolTable.declarations, declaration => hasExternalModuleSymbol(declaration)) &&
688+
canQualifySymbol(symbolFromSymbolTable, meaning);
687689
}
688690
}
689691

@@ -779,14 +781,42 @@ module ts {
779781
symbol = symbol.parent;
780782
}
781783

782-
// This is a local symbol that cannot be named
784+
// This could be a symbol that is not exported in the external module
785+
// or it could be a symbol from different external module that is not aliased and hence cannot be named
786+
var symbolExternalModule = forEach(initialSymbol.declarations, declaration => getExternalModuleContainer(declaration));
787+
if (symbolExternalModule) {
788+
var enclosingExternalModule = getExternalModuleContainer(enclosingDeclaration);
789+
if (symbolExternalModule !== enclosingExternalModule) {
790+
// name from different external module that is not visibile
791+
return {
792+
accessibility: SymbolAccessibility.CannotBeNamed,
793+
errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
794+
errorModuleName: symbolToString(symbolExternalModule)
795+
};
796+
}
797+
}
798+
799+
// Just a local name that is not accessible
783800
return {
784-
accessibility: SymbolAccessibility.CannotBeNamed,
801+
accessibility: SymbolAccessibility.NotAccessible,
785802
errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
786803
};
787804
}
788805

789806
return { accessibility: SymbolAccessibility.Accessible };
807+
808+
function getExternalModuleContainer(declaration: Declaration) {
809+
for (; declaration; declaration = declaration.parent) {
810+
if (hasExternalModuleSymbol(declaration)) {
811+
return getSymbolOfNode(declaration);
812+
}
813+
}
814+
}
815+
}
816+
817+
function hasExternalModuleSymbol(declaration: Declaration) {
818+
return (declaration.kind === SyntaxKind.ModuleDeclaration && declaration.name.kind === SyntaxKind.StringLiteral) ||
819+
(declaration.kind === SyntaxKind.SourceFile && isExternalModule(<SourceFile>declaration));
790820
}
791821

792822
function hasVisibleDeclarations(symbol: Symbol): { aliasesToMakeVisible?: ImportDeclaration[]; } {
@@ -855,7 +885,18 @@ module ts {
855885
while (symbol) {
856886
var isFirstName = !symbolName;
857887
var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning);
858-
var currentSymbolName = accessibleSymbolChain ? ts.map(accessibleSymbolChain, accessibleSymbol => getSymbolName(accessibleSymbol)).join(".") : getSymbolName(symbol);
888+
889+
var currentSymbolName: string;
890+
if (accessibleSymbolChain) {
891+
currentSymbolName = ts.map(accessibleSymbolChain, accessibleSymbol => getSymbolName(accessibleSymbol)).join(".");
892+
}
893+
else {
894+
// If we didnt find accessible symbol chain for this symbol, break if this is external module
895+
if (!isFirstName && ts.forEach(symbol.declarations, declaration => hasExternalModuleSymbol(declaration))) {
896+
break;
897+
}
898+
currentSymbolName = getSymbolName(symbol);
899+
}
859900
symbolName = currentSymbolName + (isFirstName ? "" : ("." + symbolName));
860901
if (accessibleSymbolChain && !needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) {
861902
break;

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,18 @@ module ts {
231231
A_parameter_property_is_only_allowed_in_a_constructor_implementation: { code: 2246, category: DiagnosticCategory.Error, key: "A parameter property is only allowed in a constructor implementation." },
232232
Function_overload_must_be_static: { code: 2247, category: DiagnosticCategory.Error, key: "Function overload must be static." },
233233
Function_overload_must_not_be_static: { code: 2248, category: DiagnosticCategory.Error, key: "Function overload must not be static." },
234+
Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 2249, category: DiagnosticCategory.Error, key: "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named." },
235+
Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 2250, category: DiagnosticCategory.Error, key: "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named." },
236+
Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 2251, category: DiagnosticCategory.Error, key: "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named." },
237+
Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 2252, category: DiagnosticCategory.Error, key: "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named." },
238+
Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 2253, category: DiagnosticCategory.Error, key: "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named." },
239+
Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 2254, category: DiagnosticCategory.Error, key: "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named." },
240+
Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 2255, category: DiagnosticCategory.Error, key: "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named." },
241+
Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: { code: 2256, category: DiagnosticCategory.Error, key: "Return type of public static property getter from exported class has or is using name '{0}' from external module {1} but cannot be named." },
242+
Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: { code: 2257, category: DiagnosticCategory.Error, key: "Return type of public property getter from exported class has or is using name '{0}' from external module {1} but cannot be named." },
243+
Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: { code: 2258, category: DiagnosticCategory.Error, key: "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named." },
244+
Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: { code: 2259, category: DiagnosticCategory.Error, key: "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named." },
245+
Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: { code: 2260, category: DiagnosticCategory.Error, key: "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named." },
234246
Circular_definition_of_import_alias_0: { code: 3000, category: DiagnosticCategory.Error, key: "Circular definition of import alias '{0}'." },
235247
Cannot_find_name_0: { code: 3001, category: DiagnosticCategory.Error, key: "Cannot find name '{0}'." },
236248
Module_0_has_no_exported_member_1: { code: 3002, category: DiagnosticCategory.Error, key: "Module '{0}' has no exported member '{1}'." },

src/compiler/diagnosticMessages.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,54 @@
916916
"category": "Error",
917917
"code": 2248
918918
},
919+
"Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.": {
920+
"category": "Error",
921+
"code": 2249
922+
},
923+
"Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.": {
924+
"category": "Error",
925+
"code": 2250
926+
},
927+
"Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named.": {
928+
"category": "Error",
929+
"code": 2251
930+
},
931+
"Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named.": {
932+
"category": "Error",
933+
"code": 2252
934+
},
935+
"Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named.": {
936+
"category": "Error",
937+
"code": 2253
938+
},
939+
"Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named.": {
940+
"category": "Error",
941+
"code": 2254
942+
},
943+
"Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named.": {
944+
"category": "Error",
945+
"code": 2255
946+
},
947+
"Return type of public static property getter from exported class has or is using name '{0}' from external module {1} but cannot be named.": {
948+
"category": "Error",
949+
"code": 2256
950+
},
951+
"Return type of public property getter from exported class has or is using name '{0}' from external module {1} but cannot be named.": {
952+
"category": "Error",
953+
"code": 2257
954+
},
955+
"Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named.": {
956+
"category": "Error",
957+
"code": 2258
958+
},
959+
"Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named.": {
960+
"category": "Error",
961+
"code": 2259
962+
},
963+
"Return type of exported function has or is using name '{0}' from external module {1} but cannot be named.": {
964+
"category": "Error",
965+
"code": 2260
966+
},
919967
"Circular definition of import alias '{0}'.": {
920968
"category": "Error",
921969
"code": 3000

0 commit comments

Comments
 (0)