Skip to content

Commit 2cc2094

Browse files
committed
Quick info on undefined
Fixes #775
1 parent 430f361 commit 2cc2094

File tree

5 files changed

+39
-16
lines changed

5 files changed

+39
-16
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ module ts {
107107
isImplementationOfOverload: isImplementationOfOverload
108108
};
109109

110-
var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined");
110+
var undefinedSymbol = createSymbol(SymbolFlags.Undefined | SymbolFlags.Property | SymbolFlags.Transient, "undefined");
111111
var argumentsSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "arguments");
112112
var unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown");
113113
var resolvingSymbol = createSymbol(SymbolFlags.Transient, "__resolving__");
@@ -1067,7 +1067,12 @@ module ts {
10671067
return writeType(type, flags | TypeFormatFlags.WriteArrowStyleSignature);
10681068

10691069
function writeType(type: Type, flags: TypeFormatFlags) {
1070-
if (type.flags & TypeFlags.Intrinsic) {
1070+
// Write undefined/null type as any
1071+
if ((flags & TypeFormatFlags.WriteUndefinedAndNullAsAny) &&
1072+
((type.flags & TypeFlags.Undefined) || (type.flags & TypeFlags.Null))) {
1073+
writeKeyword(writer, SyntaxKind.AnyKeyword);
1074+
}
1075+
else if (type.flags & TypeFlags.Intrinsic) {
10711076
// Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving
10721077
writer.writeKind(!(flags & TypeFormatFlags.WriteOwnNameForAnyLike) &&
10731078
(type.flags & TypeFlags.Any) ? "any" : (<IntrinsicType>type).intrinsicName, SymbolDisplayPartKind.keyword);

src/compiler/types.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -679,13 +679,14 @@ module ts {
679679
}
680680

681681
export enum TypeFormatFlags {
682-
None = 0x00000000,
683-
WriteArrayAsGenericType = 0x00000001, // Write Array<T> instead T[]
684-
UseTypeOfFunction = 0x00000002, // Write typeof instead of function type literal
685-
NoTruncation = 0x00000004, // Don't truncate typeToString result
686-
WriteArrowStyleSignature= 0x00000008, // Write arrow style signature
687-
WriteOwnNameForAnyLike = 0x00000010, // Write symbol's own name instead of 'any' for any like types (eg. unknown, __resolving__ etc)
688-
WriteTypeArgumentsOfSignature = 0x00000020, // Write the type arguments instead of type parameters of the signature
682+
None = 0x00000000,
683+
WriteArrayAsGenericType = 0x00000001, // Write Array<T> instead T[]
684+
UseTypeOfFunction = 0x00000002, // Write typeof instead of function type literal
685+
NoTruncation = 0x00000004, // Don't truncate typeToString result
686+
WriteArrowStyleSignature = 0x00000008, // Write arrow style signature
687+
WriteOwnNameForAnyLike = 0x00000010, // Write symbol's own name instead of 'any' for any like types (eg. unknown, __resolving__ etc)
688+
WriteTypeArgumentsOfSignature = 0x00000020, // Write the type arguments instead of type parameters of the signature
689+
WriteUndefinedAndNullAsAny = 0x00000040, // Write undefined and null as any
689690
}
690691

691692
export enum SymbolFormatFlags {
@@ -763,6 +764,8 @@ module ts {
763764
Transient = 0x02000000, // Transient symbol (created during type check)
764765
Prototype = 0x04000000, // Symbol for the prototype property (without source code representation)
765766

767+
Undefined = 0x08000000, // Symbol for the undefined
768+
766769
Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor,
767770
Type = Class | Interface | Enum | TypeLiteral | ObjectLiteral | TypeParameter,
768771
Namespace = ValueModule | NamespaceModule,

src/services/services.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,7 +1415,7 @@ module ts {
14151415

14161416
export function typeToDisplayParts(typechecker: TypeChecker, type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[] {
14171417
return mapToDisplayParts(writer => {
1418-
typechecker.writeType(type, writer, enclosingDeclaration, flags);
1418+
typechecker.writeType(type, writer, enclosingDeclaration, flags | TypeFormatFlags.WriteUndefinedAndNullAsAny);
14191419
});
14201420
}
14211421

@@ -1427,7 +1427,7 @@ module ts {
14271427

14281428
function signatureToDisplayParts(typechecker: TypeChecker, signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[]{
14291429
return mapToDisplayParts(writer => {
1430-
typechecker.writeSignature(signature, writer, enclosingDeclaration, flags);
1430+
typechecker.writeSignature(signature, writer, enclosingDeclaration, flags | TypeFormatFlags.WriteUndefinedAndNullAsAny);
14311431
});
14321432
}
14331433

@@ -2626,6 +2626,9 @@ module ts {
26262626
}
26272627
return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localVariableElement : ScriptElementKind.variableElement;
26282628
}
2629+
if (flags & SymbolFlags.Undefined) {
2630+
return ScriptElementKind.variableElement;
2631+
}
26292632
if (flags & SymbolFlags.Function) return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localFunctionElement : ScriptElementKind.functionElement;
26302633
if (flags & SymbolFlags.GetAccessor) return ScriptElementKind.memberGetAccessorElement;
26312634
if (flags & SymbolFlags.SetAccessor) return ScriptElementKind.memberSetAccessorElement;
@@ -2705,6 +2708,10 @@ module ts {
27052708
if (symbolKind === ScriptElementKind.memberGetAccessorElement || symbolKind === ScriptElementKind.memberSetAccessorElement) {
27062709
symbolKind = ScriptElementKind.memberVariableElement;
27072710
}
2711+
else if (symbol.name === "undefined") {
2712+
// undefined is symbol and not property
2713+
symbolKind = ScriptElementKind.variableElement;
2714+
}
27082715

27092716
var type = typeResolver.getTypeOfSymbol(symbol);
27102717
if (type) {
@@ -2874,7 +2881,7 @@ module ts {
28742881
// If the type is type parameter, format it specially
28752882
if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) {
28762883
var typeParameterParts = mapToDisplayParts(writer => {
2877-
typeResolver.writeTypeParameter(<TypeParameter>type, writer, enclosingDeclaration, TypeFormatFlags.NoTruncation);
2884+
typeResolver.writeTypeParameter(<TypeParameter>type, writer, enclosingDeclaration, TypeFormatFlags.NoTruncation | TypeFormatFlags.WriteUndefinedAndNullAsAny);
28782885
});
28792886
displayParts.push.apply(displayParts, typeParameterParts);
28802887
}
@@ -2941,7 +2948,7 @@ module ts {
29412948

29422949
function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) {
29432950
var typeParameterParts = mapToDisplayParts(writer => {
2944-
typeResolver.writeTypeParametersOfSymbol(symbol, writer, enclosingDeclaration, TypeFormatFlags.NoTruncation);
2951+
typeResolver.writeTypeParametersOfSymbol(symbol, writer, enclosingDeclaration, TypeFormatFlags.NoTruncation | TypeFormatFlags.WriteUndefinedAndNullAsAny);
29452952
});
29462953
displayParts.push.apply(displayParts, typeParameterParts);
29472954
}

tests/cases/fourslash/contextualTyping.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ verify.quickInfoIs("(parameter) s: any");
262262
goTo.marker('33');
263263
verify.quickInfoIs("(var) c3t14: IFoo");
264264
goTo.marker('34');
265-
verify.quickInfoIs("(property) a: undefined[]");
265+
verify.quickInfoIs("(property) a: any[]");
266266
goTo.marker('35');
267267
verify.quickInfoIs("(property) C4T5.foo: (i: number, s: string) => string");
268268
goTo.marker('36');
@@ -334,7 +334,7 @@ verify.quickInfoIs("(parameter) s: any");
334334
goTo.marker('69');
335335
verify.quickInfoIs("(property) t14: IFoo");
336336
goTo.marker('70');
337-
verify.quickInfoIs("(property) a: undefined[]");
337+
verify.quickInfoIs("(property) a: any[]");
338338
goTo.marker('71');
339339
verify.quickInfoIs("(parameter) n: number");
340340
goTo.marker('72');
@@ -394,7 +394,7 @@ verify.quickInfoIs("(parameter) s: any");
394394
goTo.marker('99');
395395
verify.quickInfoIs("(var) c12t14: IFoo");
396396
goTo.marker('100');
397-
verify.quickInfoIs("(property) a: undefined[]");
397+
verify.quickInfoIs("(property) a: any[]");
398398
goTo.marker('101');
399399
verify.quickInfoIs("(function) EF1(a: number, b: number): number");
400400
goTo.marker('102');
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
////function foo(a: string) {
4+
////}
5+
////foo(/*1*/undefined);
6+
7+
goTo.marker('1');
8+
verify.quickInfoIs('(var) undefined');

0 commit comments

Comments
 (0)