Merge pull request #1575 from chrisbubernak/betterErrorsForTypesWithSameName

Better errors for types with same name
This commit is contained in:
Daniel Rosenwasser 2015-01-30 21:08:48 -08:00
commit e174fe4f47
8 changed files with 109 additions and 23 deletions

View File

@ -1069,7 +1069,7 @@ module ts {
* Enclosing declaration is optional when we don't want to get qualified name in the enclosing declaration scope
* Meaning needs to be specified if the enclosing declaration is given
*/
function buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void {
function buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags, typeFlags?: TypeFormatFlags): void {
var parentSymbol: Symbol;
function appendParentTypeArgumentsAndSymbolName(symbol: Symbol): void {
if (parentSymbol) {
@ -1131,11 +1131,12 @@ module ts {
}
}
// Get qualified name
if (enclosingDeclaration &&
// TypeParameters do not need qualification
!(symbol.flags & SymbolFlags.TypeParameter)) {
// Get qualified name if the symbol is not a type parameter
// and there is an enclosing declaration or we specifically
// asked for it
var isTypeParameter = symbol.flags & SymbolFlags.TypeParameter;
var typeFormatFlag = TypeFormatFlags.UseFullyQualifiedType & typeFlags;
if (!isTypeParameter && (enclosingDeclaration || typeFormatFlag)) {
walkSymbol(symbol, meaning);
return;
}
@ -1158,7 +1159,8 @@ module ts {
writeTypeReference(<TypeReference>type, flags);
}
else if (type.flags & (TypeFlags.Class | TypeFlags.Interface | TypeFlags.Enum | TypeFlags.TypeParameter)) {
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type);
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
else if (type.flags & TypeFlags.Tuple) {
writeTupleType(<TupleType>type);
@ -1229,17 +1231,18 @@ module ts {
function writeAnonymousType(type: ObjectType, flags: TypeFormatFlags) {
// Always use 'typeof T' for type of class, enum, and module objects
if (type.symbol && type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) {
writeTypeofSymbol(type);
writeTypeofSymbol(type, flags);
}
// Use 'typeof T' for types of functions and methods that circularly reference themselves
else if (shouldWriteTypeOfFunctionSymbol()) {
writeTypeofSymbol(type);
writeTypeofSymbol(type, flags);
}
else if (typeStack && contains(typeStack, type)) {
// If type is an anonymous type literal in a type alias declaration, use type alias name
var typeAlias = getTypeAliasForTypeLiteral(type);
if (typeAlias) {
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type);
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
else {
// Recursive usage, use any
@ -1273,10 +1276,10 @@ module ts {
}
}
function writeTypeofSymbol(type: ObjectType) {
function writeTypeofSymbol(type: ObjectType, typeFormatFlags?: TypeFormatFlags) {
writeKeyword(writer, SyntaxKind.TypeOfKeyword);
writeSpace(writer);
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Value);
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Value, SymbolFormatFlags.None, typeFormatFlags);
}
function getIndexerParameterName(type: ObjectType, indexKind: IndexKind, fallbackName: string): string {
@ -3562,7 +3565,13 @@ module ts {
}
if (reportErrors) {
headMessage = headMessage || Diagnostics.Type_0_is_not_assignable_to_type_1;
reportError(headMessage, typeToString(source), typeToString(target));
var sourceType = typeToString(source);
var targetType = typeToString(target);
if (sourceType === targetType) {
sourceType = typeToString(source, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
targetType = typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
}
reportError(headMessage, sourceType, targetType);
}
return Ternary.False;
}

View File

@ -1080,6 +1080,7 @@ module ts {
WriteOwnNameForAnyLike = 0x00000010, // Write symbol's own name instead of 'any' for any like types (eg. unknown, __resolving__ etc)
WriteTypeArgumentsOfSignature = 0x00000020, // Write the type arguments instead of type parameters of the signature
InElementType = 0x00000040, // Writing an array or union element type
UseFullyQualifiedType = 0x00000080, // Write out the fully qualified type name (eg. Module.Type, instead of Type)
}
export const enum SymbolFormatFlags {

View File

@ -1,6 +1,6 @@
tests/cases/compiler/clodulesDerivedClasses.ts(9,7): error TS2417: Class static side 'typeof Path' incorrectly extends base class static side 'typeof Shape'.
Types of property 'Utils' are incompatible.
Type 'typeof Utils' is not assignable to type 'typeof Utils'.
Type 'typeof Path.Utils' is not assignable to type 'typeof Shape.Utils'.
Property 'convert' is missing in type 'typeof Utils'.
@ -17,7 +17,7 @@ tests/cases/compiler/clodulesDerivedClasses.ts(9,7): error TS2417: Class static
~~~~
!!! error TS2417: Class static side 'typeof Path' incorrectly extends base class static side 'typeof Shape'.
!!! error TS2417: Types of property 'Utils' are incompatible.
!!! error TS2417: Type 'typeof Utils' is not assignable to type 'typeof Utils'.
!!! error TS2417: Type 'typeof Path.Utils' is not assignable to type 'typeof Shape.Utils'.
!!! error TS2417: Property 'convert' is missing in type 'typeof Utils'.
name: string;

View File

@ -0,0 +1,22 @@
tests/cases/compiler/differentTypesWithSameName.ts(16,15): error TS2345: Argument of type 'variable' is not assignable to parameter of type 'm.variable'.
==== tests/cases/compiler/differentTypesWithSameName.ts (1 errors) ====
module m {
export class variable{
s: string;
}
export function doSomething(v: m.variable) {
}
}
class variable {
t: number;
}
var v: variable = new variable();
m.doSomething(v);
~
!!! error TS2345: Argument of type 'variable' is not assignable to parameter of type 'm.variable'.

View File

@ -0,0 +1,38 @@
//// [differentTypesWithSameName.ts]
module m {
export class variable{
s: string;
}
export function doSomething(v: m.variable) {
}
}
class variable {
t: number;
}
var v: variable = new variable();
m.doSomething(v);
//// [differentTypesWithSameName.js]
var m;
(function (m) {
var variable = (function () {
function variable() {
}
return variable;
})();
m.variable = variable;
function doSomething(v) {
}
m.doSomething = doSomething;
})(m || (m = {}));
var variable = (function () {
function variable() {
}
return variable;
})();
var v = new variable();
m.doSomething(v);

View File

@ -25,10 +25,10 @@ tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAnd
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts(50,5): error TS2322: Type 'typeof N' is not assignable to type 'typeof M'.
Types of property 'A' are incompatible.
Type 'typeof A' is not assignable to type 'typeof A'.
Type 'A' is not assignable to type 'A'.
Type 'typeof N.A' is not assignable to type 'typeof M.A'.
Type 'N.A' is not assignable to type 'M.A'.
Property 'name' is missing in type 'A'.
tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts(51,5): error TS2322: Type 'A' is not assignable to type 'A'.
tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts(51,5): error TS2322: Type 'N.A' is not assignable to type 'M.A'.
tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts(52,5): error TS2322: Type '(x: number) => boolean' is not assignable to type '(x: number) => string'.
Type 'boolean' is not assignable to type 'string'.
@ -124,12 +124,12 @@ tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAnd
~~~~~~~
!!! error TS2322: Type 'typeof N' is not assignable to type 'typeof M'.
!!! error TS2322: Types of property 'A' are incompatible.
!!! error TS2322: Type 'typeof A' is not assignable to type 'typeof A'.
!!! error TS2322: Type 'A' is not assignable to type 'A'.
!!! error TS2322: Type 'typeof N.A' is not assignable to type 'typeof M.A'.
!!! error TS2322: Type 'N.A' is not assignable to type 'M.A'.
!!! error TS2322: Property 'name' is missing in type 'A'.
var aClassInModule: M.A = new N.A();
~~~~~~~~~~~~~~
!!! error TS2322: Type 'A' is not assignable to type 'A'.
!!! error TS2322: Type 'N.A' is not assignable to type 'M.A'.
var aFunctionInModule: typeof M.F2 = F2;
~~~~~~~~~~~~~~~~~
!!! error TS2322: Type '(x: number) => boolean' is not assignable to type '(x: number) => string'.

View File

@ -10,7 +10,7 @@ tests/cases/compiler/qualify.ts(47,13): error TS2322: Type 'I4' is not assignabl
tests/cases/compiler/qualify.ts(48,13): error TS2322: Type 'I4' is not assignable to type '(k: I3) => void'.
tests/cases/compiler/qualify.ts(49,13): error TS2322: Type 'I4' is not assignable to type '{ k: I3; }'.
Property 'k' is missing in type 'I4'.
tests/cases/compiler/qualify.ts(58,5): error TS2322: Type 'I' is not assignable to type 'I'.
tests/cases/compiler/qualify.ts(58,5): error TS2322: Type 'I' is not assignable to type 'T.I'.
Property 'p' is missing in type 'I'.
@ -93,7 +93,7 @@ tests/cases/compiler/qualify.ts(58,5): error TS2322: Type 'I' is not assignable
var y:I;
var x:T.I=y;
~
!!! error TS2322: Type 'I' is not assignable to type 'I'.
!!! error TS2322: Type 'I' is not assignable to type 'T.I'.
!!! error TS2322: Property 'p' is missing in type 'I'.

View File

@ -0,0 +1,16 @@
module m {
export class variable{
s: string;
}
export function doSomething(v: m.variable) {
}
}
class variable {
t: number;
}
var v: variable = new variable();
m.doSomething(v);