Skip to content

Commit af661ae

Browse files
committed
Merge branch 'master' into rootDir
Conflicts: tests/baselines/reference/APISample_compile.types tests/baselines/reference/APISample_linter.types tests/baselines/reference/APISample_transform.types tests/baselines/reference/APISample_watcher.types
2 parents 16bbedc + 695efa9 commit af661ae

22 files changed

Lines changed: 688 additions & 428 deletions

src/compiler/checker.ts

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2904,16 +2904,17 @@ module ts {
29042904
}
29052905

29062906
function getPropertiesOfType(type: Type): Symbol[] {
2907-
if (type.flags & TypeFlags.Union) {
2908-
return getPropertiesOfUnionType(<UnionType>type);
2909-
}
2910-
return getPropertiesOfObjectType(getApparentType(type));
2907+
type = getApparentType(type);
2908+
return type.flags & TypeFlags.Union ? getPropertiesOfUnionType(<UnionType>type) : getPropertiesOfObjectType(type);
29112909
}
29122910

29132911
// For a type parameter, return the base constraint of the type parameter. For the string, number,
29142912
// boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
29152913
// type itself. Note that the apparent type of a union type is the union type itself.
29162914
function getApparentType(type: Type): Type {
2915+
if (type.flags & TypeFlags.Union) {
2916+
type = getReducedTypeOfUnionType(<UnionType>type);
2917+
}
29172918
if (type.flags & TypeFlags.TypeParameter) {
29182919
do {
29192920
type = getConstraintOfTypeParameter(<TypeParameter>type);
@@ -2986,27 +2987,27 @@ module ts {
29862987
// necessary, maps primitive types and type parameters are to their apparent types, and augments with properties from
29872988
// Object and Function as appropriate.
29882989
function getPropertyOfType(type: Type, name: string): Symbol {
2989-
if (type.flags & TypeFlags.Union) {
2990-
return getPropertyOfUnionType(<UnionType>type, name);
2991-
}
2992-
if (!(type.flags & TypeFlags.ObjectType)) {
2993-
type = getApparentType(type);
2994-
if (!(type.flags & TypeFlags.ObjectType)) {
2995-
return undefined;
2990+
type = getApparentType(type);
2991+
if (type.flags & TypeFlags.ObjectType) {
2992+
let resolved = resolveObjectOrUnionTypeMembers(type);
2993+
if (hasProperty(resolved.members, name)) {
2994+
let symbol = resolved.members[name];
2995+
if (symbolIsValue(symbol)) {
2996+
return symbol;
2997+
}
29962998
}
2997-
}
2998-
let resolved = resolveObjectOrUnionTypeMembers(type);
2999-
if (hasProperty(resolved.members, name)) {
3000-
let symbol = resolved.members[name];
3001-
if (symbolIsValue(symbol)) {
3002-
return symbol;
2999+
if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) {
3000+
let symbol = getPropertyOfObjectType(globalFunctionType, name);
3001+
if (symbol) {
3002+
return symbol;
3003+
}
30033004
}
3005+
return getPropertyOfObjectType(globalObjectType, name);
30043006
}
3005-
if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) {
3006-
let symbol = getPropertyOfObjectType(globalFunctionType, name);
3007-
if (symbol) return symbol;
3007+
if (type.flags & TypeFlags.Union) {
3008+
return getPropertyOfUnionType(<UnionType>type, name);
30083009
}
3009-
return getPropertyOfObjectType(globalObjectType, name);
3010+
return undefined;
30103011
}
30113012

30123013
function getSignaturesOfObjectOrUnionType(type: Type, kind: SignatureKind): Signature[] {
@@ -3581,6 +3582,10 @@ module ts {
35813582
}
35823583
}
35833584

3585+
// The noSubtypeReduction flag is there because it isn't possible to always do subtype reduction. The flag
3586+
// is true when creating a union type from a type node and when instantiating a union type. In both of those
3587+
// cases subtype reduction has to be deferred to properly support recursive union types. For example, a
3588+
// type alias of the form "type Item = string | (() => Item)" cannot be reduced during its declaration.
35843589
function getUnionType(types: Type[], noSubtypeReduction?: boolean): Type {
35853590
if (types.length === 0) {
35863591
return emptyObjectType;
@@ -3605,10 +3610,19 @@ module ts {
36053610
if (!type) {
36063611
type = unionTypes[id] = <UnionType>createObjectType(TypeFlags.Union | getWideningFlagsOfTypes(sortedTypes));
36073612
type.types = sortedTypes;
3613+
type.reducedType = noSubtypeReduction ? undefined : type;
36083614
}
36093615
return type;
36103616
}
36113617

3618+
function getReducedTypeOfUnionType(type: UnionType): Type {
3619+
// If union type was created without subtype reduction, perform the deferred reduction now
3620+
if (!type.reducedType) {
3621+
type.reducedType = getUnionType(type.types, /*noSubtypeReduction*/ false);
3622+
}
3623+
return type.reducedType;
3624+
}
3625+
36123626
function getTypeFromUnionTypeNode(node: UnionTypeNode): Type {
36133627
let links = getNodeLinks(node);
36143628
if (!links.resolvedType) {

src/compiler/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ module ts {
121121
WhileKeyword,
122122
WithKeyword,
123123
// Strict mode reserved words
124-
AsKeyword,
125124
ImplementsKeyword,
126125
InterfaceKeyword,
127126
LetKeyword,
@@ -132,6 +131,7 @@ module ts {
132131
StaticKeyword,
133132
YieldKeyword,
134133
// Contextual keywords
134+
AsKeyword,
135135
AnyKeyword,
136136
BooleanKeyword,
137137
ConstructorKeyword,
@@ -1512,6 +1512,8 @@ module ts {
15121512
export interface UnionType extends Type {
15131513
types: Type[]; // Constituent types
15141514
/* @internal */
1515+
reducedType: Type; // Reduced union type (all subtypes removed)
1516+
/* @internal */
15151517
resolvedProperties: SymbolTable; // Cache of resolved properties
15161518
}
15171519

src/services/navigateTo.ts

Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ module ts.NavigateTo {
1010
forEach(program.getSourceFiles(), sourceFile => {
1111
cancellationToken.throwIfCancellationRequested();
1212

13-
let declarations = sourceFile.getNamedDeclarations();
14-
for (let declaration of declarations) {
15-
var name = getDeclarationName(declaration);
16-
if (name !== undefined) {
17-
13+
let nameToDeclarations = sourceFile.getNamedDeclarations();
14+
for (let name in nameToDeclarations) {
15+
let declarations = getProperty(nameToDeclarations, name);
16+
if (declarations) {
1817
// First do a quick check to see if the name of the declaration matches the
1918
// last portion of the (possibly) dotted name they're searching for.
2019
let matches = patternMatcher.getMatchesForLastSegmentOfPattern(name);
@@ -23,24 +22,26 @@ module ts.NavigateTo {
2322
continue;
2423
}
2524

26-
// It was a match! If the pattern has dots in it, then also see if the
27-
// declaration container matches as well.
28-
if (patternMatcher.patternContainsDots) {
29-
let containers = getContainers(declaration);
30-
if (!containers) {
31-
return undefined;
32-
}
25+
for (let declaration of declarations) {
26+
// It was a match! If the pattern has dots in it, then also see if the
27+
// declaration container matches as well.
28+
if (patternMatcher.patternContainsDots) {
29+
let containers = getContainers(declaration);
30+
if (!containers) {
31+
return undefined;
32+
}
3333

34-
matches = patternMatcher.getMatches(containers, name);
34+
matches = patternMatcher.getMatches(containers, name);
3535

36-
if (!matches) {
37-
continue;
36+
if (!matches) {
37+
continue;
38+
}
3839
}
39-
}
4040

41-
let fileName = sourceFile.fileName;
42-
let matchKind = bestMatchKind(matches);
43-
rawItems.push({ name, fileName, matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration });
41+
let fileName = sourceFile.fileName;
42+
let matchKind = bestMatchKind(matches);
43+
rawItems.push({ name, fileName, matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration });
44+
}
4445
}
4546
}
4647
});
@@ -67,30 +68,14 @@ module ts.NavigateTo {
6768
return true;
6869
}
6970

70-
function getDeclarationName(declaration: Declaration): string {
71-
let result = getTextOfIdentifierOrLiteral(declaration.name);
72-
if (result !== undefined) {
73-
return result;
74-
}
75-
76-
if (declaration.name.kind === SyntaxKind.ComputedPropertyName) {
77-
let expr = (<ComputedPropertyName>declaration.name).expression;
78-
if (expr.kind === SyntaxKind.PropertyAccessExpression) {
79-
return (<PropertyAccessExpression>expr).name.text;
80-
}
81-
82-
return getTextOfIdentifierOrLiteral(expr);
83-
}
84-
85-
return undefined;
86-
}
87-
8871
function getTextOfIdentifierOrLiteral(node: Node) {
89-
if (node.kind === SyntaxKind.Identifier ||
90-
node.kind === SyntaxKind.StringLiteral ||
91-
node.kind === SyntaxKind.NumericLiteral) {
72+
if (node) {
73+
if (node.kind === SyntaxKind.Identifier ||
74+
node.kind === SyntaxKind.StringLiteral ||
75+
node.kind === SyntaxKind.NumericLiteral) {
9276

93-
return (<Identifier | LiteralExpression>node).text;
77+
return (<Identifier | LiteralExpression>node).text;
78+
}
9479
}
9580

9681
return undefined;

0 commit comments

Comments
 (0)