diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 98dfea08e0e..5d76a3b127f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4130,7 +4130,7 @@ module ts { // DECLARATION AND STATEMENT TYPE CHECKING function checkTypeParameter(node: TypeParameterDeclaration) { - checkNameIsReserved(node.name, Diagnostics.Type_parameter_name_cannot_be_0); + checkTypeNameIsReserved(node.name, Diagnostics.Type_parameter_name_cannot_be_0); checkSourceElement(node.constraint); checkTypeParameterHasIllegalReferencesInConstraint(node); // TODO: Check multiple declarations are identical @@ -5027,7 +5027,7 @@ module ts { } } - function checkNameIsReserved(name: Identifier, message: DiagnosticMessage): boolean { + function checkTypeNameIsReserved(name: Identifier, message: DiagnosticMessage): void { // TS 1.0 spec (April 2014): 3.6.1 // The predefined type keywords are reserved and cannot be used as names of user defined types. switch (name.text) { @@ -5037,7 +5037,6 @@ module ts { case "string": case "void": error(name, message, name.text); - return true; } } @@ -5058,7 +5057,7 @@ module ts { function checkClassDeclaration(node: ClassDeclaration) { checkDeclarationModifiers(node); - checkNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0); + checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0); checkTypeParameters(node.typeParameters); var symbol = getSymbolOfNode(node); var type = getDeclaredTypeOfSymbol(symbol); @@ -5213,7 +5212,7 @@ module ts { function checkInterfaceDeclaration(node: InterfaceDeclaration) { checkDeclarationModifiers(node); - checkNameIsReserved(node.name, Diagnostics.Interface_name_cannot_be_0); + checkTypeNameIsReserved(node.name, Diagnostics.Interface_name_cannot_be_0); checkTypeParameters(node.typeParameters); var symbol = getSymbolOfNode(node); var firstInterfaceDecl = getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration); @@ -5259,7 +5258,7 @@ module ts { function checkEnumDeclaration(node: EnumDeclaration) { checkDeclarationModifiers(node); - checkNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0); + checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0); var enumSymbol = getSymbolOfNode(node); var enumType = getDeclaredTypeOfSymbol(enumSymbol); var autoValue = 0; @@ -5334,16 +5333,20 @@ module ts { function checkImportDeclaration(node: ImportDeclaration) { checkDeclarationModifiers(node); - checkNameIsReserved(node.name, Diagnostics.Import_name_cannot_be_0); var symbol = getSymbolOfNode(node); var target: Symbol; if (node.entityName) { target = resolveImport(symbol); // Import declaration for an internal module - if (target !== unknownSymbol && target.flags & SymbolFlags.Value) { - // Target is a value symbol, check that it can be evaluated as an expression - checkExpression(node.entityName); + if (target !== unknownSymbol) { + if (target.flags & SymbolFlags.Value) { + // Target is a value symbol, check that it can be evaluated as an expression + checkExpression(node.entityName); + } + if (target.flags & SymbolFlags.Type) { + checkTypeNameIsReserved(node.name, Diagnostics.Import_name_cannot_be_0); + } } } else { diff --git a/tests/baselines/reference/reservedNameOnInterfaceImport.errors.txt b/tests/baselines/reference/reservedNameOnInterfaceImport.errors.txt new file mode 100644 index 00000000000..1d2b5665a2f --- /dev/null +++ b/tests/baselines/reference/reservedNameOnInterfaceImport.errors.txt @@ -0,0 +1,10 @@ +==== tests/cases/compiler/reservedNameOnInterfaceImport.ts (1 errors) ==== + declare module test { + interface istring { } + + // Should error; 'test.istring' is a type, so this import conflicts with the 'string' type. + import string = test.istring; + ~~~~~~ +!!! Import name cannot be 'string' + } + \ No newline at end of file diff --git a/tests/baselines/reference/reservedNameOnInterfaceImport.js b/tests/baselines/reference/reservedNameOnInterfaceImport.js new file mode 100644 index 00000000000..028fe49abca --- /dev/null +++ b/tests/baselines/reference/reservedNameOnInterfaceImport.js @@ -0,0 +1,10 @@ +//// [reservedNameOnInterfaceImport.ts] +declare module test { + interface istring { } + + // Should error; 'test.istring' is a type, so this import conflicts with the 'string' type. + import string = test.istring; +} + + +//// [reservedNameOnInterfaceImport.js] diff --git a/tests/baselines/reference/reservedNameOnModuleImport.js b/tests/baselines/reference/reservedNameOnModuleImport.js new file mode 100644 index 00000000000..4024afc4ba1 --- /dev/null +++ b/tests/baselines/reference/reservedNameOnModuleImport.js @@ -0,0 +1,10 @@ +//// [reservedNameOnModuleImport.ts] +declare module test { + module mstring { } + + // Should be fine; this does not clobber any declared values. + export import string = mstring; +} + + +//// [reservedNameOnModuleImport.js] diff --git a/tests/baselines/reference/reservedNameOnModuleImportWithInterface.errors.txt b/tests/baselines/reference/reservedNameOnModuleImportWithInterface.errors.txt new file mode 100644 index 00000000000..57ec0f94b91 --- /dev/null +++ b/tests/baselines/reference/reservedNameOnModuleImportWithInterface.errors.txt @@ -0,0 +1,11 @@ +==== tests/cases/compiler/reservedNameOnModuleImportWithInterface.ts (1 errors) ==== + declare module test { + interface mi_string { } + module mi_string { } + + // Should error; imports both a type and a module, which means it conflicts with the 'string' type. + import string = mi_string; + ~~~~~~ +!!! Import name cannot be 'string' + } + \ No newline at end of file diff --git a/tests/baselines/reference/reservedNameOnModuleImportWithInterface.js b/tests/baselines/reference/reservedNameOnModuleImportWithInterface.js new file mode 100644 index 00000000000..c5dc15747e2 --- /dev/null +++ b/tests/baselines/reference/reservedNameOnModuleImportWithInterface.js @@ -0,0 +1,11 @@ +//// [reservedNameOnModuleImportWithInterface.ts] +declare module test { + interface mi_string { } + module mi_string { } + + // Should error; imports both a type and a module, which means it conflicts with the 'string' type. + import string = mi_string; +} + + +//// [reservedNameOnModuleImportWithInterface.js] diff --git a/tests/cases/compiler/reservedNameOnInterfaceImport.ts b/tests/cases/compiler/reservedNameOnInterfaceImport.ts new file mode 100644 index 00000000000..0a706a9acba --- /dev/null +++ b/tests/cases/compiler/reservedNameOnInterfaceImport.ts @@ -0,0 +1,6 @@ +declare module test { + interface istring { } + + // Should error; 'test.istring' is a type, so this import conflicts with the 'string' type. + import string = test.istring; +} diff --git a/tests/cases/compiler/reservedNameOnModuleImport.ts b/tests/cases/compiler/reservedNameOnModuleImport.ts new file mode 100644 index 00000000000..de0344f56f3 --- /dev/null +++ b/tests/cases/compiler/reservedNameOnModuleImport.ts @@ -0,0 +1,6 @@ +declare module test { + module mstring { } + + // Should be fine; this does not clobber any declared values. + export import string = mstring; +} diff --git a/tests/cases/compiler/reservedNameOnModuleImportWithInterface.ts b/tests/cases/compiler/reservedNameOnModuleImportWithInterface.ts new file mode 100644 index 00000000000..bde58f92795 --- /dev/null +++ b/tests/cases/compiler/reservedNameOnModuleImportWithInterface.ts @@ -0,0 +1,7 @@ +declare module test { + interface mi_string { } + module mi_string { } + + // Should error; imports both a type and a module, which means it conflicts with the 'string' type. + import string = mi_string; +}