Skip to content

Commit 97e1973

Browse files
committed
Merge branch 'master' into exposeHelpers
2 parents 27b79ff + 695efa9 commit 97e1973

File tree

2,524 files changed

+95780
-86627
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,524 files changed

+95780
-86627
lines changed

scripts/processDiagnosticMessages.ts

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap:
5454
var result =
5555
'// <auto-generated />\r\n' +
5656
'/// <reference path="types.ts" />\r\n' +
57+
'/* @internal */\r\n' +
5758
'module ts {\r\n' +
5859
' export var Diagnostics = {\r\n';
5960
var names = Utilities.getObjectKeys(messageTable);

src/compiler/checker.ts

+39-22
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) {
@@ -9412,7 +9426,10 @@ module ts {
94129426
}
94139427

94149428
if (isArrayLikeType(inputType)) {
9415-
return getIndexTypeOfType(inputType, IndexKind.Number);
9429+
let indexType = getIndexTypeOfType(inputType, IndexKind.Number);
9430+
if (indexType) {
9431+
return indexType;
9432+
}
94169433
}
94179434

94189435
error(errorNode, Diagnostics.Type_0_is_not_an_array_type, typeToString(inputType));

src/compiler/diagnosticMessages.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -2043,19 +2043,19 @@
20432043
},
20442044
"'import ... =' can only be used in a .ts file.": {
20452045
"category": "Error",
2046-
"code": 8002
2046+
"code": 8002
20472047
},
20482048
"'export=' can only be used in a .ts file.": {
20492049
"category": "Error",
2050-
"code": 8003
2050+
"code": 8003
20512051
},
20522052
"'type parameter declarations' can only be used in a .ts file.": {
20532053
"category": "Error",
2054-
"code": 8004
2054+
"code": 8004
20552055
},
20562056
"'implements clauses' can only be used in a .ts file.": {
20572057
"category": "Error",
2058-
"code": 8005
2058+
"code": 8005
20592059
},
20602060
"'interface declarations' can only be used in a .ts file.": {
20612061
"category": "Error",

src/compiler/types.ts

+3-1
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/harness/typeWriter.ts

+25-73
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
interface TypeWriterResult {
22
line: number;
3-
column: number;
43
syntaxKind: number;
54
sourceText: string;
65
type: string;
@@ -29,90 +28,43 @@ class TypeWriterWalker {
2928
}
3029

3130
private visitNode(node: ts.Node): void {
32-
switch (node.kind) {
33-
// Should always log expressions that are not tokens
34-
// Also, always log the "this" keyword
35-
// TODO: Ideally we should log all expressions, but to compare to the
36-
// old typeWriter baselines, suppress tokens
37-
case ts.SyntaxKind.ThisKeyword:
38-
case ts.SyntaxKind.SuperKeyword:
39-
case ts.SyntaxKind.ArrayLiteralExpression:
40-
case ts.SyntaxKind.ObjectLiteralExpression:
41-
case ts.SyntaxKind.ElementAccessExpression:
42-
case ts.SyntaxKind.CallExpression:
43-
case ts.SyntaxKind.NewExpression:
44-
case ts.SyntaxKind.TypeAssertionExpression:
45-
case ts.SyntaxKind.ParenthesizedExpression:
46-
case ts.SyntaxKind.FunctionExpression:
47-
case ts.SyntaxKind.ArrowFunction:
48-
case ts.SyntaxKind.TypeOfExpression:
49-
case ts.SyntaxKind.VoidExpression:
50-
case ts.SyntaxKind.DeleteExpression:
51-
case ts.SyntaxKind.PrefixUnaryExpression:
52-
case ts.SyntaxKind.PostfixUnaryExpression:
53-
case ts.SyntaxKind.BinaryExpression:
54-
case ts.SyntaxKind.ConditionalExpression:
55-
case ts.SyntaxKind.SpreadElementExpression:
56-
this.log(node, this.getTypeOfNode(node));
57-
break;
58-
59-
case ts.SyntaxKind.PropertyAccessExpression:
60-
for (var current = node; current.kind === ts.SyntaxKind.PropertyAccessExpression; current = current.parent) {
61-
}
62-
if (current.kind !== ts.SyntaxKind.HeritageClauseElement) {
63-
this.log(node, this.getTypeOfNode(node));
64-
}
65-
break;
66-
67-
// Should not change expression status (maybe expressions)
68-
// TODO: Again, ideally should log number and string literals too,
69-
// but to be consistent with the old typeWriter, just log identifiers
70-
case ts.SyntaxKind.Identifier:
71-
var identifier = <ts.Identifier>node;
72-
if (!this.isLabel(identifier)) {
73-
var type = this.getTypeOfNode(identifier);
74-
this.log(node, type);
75-
}
76-
break;
31+
if (ts.isExpression(node) || node.kind === ts.SyntaxKind.Identifier) {
32+
this.logTypeAndSymbol(node);
7733
}
7834

7935
ts.forEachChild(node, child => this.visitNode(child));
8036
}
8137

82-
private isLabel(identifier: ts.Identifier): boolean {
83-
var parent = identifier.parent;
84-
switch (parent.kind) {
85-
case ts.SyntaxKind.ContinueStatement:
86-
case ts.SyntaxKind.BreakStatement:
87-
return (<ts.BreakOrContinueStatement>parent).label === identifier;
88-
case ts.SyntaxKind.LabeledStatement:
89-
return (<ts.LabeledStatement>parent).label === identifier;
90-
}
91-
return false;
92-
}
93-
94-
private log(node: ts.Node, type: ts.Type): void {
38+
private logTypeAndSymbol(node: ts.Node): void {
9539
var actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
9640
var lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos);
9741
var sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node);
98-
99-
// If we got an unknown type, we temporarily want to fall back to just pretending the name
100-
// (source text) of the node is the type. This is to align with the old typeWriter to make
101-
// baseline comparisons easier. In the long term, we will want to just call typeToString
42+
43+
var type = this.checker.getTypeAtLocation(node);
44+
ts.Debug.assert(type !== undefined, "type doesn't exist");
45+
var symbol = this.checker.getSymbolAtLocation(node);
46+
47+
var typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation);
48+
if (symbol) {
49+
var symbolString = "Symbol(" + this.checker.symbolToString(symbol, node.parent);
50+
if (symbol.declarations) {
51+
for (let declaration of symbol.declarations) {
52+
symbolString += ", ";
53+
let declSourceFile = declaration.getSourceFile();
54+
let declLineAndCharacter = declSourceFile.getLineAndCharacterOfPosition(declaration.pos);
55+
symbolString += `Decl(${ ts.getBaseFileName(declSourceFile.fileName) }, ${ declLineAndCharacter.line }, ${ declLineAndCharacter.character })`
56+
}
57+
}
58+
symbolString += ")";
59+
60+
typeString += ", " + symbolString;
61+
}
62+
10263
this.results.push({
10364
line: lineAndCharacter.line,
104-
// todo(cyrusn): Not sure why column is one-based for type-writer. But I'm preserving
105-
// that behavior to prevent having a lot of baselines to fix up.
106-
column: lineAndCharacter.character + 1,
10765
syntaxKind: node.kind,
10866
sourceText: sourceText,
109-
type: this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.WriteOwnNameForAnyLike)
67+
type: typeString
11068
});
11169
}
112-
113-
private getTypeOfNode(node: ts.Node): ts.Type {
114-
var type = this.checker.getTypeAtLocation(node);
115-
ts.Debug.assert(type !== undefined, "type doesn't exist");
116-
return type;
117-
}
11870
}

0 commit comments

Comments
 (0)