Skip to content

Commit b1e100e

Browse files
author
Andy Hanson
committed
Merge branch 'master' into kind
2 parents f6240cb + 567b10d commit b1e100e

File tree

59 files changed

+9238
-8778
lines changed

Some content is hidden

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

59 files changed

+9238
-8778
lines changed

src/compiler/binder.ts

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -260,18 +260,9 @@ namespace ts {
260260
case SyntaxKind.ExportAssignment:
261261
return (<ExportAssignment>node).isExportEquals ? "export=" : "default";
262262
case SyntaxKind.BinaryExpression:
263-
switch (getSpecialPropertyAssignmentKind(node as BinaryExpression)) {
264-
case SpecialPropertyAssignmentKind.ModuleExports:
265-
// module.exports = ...
266-
return "export=";
267-
case SpecialPropertyAssignmentKind.ExportsProperty:
268-
case SpecialPropertyAssignmentKind.ThisProperty:
269-
case SpecialPropertyAssignmentKind.Property:
270-
// exports.x = ... or this.y = ...
271-
return ((node as BinaryExpression).left as PropertyAccessExpression).name.text;
272-
case SpecialPropertyAssignmentKind.PrototypeProperty:
273-
// className.prototype.methodName = ...
274-
return (((node as BinaryExpression).left as PropertyAccessExpression).expression as PropertyAccessExpression).name.text;
263+
if (getSpecialPropertyAssignmentKind(node as BinaryExpression) === SpecialPropertyAssignmentKind.ModuleExports) {
264+
// module.exports = ...
265+
return "export=";
275266
}
276267
Debug.fail("Unknown binary declaration kind");
277268
break;
@@ -439,6 +430,7 @@ namespace ts {
439430
// during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
440431
// and this case is specially handled. Module augmentations should only be merged with original module definition
441432
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
433+
if (node.kind === SyntaxKind.JSDocTypedefTag) Debug.assert(isInJavaScriptFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
442434
const isJSDocTypedefInJSDocNamespace = node.kind === SyntaxKind.JSDocTypedefTag &&
443435
(node as JSDocTypedefTag).name &&
444436
(node as JSDocTypedefTag).name.kind === SyntaxKind.Identifier &&
@@ -603,9 +595,7 @@ namespace ts {
603595
// Binding of JsDocComment should be done before the current block scope container changes.
604596
// because the scope of JsDocComment should not be affected by whether the current node is a
605597
// container or not.
606-
if (isInJavaScriptFile(node) && node.jsDoc) {
607-
forEach(node.jsDoc, bind);
608-
}
598+
forEach(node.jsDoc, bind);
609599
if (checkUnreachable(node)) {
610600
bindEachChild(node);
611601
return;
@@ -1913,9 +1903,7 @@ namespace ts {
19131903
// Here the current node is "foo", which is a container, but the scope of "MyType" should
19141904
// not be inside "foo". Therefore we always bind @typedef before bind the parent node,
19151905
// and skip binding this tag later when binding all the other jsdoc tags.
1916-
if (isInJavaScriptFile(node)) {
1917-
bindJSDocTypedefTagIfAny(node);
1918-
}
1906+
bindJSDocTypedefTagIfAny(node);
19191907

19201908
// First we bind declaration nodes to a symbol if possible. We'll both create a symbol
19211909
// and then potentially add the symbol to an appropriate symbol table. Possible
@@ -2003,7 +1991,7 @@ namespace ts {
20031991
// for typedef type names with namespaces, bind the new jsdoc type symbol here
20041992
// because it requires all containing namespaces to be in effect, namely the
20051993
// current "blockScopeContainer" needs to be set to its immediate namespace parent.
2006-
if ((<Identifier>node).isInJSDocNamespace) {
1994+
if (isInJavaScriptFile(node) && (<Identifier>node).isInJSDocNamespace) {
20071995
let parentNode = node.parent;
20081996
while (parentNode && parentNode.kind !== SyntaxKind.JSDocTypedefTag) {
20091997
parentNode = parentNode.parent;
@@ -2073,10 +2061,7 @@ namespace ts {
20732061
return bindVariableDeclarationOrBindingElement(<VariableDeclaration | BindingElement>node);
20742062
case SyntaxKind.PropertyDeclaration:
20752063
case SyntaxKind.PropertySignature:
2076-
case SyntaxKind.JSDocRecordMember:
2077-
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Property | ((<PropertyDeclaration>node).questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes);
2078-
case SyntaxKind.JSDocPropertyTag:
2079-
return bindJSDocProperty(<JSDocPropertyTag>node);
2064+
return bindPropertyWorker(node as PropertyDeclaration | PropertySignature);
20802065
case SyntaxKind.PropertyAssignment:
20812066
case SyntaxKind.ShorthandPropertyAssignment:
20822067
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
@@ -2121,13 +2106,10 @@ namespace ts {
21212106
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes);
21222107
case SyntaxKind.FunctionType:
21232108
case SyntaxKind.ConstructorType:
2124-
case SyntaxKind.JSDocFunctionType:
21252109
return bindFunctionOrConstructorType(<SignatureDeclaration>node);
21262110
case SyntaxKind.TypeLiteral:
21272111
case SyntaxKind.MappedType:
2128-
case SyntaxKind.JSDocTypeLiteral:
2129-
case SyntaxKind.JSDocRecordType:
2130-
return bindAnonymousDeclaration(<Declaration>node, SymbolFlags.TypeLiteral, "__type");
2112+
return bindAnonymousTypeWorker(node as TypeLiteralNode | MappedTypeNode);
21312113
case SyntaxKind.ObjectLiteralExpression:
21322114
return bindObjectLiteralExpression(<ObjectLiteralExpression>node);
21332115
case SyntaxKind.FunctionExpression:
@@ -2148,11 +2130,6 @@ namespace ts {
21482130
return bindClassLikeDeclaration(<ClassLikeDeclaration>node);
21492131
case SyntaxKind.InterfaceDeclaration:
21502132
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes);
2151-
case SyntaxKind.JSDocTypedefTag:
2152-
if (!(<JSDocTypedefTag>node).fullName || (<JSDocTypedefTag>node).fullName.kind === SyntaxKind.Identifier) {
2153-
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
2154-
}
2155-
break;
21562133
case SyntaxKind.TypeAliasDeclaration:
21572134
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
21582135
case SyntaxKind.EnumDeclaration:
@@ -2190,9 +2167,41 @@ namespace ts {
21902167
// falls through
21912168
case SyntaxKind.ModuleBlock:
21922169
return updateStrictModeStatementList((<Block | ModuleBlock>node).statements);
2170+
2171+
default:
2172+
if (isInJavaScriptFile(node)) return bindJSDocWorker(node);
2173+
}
2174+
}
2175+
2176+
function bindJSDocWorker(node: Node) {
2177+
switch (node.kind) {
2178+
case SyntaxKind.JSDocRecordMember:
2179+
return bindPropertyWorker(node as JSDocRecordMember);
2180+
case SyntaxKind.JSDocPropertyTag:
2181+
return declareSymbolAndAddToSymbolTable(node as JSDocPropertyTag, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
2182+
case SyntaxKind.JSDocFunctionType:
2183+
return bindFunctionOrConstructorType(<SignatureDeclaration>node);
2184+
case SyntaxKind.JSDocTypeLiteral:
2185+
case SyntaxKind.JSDocRecordType:
2186+
return bindAnonymousTypeWorker(node as JSDocTypeLiteral | JSDocRecordType);
2187+
case SyntaxKind.JSDocTypedefTag: {
2188+
const { fullName } = node as JSDocTypedefTag;
2189+
if (!fullName || fullName.kind === SyntaxKind.Identifier) {
2190+
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
2191+
}
2192+
break;
2193+
}
21932194
}
21942195
}
21952196

2197+
function bindPropertyWorker(node: PropertyDeclaration | PropertySignature) {
2198+
return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | (node.questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes);
2199+
}
2200+
2201+
function bindAnonymousTypeWorker(node: TypeLiteralNode | MappedTypeNode | JSDocTypeLiteral | JSDocRecordType) {
2202+
return bindAnonymousDeclaration(<Declaration>node, SymbolFlags.TypeLiteral, "__type");
2203+
}
2204+
21962205
function checkTypePredicate(node: TypePredicateNode) {
21972206
const { parameterName, type } = node;
21982207
if (parameterName && parameterName.kind === SyntaxKind.Identifier) {
@@ -2558,10 +2567,8 @@ namespace ts {
25582567
}
25592568

25602569
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
2561-
if (!file.isDeclarationFile && !isInAmbientContext(node)) {
2562-
if (isAsyncFunction(node)) {
2563-
emitFlags |= NodeFlags.HasAsyncFunctions;
2564-
}
2570+
if (!file.isDeclarationFile && !isInAmbientContext(node) && isAsyncFunction(node)) {
2571+
emitFlags |= NodeFlags.HasAsyncFunctions;
25652572
}
25662573

25672574
if (currentFlow && isObjectLiteralOrClassExpressionMethod(node)) {
@@ -2573,10 +2580,6 @@ namespace ts {
25732580
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
25742581
}
25752582

2576-
function bindJSDocProperty(node: JSDocPropertyTag) {
2577-
return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
2578-
}
2579-
25802583
// reachability checks
25812584

25822585
function shouldReportErrorOnModuleDeclaration(node: ModuleDeclaration): boolean {

src/compiler/checker.ts

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3161,7 +3161,7 @@ namespace ts {
31613161
}
31623162

31633163
function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) {
3164-
const globalFlagsToPass = globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike;
3164+
const globalFlagsToPass = globalFlags & (TypeFormatFlags.WriteOwnNameForAnyLike | TypeFormatFlags.WriteClassExpressionAsTypeLiteral);
31653165
let inObjectTypeLiteral = false;
31663166
return writeType(type, globalFlags);
31673167

@@ -3278,6 +3278,11 @@ namespace ts {
32783278
writeTypeList(type.typeArguments.slice(0, getTypeReferenceArity(type)), SyntaxKind.CommaToken);
32793279
writePunctuation(writer, SyntaxKind.CloseBracketToken);
32803280
}
3281+
else if (flags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral &&
3282+
type.symbol.valueDeclaration &&
3283+
type.symbol.valueDeclaration.kind === SyntaxKind.ClassExpression) {
3284+
writeAnonymousType(getDeclaredTypeOfClassOrInterface(type.symbol), flags);
3285+
}
32813286
else {
32823287
// Write the type reference in the format f<A>.g<B>.C<X, Y> where A and B are type arguments
32833288
// for outer type parameters, and f and g are the respective declaring containers of those
@@ -3325,7 +3330,9 @@ namespace ts {
33253330
const symbol = type.symbol;
33263331
if (symbol) {
33273332
// Always use 'typeof T' for type of class, enum, and module objects
3328-
if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) ||
3333+
if (symbol.flags & SymbolFlags.Class &&
3334+
!getBaseTypeVariableOfClass(symbol) &&
3335+
!(symbol.valueDeclaration.kind === SyntaxKind.ClassExpression && flags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral) ||
33293336
symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule)) {
33303337
writeTypeOfSymbol(type, flags);
33313338
}
@@ -3347,12 +3354,23 @@ namespace ts {
33473354
else {
33483355
// Since instantiations of the same anonymous type have the same symbol, tracking symbols instead
33493356
// of types allows us to catch circular references to instantiations of the same anonymous type
3357+
// However, in case of class expressions, we want to write both the static side and the instance side.
3358+
// We skip adding the static side so that the instance side has a chance to be written
3359+
// before checking for circular references.
33503360
if (!symbolStack) {
33513361
symbolStack = [];
33523362
}
3353-
symbolStack.push(symbol);
3354-
writeLiteralType(type, flags);
3355-
symbolStack.pop();
3363+
const isConstructorObject = type.flags & TypeFlags.Object &&
3364+
getObjectFlags(type) & ObjectFlags.Anonymous &&
3365+
type.symbol && type.symbol.flags & SymbolFlags.Class;
3366+
if (isConstructorObject) {
3367+
writeLiteralType(type, flags);
3368+
}
3369+
else {
3370+
symbolStack.push(symbol);
3371+
writeLiteralType(type, flags);
3372+
symbolStack.pop();
3373+
}
33563374
}
33573375
}
33583376
else {
@@ -3471,6 +3489,14 @@ namespace ts {
34713489
buildIndexSignatureDisplay(resolved.stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack);
34723490
buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, IndexKind.Number, enclosingDeclaration, globalFlags, symbolStack);
34733491
for (const p of resolved.properties) {
3492+
if (globalFlags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral) {
3493+
if (p.flags & SymbolFlags.Prototype) {
3494+
continue;
3495+
}
3496+
if (getDeclarationModifierFlagsFromSymbol(p) & (ModifierFlags.Private | ModifierFlags.Protected)) {
3497+
writer.reportPrivateInBaseOfClassExpression(p.name);
3498+
}
3499+
}
34743500
const t = getTypeOfSymbol(p);
34753501
if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) {
34763502
const signatures = getSignaturesOfType(t, SignatureKind.Call);
@@ -3485,7 +3511,7 @@ namespace ts {
34853511
writePropertyWithModifiers(p);
34863512
writePunctuation(writer, SyntaxKind.ColonToken);
34873513
writeSpace(writer);
3488-
writeType(t, TypeFormatFlags.None);
3514+
writeType(t, globalFlags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral);
34893515
writePunctuation(writer, SyntaxKind.SemicolonToken);
34903516
writer.writeLine();
34913517
}
@@ -22327,6 +22353,11 @@ namespace ts {
2232722353
}
2232822354
}
2232922355

22356+
if (entityName.parent!.kind === SyntaxKind.JSDocParameterTag) {
22357+
const parameter = ts.getParameterFromJSDoc(entityName.parent as JSDocParameterTag);
22358+
return parameter && parameter.symbol;
22359+
}
22360+
2233022361
if (isPartOfExpression(entityName)) {
2233122362
if (nodeIsMissing(entityName)) {
2233222363
// Missing entity name.

src/compiler/core.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,7 +1783,8 @@ namespace ts {
17831783
return path.length > extension.length && endsWith(path, extension);
17841784
}
17851785

1786-
export function fileExtensionIsAny(path: string, extensions: string[]): boolean {
1786+
/* @internal */
1787+
export function fileExtensionIsOneOf(path: string, extensions: string[]): boolean {
17871788
for (const extension of extensions) {
17881789
if (fileExtensionIs(path, extension)) {
17891790
return true;
@@ -1983,7 +1984,7 @@ namespace ts {
19831984
for (const current of files) {
19841985
const name = combinePaths(path, current);
19851986
const absoluteName = combinePaths(absolutePath, current);
1986-
if (extensions && !fileExtensionIsAny(name, extensions)) continue;
1987+
if (extensions && !fileExtensionIsOneOf(name, extensions)) continue;
19871988
if (excludeRegex && excludeRegex.test(absoluteName)) continue;
19881989
if (!includeFileRegexes) {
19891990
results[0].push(name);

0 commit comments

Comments
 (0)