Skip to content

Commit 35facf5

Browse files
author
Yui T
committed
Merge branch 'master' into refactorRefFilesPath
2 parents 6c9c502 + 8ab038f commit 35facf5

26 files changed

+2157
-29
lines changed

src/compiler/checker.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ module ts {
8585
checkProgram: checkProgram,
8686
emitFiles: invokeEmitter,
8787
getParentOfSymbol: getParentOfSymbol,
88-
getTypeOfSymbol: getTypeOfSymbol,
88+
getNarrowedTypeOfSymbol: getNarrowedTypeOfSymbol,
8989
getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol,
9090
getPropertiesOfType: getPropertiesOfType,
9191
getPropertyOfType: getPropertyOfType,
@@ -4318,7 +4318,7 @@ module ts {
43184318
function getNarrowedTypeOfSymbol(symbol: Symbol, node: Node) {
43194319
var type = getTypeOfSymbol(symbol);
43204320
// Only narrow when symbol is variable of a structured type
4321-
if (symbol.flags & SymbolFlags.Variable && type.flags & TypeFlags.Structured) {
4321+
if (node && (symbol.flags & SymbolFlags.Variable && type.flags & TypeFlags.Structured)) {
43224322
while (true) {
43234323
var child = node;
43244324
node = node.parent;
@@ -4890,8 +4890,9 @@ module ts {
48904890

48914891
// Return the contextual signature for a given expression node. A contextual type provides a
48924892
// contextual signature if it has a single call signature and if that call signature is non-generic.
4893-
// If the contextual type is a union type and each constituent type that has a contextual signature
4894-
// provides the same contextual signature, then the union type provides that contextual signature.
4893+
// If the contextual type is a union type, get the signature from each type possible and if they are
4894+
// all identical ignoring their return type, the result is same signature but with return type as
4895+
// union type of return types from these signatures
48954896
function getContextualSignature(node: Expression): Signature {
48964897
var type = getContextualType(node);
48974898
if (!type) {
@@ -4900,19 +4901,41 @@ module ts {
49004901
if (!(type.flags & TypeFlags.Union)) {
49014902
return getNonGenericSignature(type);
49024903
}
4903-
var result: Signature;
4904+
var signatureList: Signature[];
49044905
var types = (<UnionType>type).types;
49054906
for (var i = 0; i < types.length; i++) {
4907+
// The signature set of all constituent type with call signatures should match
4908+
// So number of signatures allowed is either 0 or 1
4909+
if (signatureList &&
4910+
getSignaturesOfObjectOrUnionType(types[i], SignatureKind.Call).length > 1) {
4911+
return undefined;
4912+
}
4913+
49064914
var signature = getNonGenericSignature(types[i]);
49074915
if (signature) {
4908-
if (!result) {
4909-
result = signature;
4916+
if (!signatureList) {
4917+
// This signature will contribute to contextual union signature
4918+
signatureList = [signature];
49104919
}
4911-
else if (!compareSignatures(result, signature, /*compareReturnTypes*/ true, compareTypes)) {
4920+
else if (!compareSignatures(signatureList[0], signature, /*compareReturnTypes*/ false, compareTypes)) {
4921+
// Signatures arent identical, do not use
49124922
return undefined;
49134923
}
4924+
else {
4925+
// Use this signature for contextual union signature
4926+
signatureList.push(signature);
4927+
}
49144928
}
49154929
}
4930+
4931+
// Result is union of signatures collected (return type is union of return types of this signature set)
4932+
var result: Signature;
4933+
if (signatureList) {
4934+
result = cloneSignature(signatureList[0]);
4935+
// Clear resolved return type we possibly got from cloneSignature
4936+
result.resolvedReturnType = undefined;
4937+
result.unionSignatures = signatureList;
4938+
}
49164939
return result;
49174940
}
49184941

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ module ts {
701701
checkProgram(): void;
702702
emitFiles(targetSourceFile?: SourceFile): EmitResult;
703703
getParentOfSymbol(symbol: Symbol): Symbol;
704-
getTypeOfSymbol(symbol: Symbol): Type;
704+
getNarrowedTypeOfSymbol(symbol: Symbol, node: Node): Type;
705705
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
706706
getPropertiesOfType(type: Type): Symbol[];
707707
getPropertyOfType(type: Type, propertyName: string): Symbol;

src/services/breakpoints.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,9 @@ module ts.BreakpointResolver {
194194
// span in statement
195195
return spanInNode((<WithStatement>node).statement);
196196

197-
// No breakpoint in interface
197+
// No breakpoint in interface, type alias
198198
case SyntaxKind.InterfaceDeclaration:
199+
case SyntaxKind.TypeAliasDeclaration:
199200
return undefined;
200201

201202
// Tokens:

src/services/services.ts

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2378,7 +2378,7 @@ module ts {
23782378
return undefined;
23792379
}
23802380

2381-
function createCompletionEntry(symbol: Symbol, typeChecker: TypeChecker): CompletionEntry {
2381+
function createCompletionEntry(symbol: Symbol, typeChecker: TypeChecker, location: Node): CompletionEntry {
23822382
// Try to get a valid display name for this symbol, if we could not find one, then ignore it.
23832383
// We would like to only show things that can be added after a dot, so for instance numeric properties can
23842384
// not be accessed with a dot (a.1 <- invalid)
@@ -2393,7 +2393,7 @@ module ts {
23932393
// We COULD also just do what 'getSymbolModifiers' does, which is to use the first declaration.
23942394
return {
23952395
name: displayName,
2396-
kind: getSymbolKind(symbol, typeChecker),
2396+
kind: getSymbolKind(symbol, typeChecker, location),
23972397
kindModifiers: getSymbolModifiers(symbol)
23982398
};
23992399
}
@@ -2464,6 +2464,7 @@ module ts {
24642464
};
24652465
host.log("getCompletionsAtPosition: Syntactic work: " + (new Date().getTime() - syntacticStart));
24662466

2467+
var location = getTouchingPropertyName(sourceFile, position);
24672468
// Populate the completion list
24682469
var semanticStart = new Date().getTime();
24692470
if (isRightOfDot) {
@@ -2545,7 +2546,7 @@ module ts {
25452546
function getCompletionEntriesFromSymbols(symbols: Symbol[], session: CompletionSession): void {
25462547
var start = new Date().getTime();
25472548
forEach(symbols, symbol => {
2548-
var entry = createCompletionEntry(symbol, session.typeChecker);
2549+
var entry = createCompletionEntry(symbol, session.typeChecker, location);
25492550
if (entry && !lookUp(session.symbols, entry.name)) {
25502551
session.entries.push(entry);
25512552
session.symbols[entry.name] = symbol;
@@ -2757,14 +2758,13 @@ module ts {
27572758

27582759
var symbol = lookUp(activeCompletionSession.symbols, entryName);
27592760
if (symbol) {
2760-
var type = session.typeChecker.getTypeOfSymbol(symbol);
2761-
Debug.assert(type !== undefined, "Could not find type for symbol");
2762-
var completionEntry = createCompletionEntry(symbol, session.typeChecker);
2761+
var location = getTouchingPropertyName(sourceFile, position);
2762+
var completionEntry = createCompletionEntry(symbol, session.typeChecker, location);
27632763
// TODO(drosen): Right now we just permit *all* semantic meanings when calling 'getSymbolKind'
27642764
// which is permissible given that it is backwards compatible; but really we should consider
27652765
// passing the meaning for the node so that we don't report that a suggestion for a value is an interface.
27662766
// We COULD also just do what 'getSymbolModifiers' does, which is to use the first declaration.
2767-
var location = getTouchingPropertyName(sourceFile, position);
2767+
Debug.assert(session.typeChecker.getNarrowedTypeOfSymbol(symbol, location) !== undefined, "Could not find type for symbol");
27682768
var displayPartsDocumentationsAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getSourceFile(filename), location, session.typeChecker, location, SemanticMeaning.All);
27692769
return {
27702770
name: entryName,
@@ -2809,7 +2809,7 @@ module ts {
28092809
}
28102810

28112811
// TODO(drosen): use contextual SemanticMeaning.
2812-
function getSymbolKind(symbol: Symbol, typeResolver: TypeChecker): string {
2812+
function getSymbolKind(symbol: Symbol, typeResolver: TypeChecker, location?: Node): string {
28132813
var flags = symbol.getFlags();
28142814

28152815
if (flags & SymbolFlags.Class) return ScriptElementKind.classElement;
@@ -2818,7 +2818,7 @@ module ts {
28182818
if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement;
28192819
if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement;
28202820

2821-
var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, typeResolver);
2821+
var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, typeResolver, location);
28222822
if (result === ScriptElementKind.unknown) {
28232823
if (flags & SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement;
28242824
if (flags & SymbolFlags.EnumMember) return ScriptElementKind.variableElement;
@@ -2828,7 +2828,7 @@ module ts {
28282828
return result;
28292829
}
28302830

2831-
function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol: Symbol, flags: SymbolFlags, typeResolver: TypeChecker) {
2831+
function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol: Symbol, flags: SymbolFlags, typeResolver: TypeChecker, location: Node) {
28322832
if (typeResolver.isUndefinedSymbol(symbol)) {
28332833
return ScriptElementKind.variableElement;
28342834
}
@@ -2852,15 +2852,24 @@ module ts {
28522852

28532853
if (flags & SymbolFlags.Property) {
28542854
if (flags & SymbolFlags.UnionProperty) {
2855-
return forEach(typeInfoResolver.getRootSymbols(symbol), rootSymbol => {
2855+
// If union property is result of union of non method (property/accessors), it is labeled as property
2856+
var unionPropertyKind = forEach(typeInfoResolver.getRootSymbols(symbol), rootSymbol => {
28562857
var rootSymbolFlags = rootSymbol.getFlags();
2857-
if (rootSymbolFlags & SymbolFlags.Property) {
2858+
if (rootSymbolFlags & (SymbolFlags.Property | SymbolFlags.GetAccessor | SymbolFlags.SetAccessor)) {
28582859
return ScriptElementKind.memberVariableElement;
28592860
}
2860-
if (rootSymbolFlags & SymbolFlags.GetAccessor) return ScriptElementKind.memberVariableElement;
2861-
if (rootSymbolFlags & SymbolFlags.SetAccessor) return ScriptElementKind.memberVariableElement;
2862-
Debug.assert((rootSymbolFlags & SymbolFlags.Method) !== undefined);
2863-
}) || ScriptElementKind.memberFunctionElement;
2861+
Debug.assert(!!(rootSymbolFlags & SymbolFlags.Method));
2862+
});
2863+
if (!unionPropertyKind) {
2864+
// If this was union of all methods,
2865+
//make sure it has call signatures before we can label it as method
2866+
var typeOfUnionProperty = typeInfoResolver.getNarrowedTypeOfSymbol(symbol, location);
2867+
if (typeOfUnionProperty.getCallSignatures().length) {
2868+
return ScriptElementKind.memberFunctionElement;
2869+
}
2870+
return ScriptElementKind.memberVariableElement;
2871+
}
2872+
return unionPropertyKind;
28642873
}
28652874
return ScriptElementKind.memberVariableElement;
28662875
}
@@ -2918,7 +2927,7 @@ module ts {
29182927
var displayParts: SymbolDisplayPart[] = [];
29192928
var documentation: SymbolDisplayPart[];
29202929
var symbolFlags = symbol.flags;
2921-
var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, typeResolver);
2930+
var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, typeResolver, location);
29222931
var hasAddedSymbolInfo: boolean;
29232932
// Class at constructor site need to be shown as constructor apart from property,method, vars
29242933
if (symbolKind !== ScriptElementKind.unknown || symbolFlags & SymbolFlags.Class || symbolFlags & SymbolFlags.Import) {
@@ -2927,7 +2936,7 @@ module ts {
29272936
symbolKind = ScriptElementKind.memberVariableElement;
29282937
}
29292938

2930-
var type = typeResolver.getTypeOfSymbol(symbol);
2939+
var type = typeResolver.getNarrowedTypeOfSymbol(symbol, location);
29312940
if (type) {
29322941
if (location.parent && location.parent.kind === SyntaxKind.PropertyAccess) {
29332942
var right = (<PropertyAccess>location.parent).right;
@@ -3173,7 +3182,7 @@ module ts {
31733182
}
31743183
}
31753184
else {
3176-
symbolKind = getSymbolKind(symbol, typeResolver);
3185+
symbolKind = getSymbolKind(symbol, typeResolver, location);
31773186
}
31783187
}
31793188

0 commit comments

Comments
 (0)