From 2cc209459b980b2ff91c3b2054530b52213da020 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 7 Oct 2014 13:00:46 -0700 Subject: [PATCH] Quick info on undefined Fixes #775 --- src/compiler/checker.ts | 9 +++++++-- src/compiler/types.ts | 17 ++++++++++------- src/services/services.ts | 15 +++++++++++---- tests/cases/fourslash/contextualTyping.ts | 6 +++--- tests/cases/fourslash/quickInfoOnUndefined.ts | 8 ++++++++ 5 files changed, 39 insertions(+), 16 deletions(-) create mode 100644 tests/cases/fourslash/quickInfoOnUndefined.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fb4ded66e65..fdc00d16940 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -107,7 +107,7 @@ module ts { isImplementationOfOverload: isImplementationOfOverload }; - var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined"); + var undefinedSymbol = createSymbol(SymbolFlags.Undefined | SymbolFlags.Property | SymbolFlags.Transient, "undefined"); var argumentsSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "arguments"); var unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown"); var resolvingSymbol = createSymbol(SymbolFlags.Transient, "__resolving__"); @@ -1067,7 +1067,12 @@ module ts { return writeType(type, flags | TypeFormatFlags.WriteArrowStyleSignature); function writeType(type: Type, flags: TypeFormatFlags) { - if (type.flags & TypeFlags.Intrinsic) { + // Write undefined/null type as any + if ((flags & TypeFormatFlags.WriteUndefinedAndNullAsAny) && + ((type.flags & TypeFlags.Undefined) || (type.flags & TypeFlags.Null))) { + writeKeyword(writer, SyntaxKind.AnyKeyword); + } + else if (type.flags & TypeFlags.Intrinsic) { // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving writer.writeKind(!(flags & TypeFormatFlags.WriteOwnNameForAnyLike) && (type.flags & TypeFlags.Any) ? "any" : (type).intrinsicName, SymbolDisplayPartKind.keyword); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 72825713427..82e91487ad1 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -679,13 +679,14 @@ module ts { } export enum TypeFormatFlags { - None = 0x00000000, - WriteArrayAsGenericType = 0x00000001, // Write Array instead T[] - UseTypeOfFunction = 0x00000002, // Write typeof instead of function type literal - NoTruncation = 0x00000004, // Don't truncate typeToString result - WriteArrowStyleSignature= 0x00000008, // Write arrow style signature - 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 + None = 0x00000000, + WriteArrayAsGenericType = 0x00000001, // Write Array instead T[] + UseTypeOfFunction = 0x00000002, // Write typeof instead of function type literal + NoTruncation = 0x00000004, // Don't truncate typeToString result + WriteArrowStyleSignature = 0x00000008, // Write arrow style signature + 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 + WriteUndefinedAndNullAsAny = 0x00000040, // Write undefined and null as any } export enum SymbolFormatFlags { @@ -763,6 +764,8 @@ module ts { Transient = 0x02000000, // Transient symbol (created during type check) Prototype = 0x04000000, // Symbol for the prototype property (without source code representation) + Undefined = 0x08000000, // Symbol for the undefined + Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor, Type = Class | Interface | Enum | TypeLiteral | ObjectLiteral | TypeParameter, Namespace = ValueModule | NamespaceModule, diff --git a/src/services/services.ts b/src/services/services.ts index f8ea40bf489..af61e342a8e 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1415,7 +1415,7 @@ module ts { export function typeToDisplayParts(typechecker: TypeChecker, type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[] { return mapToDisplayParts(writer => { - typechecker.writeType(type, writer, enclosingDeclaration, flags); + typechecker.writeType(type, writer, enclosingDeclaration, flags | TypeFormatFlags.WriteUndefinedAndNullAsAny); }); } @@ -1427,7 +1427,7 @@ module ts { function signatureToDisplayParts(typechecker: TypeChecker, signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[]{ return mapToDisplayParts(writer => { - typechecker.writeSignature(signature, writer, enclosingDeclaration, flags); + typechecker.writeSignature(signature, writer, enclosingDeclaration, flags | TypeFormatFlags.WriteUndefinedAndNullAsAny); }); } @@ -2626,6 +2626,9 @@ module ts { } return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localVariableElement : ScriptElementKind.variableElement; } + if (flags & SymbolFlags.Undefined) { + return ScriptElementKind.variableElement; + } if (flags & SymbolFlags.Function) return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localFunctionElement : ScriptElementKind.functionElement; if (flags & SymbolFlags.GetAccessor) return ScriptElementKind.memberGetAccessorElement; if (flags & SymbolFlags.SetAccessor) return ScriptElementKind.memberSetAccessorElement; @@ -2705,6 +2708,10 @@ module ts { if (symbolKind === ScriptElementKind.memberGetAccessorElement || symbolKind === ScriptElementKind.memberSetAccessorElement) { symbolKind = ScriptElementKind.memberVariableElement; } + else if (symbol.name === "undefined") { + // undefined is symbol and not property + symbolKind = ScriptElementKind.variableElement; + } var type = typeResolver.getTypeOfSymbol(symbol); if (type) { @@ -2874,7 +2881,7 @@ module ts { // If the type is type parameter, format it specially if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) { var typeParameterParts = mapToDisplayParts(writer => { - typeResolver.writeTypeParameter(type, writer, enclosingDeclaration, TypeFormatFlags.NoTruncation); + typeResolver.writeTypeParameter(type, writer, enclosingDeclaration, TypeFormatFlags.NoTruncation | TypeFormatFlags.WriteUndefinedAndNullAsAny); }); displayParts.push.apply(displayParts, typeParameterParts); } @@ -2941,7 +2948,7 @@ module ts { function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) { var typeParameterParts = mapToDisplayParts(writer => { - typeResolver.writeTypeParametersOfSymbol(symbol, writer, enclosingDeclaration, TypeFormatFlags.NoTruncation); + typeResolver.writeTypeParametersOfSymbol(symbol, writer, enclosingDeclaration, TypeFormatFlags.NoTruncation | TypeFormatFlags.WriteUndefinedAndNullAsAny); }); displayParts.push.apply(displayParts, typeParameterParts); } diff --git a/tests/cases/fourslash/contextualTyping.ts b/tests/cases/fourslash/contextualTyping.ts index dad6ee8b587..503e931b60c 100644 --- a/tests/cases/fourslash/contextualTyping.ts +++ b/tests/cases/fourslash/contextualTyping.ts @@ -262,7 +262,7 @@ verify.quickInfoIs("(parameter) s: any"); goTo.marker('33'); verify.quickInfoIs("(var) c3t14: IFoo"); goTo.marker('34'); -verify.quickInfoIs("(property) a: undefined[]"); +verify.quickInfoIs("(property) a: any[]"); goTo.marker('35'); verify.quickInfoIs("(property) C4T5.foo: (i: number, s: string) => string"); goTo.marker('36'); @@ -334,7 +334,7 @@ verify.quickInfoIs("(parameter) s: any"); goTo.marker('69'); verify.quickInfoIs("(property) t14: IFoo"); goTo.marker('70'); -verify.quickInfoIs("(property) a: undefined[]"); +verify.quickInfoIs("(property) a: any[]"); goTo.marker('71'); verify.quickInfoIs("(parameter) n: number"); goTo.marker('72'); @@ -394,7 +394,7 @@ verify.quickInfoIs("(parameter) s: any"); goTo.marker('99'); verify.quickInfoIs("(var) c12t14: IFoo"); goTo.marker('100'); -verify.quickInfoIs("(property) a: undefined[]"); +verify.quickInfoIs("(property) a: any[]"); goTo.marker('101'); verify.quickInfoIs("(function) EF1(a: number, b: number): number"); goTo.marker('102'); diff --git a/tests/cases/fourslash/quickInfoOnUndefined.ts b/tests/cases/fourslash/quickInfoOnUndefined.ts new file mode 100644 index 00000000000..252da49d4fe --- /dev/null +++ b/tests/cases/fourslash/quickInfoOnUndefined.ts @@ -0,0 +1,8 @@ +/// + +////function foo(a: string) { +////} +////foo(/*1*/undefined); + +goTo.marker('1'); +verify.quickInfoIs('(var) undefined'); \ No newline at end of file