From e5910af2c835ffbc8b67469ad1fff6bbec4e112b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 14:15:49 -0700 Subject: [PATCH 001/194] Always recurse into children in the binder in a uniform manner. --- src/compiler/binder.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 9d6d9fab35b..1682cbdcd44 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -575,10 +575,8 @@ module ts { bindChildren(node, 0, /*isBlockScopeContainer*/ true); break; default: - let saveParent = parent; - parent = node; - forEachChild(node, bind); - parent = saveParent; + bindChildren(node, 0, /*isBlockScopeContainer*/ false); + break; } } From 14e925beb980790b271aec0ee8d6b54da4cfa669 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 14:21:52 -0700 Subject: [PATCH 002/194] ConstructorType's name should be __call not __constructor. --- src/compiler/binder.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 1682cbdcd44..4bc79e35c33 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -111,12 +111,12 @@ module ts { return (node.name).text; } switch (node.kind) { - case SyntaxKind.ConstructorType: case SyntaxKind.Constructor: return "__constructor"; case SyntaxKind.FunctionType: case SyntaxKind.CallSignature: return "__call"; + case SyntaxKind.ConstructorType: case SyntaxKind.ConstructSignature: return "__new"; case SyntaxKind.IndexSignature: @@ -368,15 +368,14 @@ module ts { // We do that by making an anonymous type literal symbol, and then setting the function // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable // from an actual type literal symbol you would have gotten had you used the long form. - - let symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node)); + let name = getDeclarationName(node); + let symbol = createSymbol(SymbolFlags.Signature, name); addDeclarationToSymbol(symbol, node, SymbolFlags.Signature); bindChildren(node, SymbolFlags.Signature, /*isBlockScopeContainer:*/ false); let typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); - typeLiteralSymbol.members = {}; - typeLiteralSymbol.members[node.kind === SyntaxKind.FunctionType ? "__call" : "__new"] = symbol + typeLiteralSymbol.members = { [name]: symbol }; } function bindAnonymousDeclaration(node: Declaration, symbolKind: SymbolFlags, name: string, isBlockScopeContainer: boolean) { From 6478155aac000a15c95d6e0bb60bad1d72dd6626 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 14:30:35 -0700 Subject: [PATCH 003/194] Rename locals to more clearly indicate they are flags and not kinds. --- src/compiler/binder.ts | 98 ++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 41 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4bc79e35c33..b11a7b5b8c0 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -86,14 +86,27 @@ module ts { } } - function addDeclarationToSymbol(symbol: Symbol, node: Declaration, symbolKind: SymbolFlags) { - symbol.flags |= symbolKind; - if (!symbol.declarations) symbol.declarations = []; - symbol.declarations.push(node); - if (symbolKind & SymbolFlags.HasExports && !symbol.exports) symbol.exports = {}; - if (symbolKind & SymbolFlags.HasMembers && !symbol.members) symbol.members = {}; + function addDeclarationToSymbol(symbol: Symbol, node: Declaration, symbolFlags: SymbolFlags) { + symbol.flags |= symbolFlags; + node.symbol = symbol; - if (symbolKind & SymbolFlags.Value && !symbol.valueDeclaration) symbol.valueDeclaration = node; + + if (!symbol.declarations) { + symbol.declarations = []; + } + symbol.declarations.push(node); + + if (symbolFlags & SymbolFlags.HasExports && !symbol.exports) { + symbol.exports = {}; + } + + if (symbolFlags & SymbolFlags.HasMembers && !symbol.members) { + symbol.members = {}; + } + + if (symbolFlags & SymbolFlags.Value && !symbol.valueDeclaration) { + symbol.valueDeclaration = node; + } } // Should not be called on a declaration with a computed property name, @@ -189,14 +202,14 @@ module ts { return symbol; } - function declareModuleMember(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) { + function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { let hasExportModifier = getCombinedNodeFlags(node) & NodeFlags.Export; - if (symbolKind & SymbolFlags.Alias) { + if (symbolFlags & SymbolFlags.Alias) { if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); } else { - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); + declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } else { @@ -212,23 +225,23 @@ module ts { // but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way // when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope. if (hasExportModifier || container.flags & NodeFlags.ExportContext) { - let exportKind = (symbolKind & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) | - (symbolKind & SymbolFlags.Type ? SymbolFlags.ExportType : 0) | - (symbolKind & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0); + let exportKind = (symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) | + (symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) | + (symbolFlags & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0); let local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes); - local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); node.localSymbol = local; } else { - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); + declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } } // All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function // in the type checker to validate that the local name used for a container is unique. - function bindChildren(node: Node, symbolKind: SymbolFlags, isBlockScopeContainer: boolean) { - if (symbolKind & SymbolFlags.HasLocals) { + function bindChildren(node: Node, symbolFlags: SymbolFlags, isBlockScopeContainer: boolean) { + if (symbolFlags & SymbolFlags.HasLocals) { node.locals = {}; } @@ -236,7 +249,7 @@ module ts { let saveContainer = container; let savedBlockScopeContainer = blockScopeContainer; parent = node; - if (symbolKind & SymbolFlags.IsContainer) { + if (symbolFlags & SymbolFlags.IsContainer) { container = node; if (lastContainer) { @@ -253,7 +266,7 @@ module ts { // these cases are: // - node has locals (symbolKind & HasLocals) !== 0 // - node is a source file - setBlockScopeContainer(node, /*cleanLocals*/ (symbolKind & SymbolFlags.HasLocals) === 0 && node.kind !== SyntaxKind.SourceFile); + setBlockScopeContainer(node, /*cleanLocals*/ (symbolFlags & SymbolFlags.HasLocals) === 0 && node.kind !== SyntaxKind.SourceFile); } forEachChild(node, bind); @@ -262,14 +275,14 @@ module ts { blockScopeContainer = savedBlockScopeContainer; } - function bindDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) { + function bindDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) { switch (container.kind) { case SyntaxKind.ModuleDeclaration: - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; case SyntaxKind.SourceFile: if (isExternalModule(container)) { - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; } case SyntaxKind.FunctionType: @@ -285,29 +298,32 @@ module ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); + declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); break; case SyntaxKind.ClassExpression: case SyntaxKind.ClassDeclaration: if (node.flags & NodeFlags.Static) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); break; } case SyntaxKind.TypeLiteral: case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.InterfaceDeclaration: - declareSymbol(container.symbol.members, container.symbol, node, symbolKind, symbolExcludes); + declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); break; case SyntaxKind.EnumDeclaration: - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); break; } - bindChildren(node, symbolKind, isBlockScopeContainer); + bindChildren(node, symbolFlags, isBlockScopeContainer); } function isAmbientContext(node: Node): boolean { while (node) { - if (node.flags & NodeFlags.Ambient) return true; + if (node.flags & NodeFlags.Ambient) { + return true; + } + node = node.parent; } return false; @@ -378,24 +394,24 @@ module ts { typeLiteralSymbol.members = { [name]: symbol }; } - function bindAnonymousDeclaration(node: Declaration, symbolKind: SymbolFlags, name: string, isBlockScopeContainer: boolean) { - let symbol = createSymbol(symbolKind, name); - addDeclarationToSymbol(symbol, node, symbolKind); - bindChildren(node, symbolKind, isBlockScopeContainer); + function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string, isBlockScopeContainer: boolean) { + let symbol = createSymbol(symbolFlags, name); + addDeclarationToSymbol(symbol, node, symbolFlags); + bindChildren(node, symbolFlags, isBlockScopeContainer); } function bindCatchVariableDeclaration(node: CatchClause) { bindChildren(node, /*symbolKind:*/ 0, /*isBlockScopeContainer:*/ true); } - function bindBlockScopedDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) { + function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { switch (blockScopeContainer.kind) { case SyntaxKind.ModuleDeclaration: - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; case SyntaxKind.SourceFile: if (isExternalModule(container)) { - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; } // fall through. @@ -403,9 +419,9 @@ module ts { if (!blockScopeContainer.locals) { blockScopeContainer.locals = {}; } - declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, symbolExcludes); + declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolKind, /*isBlockScopeContainer*/ false); + bindChildren(node, symbolFlags, /*isBlockScopeContainer*/ false); } function bindBlockScopedVariableDeclaration(node: Declaration) { @@ -598,12 +614,12 @@ module ts { } } - function bindPropertyOrMethodOrAccessor(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) { + function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) { if (hasDynamicName(node)) { - bindAnonymousDeclaration(node, symbolKind, "__computed", isBlockScopeContainer); + bindAnonymousDeclaration(node, symbolFlags, "__computed", isBlockScopeContainer); } else { - bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer); + bindDeclaration(node, symbolFlags, symbolExcludes, isBlockScopeContainer); } } } From 71d0f7affe4d8c5ec9b1841fca9a403ffe14b8a2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 14:46:01 -0700 Subject: [PATCH 004/194] Simplify concerns in the binder. --- src/compiler/binder.ts | 89 ++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 38 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b11a7b5b8c0..af7226eee2d 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -202,14 +202,14 @@ module ts { return symbol; } - function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { + function declareModuleMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { let hasExportModifier = getCombinedNodeFlags(node) & NodeFlags.Export; if (symbolFlags & SymbolFlags.Alias) { if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); } else { - declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } else { @@ -231,9 +231,10 @@ module ts { let local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes); local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); node.localSymbol = local; + return local; } else { - declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } } @@ -275,16 +276,17 @@ module ts { blockScopeContainer = savedBlockScopeContainer; } - function bindDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) { + function declareSymbolForDeclarationAndBindChildren(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean): void { + declareSymbolAndAddToAppropriateContainer(node, symbolFlags, symbolExcludes, isBlockScopeContainer); + bindChildren(node, symbolFlags, isBlockScopeContainer); + } + + function declareSymbolAndAddToAppropriateContainer(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean): Symbol { switch (container.kind) { case SyntaxKind.ModuleDeclaration: - declareModuleMember(node, symbolFlags, symbolExcludes); - break; + return declareModuleMember(node, symbolFlags, symbolExcludes); case SyntaxKind.SourceFile: - if (isExternalModule(container)) { - declareModuleMember(node, symbolFlags, symbolExcludes); - break; - } + return declareSourceFileMember(container, node, symbolFlags, symbolExcludes); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: case SyntaxKind.CallSignature: @@ -298,24 +300,35 @@ module ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); - break; + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); case SyntaxKind.ClassExpression: case SyntaxKind.ClassDeclaration: - if (node.flags & NodeFlags.Static) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); - break; - } + return declareClassMember(node, symbolFlags, symbolExcludes); case SyntaxKind.TypeLiteral: case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.InterfaceDeclaration: - declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); - break; + return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); case SyntaxKind.EnumDeclaration: - declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); - break; + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); + } + } + + function declareClassMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { + if (node.flags & NodeFlags.Static) { + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); + } + else { + return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); + } + } + + function declareSourceFileMember(container: SourceFile, node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { + if (isExternalModule(container)) { + return declareModuleMember(node, symbolFlags, symbolExcludes); + } + else { + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolFlags, isBlockScopeContainer); } function isAmbientContext(node: Node): boolean { @@ -355,15 +368,15 @@ module ts { function bindModuleDeclaration(node: ModuleDeclaration) { setExportContextFlag(node); if (node.name.kind === SyntaxKind.StringLiteral) { - bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true); } else { let state = getModuleInstanceState(node); if (state === ModuleInstanceState.NonInstantiated) { - bindDeclaration(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes, /*isBlockScopeContainer*/ true); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes, /*isBlockScopeContainer*/ true); } else { - bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true); let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly; if (node.symbol.constEnumOnlyModule === undefined) { // non-merged case - use the current state @@ -437,7 +450,7 @@ module ts { switch (node.kind) { case SyntaxKind.TypeParameter: - bindDeclaration(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.Parameter: bindParameter(node); @@ -451,7 +464,7 @@ module ts { bindBlockScopedVariableDeclaration(node); } else { - bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false); } break; case SyntaxKind.PropertyDeclaration: @@ -468,7 +481,7 @@ module ts { case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: - bindDeclaration(node, SymbolFlags.Signature, 0, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Signature, 0, /*isBlockScopeContainer*/ false); break; case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: @@ -480,10 +493,10 @@ module ts { isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true); break; case SyntaxKind.FunctionDeclaration: - bindDeclaration(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes, /*isBlockScopeContainer*/ true); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes, /*isBlockScopeContainer*/ true); break; case SyntaxKind.Constructor: - bindDeclaration(node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0, /*isBlockScopeContainer:*/ true); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0, /*isBlockScopeContainer:*/ true); break; case SyntaxKind.GetAccessor: bindPropertyOrMethodOrAccessor(node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes, /*isBlockScopeContainer*/ true); @@ -517,17 +530,17 @@ module ts { bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); break; case SyntaxKind.InterfaceDeclaration: - bindDeclaration(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.TypeAliasDeclaration: - bindDeclaration(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.EnumDeclaration: if (isConst(node)) { - bindDeclaration(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes, /*isBlockScopeContainer*/ false); } else { - bindDeclaration(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes, /*isBlockScopeContainer*/ false); } break; case SyntaxKind.ModuleDeclaration: @@ -537,11 +550,11 @@ module ts { case SyntaxKind.NamespaceImport: case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: - bindDeclaration(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.ImportClause: if ((node).name) { - bindDeclaration(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes, /*isBlockScopeContainer*/ false); } else { bindChildren(node, 0, /*isBlockScopeContainer*/ false); @@ -600,7 +613,7 @@ module ts { bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node), /*isBlockScopeContainer*/ false); } else { - bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false); } // If this is a property-parameter, then also declare the property symbol into the @@ -619,7 +632,7 @@ module ts { bindAnonymousDeclaration(node, symbolFlags, "__computed", isBlockScopeContainer); } else { - bindDeclaration(node, symbolFlags, symbolExcludes, isBlockScopeContainer); + declareSymbolForDeclarationAndBindChildren(node, symbolFlags, symbolExcludes, isBlockScopeContainer); } } } From 9e64b4500118a662c9087f42997d9a1e242d81f0 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 14:57:35 -0700 Subject: [PATCH 005/194] Add explanatory comments to the binder. --- src/compiler/binder.ts | 59 ++++++++++++++++++++++++++++++++---------- src/compiler/types.ts | 9 ++++--- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index af7226eee2d..0beed9b1152 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -277,16 +277,51 @@ module ts { } function declareSymbolForDeclarationAndBindChildren(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean): void { + // First we declare a symbol for the provided node. The symbol will be added to an + // appropriate symbol table. Possible symbol tables include: + // + // 1) The 'exports' table of the current container's symbol. + // 2) The 'members' table of the current container's symbol. + // 3) The 'locals' table of the current container. + // + // Then, we recurse down the children of this declaration, seeking more declarations + // to bind. + declareSymbolAndAddToAppropriateContainer(node, symbolFlags, symbolExcludes, isBlockScopeContainer); bindChildren(node, symbolFlags, isBlockScopeContainer); } function declareSymbolAndAddToAppropriateContainer(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean): Symbol { switch (container.kind) { + // Modules, source files, and classes need specialized handling for how their + // members are declared (for example, a member of a class will go into a specific + // symbol table depending on if it is static or not). As such, we defer to + // specialized handlers to take care of declaring these child members. case SyntaxKind.ModuleDeclaration: return declareModuleMember(node, symbolFlags, symbolExcludes); + case SyntaxKind.SourceFile: - return declareSourceFileMember(container, node, symbolFlags, symbolExcludes); + return declareSourceFileMember(node, symbolFlags, symbolExcludes); + + case SyntaxKind.ClassExpression: + case SyntaxKind.ClassDeclaration: + return declareClassMember(node, symbolFlags, symbolExcludes); + + case SyntaxKind.EnumDeclaration: + // Enum members are always put int the 'exports' of the containing enum. + // They are only accessibly through their container, and are never in + // scope otherwise (even inside the body of the enum declaring them.). + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); + + case SyntaxKind.TypeLiteral: + case SyntaxKind.ObjectLiteralExpression: + case SyntaxKind.InterfaceDeclaration: + // Interface/Object-types always have their children added to the 'members' of + // their container. They are only accessible through an instance of their + // container, and are never in scope otherwise (even inside the body of the + // object / type / interface declaring them). + return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); + case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: case SyntaxKind.CallSignature: @@ -300,16 +335,14 @@ module ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: + // All the children of these container types are never visible through another + // symbol (i.e. through another symbol's 'exports' or 'members'). Instead, + // more or less, they're only accessed 'lexically' (i.e. from code that exists + // underneath their container in the tree. To accomplish this, we simply add + // their declared symbol to the 'locals' of the container. These symbols can + // then be found as the type checker walks up the containers, checking them + // for matching names. return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); - case SyntaxKind.ClassExpression: - case SyntaxKind.ClassDeclaration: - return declareClassMember(node, symbolFlags, symbolExcludes); - case SyntaxKind.TypeLiteral: - case SyntaxKind.ObjectLiteralExpression: - case SyntaxKind.InterfaceDeclaration: - return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); - case SyntaxKind.EnumDeclaration: - return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); } } @@ -322,12 +355,12 @@ module ts { } } - function declareSourceFileMember(container: SourceFile, node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - if (isExternalModule(container)) { + function declareSourceFileMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { + if (isExternalModule(file)) { return declareModuleMember(node, symbolFlags, symbolExcludes); } else { - return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); + return declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 078f3d060a6..6b1191f4a5e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1360,14 +1360,15 @@ module ts { export interface Symbol { flags: SymbolFlags; // Symbol flags name: string; // Name of symbol - /* @internal */ id?: number; // Unique id (used to look up SymbolLinks) - /* @internal */ mergeId?: number; // Merge id (used to look up merged symbol) declarations?: Declaration[]; // Declarations associated with this symbol - /* @internal */ parent?: Symbol; // Parent symbol + valueDeclaration?: Declaration; // First value declaration of the symbol + members?: SymbolTable; // Class, interface or literal instance members exports?: SymbolTable; // Module exports + /* @internal */ id?: number; // Unique id (used to look up SymbolLinks) + /* @internal */ mergeId?: number; // Merge id (used to look up merged symbol) + /* @internal */ parent?: Symbol; // Parent symbol /* @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol - valueDeclaration?: Declaration; // First value declaration of the symbol /* @internal */ constEnumOnlyModule?: boolean; // True if module contains only const enums or other modules with only const enums } From e7ddba508ab30e4961467cdeb1e2c9e06e877e2c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 15:50:02 -0700 Subject: [PATCH 006/194] Merge block container logic in the binder to use the same mechanism as SymbolFlags --- src/compiler/binder.ts | 96 +++++++++++++++++++++--------------------- src/compiler/types.ts | 2 + 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 0beed9b1152..9670b44d80e 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -241,7 +241,7 @@ module ts { // All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function // in the type checker to validate that the local name used for a container is unique. - function bindChildren(node: Node, symbolFlags: SymbolFlags, isBlockScopeContainer: boolean) { + function bindChildren(node: Node, symbolFlags: SymbolFlags) { if (symbolFlags & SymbolFlags.HasLocals) { node.locals = {}; } @@ -260,7 +260,7 @@ module ts { lastContainer = container; } - if (isBlockScopeContainer) { + if (symbolFlags & SymbolFlags.IsBlockScopedContainer) { // in incremental scenarios we might reuse nodes that already have locals being allocated // during the bind step these locals should be dropped to prevent using stale data. // locals should always be dropped unless they were previously initialized by the binder @@ -276,7 +276,7 @@ module ts { blockScopeContainer = savedBlockScopeContainer; } - function declareSymbolForDeclarationAndBindChildren(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean): void { + function declareSymbolForDeclarationAndBindChildren(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): void { // First we declare a symbol for the provided node. The symbol will be added to an // appropriate symbol table. Possible symbol tables include: // @@ -287,11 +287,11 @@ module ts { // Then, we recurse down the children of this declaration, seeking more declarations // to bind. - declareSymbolAndAddToAppropriateContainer(node, symbolFlags, symbolExcludes, isBlockScopeContainer); - bindChildren(node, symbolFlags, isBlockScopeContainer); + declareSymbolAndAddToAppropriateContainer(node, symbolFlags, symbolExcludes); + bindChildren(node, symbolFlags); } - function declareSymbolAndAddToAppropriateContainer(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean): Symbol { + function declareSymbolAndAddToAppropriateContainer(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { switch (container.kind) { // Modules, source files, and classes need specialized handling for how their // members are declared (for example, a member of a class will go into a specific @@ -401,15 +401,15 @@ module ts { function bindModuleDeclaration(node: ModuleDeclaration) { setExportContextFlag(node); if (node.name.kind === SyntaxKind.StringLiteral) { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); } else { let state = getModuleInstanceState(node); if (state === ModuleInstanceState.NonInstantiated) { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes, /*isBlockScopeContainer*/ true); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); } else { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly; if (node.symbol.constEnumOnlyModule === undefined) { // non-merged case - use the current state @@ -433,21 +433,21 @@ module ts { let name = getDeclarationName(node); let symbol = createSymbol(SymbolFlags.Signature, name); addDeclarationToSymbol(symbol, node, SymbolFlags.Signature); - bindChildren(node, SymbolFlags.Signature, /*isBlockScopeContainer:*/ false); + bindChildren(node, SymbolFlags.Signature); let typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); typeLiteralSymbol.members = { [name]: symbol }; } - function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string, isBlockScopeContainer: boolean) { + function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) { let symbol = createSymbol(symbolFlags, name); addDeclarationToSymbol(symbol, node, symbolFlags); - bindChildren(node, symbolFlags, isBlockScopeContainer); + bindChildren(node, symbolFlags); } function bindCatchVariableDeclaration(node: CatchClause) { - bindChildren(node, /*symbolKind:*/ 0, /*isBlockScopeContainer:*/ true); + bindChildren(node, SymbolFlags.BlockScopedContainer); } function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { @@ -467,7 +467,7 @@ module ts { } declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolFlags, /*isBlockScopeContainer*/ false); + bindChildren(node, symbolFlags); } function bindBlockScopedVariableDeclaration(node: Declaration) { @@ -483,7 +483,7 @@ module ts { switch (node.kind) { case SyntaxKind.TypeParameter: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); break; case SyntaxKind.Parameter: bindParameter(node); @@ -491,30 +491,30 @@ module ts { case SyntaxKind.VariableDeclaration: case SyntaxKind.BindingElement: if (isBindingPattern((node).name)) { - bindChildren(node, 0, /*isBlockScopeContainer*/ false); + bindChildren(node, 0); } else if (isBlockOrCatchScoped(node)) { bindBlockScopedVariableDeclaration(node); } else { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); } break; case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | ((node).questionToken ? SymbolFlags.Optional : 0), SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false); + bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | ((node).questionToken ? SymbolFlags.Optional : 0), SymbolFlags.PropertyExcludes); break; case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: - bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false); + bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); break; case SyntaxKind.EnumMember: - bindPropertyOrMethodOrAccessor(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes, /*isBlockScopeContainer*/ false); + bindPropertyOrMethodOrAccessor(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes); break; case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Signature, 0, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Signature, 0); break; case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: @@ -523,19 +523,19 @@ module ts { // so that it will conflict with any other object literal members with the same // name. bindPropertyOrMethodOrAccessor(node, SymbolFlags.Method | ((node).questionToken ? SymbolFlags.Optional : 0), - isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true); + isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes); break; case SyntaxKind.FunctionDeclaration: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes, /*isBlockScopeContainer*/ true); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); break; case SyntaxKind.Constructor: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0, /*isBlockScopeContainer:*/ true); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0); break; case SyntaxKind.GetAccessor: - bindPropertyOrMethodOrAccessor(node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes, /*isBlockScopeContainer*/ true); + bindPropertyOrMethodOrAccessor(node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes); break; case SyntaxKind.SetAccessor: - bindPropertyOrMethodOrAccessor(node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes, /*isBlockScopeContainer*/ true); + bindPropertyOrMethodOrAccessor(node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes); break; case SyntaxKind.FunctionType: @@ -544,17 +544,17 @@ module ts { break; case SyntaxKind.TypeLiteral: - bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type", /*isBlockScopeContainer*/ false); + bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type"); break; case SyntaxKind.ObjectLiteralExpression: - bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object", /*isBlockScopeContainer*/ false); + bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object"); break; case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - bindAnonymousDeclaration(node, SymbolFlags.Function, "__function", /*isBlockScopeContainer*/ true); + bindAnonymousDeclaration(node, SymbolFlags.Function, "__function"); break; case SyntaxKind.ClassExpression: - bindAnonymousDeclaration(node, SymbolFlags.Class, "__class", /*isBlockScopeContainer*/ false); + bindAnonymousDeclaration(node, SymbolFlags.Class, "__class"); break; case SyntaxKind.CatchClause: bindCatchVariableDeclaration(node); @@ -563,17 +563,17 @@ module ts { bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); break; case SyntaxKind.InterfaceDeclaration: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes); break; case SyntaxKind.TypeAliasDeclaration: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); break; case SyntaxKind.EnumDeclaration: if (isConst(node)) { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes); } else { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); } break; case SyntaxKind.ModuleDeclaration: @@ -583,14 +583,14 @@ module ts { case SyntaxKind.NamespaceImport: case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); break; case SyntaxKind.ImportClause: if ((node).name) { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); } else { - bindChildren(node, 0, /*isBlockScopeContainer*/ false); + bindChildren(node, 0); } break; case SyntaxKind.ExportDeclaration: @@ -598,7 +598,7 @@ module ts { // All export * declarations are collected in an __export symbol declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, 0); } - bindChildren(node, 0, /*isBlockScopeContainer*/ false); + bindChildren(node, 0); break; case SyntaxKind.ExportAssignment: if ((node).expression.kind === SyntaxKind.Identifier) { @@ -609,12 +609,12 @@ module ts { // An export default clause with an expression exports a value declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); } - bindChildren(node, 0, /*isBlockScopeContainer*/ false); + bindChildren(node, 0); break; case SyntaxKind.SourceFile: setExportContextFlag(node); if (isExternalModule(node)) { - bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((node).fileName) + '"', /*isBlockScopeContainer*/ true); + bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((node).fileName) + '"'); break; } case SyntaxKind.Block: @@ -626,27 +626,27 @@ module ts { // let x; // } // 'let x' will be placed into the function locals and 'let x' - into the locals of the block - bindChildren(node, 0, /*isBlockScopeContainer*/ !isFunctionLike(node.parent)); + bindChildren(node, isFunctionLike(node.parent) ? 0 : SymbolFlags.BlockScopedContainer); break; case SyntaxKind.CatchClause: case SyntaxKind.ForStatement: case SyntaxKind.ForInStatement: case SyntaxKind.ForOfStatement: case SyntaxKind.CaseBlock: - bindChildren(node, 0, /*isBlockScopeContainer*/ true); + bindChildren(node, SymbolFlags.BlockScopedContainer); break; default: - bindChildren(node, 0, /*isBlockScopeContainer*/ false); + bindChildren(node, 0); break; } } function bindParameter(node: ParameterDeclaration) { if (isBindingPattern(node.name)) { - bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node), /*isBlockScopeContainer*/ false); + bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node)); } else { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false); + declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); } // If this is a property-parameter, then also declare the property symbol into the @@ -660,12 +660,12 @@ module ts { } } - function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) { + function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { if (hasDynamicName(node)) { - bindAnonymousDeclaration(node, symbolFlags, "__computed", isBlockScopeContainer); + bindAnonymousDeclaration(node, symbolFlags, "__computed"); } else { - declareSymbolForDeclarationAndBindChildren(node, symbolFlags, symbolExcludes, isBlockScopeContainer); + declareSymbolForDeclarationAndBindChildren(node, symbolFlags, symbolExcludes); } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6b1191f4a5e..5b5150ab132 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1310,6 +1310,7 @@ module ts { UnionProperty = 0x10000000, // Property in union type Optional = 0x20000000, // Optional property ExportStar = 0x40000000, // Export * declaration + BlockScopedContainer = 0x80000000, Enum = RegularEnum | ConstEnum, Variable = FunctionScopedVariable | BlockScopedVariable, @@ -1352,6 +1353,7 @@ module ts { HasExports = Class | Enum | Module, HasMembers = Class | Interface | TypeLiteral | ObjectLiteral, + IsBlockScopedContainer = BlockScopedContainer | Module | Function | Accessor | Method | Constructor, IsContainer = HasLocals | HasExports | HasMembers, PropertyOrAccessor = Property | Accessor, Export = ExportNamespace | ExportType | ExportValue, From b75fda1052f637853802962fa8793c2fe1b2d4ad Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 15:55:21 -0700 Subject: [PATCH 007/194] Explicitly type 'bind' as being a void function. --- src/compiler/binder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 9670b44d80e..1665da1431f 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -478,7 +478,7 @@ module ts { return "__" + indexOf((node.parent).parameters, node); } - function bind(node: Node) { + function bind(node: Node): void { node.parent = parent; switch (node.kind) { From 9043121188f6d6544bdb599bb2660d8da9231a89 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 16:02:07 -0700 Subject: [PATCH 008/194] Add a 'None' member to SymbolFlags enum. --- src/compiler/binder.ts | 1 - src/compiler/types.ts | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 1665da1431f..f5364f71d13 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -480,7 +480,6 @@ module ts { function bind(node: Node): void { node.parent = parent; - switch (node.kind) { case SyntaxKind.TypeParameter: declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5b5150ab132..010b6308348 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1279,6 +1279,7 @@ module ts { } export const enum SymbolFlags { + None = 0, FunctionScopedVariable = 0x00000001, // Variable (var) or parameter BlockScopedVariable = 0x00000002, // A block-scoped variable (let or const) Property = 0x00000004, // Property or enum member From c5d920e912585084dbe04d7993890a43ed6a511d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 16:23:56 -0700 Subject: [PATCH 009/194] Simplify recursion in the binder. We now only recurse in a single place in the binder. The rest of the binding code is only concerned with how to bind a single node to a symbol and add that symbol to a symbol table. Recursion is handled as a separate concern, greatly simplifying binder flow. --- src/compiler/binder.ts | 193 +++++++++++++++++++++-------------------- 1 file changed, 100 insertions(+), 93 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index f5364f71d13..cee2ff08a78 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -276,7 +276,7 @@ module ts { blockScopeContainer = savedBlockScopeContainer; } - function declareSymbolForDeclarationAndBindChildren(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): void { + function declareSymbolForDeclarationAndBindChildren(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): SymbolFlags { // First we declare a symbol for the provided node. The symbol will be added to an // appropriate symbol table. Possible symbol tables include: // @@ -288,7 +288,7 @@ module ts { // to bind. declareSymbolAndAddToAppropriateContainer(node, symbolFlags, symbolExcludes); - bindChildren(node, symbolFlags); + return symbolFlags; } function declareSymbolAndAddToAppropriateContainer(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { @@ -401,16 +401,25 @@ module ts { function bindModuleDeclaration(node: ModuleDeclaration) { setExportContextFlag(node); if (node.name.kind === SyntaxKind.StringLiteral) { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); } else { let state = getModuleInstanceState(node); if (state === ModuleInstanceState.NonInstantiated) { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); } else { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); + } + } + } + + function postBindModuleDeclarationChildren(node: ModuleDeclaration) { + if (node.name.kind !== SyntaxKind.StringLiteral) { + let state = getModuleInstanceState(node); + if (state !== ModuleInstanceState.NonInstantiated) { let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly; + if (node.symbol.constEnumOnlyModule === undefined) { // non-merged case - use the current state node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly; @@ -423,7 +432,7 @@ module ts { } } - function bindFunctionOrConstructorType(node: SignatureDeclaration) { + function bindFunctionOrConstructorType(node: SignatureDeclaration): SymbolFlags { // For a given function symbol "<...>(...) => T" we want to generate a symbol identical // to the one we would get for: { <...>(...): T } // @@ -433,24 +442,24 @@ module ts { let name = getDeclarationName(node); let symbol = createSymbol(SymbolFlags.Signature, name); addDeclarationToSymbol(symbol, node, SymbolFlags.Signature); - bindChildren(node, SymbolFlags.Signature); + return SymbolFlags.Signature; + } + function postBindFunctionOrConstructorTypeChildren(node: SignatureDeclaration): void { + let symbol = node.symbol; + let name = symbol.name; let typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); typeLiteralSymbol.members = { [name]: symbol }; } - function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) { + function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string): SymbolFlags { let symbol = createSymbol(symbolFlags, name); addDeclarationToSymbol(symbol, node, symbolFlags); - bindChildren(node, symbolFlags); + return symbolFlags; } - function bindCatchVariableDeclaration(node: CatchClause) { - bindChildren(node, SymbolFlags.BlockScopedContainer); - } - - function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { + function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): SymbolFlags { switch (blockScopeContainer.kind) { case SyntaxKind.ModuleDeclaration: declareModuleMember(node, symbolFlags, symbolExcludes); @@ -467,11 +476,12 @@ module ts { } declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolFlags); + + return symbolFlags; } - function bindBlockScopedVariableDeclaration(node: Declaration) { - bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); + function bindBlockScopedVariableDeclaration(node: Declaration): SymbolFlags { + return bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); } function getDestructuringParameterName(node: Declaration) { @@ -479,126 +489,112 @@ module ts { } function bind(node: Node): void { + // First we bind declaration nodes to a symbol if possible. We'll both create a symbol + // and add the symbol to an appropriate symbol table. The symbolFlags that are retuerned + // from this help inform how we recurse into the children of this node. + var symbolFlags = bindWorker(node); + + // Then we recurse into the children of the node to bind them as well. For certain + // symbols we do specialized work when we recurse. For example, we'll keep track of + // the current 'container' node when it changes. This helps us know which symbol table + // a local should go into for example. + bindChildren(node, symbolFlags); + + // Allow certain nodes to do specialized work after their children have been bound. + postBindChildren(node); + } + + function bindWorker(node: Node): SymbolFlags { node.parent = parent; switch (node.kind) { case SyntaxKind.TypeParameter: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); - break; + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); case SyntaxKind.Parameter: - bindParameter(node); - break; + return bindParameter(node); case SyntaxKind.VariableDeclaration: case SyntaxKind.BindingElement: if (isBindingPattern((node).name)) { - bindChildren(node, 0); + return SymbolFlags.None; } else if (isBlockOrCatchScoped(node)) { - bindBlockScopedVariableDeclaration(node); + return bindBlockScopedVariableDeclaration(node); } else { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); } - break; case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | ((node).questionToken ? SymbolFlags.Optional : 0), SymbolFlags.PropertyExcludes); - break; + return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | ((node).questionToken ? SymbolFlags.Optional : 0), SymbolFlags.PropertyExcludes); case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: - bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); - break; + return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); case SyntaxKind.EnumMember: - bindPropertyOrMethodOrAccessor(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes); - break; + return bindPropertyOrMethodOrAccessor(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes); case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Signature, 0); - break; + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Signature, 0); case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: // If this is an ObjectLiteralExpression method, then it sits in the same space // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes // so that it will conflict with any other object literal members with the same // name. - bindPropertyOrMethodOrAccessor(node, SymbolFlags.Method | ((node).questionToken ? SymbolFlags.Optional : 0), + return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Method | ((node).questionToken ? SymbolFlags.Optional : 0), isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes); - break; case SyntaxKind.FunctionDeclaration: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); - break; + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); case SyntaxKind.Constructor: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0); - break; + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0); case SyntaxKind.GetAccessor: - bindPropertyOrMethodOrAccessor(node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes); - break; + return bindPropertyOrMethodOrAccessor(node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes); case SyntaxKind.SetAccessor: - bindPropertyOrMethodOrAccessor(node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes); - break; - + return bindPropertyOrMethodOrAccessor(node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: - bindFunctionOrConstructorType(node); - break; - + return bindFunctionOrConstructorType(node); case SyntaxKind.TypeLiteral: - bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type"); - break; + return bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type"); case SyntaxKind.ObjectLiteralExpression: - bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object"); - break; + return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object"); case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - bindAnonymousDeclaration(node, SymbolFlags.Function, "__function"); - break; + return bindAnonymousDeclaration(node, SymbolFlags.Function, "__function"); case SyntaxKind.ClassExpression: - bindAnonymousDeclaration(node, SymbolFlags.Class, "__class"); - break; - case SyntaxKind.CatchClause: - bindCatchVariableDeclaration(node); - break; + return bindAnonymousDeclaration(node, SymbolFlags.Class, "__class"); case SyntaxKind.ClassDeclaration: - bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); - break; + return bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); case SyntaxKind.InterfaceDeclaration: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes); - break; + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes); case SyntaxKind.TypeAliasDeclaration: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); - break; + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); case SyntaxKind.EnumDeclaration: if (isConst(node)) { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes); + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes); } else { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); } - break; case SyntaxKind.ModuleDeclaration: - bindModuleDeclaration(node); - break; + return bindModuleDeclaration(node); case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.NamespaceImport: case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); - break; + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); case SyntaxKind.ImportClause: if ((node).name) { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); } else { - bindChildren(node, 0); + return SymbolFlags.None; } - break; case SyntaxKind.ExportDeclaration: if (!(node).exportClause) { // All export * declarations are collected in an __export symbol declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, 0); } - bindChildren(node, 0); - break; + return SymbolFlags.None; case SyntaxKind.ExportAssignment: if ((node).expression.kind === SyntaxKind.Identifier) { // An export default clause with an identifier exports all meanings of that identifier @@ -608,14 +604,14 @@ module ts { // An export default clause with an expression exports a value declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); } - bindChildren(node, 0); - break; + return SymbolFlags.None; case SyntaxKind.SourceFile: setExportContextFlag(node); if (isExternalModule(node)) { - bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((node).fileName) + '"'); - break; + return bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((node).fileName) + '"'); } + // fall through. + case SyntaxKind.Block: // do not treat function block a block-scope container // all block-scope locals that reside in this block should go to the function locals. @@ -625,29 +621,40 @@ module ts { // let x; // } // 'let x' will be placed into the function locals and 'let x' - into the locals of the block - bindChildren(node, isFunctionLike(node.parent) ? 0 : SymbolFlags.BlockScopedContainer); - break; + return isFunctionLike(node.parent) ? 0 : SymbolFlags.BlockScopedContainer; case SyntaxKind.CatchClause: case SyntaxKind.ForStatement: case SyntaxKind.ForInStatement: case SyntaxKind.ForOfStatement: case SyntaxKind.CaseBlock: - bindChildren(node, SymbolFlags.BlockScopedContainer); - break; - default: - bindChildren(node, 0); - break; + return SymbolFlags.BlockScopedContainer; + } + + return SymbolFlags.None; + } + + function postBindChildren(node: Node) { + switch (node.kind) { + case SyntaxKind.Parameter: + return postParameterChildren(node); + case SyntaxKind.ModuleDeclaration: + return postBindModuleDeclarationChildren(node); + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: + return postBindFunctionOrConstructorTypeChildren(node); } } - function bindParameter(node: ParameterDeclaration) { + function bindParameter(node: ParameterDeclaration): SymbolFlags { if (isBindingPattern(node.name)) { - bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node)); + return bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node)); } else { - declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); } + } + function postParameterChildren(node: ParameterDeclaration): void { // If this is a property-parameter, then also declare the property symbol into the // containing class. if (node.flags & NodeFlags.AccessibilityModifier && @@ -659,12 +666,12 @@ module ts { } } - function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { + function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): SymbolFlags { if (hasDynamicName(node)) { - bindAnonymousDeclaration(node, symbolFlags, "__computed"); + return bindAnonymousDeclaration(node, symbolFlags, "__computed"); } else { - declareSymbolForDeclarationAndBindChildren(node, symbolFlags, symbolExcludes); + return declareSymbolForDeclarationAndBindChildren(node, symbolFlags, symbolExcludes); } } } From 02640a397f8af4b7d33e9cd2b6e4c62a6dd85d34 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 16:37:24 -0700 Subject: [PATCH 010/194] Extract any complicated code in top level bind function to individual helpers. --- src/compiler/binder.ts | 102 ++++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index cee2ff08a78..fdff9d2e7ea 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -513,15 +513,7 @@ module ts { return bindParameter(node); case SyntaxKind.VariableDeclaration: case SyntaxKind.BindingElement: - if (isBindingPattern((node).name)) { - return SymbolFlags.None; - } - else if (isBlockOrCatchScoped(node)) { - return bindBlockScopedVariableDeclaration(node); - } - else { - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); - } + return bindVariableDeclarationOrBindingElement(node); case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | ((node).questionToken ? SymbolFlags.Optional : 0), SymbolFlags.PropertyExcludes); @@ -569,12 +561,7 @@ module ts { case SyntaxKind.TypeAliasDeclaration: return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); case SyntaxKind.EnumDeclaration: - if (isConst(node)) { - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes); - } - else { - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); - } + return bindEnumDeclaration(node); case SyntaxKind.ModuleDeclaration: return bindModuleDeclaration(node); case SyntaxKind.ImportEqualsDeclaration: @@ -583,35 +570,13 @@ module ts { case SyntaxKind.ExportSpecifier: return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); case SyntaxKind.ImportClause: - if ((node).name) { - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); - } - else { - return SymbolFlags.None; - } + return bindImportClause(node); case SyntaxKind.ExportDeclaration: - if (!(node).exportClause) { - // All export * declarations are collected in an __export symbol - declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, 0); - } - return SymbolFlags.None; + return bindExportDeclaration(node); case SyntaxKind.ExportAssignment: - if ((node).expression.kind === SyntaxKind.Identifier) { - // An export default clause with an identifier exports all meanings of that identifier - declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); - } - else { - // An export default clause with an expression exports a value - declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); - } - return SymbolFlags.None; + return bindExportAssignment(node); case SyntaxKind.SourceFile: - setExportContextFlag(node); - if (isExternalModule(node)) { - return bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((node).fileName) + '"'); - } - // fall through. - + return bindSourceFileIfExternalModule(); case SyntaxKind.Block: // do not treat function block a block-scope container // all block-scope locals that reside in this block should go to the function locals. @@ -645,6 +610,61 @@ module ts { } } + function bindSourceFileIfExternalModule() { + setExportContextFlag(file); + return isExternalModule(file) + ? bindAnonymousDeclaration(file, SymbolFlags.ValueModule, '"' + removeFileExtension(file.fileName) + '"') + : SymbolFlags.BlockScopedContainer; + } + + function bindExportAssignment(node: ExportAssignment) { + if (node.expression.kind === SyntaxKind.Identifier) { + // An export default clause with an identifier exports all meanings of that identifier + declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); + } + else { + // An export default clause with an expression exports a value + declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); + } + + return SymbolFlags.None; + } + + function bindExportDeclaration(node: ExportDeclaration) { + if (!node.exportClause) { + // All export * declarations are collected in an __export symbol + declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, 0); + } + return SymbolFlags.None; + } + + function bindImportClause(node: ImportClause) { + if (node.name) { + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + } + else { + return SymbolFlags.None; + } + } + + function bindEnumDeclaration(node: EnumDeclaration) { + return isConst(node) + ? declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes) + : declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); + } + + function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement) { + if (isBindingPattern(node.name)) { + return SymbolFlags.None; + } + else if (isBlockOrCatchScoped(node)) { + return bindBlockScopedVariableDeclaration(node); + } + else { + return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); + } + } + function bindParameter(node: ParameterDeclaration): SymbolFlags { if (isBindingPattern(node.name)) { return bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node)); From fb925ee4d136792fc1ed4283b5840187cdc43759 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 16:39:09 -0700 Subject: [PATCH 011/194] Rename methods. --- src/compiler/binder.ts | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index fdff9d2e7ea..b994f3ea7bc 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -276,7 +276,7 @@ module ts { blockScopeContainer = savedBlockScopeContainer; } - function declareSymbolForDeclarationAndBindChildren(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): SymbolFlags { + function declareSymbolAndAddToSymbolTable(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): SymbolFlags { // First we declare a symbol for the provided node. The symbol will be added to an // appropriate symbol table. Possible symbol tables include: // @@ -287,11 +287,11 @@ module ts { // Then, we recurse down the children of this declaration, seeking more declarations // to bind. - declareSymbolAndAddToAppropriateContainer(node, symbolFlags, symbolExcludes); + declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes); return symbolFlags; } - function declareSymbolAndAddToAppropriateContainer(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { + function declareSymbolAndAddToSymbolTableWorker(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { switch (container.kind) { // Modules, source files, and classes need specialized handling for how their // members are declared (for example, a member of a class will go into a specific @@ -401,15 +401,15 @@ module ts { function bindModuleDeclaration(node: ModuleDeclaration) { setExportContextFlag(node); if (node.name.kind === SyntaxKind.StringLiteral) { - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); } else { let state = getModuleInstanceState(node); if (state === ModuleInstanceState.NonInstantiated) { - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); } else { - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); } } } @@ -508,7 +508,7 @@ module ts { node.parent = parent; switch (node.kind) { case SyntaxKind.TypeParameter: - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); case SyntaxKind.Parameter: return bindParameter(node); case SyntaxKind.VariableDeclaration: @@ -525,7 +525,7 @@ module ts { case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Signature, 0); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Signature, 0); case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: // If this is an ObjectLiteralExpression method, then it sits in the same space @@ -535,9 +535,9 @@ module ts { return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Method | ((node).questionToken ? SymbolFlags.Optional : 0), isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes); case SyntaxKind.FunctionDeclaration: - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); case SyntaxKind.Constructor: - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0); case SyntaxKind.GetAccessor: return bindPropertyOrMethodOrAccessor(node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes); case SyntaxKind.SetAccessor: @@ -557,9 +557,9 @@ module ts { case SyntaxKind.ClassDeclaration: return bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); case SyntaxKind.InterfaceDeclaration: - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes); case SyntaxKind.TypeAliasDeclaration: - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); case SyntaxKind.EnumDeclaration: return bindEnumDeclaration(node); case SyntaxKind.ModuleDeclaration: @@ -568,7 +568,7 @@ module ts { case SyntaxKind.NamespaceImport: case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); case SyntaxKind.ImportClause: return bindImportClause(node); case SyntaxKind.ExportDeclaration: @@ -640,7 +640,7 @@ module ts { function bindImportClause(node: ImportClause) { if (node.name) { - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); } else { return SymbolFlags.None; @@ -649,8 +649,8 @@ module ts { function bindEnumDeclaration(node: EnumDeclaration) { return isConst(node) - ? declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes) - : declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); + ? declareSymbolAndAddToSymbolTable(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes) + : declareSymbolAndAddToSymbolTable(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); } function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement) { @@ -661,7 +661,7 @@ module ts { return bindBlockScopedVariableDeclaration(node); } else { - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); } } @@ -670,7 +670,7 @@ module ts { return bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node)); } else { - return declareSymbolForDeclarationAndBindChildren(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); } } @@ -691,7 +691,7 @@ module ts { return bindAnonymousDeclaration(node, symbolFlags, "__computed"); } else { - return declareSymbolForDeclarationAndBindChildren(node, symbolFlags, symbolExcludes); + return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } } } From eb29eb9acd5074c1e8ca698e4d34013492a988c4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 16:43:42 -0700 Subject: [PATCH 012/194] Remove code to post bind parameters. --- src/compiler/binder.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b994f3ea7bc..3d9204c81a9 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -600,8 +600,6 @@ module ts { function postBindChildren(node: Node) { switch (node.kind) { - case SyntaxKind.Parameter: - return postParameterChildren(node); case SyntaxKind.ModuleDeclaration: return postBindModuleDeclarationChildren(node); case SyntaxKind.FunctionType: @@ -667,14 +665,12 @@ module ts { function bindParameter(node: ParameterDeclaration): SymbolFlags { if (isBindingPattern(node.name)) { - return bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node)); + bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node)); } else { - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); + declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); } - } - function postParameterChildren(node: ParameterDeclaration): void { // If this is a property-parameter, then also declare the property symbol into the // containing class. if (node.flags & NodeFlags.AccessibilityModifier && @@ -684,6 +680,8 @@ module ts { let classDeclaration = node.parent.parent; declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); } + + return SymbolFlags.FunctionScopedVariable; } function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): SymbolFlags { From fab6fca5b4af8685ace4496a02db8eb312662605 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 16:48:28 -0700 Subject: [PATCH 013/194] Remove post bind step for modules. --- src/compiler/binder.ts | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 3d9204c81a9..d214cba6140 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -409,17 +409,9 @@ module ts { return declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); } else { - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); - } - } - } + let result = declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); - function postBindModuleDeclarationChildren(node: ModuleDeclaration) { - if (node.name.kind !== SyntaxKind.StringLiteral) { - let state = getModuleInstanceState(node); - if (state !== ModuleInstanceState.NonInstantiated) { let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly; - if (node.symbol.constEnumOnlyModule === undefined) { // non-merged case - use the current state node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly; @@ -428,6 +420,8 @@ module ts { // merged case: module is const enum only if all its pieces are non-instantiated or const enum node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly; } + + return result; } } } @@ -600,8 +594,6 @@ module ts { function postBindChildren(node: Node) { switch (node.kind) { - case SyntaxKind.ModuleDeclaration: - return postBindModuleDeclarationChildren(node); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: return postBindFunctionOrConstructorTypeChildren(node); From ea7bafa9fb0e4a95e879fc5ca024726d3aedae06 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 16:54:09 -0700 Subject: [PATCH 014/194] Remove unncessary postbind for function/constructor types. --- src/compiler/binder.ts | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d214cba6140..381e2750fd5 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -436,15 +436,12 @@ module ts { let name = getDeclarationName(node); let symbol = createSymbol(SymbolFlags.Signature, name); addDeclarationToSymbol(symbol, node, SymbolFlags.Signature); - return SymbolFlags.Signature; - } - function postBindFunctionOrConstructorTypeChildren(node: SignatureDeclaration): void { - let symbol = node.symbol; - let name = symbol.name; let typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); typeLiteralSymbol.members = { [name]: symbol }; + + return SymbolFlags.Signature; } function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string): SymbolFlags { @@ -483,6 +480,8 @@ module ts { } function bind(node: Node): void { + node.parent = parent; + // First we bind declaration nodes to a symbol if possible. We'll both create a symbol // and add the symbol to an appropriate symbol table. The symbolFlags that are retuerned // from this help inform how we recurse into the children of this node. @@ -493,13 +492,9 @@ module ts { // the current 'container' node when it changes. This helps us know which symbol table // a local should go into for example. bindChildren(node, symbolFlags); - - // Allow certain nodes to do specialized work after their children have been bound. - postBindChildren(node); } function bindWorker(node: Node): SymbolFlags { - node.parent = parent; switch (node.kind) { case SyntaxKind.TypeParameter: return declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); @@ -592,14 +587,6 @@ module ts { return SymbolFlags.None; } - function postBindChildren(node: Node) { - switch (node.kind) { - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: - return postBindFunctionOrConstructorTypeChildren(node); - } - } - function bindSourceFileIfExternalModule() { setExportContextFlag(file); return isExternalModule(file) From db128252b0b59ca0fe0ef8fa437a64e35439f077 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 16:57:44 -0700 Subject: [PATCH 015/194] Simplify code in the binder. --- src/compiler/binder.ts | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 381e2750fd5..56022bc61d4 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -347,21 +347,15 @@ module ts { } function declareClassMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - if (node.flags & NodeFlags.Static) { - return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); - } - else { - return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); - } + return node.flags & NodeFlags.Static + ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes) + : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); } function declareSourceFileMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { - if (isExternalModule(file)) { - return declareModuleMember(node, symbolFlags, symbolExcludes); - } - else { - return declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes); - } + return isExternalModule(file) + ? declareModuleMember(node, symbolFlags, symbolExcludes) + : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes); } function isAmbientContext(node: Node): boolean { @@ -616,12 +610,9 @@ module ts { } function bindImportClause(node: ImportClause) { - if (node.name) { - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); - } - else { - return SymbolFlags.None; - } + return node.name + ? declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes) + : SymbolFlags.None; } function bindEnumDeclaration(node: EnumDeclaration) { @@ -664,12 +655,9 @@ module ts { } function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): SymbolFlags { - if (hasDynamicName(node)) { - return bindAnonymousDeclaration(node, symbolFlags, "__computed"); - } - else { - return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); - } + return hasDynamicName(node) + ? bindAnonymousDeclaration(node, symbolFlags, "__computed") + : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } } } From 941128ba79483a73a3ba3800f1201c6d89a3e962 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 17:02:49 -0700 Subject: [PATCH 016/194] Clean up comments. --- src/compiler/binder.ts | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 56022bc61d4..4fca9a65508 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -277,16 +277,6 @@ module ts { } function declareSymbolAndAddToSymbolTable(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): SymbolFlags { - // First we declare a symbol for the provided node. The symbol will be added to an - // appropriate symbol table. Possible symbol tables include: - // - // 1) The 'exports' table of the current container's symbol. - // 2) The 'members' table of the current container's symbol. - // 3) The 'locals' table of the current container. - // - // Then, we recurse down the children of this declaration, seeking more declarations - // to bind. - declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes); return symbolFlags; } @@ -477,8 +467,17 @@ module ts { node.parent = parent; // First we bind declaration nodes to a symbol if possible. We'll both create a symbol - // and add the symbol to an appropriate symbol table. The symbolFlags that are retuerned - // from this help inform how we recurse into the children of this node. + // and add the symbol to an appropriate symbol table (if appropriate). The symbolFlags + // that are returned from this help inform how we recurse into the children of this node. + // + // Possible destination symbol tables are: + // + // 1) The 'exports' table of the current container's symbol. + // 2) The 'members' table of the current container's symbol. + // 3) The 'locals' table of the current container. + // + // However, not all symbols will end up in any of these tables. 'Anonymous' symbols + // (like TypeLiterals for example) will not be put in any table. var symbolFlags = bindWorker(node); // Then we recurse into the children of the node to bind them as well. For certain From 44559954772fe222c4025644a9e1488b48c33e4f Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 17:09:17 -0700 Subject: [PATCH 017/194] Move all symbol table initialization into the same method. --- src/compiler/binder.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4fca9a65508..5d449b8b4b1 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -90,6 +90,9 @@ module ts { symbol.flags |= symbolFlags; node.symbol = symbol; + if (symbolFlags & SymbolFlags.HasLocals) { + node.locals = {}; + } if (!symbol.declarations) { symbol.declarations = []; @@ -242,10 +245,6 @@ module ts { // All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function // in the type checker to validate that the local name used for a container is unique. function bindChildren(node: Node, symbolFlags: SymbolFlags) { - if (symbolFlags & SymbolFlags.HasLocals) { - node.locals = {}; - } - let saveParent = parent; let saveContainer = container; let savedBlockScopeContainer = blockScopeContainer; @@ -271,6 +270,7 @@ module ts { } forEachChild(node, bind); + container = saveContainer; parent = saveParent; blockScopeContainer = savedBlockScopeContainer; From 221262314c8e1c6d0ae425018e99175ad7c583b8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 17:14:31 -0700 Subject: [PATCH 018/194] Inline binder method. --- src/compiler/binder.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 5d449b8b4b1..fa9cc95128e 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -68,8 +68,7 @@ module ts { if (!file.locals) { file.locals = {}; - container = file; - setBlockScopeContainer(file, /*cleanLocals*/ false); + container = blockScopeContainer = file; bind(file); file.symbolCount = symbolCount; } @@ -79,13 +78,6 @@ module ts { return new Symbol(flags, name); } - function setBlockScopeContainer(node: Node, cleanLocals: boolean) { - blockScopeContainer = node; - if (cleanLocals) { - blockScopeContainer.locals = undefined; - } - } - function addDeclarationToSymbol(symbol: Symbol, node: Declaration, symbolFlags: SymbolFlags) { symbol.flags |= symbolFlags; @@ -266,7 +258,10 @@ module ts { // these cases are: // - node has locals (symbolKind & HasLocals) !== 0 // - node is a source file - setBlockScopeContainer(node, /*cleanLocals*/ (symbolFlags & SymbolFlags.HasLocals) === 0 && node.kind !== SyntaxKind.SourceFile); + blockScopeContainer = node; + if ((symbolFlags & SymbolFlags.HasLocals) === 0 && node.kind !== SyntaxKind.SourceFile) { + blockScopeContainer.locals = undefined; + } } forEachChild(node, bind); From 4f8d68bb23a44f6f8603e8e64de009f83a5bbf92 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 17:31:52 -0700 Subject: [PATCH 019/194] Use SymbolFlags.None in the binder. --- src/compiler/binder.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index fa9cc95128e..7abf9d27cc5 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -151,7 +151,7 @@ module ts { let symbol: Symbol; if (name !== undefined) { - symbol = hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(0, name)); + symbol = hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(SymbolFlags.None, name)); if (symbol.flags & excludes) { if (node.name) { node.name.parent = node; @@ -168,11 +168,11 @@ module ts { }); file.bindDiagnostics.push(createDiagnosticForNode(node.name || node, message, getDisplayName(node))); - symbol = createSymbol(0, name); + symbol = createSymbol(SymbolFlags.None, name); } } else { - symbol = createSymbol(0, "__missing"); + symbol = createSymbol(SymbolFlags.None, "__missing"); } addDeclarationToSymbol(symbol, node, includes); symbol.parent = parent; @@ -493,7 +493,7 @@ module ts { return bindVariableDeclarationOrBindingElement(node); case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | ((node).questionToken ? SymbolFlags.Optional : 0), SymbolFlags.PropertyExcludes); + return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | ((node).questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes); case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); @@ -502,19 +502,19 @@ module ts { case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Signature, 0); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Signature, SymbolFlags.None); case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: // If this is an ObjectLiteralExpression method, then it sits in the same space // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes // so that it will conflict with any other object literal members with the same // name. - return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Method | ((node).questionToken ? SymbolFlags.Optional : 0), + return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Method | ((node).questionToken ? SymbolFlags.Optional : SymbolFlags.None), isObjectLiteralMethod(node) ? SymbolFlags.PropertyExcludes : SymbolFlags.MethodExcludes); case SyntaxKind.FunctionDeclaration: return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); case SyntaxKind.Constructor: - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Constructor, /*symbolExcludes:*/ 0); + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Constructor, /*symbolExcludes:*/ SymbolFlags.None); case SyntaxKind.GetAccessor: return bindPropertyOrMethodOrAccessor(node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes); case SyntaxKind.SetAccessor: @@ -563,7 +563,7 @@ module ts { // let x; // } // 'let x' will be placed into the function locals and 'let x' - into the locals of the block - return isFunctionLike(node.parent) ? 0 : SymbolFlags.BlockScopedContainer; + return isFunctionLike(node.parent) ? SymbolFlags.None : SymbolFlags.BlockScopedContainer; case SyntaxKind.CatchClause: case SyntaxKind.ForStatement: case SyntaxKind.ForInStatement: @@ -598,7 +598,7 @@ module ts { function bindExportDeclaration(node: ExportDeclaration) { if (!node.exportClause) { // All export * declarations are collected in an __export symbol - declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, 0); + declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, SymbolFlags.None); } return SymbolFlags.None; } From 38bae987284d4561299ac5074947094a80c40dd1 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 23:06:42 -0700 Subject: [PATCH 020/194] CR feedback. --- src/compiler/binder.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 7abf9d27cc5..4f65c81bd53 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -293,8 +293,8 @@ module ts { return declareClassMember(node, symbolFlags, symbolExcludes); case SyntaxKind.EnumDeclaration: - // Enum members are always put int the 'exports' of the containing enum. - // They are only accessibly through their container, and are never in + // Enum members are always put in the 'exports' of the containing enum. + // They are only accessible through their container, and are never in // scope otherwise (even inside the body of the enum declaring them.). return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); @@ -462,7 +462,7 @@ module ts { node.parent = parent; // First we bind declaration nodes to a symbol if possible. We'll both create a symbol - // and add the symbol to an appropriate symbol table (if appropriate). The symbolFlags + // and then potentially add the symbol to an appropriate symbol table. The symbolFlags // that are returned from this help inform how we recurse into the children of this node. // // Possible destination symbol tables are: From e9a73e0cf866f36db72478d275018d7755b4a34f Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 23:20:04 -0700 Subject: [PATCH 021/194] Move code for creating a prototype out of the common declareSymbol codepath. --- src/compiler/binder.ts | 50 ++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4f65c81bd53..a4bf77b22c1 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -174,26 +174,10 @@ module ts { else { symbol = createSymbol(SymbolFlags.None, "__missing"); } + addDeclarationToSymbol(symbol, node, includes); symbol.parent = parent; - if ((node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression) && symbol.exports) { - // TypeScript 1.0 spec (April 2014): 8.4 - // Every class automatically contains a static property member named 'prototype', - // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter. - // It is an error to explicitly declare a static property member with the name 'prototype'. - let prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype"); - if (hasProperty(symbol.exports, prototypeSymbol.name)) { - if (node.name) { - node.name.parent = node; - } - file.bindDiagnostics.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], - Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); - } - symbol.exports[prototypeSymbol.name] = prototypeSymbol; - prototypeSymbol.parent = symbol; - } - return symbol; } @@ -530,9 +514,8 @@ module ts { case SyntaxKind.ArrowFunction: return bindAnonymousDeclaration(node, SymbolFlags.Function, "__function"); case SyntaxKind.ClassExpression: - return bindAnonymousDeclaration(node, SymbolFlags.Class, "__class"); case SyntaxKind.ClassDeclaration: - return bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); + return bindClassLikeDeclaration(node); case SyntaxKind.InterfaceDeclaration: return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes); case SyntaxKind.TypeAliasDeclaration: @@ -609,6 +592,35 @@ module ts { : SymbolFlags.None; } + function bindClassLikeDeclaration(node: ClassLikeDeclaration) { + if (node.kind === SyntaxKind.ClassDeclaration) { + bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); + } + else { + bindAnonymousDeclaration(node, SymbolFlags.Class, "__class"); + } + + let symbol = node.symbol; + if (symbol.exports) { + // TypeScript 1.0 spec (April 2014): 8.4 + // Every class automatically contains a static property member named 'prototype', + // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter. + // It is an error to explicitly declare a static property member with the name 'prototype'. + let prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype"); + if (hasProperty(symbol.exports, prototypeSymbol.name)) { + if (node.name) { + node.name.parent = node; + } + file.bindDiagnostics.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], + Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); + } + symbol.exports[prototypeSymbol.name] = prototypeSymbol; + prototypeSymbol.parent = symbol; + } + + return SymbolFlags.Class; + } + function bindEnumDeclaration(node: EnumDeclaration) { return isConst(node) ? declareSymbolAndAddToSymbolTable(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes) From ee6c7dc0e480f149b967f0432896807466ab0f11 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 23:23:44 -0700 Subject: [PATCH 022/194] Remove unnecessary check. Classes always have exports. --- src/compiler/binder.ts | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index a4bf77b22c1..2100936c775 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -601,22 +601,21 @@ module ts { } let symbol = node.symbol; - if (symbol.exports) { - // TypeScript 1.0 spec (April 2014): 8.4 - // Every class automatically contains a static property member named 'prototype', - // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter. - // It is an error to explicitly declare a static property member with the name 'prototype'. - let prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype"); - if (hasProperty(symbol.exports, prototypeSymbol.name)) { - if (node.name) { - node.name.parent = node; - } - file.bindDiagnostics.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], - Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); + + // TypeScript 1.0 spec (April 2014): 8.4 + // Every class automatically contains a static property member named 'prototype', + // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter. + // It is an error to explicitly declare a static property member with the name 'prototype'. + let prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype"); + if (hasProperty(symbol.exports, prototypeSymbol.name)) { + if (node.name) { + node.name.parent = node; } - symbol.exports[prototypeSymbol.name] = prototypeSymbol; - prototypeSymbol.parent = symbol; + file.bindDiagnostics.push(createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], + Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); } + symbol.exports[prototypeSymbol.name] = prototypeSymbol; + prototypeSymbol.parent = symbol; return SymbolFlags.Class; } From aaf9371357faa9b38c2adcfef8dd372d22f537d2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sun, 19 Apr 2015 23:30:06 -0700 Subject: [PATCH 023/194] Add clarifying comments to binder. --- src/compiler/binder.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 2100936c775..6f8140a983a 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -603,9 +603,14 @@ module ts { let symbol = node.symbol; // TypeScript 1.0 spec (April 2014): 8.4 - // Every class automatically contains a static property member named 'prototype', - // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter. - // It is an error to explicitly declare a static property member with the name 'prototype'. + // Every class automatically contains a static property member named 'prototype', the + // type of which is an instantiation of the class type with type Any supplied as a type + // argument for each type parameter. It is an error to explicitly declare a static + // property member with the name 'prototype'. + // + // Note: we check for this here because this class may be merging into a module. The + // module might have an exported variable called 'prototype'. We can't allow that as + // that would clash with the built-in 'prototype' for the class. let prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype"); if (hasProperty(symbol.exports, prototypeSymbol.name)) { if (node.name) { From 2e8e4a1f5c22cc5514a0a2137217b6037cde4779 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 20 Apr 2015 02:24:47 -0700 Subject: [PATCH 024/194] Add clarifying comments to the binder. --- src/compiler/binder.ts | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 6f8140a983a..e27851c7806 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -143,7 +143,7 @@ module ts { return node.name ? declarationNameToString(node.name) : getDeclarationName(node); } - function declareSymbol(symbols: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol { + function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol { Debug.assert(!hasDynamicName(node)); // The exported symbol for an export default function/class node is always named "default" @@ -151,7 +151,27 @@ module ts { let symbol: Symbol; if (name !== undefined) { - symbol = hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(SymbolFlags.None, name)); + // Check and see if the symbol table already has a symbol with this name. If not, + // create a new symbol with this name and add it to the table. Note that we don't + // give the new symbol any flags *yet*. This ensures that it will not conflict + // witht he 'excludes' flags we pass in. + // + // If we do get an existing symbol, see if it conflicts with the new symbol we're + // creating. For example, a 'var' symbol and a 'class' symbol will conflict within + // the same symbol table. If we have a conflict, report the issue on each + // declaration we have for this symbol, and then create a new symbol for this + // declaration. + // + // If we created a new symbol, either because we didn't have a symbol with this name + // in the symbol table, or we conflicted with an existing symbol, then just add this + // node as the sole declaration of the new symbol. + // + // Otherwise, we'll be merging into a compatible existing symbol (for example when + // you have multiple 'vars' with the same name in the same container). In this case + // just add this node into the declarations list of the symbol. + symbol = hasProperty(symbolTable, name) + ? symbolTable[name] + : (symbolTable[name] = createSymbol(SymbolFlags.None, name)); if (symbol.flags & excludes) { if (node.name) { node.name.parent = node; @@ -160,9 +180,8 @@ module ts { // Report errors every position with duplicate declaration // Report errors on previous encountered declarations let message = symbol.flags & SymbolFlags.BlockScopedVariable - ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 + ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0; - forEach(symbol.declarations, declaration => { file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration))); }); @@ -204,7 +223,8 @@ module ts { // but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way // when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope. if (hasExportModifier || container.flags & NodeFlags.ExportContext) { - let exportKind = (symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) | + let exportKind = + (symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) | (symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) | (symbolFlags & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0); let local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes); @@ -541,11 +561,10 @@ module ts { // do not treat function block a block-scope container // all block-scope locals that reside in this block should go to the function locals. // Otherwise this won't be considered as redeclaration of a block scoped local: - // function foo() { - // let x; + // function foo(x) { // let x; // } - // 'let x' will be placed into the function locals and 'let x' - into the locals of the block + // 'x' will be placed into the function locals and 'let x' - into the locals of the block return isFunctionLike(node.parent) ? SymbolFlags.None : SymbolFlags.BlockScopedContainer; case SyntaxKind.CatchClause: case SyntaxKind.ForStatement: From 33a74101b8804c10f5a5b915e9598983fd0132ef Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 20 Apr 2015 23:28:16 -0700 Subject: [PATCH 025/194] Split out the concerns of the binder even more. Don't use SymbolFlags to direct how we handle containers in the binder. Instead, Just determine what we should do based on the .kind of the node itself, and nothing more. --- src/compiler/binder.ts | 200 +++++++++++++++++++++++------------------ src/compiler/types.ts | 4 - 2 files changed, 111 insertions(+), 93 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e27851c7806..612b957cf4a 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -52,6 +52,15 @@ module ts { } } + const enum ContainerFlags { + None = 0, + IsContainer = 0x01, + IsBlockScopedContainer = 0x02, + HasLocals = 0x04, + + IsContainerWithLocals = IsContainer | HasLocals + } + export function bindSourceFile(file: SourceFile): void { let start = new Date().getTime(); bindSourceFileWorker(file); @@ -67,8 +76,6 @@ module ts { let Symbol = objectAllocator.getSymbolConstructor(); if (!file.locals) { - file.locals = {}; - container = blockScopeContainer = file; bind(file); file.symbolCount = symbolCount; } @@ -82,9 +89,6 @@ module ts { symbol.flags |= symbolFlags; node.symbol = symbol; - if (symbolFlags & SymbolFlags.HasLocals) { - node.locals = {}; - } if (!symbol.declarations) { symbol.declarations = []; @@ -238,34 +242,29 @@ module ts { } } - // All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function - // in the type checker to validate that the local name used for a container is unique. - function bindChildren(node: Node, symbolFlags: SymbolFlags) { + // All container nodes are kept on a linked list in declaration order. This list is used by + // the getLocalNameOfContainer function in the type checker to validate that the local name + // used for a container is unique. + function bindChildren(node: Node): void { let saveParent = parent; let saveContainer = container; let savedBlockScopeContainer = blockScopeContainer; parent = node; - if (symbolFlags & SymbolFlags.IsContainer) { - container = node; - if (lastContainer) { - lastContainer.nextContainer = container; + let containerFlags = getContainerFlags(node); + if (containerFlags & ContainerFlags.IsContainer) { + container = blockScopeContainer = node; + + // If this is a container that also has locals, initialize them now. + if (containerFlags & ContainerFlags.HasLocals) { + container.locals = {}; } - lastContainer = container; + addContainerToEndOfChain(); } - - if (symbolFlags & SymbolFlags.IsBlockScopedContainer) { - // in incremental scenarios we might reuse nodes that already have locals being allocated - // during the bind step these locals should be dropped to prevent using stale data. - // locals should always be dropped unless they were previously initialized by the binder - // these cases are: - // - node has locals (symbolKind & HasLocals) !== 0 - // - node is a source file + else if (containerFlags & ContainerFlags.IsBlockScopedContainer) { blockScopeContainer = node; - if ((symbolFlags & SymbolFlags.HasLocals) === 0 && node.kind !== SyntaxKind.SourceFile) { - blockScopeContainer.locals = undefined; - } + blockScopeContainer.locals = undefined; } forEachChild(node, bind); @@ -275,9 +274,64 @@ module ts { blockScopeContainer = savedBlockScopeContainer; } - function declareSymbolAndAddToSymbolTable(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): SymbolFlags { + function getContainerFlags(node: Node): ContainerFlags { + switch (node.kind) { + case SyntaxKind.ClassExpression: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.TypeLiteral: + case SyntaxKind.ObjectLiteralExpression: + return ContainerFlags.IsContainer; + + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.IndexSignature: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.Constructor: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.SourceFile: + return ContainerFlags.IsContainerWithLocals; + + case SyntaxKind.CatchClause: + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + case SyntaxKind.CaseBlock: + return ContainerFlags.IsBlockScopedContainer; + + case SyntaxKind.Block: + // do not treat function block a block-scope container + // all block-scope locals that reside in this block should go to the function locals. + // Otherwise this won't be considered as redeclaration of a block scoped local: + // function foo(x) { + // let x; + // } + // 'x' will be placed into the function locals and 'let x' - into the locals of the block + return isFunctionLike(node.parent) ? ContainerFlags.None : ContainerFlags.IsBlockScopedContainer; + } + + return ContainerFlags.None; + } + + function addContainerToEndOfChain() { + if (lastContainer) { + lastContainer.nextContainer = container; + } + + lastContainer = container; + } + + function declareSymbolAndAddToSymbolTable(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): void { declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes); - return symbolFlags; } function declareSymbolAndAddToSymbolTableWorker(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { @@ -381,7 +435,7 @@ module ts { } } - function bindModuleDeclaration(node: ModuleDeclaration) { + function bindModuleDeclaration(node: ModuleDeclaration): void { setExportContextFlag(node); if (node.name.kind === SyntaxKind.StringLiteral) { return declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); @@ -392,7 +446,7 @@ module ts { return declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); } else { - let result = declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); + declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly; if (node.symbol.constEnumOnlyModule === undefined) { @@ -403,13 +457,11 @@ module ts { // merged case: module is const enum only if all its pieces are non-instantiated or const enum node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly; } - - return result; } } } - function bindFunctionOrConstructorType(node: SignatureDeclaration): SymbolFlags { + function bindFunctionOrConstructorType(node: SignatureDeclaration): void { // For a given function symbol "<...>(...) => T" we want to generate a symbol identical // to the one we would get for: { <...>(...): T } // @@ -423,17 +475,14 @@ module ts { let typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); typeLiteralSymbol.members = { [name]: symbol }; - - return SymbolFlags.Signature; } - function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string): SymbolFlags { + function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string): void { let symbol = createSymbol(symbolFlags, name); addDeclarationToSymbol(symbol, node, symbolFlags); - return symbolFlags; } - function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): SymbolFlags { + function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): void { switch (blockScopeContainer.kind) { case SyntaxKind.ModuleDeclaration: declareModuleMember(node, symbolFlags, symbolExcludes); @@ -450,11 +499,9 @@ module ts { } declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes); } - - return symbolFlags; } - function bindBlockScopedVariableDeclaration(node: Declaration): SymbolFlags { + function bindBlockScopedVariableDeclaration(node: Declaration): void { return bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); } @@ -477,16 +524,16 @@ module ts { // // However, not all symbols will end up in any of these tables. 'Anonymous' symbols // (like TypeLiterals for example) will not be put in any table. - var symbolFlags = bindWorker(node); + bindWorker(node); // Then we recurse into the children of the node to bind them as well. For certain // symbols we do specialized work when we recurse. For example, we'll keep track of // the current 'container' node when it changes. This helps us know which symbol table // a local should go into for example. - bindChildren(node, symbolFlags); + bindChildren(node); } - function bindWorker(node: Node): SymbolFlags { + function bindWorker(node: Node): void { switch (node.kind) { case SyntaxKind.TypeParameter: return declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); @@ -557,34 +604,17 @@ module ts { return bindExportAssignment(node); case SyntaxKind.SourceFile: return bindSourceFileIfExternalModule(); - case SyntaxKind.Block: - // do not treat function block a block-scope container - // all block-scope locals that reside in this block should go to the function locals. - // Otherwise this won't be considered as redeclaration of a block scoped local: - // function foo(x) { - // let x; - // } - // 'x' will be placed into the function locals and 'let x' - into the locals of the block - return isFunctionLike(node.parent) ? SymbolFlags.None : SymbolFlags.BlockScopedContainer; - case SyntaxKind.CatchClause: - case SyntaxKind.ForStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.CaseBlock: - return SymbolFlags.BlockScopedContainer; } - - return SymbolFlags.None; } - function bindSourceFileIfExternalModule() { + function bindSourceFileIfExternalModule(): void { setExportContextFlag(file); - return isExternalModule(file) - ? bindAnonymousDeclaration(file, SymbolFlags.ValueModule, '"' + removeFileExtension(file.fileName) + '"') - : SymbolFlags.BlockScopedContainer; + if (isExternalModule(file)) { + bindAnonymousDeclaration(file, SymbolFlags.ValueModule, '"' + removeFileExtension(file.fileName) + '"'); + } } - function bindExportAssignment(node: ExportAssignment) { + function bindExportAssignment(node: ExportAssignment): void { if (node.expression.kind === SyntaxKind.Identifier) { // An export default clause with an identifier exports all meanings of that identifier declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); @@ -593,25 +623,22 @@ module ts { // An export default clause with an expression exports a value declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); } - - return SymbolFlags.None; } - function bindExportDeclaration(node: ExportDeclaration) { + function bindExportDeclaration(node: ExportDeclaration): void { if (!node.exportClause) { // All export * declarations are collected in an __export symbol declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, SymbolFlags.None); } - return SymbolFlags.None; } - function bindImportClause(node: ImportClause) { - return node.name - ? declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes) - : SymbolFlags.None; + function bindImportClause(node: ImportClause): void { + if (node.name) { + declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + } } - function bindClassLikeDeclaration(node: ClassLikeDeclaration) { + function bindClassLikeDeclaration(node: ClassLikeDeclaration): void { if (node.kind === SyntaxKind.ClassDeclaration) { bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); } @@ -640,29 +667,26 @@ module ts { } symbol.exports[prototypeSymbol.name] = prototypeSymbol; prototypeSymbol.parent = symbol; - - return SymbolFlags.Class; } - function bindEnumDeclaration(node: EnumDeclaration) { + function bindEnumDeclaration(node: EnumDeclaration): void { return isConst(node) ? declareSymbolAndAddToSymbolTable(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes) : declareSymbolAndAddToSymbolTable(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); } - function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement) { - if (isBindingPattern(node.name)) { - return SymbolFlags.None; - } - else if (isBlockOrCatchScoped(node)) { - return bindBlockScopedVariableDeclaration(node); - } - else { - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); + function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement): void { + if (!isBindingPattern(node.name)) { + if (isBlockOrCatchScoped(node)) { + return bindBlockScopedVariableDeclaration(node); + } + else { + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); + } } } - function bindParameter(node: ParameterDeclaration): SymbolFlags { + function bindParameter(node: ParameterDeclaration): void { if (isBindingPattern(node.name)) { bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node)); } @@ -679,11 +703,9 @@ module ts { let classDeclaration = node.parent.parent; declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); } - - return SymbolFlags.FunctionScopedVariable; } - function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): SymbolFlags { + function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): void { return hasDynamicName(node) ? bindAnonymousDeclaration(node, symbolFlags, "__computed") : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 010b6308348..c55f016704d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1311,7 +1311,6 @@ module ts { UnionProperty = 0x10000000, // Property in union type Optional = 0x20000000, // Optional property ExportStar = 0x40000000, // Export * declaration - BlockScopedContainer = 0x80000000, Enum = RegularEnum | ConstEnum, Variable = FunctionScopedVariable | BlockScopedVariable, @@ -1350,12 +1349,9 @@ module ts { ExportHasLocal = Function | Class | Enum | ValueModule, - HasLocals = Function | Module | Method | Constructor | Accessor | Signature, HasExports = Class | Enum | Module, HasMembers = Class | Interface | TypeLiteral | ObjectLiteral, - IsBlockScopedContainer = BlockScopedContainer | Module | Function | Accessor | Method | Constructor, - IsContainer = HasLocals | HasExports | HasMembers, PropertyOrAccessor = Property | Accessor, Export = ExportNamespace | ExportType | ExportValue, } From 602c5c8fa93d08d6fe8957bdc104e9296aa0c651 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 20 Apr 2015 23:33:13 -0700 Subject: [PATCH 026/194] Add explanatory comments. --- src/compiler/binder.ts | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 612b957cf4a..dbe705fbe35 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -246,16 +246,37 @@ module ts { // the getLocalNameOfContainer function in the type checker to validate that the local name // used for a container is unique. function bindChildren(node: Node): void { + // Before we recurse into a node's chilren, we first save the existing parent, container + // and block-container. Then after we pop out of processing the children, we restore + // these saved values. let saveParent = parent; let saveContainer = container; let savedBlockScopeContainer = blockScopeContainer; - parent = node; + // This node will now be set as the parent of all of its children as we recurse into them. + parent = node; + + // Depending on what kind of node this is, we may have to adjust the current container + // and block-container. If the current node is a container, then it is automatically + // considered the current block-container as well. Also, for containers that we know + // may contain locals, we proactively initialize the .locals field. We do this because + // it's highly likely that the .locals will be need to place some child in (for example, + // a parameter, or variable declaration). + // + // However, we do not proactively create the locals for block-containers because it's + // totally normal and common for block-containers to never actually have a block-scoped + // variable in them. We don't want to end up allocating an object for every 'block' we + // run into when most of them won't be necessary. + // + // Finally, if this is a block-container, then we clear out any existing locals object + // it may contain within it. This happens in incremental scenarios. Because we can be + // reusing a node from a previous compilation, that node may have had 'locals' created + // for it. We must clear this so we don't accidently move any stale data forward from + // a previous compilation. let containerFlags = getContainerFlags(node); if (containerFlags & ContainerFlags.IsContainer) { container = blockScopeContainer = node; - // If this is a container that also has locals, initialize them now. if (containerFlags & ContainerFlags.HasLocals) { container.locals = {}; } From 60d0b1444d16c18befe2acf3192121f926eb176e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 20 Apr 2015 23:34:19 -0700 Subject: [PATCH 027/194] CR feedback. --- src/compiler/binder.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index dbe705fbe35..0ffd60b81c7 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -372,9 +372,6 @@ module ts { return declareClassMember(node, symbolFlags, symbolExcludes); case SyntaxKind.EnumDeclaration: - // Enum members are always put in the 'exports' of the containing enum. - // They are only accessible through their container, and are never in - // scope otherwise (even inside the body of the enum declaring them.). return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); case SyntaxKind.TypeLiteral: @@ -401,11 +398,10 @@ module ts { case SyntaxKind.ArrowFunction: // All the children of these container types are never visible through another // symbol (i.e. through another symbol's 'exports' or 'members'). Instead, - // more or less, they're only accessed 'lexically' (i.e. from code that exists - // underneath their container in the tree. To accomplish this, we simply add - // their declared symbol to the 'locals' of the container. These symbols can - // then be found as the type checker walks up the containers, checking them - // for matching names. + // they're only accessed 'lexically' (i.e. from code that exists underneath + // their container in the tree. To accomplish this, we simply add their declared + // symbol to the 'locals' of the container. These symbols can then be found as + // the type checker walks up the containers, checking them for matching names. return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } From d220b7ebb4827d76ec3c4f79a19760a0bac77c82 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 20 Apr 2015 23:43:54 -0700 Subject: [PATCH 028/194] Add explanatory comments. --- src/compiler/binder.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 0ffd60b81c7..eeee76c3761 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -53,11 +53,27 @@ module ts { } const enum ContainerFlags { - None = 0, - IsContainer = 0x01, - IsBlockScopedContainer = 0x02, + // The current node is not a container, and no container manipulation should happen before + // recursing into it. + None = 0, + + // The current node is a container. It should be set as the current container (and block- + // container) before recursing into it. The current node does not have locals. Examples: + // + // Classes, ObjectLiterals, TypeLiterals, Interfaces... + IsContainer = 0x01, + + // The current node is a block-scoped-container. It should be set as the current block- + // container before recursing into it. Examples: + // + // Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements... + IsBlockScopedContainer = 0x02, + HasLocals = 0x04, + // If the current node is a container that also container that also contains locals. Examples: + // + // Functions, Methods, Modules, Source-files. IsContainerWithLocals = IsContainer | HasLocals } From 0a144e1806087bcd2ffbd81f6d44a5345bfc85a6 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 20 Apr 2015 23:44:33 -0700 Subject: [PATCH 029/194] Add explicit return to indicate the end of flow of a method.' --- src/compiler/binder.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index eeee76c3761..e20b7aca0e8 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -96,6 +96,8 @@ module ts { file.symbolCount = symbolCount; } + return; + function createSymbol(flags: SymbolFlags, name: string): Symbol { symbolCount++; return new Symbol(flags, name); From b1417d408dce2cd820ec937953b61298d0fcb481 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 20 Apr 2015 23:47:42 -0700 Subject: [PATCH 030/194] Clean up comment. --- src/compiler/binder.ts | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e20b7aca0e8..b4a993a805e 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -322,7 +322,7 @@ module ts { case SyntaxKind.TypeLiteral: case SyntaxKind.ObjectLiteralExpression: return ContainerFlags.IsContainer; - + case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: @@ -348,13 +348,19 @@ module ts { return ContainerFlags.IsBlockScopedContainer; case SyntaxKind.Block: - // do not treat function block a block-scope container - // all block-scope locals that reside in this block should go to the function locals. - // Otherwise this won't be considered as redeclaration of a block scoped local: - // function foo(x) { - // let x; - // } - // 'x' will be placed into the function locals and 'let x' - into the locals of the block + // do not treat function block a block-scope container. All block-scope locals + // that reside in this block should go to the function locals. Otherwise this + // wouldn't be considered as redeclaration of a block scoped local: + // + // function foo() { + // var x; + // let x; + // } + // + // If we placed 'var x' into the function locals and 'let x' - into the locals of + // the block, then there would be no collision. By doing this, we ensure that both + // 'var x' and 'let x' go into the Function-container's locals, and we do get a + // collision conflict. return isFunctionLike(node.parent) ? ContainerFlags.None : ContainerFlags.IsBlockScopedContainer; } From b81a2c00ba4c3d5604c1305f1f129ca37a7eec7c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 20 Apr 2015 23:52:46 -0700 Subject: [PATCH 031/194] Clean up comment. --- src/compiler/binder.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b4a993a805e..ad5ca83585e 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -348,19 +348,19 @@ module ts { return ContainerFlags.IsBlockScopedContainer; case SyntaxKind.Block: - // do not treat function block a block-scope container. All block-scope locals + // do not treat blocks directly inside a function as a block-scoped-container. // that reside in this block should go to the function locals. Otherwise this // wouldn't be considered as redeclaration of a block scoped local: // - // function foo() { - // var x; - // let x; - // } + // function foo() { + // var x; + // let x; + // } // // If we placed 'var x' into the function locals and 'let x' - into the locals of - // the block, then there would be no collision. By doing this, we ensure that both - // 'var x' and 'let x' go into the Function-container's locals, and we do get a - // collision conflict. + // the block, then there would be no collision. By not creating a new block- + // scoped-container here, we ensure that both 'var x' and 'let x' go into the + // Function - container's locals, and we do get a collision conflict. return isFunctionLike(node.parent) ? ContainerFlags.None : ContainerFlags.IsBlockScopedContainer; } From 93b7c33347b171382c19c90cb3ae9787a198fa91 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 20 Apr 2015 23:54:05 -0700 Subject: [PATCH 032/194] Remove unnecessary returns. --- src/compiler/binder.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index ad5ca83585e..6a3b410df30 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -479,12 +479,12 @@ module ts { function bindModuleDeclaration(node: ModuleDeclaration): void { setExportContextFlag(node); if (node.name.kind === SyntaxKind.StringLiteral) { - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); + declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); } else { let state = getModuleInstanceState(node); if (state === ModuleInstanceState.NonInstantiated) { - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); + declareSymbolAndAddToSymbolTable(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); } else { declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); @@ -543,7 +543,7 @@ module ts { } function bindBlockScopedVariableDeclaration(node: Declaration): void { - return bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); + bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); } function getDestructuringParameterName(node: Declaration) { @@ -719,10 +719,10 @@ module ts { function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement): void { if (!isBindingPattern(node.name)) { if (isBlockOrCatchScoped(node)) { - return bindBlockScopedVariableDeclaration(node); + bindBlockScopedVariableDeclaration(node); } else { - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); + declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); } } } From fac9ab2508d299d8a873692c4f71f5ccf2adba5a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 20 Apr 2015 23:56:38 -0700 Subject: [PATCH 033/194] Clean up comment more. --- src/compiler/binder.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 6a3b410df30..ed318e1804e 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -349,18 +349,21 @@ module ts { case SyntaxKind.Block: // do not treat blocks directly inside a function as a block-scoped-container. - // that reside in this block should go to the function locals. Otherwise this - // wouldn't be considered as redeclaration of a block scoped local: + // that reside in this block should go to the function locals. Othewise 'x' + // would not appear to be a redeclaration of a block scoped local in the following + // example: // // function foo() { // var x; // let x; // } // - // If we placed 'var x' into the function locals and 'let x' - into the locals of - // the block, then there would be no collision. By not creating a new block- - // scoped-container here, we ensure that both 'var x' and 'let x' go into the - // Function - container's locals, and we do get a collision conflict. + // If we placed 'var x' into the function locals and 'let x' into the locals of + // the block, then there would be no collision. + // + // By not creating a new block-scoped-container here, we ensure that both 'var x' + // and 'let x' go into the Function-container's locals, and we do get a collision + // conflict. return isFunctionLike(node.parent) ? ContainerFlags.None : ContainerFlags.IsBlockScopedContainer; } From a93bf1048da11678b6cde0c40f0dd445b611e0f8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 Apr 2015 00:01:06 -0700 Subject: [PATCH 034/194] Clean up comment. --- src/compiler/binder.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index ed318e1804e..40168900a6d 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -278,15 +278,15 @@ module ts { // and block-container. If the current node is a container, then it is automatically // considered the current block-container as well. Also, for containers that we know // may contain locals, we proactively initialize the .locals field. We do this because - // it's highly likely that the .locals will be need to place some child in (for example, + // it's highly likely that the .locals will be needed to place some child in (for example, // a parameter, or variable declaration). // - // However, we do not proactively create the locals for block-containers because it's + // However, we do not proactively create the .locals for block-containers because it's // totally normal and common for block-containers to never actually have a block-scoped // variable in them. We don't want to end up allocating an object for every 'block' we // run into when most of them won't be necessary. // - // Finally, if this is a block-container, then we clear out any existing locals object + // Finally, if this is a block-container, then we clear out any existing .locals object // it may contain within it. This happens in incremental scenarios. Because we can be // reusing a node from a previous compilation, that node may have had 'locals' created // for it. We must clear this so we don't accidently move any stale data forward from From cf00a2bec859eaffa8d82698e57350a149bb2aa4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 Apr 2015 00:05:08 -0700 Subject: [PATCH 035/194] Clean up comment. --- src/compiler/binder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 40168900a6d..d0bb5edd489 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -349,7 +349,7 @@ module ts { case SyntaxKind.Block: // do not treat blocks directly inside a function as a block-scoped-container. - // that reside in this block should go to the function locals. Othewise 'x' + // Locals that reside in this block should go to the function locals. Othewise 'x' // would not appear to be a redeclaration of a block scoped local in the following // example: // From ca63d6429297d450df796573be4c724a50cbfb65 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 Apr 2015 12:59:22 -0700 Subject: [PATCH 036/194] CR feedback. --- src/compiler/binder.ts | 48 ++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d0bb5edd489..daec6fee7df 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -77,13 +77,13 @@ module ts { IsContainerWithLocals = IsContainer | HasLocals } - export function bindSourceFile(file: SourceFile): void { + export function bindSourceFile(file: SourceFile) { let start = new Date().getTime(); bindSourceFileWorker(file); bindTime += new Date().getTime() - start; } - function bindSourceFileWorker(file: SourceFile): void { + function bindSourceFileWorker(file: SourceFile) { let parent: Node; let container: Node; let blockScopeContainer: Node; @@ -263,7 +263,7 @@ module ts { // All container nodes are kept on a linked list in declaration order. This list is used by // the getLocalNameOfContainer function in the type checker to validate that the local name // used for a container is unique. - function bindChildren(node: Node): void { + function bindChildren(node: Node) { // Before we recurse into a node's chilren, we first save the existing parent, container // and block-container. Then after we pop out of processing the children, we restore // these saved values. @@ -378,11 +378,11 @@ module ts { lastContainer = container; } - function declareSymbolAndAddToSymbolTable(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): void { + function declareSymbolAndAddToSymbolTable(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes); } - function declareSymbolAndAddToSymbolTableWorker(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { + function declareSymbolAndAddToSymbolTableWorker(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { switch (container.kind) { // Modules, source files, and classes need specialized handling for how their // members are declared (for example, a member of a class will go into a specific @@ -479,7 +479,7 @@ module ts { } } - function bindModuleDeclaration(node: ModuleDeclaration): void { + function bindModuleDeclaration(node: ModuleDeclaration) { setExportContextFlag(node); if (node.name.kind === SyntaxKind.StringLiteral) { declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); @@ -505,7 +505,7 @@ module ts { } } - function bindFunctionOrConstructorType(node: SignatureDeclaration): void { + function bindFunctionOrConstructorType(node: SignatureDeclaration) { // For a given function symbol "<...>(...) => T" we want to generate a symbol identical // to the one we would get for: { <...>(...): T } // @@ -521,12 +521,12 @@ module ts { typeLiteralSymbol.members = { [name]: symbol }; } - function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string): void { + function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) { let symbol = createSymbol(symbolFlags, name); addDeclarationToSymbol(symbol, node, symbolFlags); } - function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): void { + function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { switch (blockScopeContainer.kind) { case SyntaxKind.ModuleDeclaration: declareModuleMember(node, symbolFlags, symbolExcludes); @@ -545,7 +545,7 @@ module ts { } } - function bindBlockScopedVariableDeclaration(node: Declaration): void { + function bindBlockScopedVariableDeclaration(node: Declaration) { bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); } @@ -553,14 +553,12 @@ module ts { return "__" + indexOf((node.parent).parameters, node); } - function bind(node: Node): void { + function bind(node: Node) { node.parent = parent; // First we bind declaration nodes to a symbol if possible. We'll both create a symbol - // and then potentially add the symbol to an appropriate symbol table. The symbolFlags - // that are returned from this help inform how we recurse into the children of this node. - // - // Possible destination symbol tables are: + // and then potentially add the symbol to an appropriate symbol table. Possible + // destination symbol tables are: // // 1) The 'exports' table of the current container's symbol. // 2) The 'members' table of the current container's symbol. @@ -577,7 +575,7 @@ module ts { bindChildren(node); } - function bindWorker(node: Node): void { + function bindWorker(node: Node) { switch (node.kind) { case SyntaxKind.TypeParameter: return declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); @@ -651,14 +649,14 @@ module ts { } } - function bindSourceFileIfExternalModule(): void { + function bindSourceFileIfExternalModule() { setExportContextFlag(file); if (isExternalModule(file)) { bindAnonymousDeclaration(file, SymbolFlags.ValueModule, '"' + removeFileExtension(file.fileName) + '"'); } } - function bindExportAssignment(node: ExportAssignment): void { + function bindExportAssignment(node: ExportAssignment) { if (node.expression.kind === SyntaxKind.Identifier) { // An export default clause with an identifier exports all meanings of that identifier declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.Alias, SymbolFlags.PropertyExcludes | SymbolFlags.AliasExcludes); @@ -669,20 +667,20 @@ module ts { } } - function bindExportDeclaration(node: ExportDeclaration): void { + function bindExportDeclaration(node: ExportDeclaration) { if (!node.exportClause) { // All export * declarations are collected in an __export symbol declareSymbol(container.symbol.exports, container.symbol, node, SymbolFlags.ExportStar, SymbolFlags.None); } } - function bindImportClause(node: ImportClause): void { + function bindImportClause(node: ImportClause) { if (node.name) { declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); } } - function bindClassLikeDeclaration(node: ClassLikeDeclaration): void { + function bindClassLikeDeclaration(node: ClassLikeDeclaration) { if (node.kind === SyntaxKind.ClassDeclaration) { bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); } @@ -713,13 +711,13 @@ module ts { prototypeSymbol.parent = symbol; } - function bindEnumDeclaration(node: EnumDeclaration): void { + function bindEnumDeclaration(node: EnumDeclaration) { return isConst(node) ? declareSymbolAndAddToSymbolTable(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes) : declareSymbolAndAddToSymbolTable(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes); } - function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement): void { + function bindVariableDeclarationOrBindingElement(node: VariableDeclaration | BindingElement) { if (!isBindingPattern(node.name)) { if (isBlockOrCatchScoped(node)) { bindBlockScopedVariableDeclaration(node); @@ -730,7 +728,7 @@ module ts { } } - function bindParameter(node: ParameterDeclaration): void { + function bindParameter(node: ParameterDeclaration) { if (isBindingPattern(node.name)) { bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node)); } @@ -749,7 +747,7 @@ module ts { } } - function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): void { + function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { return hasDynamicName(node) ? bindAnonymousDeclaration(node, symbolFlags, "__computed") : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); From a54d4154aaad8bce527916a99ce2c4d5fbe3ca54 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 Apr 2015 13:06:40 -0700 Subject: [PATCH 037/194] CR feedback. --- src/compiler/binder.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index daec6fee7df..96cd2fdfdc7 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -61,15 +61,15 @@ module ts { // container) before recursing into it. The current node does not have locals. Examples: // // Classes, ObjectLiterals, TypeLiterals, Interfaces... - IsContainer = 0x01, + IsContainer = 1 << 0, // The current node is a block-scoped-container. It should be set as the current block- // container before recursing into it. Examples: // // Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements... - IsBlockScopedContainer = 0x02, + IsBlockScopedContainer = 1 << 1, - HasLocals = 0x04, + HasLocals = 1 << 2, // If the current node is a container that also container that also contains locals. Examples: // From 70d2938f4fe210616c7320b2afadd73da55943f7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 16 May 2015 11:38:28 -0700 Subject: [PATCH 038/194] Support "exclude" property in tsconfig.json --- src/compiler/commandLineParser.ts | 15 +++++----- src/compiler/sys.ts | 46 +++++++++++++++++++++---------- src/compiler/types.ts | 2 +- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 7a589fe61cb..1de9188aed7 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -343,7 +343,7 @@ module ts { return { options: getCompilerOptions(), - fileNames: getFiles(), + fileNames: getFileNames(), errors }; @@ -389,23 +389,24 @@ module ts { return options; } - function getFiles(): string[] { - var files: string[] = []; + function getFileNames(): string[] { + var fileNames: string[] = []; if (hasProperty(json, "files")) { if (json["files"] instanceof Array) { - var files = map(json["files"], s => combinePaths(basePath, s)); + fileNames = map(json["files"], s => combinePaths(basePath, s)); } } else { - var sysFiles = host.readDirectory(basePath, ".ts"); + var exclude = json["exclude"] instanceof Array ? map(json["exclude"], normalizeSlashes) : undefined; + var sysFiles = host.readDirectory(basePath, ".ts", exclude); for (var i = 0; i < sysFiles.length; i++) { var name = sysFiles[i]; if (!fileExtensionIs(name, ".d.ts") || !contains(sysFiles, name.substr(0, name.length - 5) + ".ts")) { - files.push(name); + fileNames.push(name); } } } - return files; + return fileNames; } } } diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index f9daf52c5f2..8f246540c61 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -15,7 +15,7 @@ module ts { createDirectory(path: string): void; getExecutingFilePath(): string; getCurrentDirectory(): string; - readDirectory(path: string, extension?: string): string[]; + readDirectory(path: string, extension?: string, exclude?: string[]): string[]; getMemoryUsage?(): number; exit(exitCode?: number): void; } @@ -109,7 +109,11 @@ module ts { } } - function getNames(collection: any): string[] { + function getCanonicalPath(path: string): string { + return path.toLowerCase(); + } + + function getNames(collection: any): string[]{ var result: string[] = []; for (var e = new Enumerator(collection); !e.atEnd(); e.moveNext()) { result.push(e.item().Name); @@ -117,21 +121,26 @@ module ts { return result.sort(); } - function readDirectory(path: string, extension?: string): string[] { + function readDirectory(path: string, extension?: string, exclude?: string[]): string[] { var result: string[] = []; + exclude = map(exclude, s => getCanonicalPath(combinePaths(path, s))); visitDirectory(path); return result; function visitDirectory(path: string) { var folder = fso.GetFolder(path || "."); var files = getNames(folder.files); - for (let name of files) { - if (!extension || fileExtensionIs(name, extension)) { - result.push(combinePaths(path, name)); + for (let current of files) { + let name = combinePaths(path, current); + if ((!extension || fileExtensionIs(name, extension)) && !contains(exclude, getCanonicalPath(name))) { + result.push(name); } } var subfolders = getNames(folder.subfolders); for (let current of subfolders) { - visitDirectory(combinePaths(path, current)); + let name = combinePaths(path, current); + if (!contains(exclude, getCanonicalPath(name))) { + visitDirectory(name); + } } } } @@ -222,8 +231,13 @@ module ts { _fs.writeFileSync(fileName, data, "utf8"); } - function readDirectory(path: string, extension?: string): string[] { + function getCanonicalPath(path: string): string { + return useCaseSensitiveFileNames ? path.toLowerCase() : path; + } + + function readDirectory(path: string, extension?: string, exclude?: string[]): string[] { var result: string[] = []; + exclude = map(exclude, s => getCanonicalPath(combinePaths(path, s))); visitDirectory(path); return result; function visitDirectory(path: string) { @@ -231,14 +245,16 @@ module ts { var directories: string[] = []; for (let current of files) { var name = combinePaths(path, current); - var stat = _fs.lstatSync(name); - if (stat.isFile()) { - if (!extension || fileExtensionIs(name, extension)) { - result.push(name); + if (!contains(exclude, getCanonicalPath(name))) { + var stat = _fs.lstatSync(name); + if (stat.isFile()) { + if (!extension || fileExtensionIs(name, extension)) { + result.push(name); + } + } + else if (stat.isDirectory()) { + directories.push(name); } - } - else if (stat.isDirectory()) { - directories.push(name); } } for (let current of directories) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 86e680ca8b0..831cc26eedf 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1035,7 +1035,7 @@ module ts { } export interface ParseConfigHost { - readDirectory(rootDir: string, extension: string): string[]; + readDirectory(rootDir: string, extension: string, exclude: string[]): string[]; } export interface WriteFileCallback { From 1da04ba8f4b3146ae26eafc00e2355586759cdc4 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 18 May 2015 21:49:41 -0700 Subject: [PATCH 039/194] Change flag --singleCompilation to --isolatedModules --- src/compiler/checker.ts | 14 +++++++------- src/compiler/commandLineParser.ts | 2 +- .../diagnosticInformationMap.generated.ts | 14 +++++++------- src/compiler/diagnosticMessages.json | 14 +++++++------- src/compiler/emitter.ts | 8 ++++---- src/compiler/program.ts | 16 ++++++++-------- src/compiler/types.ts | 2 +- src/compiler/utilities.ts | 2 +- src/harness/harness.ts | 12 ++++++------ src/services/services.ts | 4 ++-- ...eparateCompilationAmbientConstEnum.errors.txt | 4 ++-- .../separateCompilationDeclaration.errors.txt | 4 ++-- .../separateCompilationNoEmitOnError.errors.txt | 4 ++-- ...eparateCompilationNoExternalModule.errors.txt | 4 ++-- .../reference/separateCompilationOut.errors.txt | 8 ++++---- .../separateCompilationPlainFile-AMD.errors.txt | 4 ++-- ...arateCompilationPlainFile-CommonJS.errors.txt | 4 ++-- .../separateCompilationPlainFile-ES6.errors.txt | 4 ++-- ...eparateCompilationPlainFile-System.errors.txt | 4 ++-- .../separateCompilationPlainFile-UMD.errors.txt | 4 ++-- .../separateCompilationSourceMap.errors.txt | 4 ++-- ...parateCompilationUnspecifiedModule.errors.txt | 4 ++-- .../separateCompilationAmbientConstEnum.ts | 2 +- .../compiler/separateCompilationDeclaration.ts | 2 +- tests/cases/compiler/separateCompilationES6.ts | 2 +- .../separateCompilationImportExportElision.ts | 2 +- .../compiler/separateCompilationNoEmitOnError.ts | 2 +- .../separateCompilationNoExternalModule.ts | 2 +- .../separateCompilationNonAmbientConstEnum.ts | 2 +- tests/cases/compiler/separateCompilationOut.ts | 2 +- .../compiler/separateCompilationPlainFile-AMD.ts | 2 +- .../separateCompilationPlainFile-CommonJS.ts | 2 +- .../compiler/separateCompilationPlainFile-ES6.ts | 2 +- .../separateCompilationPlainFile-System.ts | 2 +- .../compiler/separateCompilationPlainFile-UMD.ts | 2 +- .../compiler/separateCompilationSourceMap.ts | 2 +- .../separateCompilationSpecifiedModule.ts | 2 +- .../separateCompilationUnspecifiedModule.ts | 2 +- .../separateCompilationWithDeclarationFile.ts | 2 +- tests/cases/compiler/systemModule10.ts | 2 +- tests/cases/compiler/systemModule10_ES5.ts | 2 +- tests/cases/compiler/systemModule11.ts | 2 +- tests/cases/compiler/systemModule9.ts | 2 +- 43 files changed, 91 insertions(+), 91 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7a4ba23ca2a..d956ac189a5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -732,7 +732,7 @@ module ts { let target = resolveAlias(symbol); if (target) { let markAlias = - (target === unknownSymbol && compilerOptions.separateCompilation) || + (target === unknownSymbol && compilerOptions.isolatedModules) || (target !== unknownSymbol && (target.flags & SymbolFlags.Value) && !isConstEnumOrConstEnumOnlyModule(target)); if (markAlias) { @@ -8889,7 +8889,7 @@ module ts { // serialize the type metadata. if (node && node.kind === SyntaxKind.TypeReference) { let type = getTypeFromTypeNode(node); - let shouldCheckIfUnknownType = type === unknownType && compilerOptions.separateCompilation; + let shouldCheckIfUnknownType = type === unknownType && compilerOptions.isolatedModules; if (!type || (!shouldCheckIfUnknownType && type.flags & (TypeFlags.Intrinsic | TypeFlags.NumberLike | TypeFlags.StringLike))) { return; } @@ -10054,7 +10054,7 @@ module ts { } } - if (baseTypes.length || (baseTypeNode && compilerOptions.separateCompilation)) { + if (baseTypes.length || (baseTypeNode && compilerOptions.isolatedModules)) { // Check that base type can be evaluated as expression checkExpressionOrQualifiedName(baseTypeNode.expression); } @@ -10470,8 +10470,8 @@ module ts { computeEnumMemberValues(node); let enumIsConst = isConst(node); - if (compilerOptions.separateCompilation && enumIsConst && isInAmbientContext(node)) { - error(node.name, Diagnostics.Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided); + if (compilerOptions.isolatedModules && enumIsConst && isInAmbientContext(node)) { + error(node.name, Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided); } // Spec 2014 - Section 9.3: @@ -10561,7 +10561,7 @@ module ts { if (symbol.flags & SymbolFlags.ValueModule && symbol.declarations.length > 1 && !isInAmbientContext(node) - && isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation)) { + && isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules)) { let firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol); if (firstNonAmbientClassOrFunc) { if (getSourceFileOfNode(node) !== getSourceFileOfNode(firstNonAmbientClassOrFunc)) { @@ -11661,7 +11661,7 @@ module ts { function isAliasResolvedToValue(symbol: Symbol): boolean { let target = resolveAlias(symbol); - if (target === unknownSymbol && compilerOptions.separateCompilation) { + if (target === unknownSymbol && compilerOptions.isolatedModules) { return true; } // const enums and modules that contain only const enums are not considered values from the emit perespective diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 6a055aebf6a..64784590024 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -142,7 +142,7 @@ module ts { paramType: Diagnostics.LOCATION, }, { - name: "separateCompilation", + name: "isolatedModules", type: "boolean", }, { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 1f8edf8fee3..8dd6ea6dc55 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -165,8 +165,8 @@ module ts { Decorators_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1205, category: DiagnosticCategory.Error, key: "Decorators are only available when targeting ECMAScript 5 and higher." }, Decorators_are_not_valid_here: { code: 1206, category: DiagnosticCategory.Error, key: "Decorators are not valid here." }, Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: { code: 1207, category: DiagnosticCategory.Error, key: "Decorators cannot be applied to multiple get/set accessors of the same name." }, - Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided: { code: 1208, category: DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--separateCompilation' flag is provided." }, - Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided: { code: 1209, category: DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--separateCompilation' flag is provided." }, + Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided: { code: 1208, category: DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--isolatedModules' flag is provided." }, + Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided: { code: 1209, category: DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--isolatedModules' flag is provided." }, Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: { code: 1210, category: DiagnosticCategory.Error, key: "Invalid use of '{0}'. Class definitions are automatically in strict mode." }, A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" }, Identifier_expected_0_is_a_reserved_word_in_strict_mode: { code: 1212, category: DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode" }, @@ -449,11 +449,11 @@ module ts { Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." }, Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." }, Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." }, - Option_sourceMap_cannot_be_specified_with_option_separateCompilation: { code: 5043, category: DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'separateCompilation'." }, - Option_declaration_cannot_be_specified_with_option_separateCompilation: { code: 5044, category: DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'separateCompilation'." }, - Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation: { code: 5045, category: DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'separateCompilation'." }, - Option_out_cannot_be_specified_with_option_separateCompilation: { code: 5046, category: DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'separateCompilation'." }, - Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: DiagnosticCategory.Error, key: "Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." }, + Option_sourceMap_cannot_be_specified_with_option_isolatedModules: { code: 5043, category: DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'isolatedModules'." }, + Option_declaration_cannot_be_specified_with_option_isolatedModules: { code: 5044, category: DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'isolatedModules'." }, + Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules: { code: 5045, category: DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'isolatedModules'." }, + Option_out_cannot_be_specified_with_option_isolatedModules: { code: 5046, category: DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'isolatedModules'." }, + Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: DiagnosticCategory.Error, key: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." }, Option_sourceMap_cannot_be_specified_with_option_inlineSourceMap: { code: 5048, category: DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'inlineSourceMap'." }, Option_sourceRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5049, category: DiagnosticCategory.Error, key: "Option 'sourceRoot' cannot be specified with option 'inlineSourceMap'." }, Option_mapRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5050, category: DiagnosticCategory.Error, key: "Option 'mapRoot' cannot be specified with option 'inlineSourceMap'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 42eae83e269..416936e741b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -647,11 +647,11 @@ "category": "Error", "code": 1207 }, - "Cannot compile namespaces when the '--separateCompilation' flag is provided.": { + "Cannot compile namespaces when the '--isolatedModules' flag is provided.": { "category": "Error", "code": 1208 }, - "Ambient const enums are not allowed when the '--separateCompilation' flag is provided.": { + "Ambient const enums are not allowed when the '--isolatedModules' flag is provided.": { "category": "Error", "code": 1209 }, @@ -1785,23 +1785,23 @@ "category": "Error", "code": 5042 }, - "Option 'sourceMap' cannot be specified with option 'separateCompilation'.": { + "Option 'sourceMap' cannot be specified with option 'isolatedModules'.": { "category": "Error", "code": 5043 }, - "Option 'declaration' cannot be specified with option 'separateCompilation'.": { + "Option 'declaration' cannot be specified with option 'isolatedModules'.": { "category": "Error", "code": 5044 }, - "Option 'noEmitOnError' cannot be specified with option 'separateCompilation'.": { + "Option 'noEmitOnError' cannot be specified with option 'isolatedModules'.": { "category": "Error", "code": 5045 }, - "Option 'out' cannot be specified with option 'separateCompilation'.": { + "Option 'out' cannot be specified with option 'isolatedModules'.": { "category": "Error", "code": 5046 }, - "Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher.": { + "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher.": { "category": "Error", "code": 5047 }, diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6d5146a6801..e1e6cba2175 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1714,7 +1714,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } function tryEmitConstantValue(node: PropertyAccessExpression | ElementAccessExpression): boolean { - if (compilerOptions.separateCompilation) { + if (compilerOptions.isolatedModules) { // do not inline enum values in separate compilation mode return false; } @@ -4364,7 +4364,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { function shouldEmitEnumDeclaration(node: EnumDeclaration) { let isConstEnum = isConst(node); - return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.separateCompilation; + return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.isolatedModules; } function emitEnumDeclaration(node: EnumDeclaration) { @@ -4456,7 +4456,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } function shouldEmitModuleDeclaration(node: ModuleDeclaration) { - return isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation); + return isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules); } function isModuleMergedWithES6Class(node: ModuleDeclaration) { @@ -5631,7 +5631,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } } - if (isExternalModule(node) || compilerOptions.separateCompilation) { + if (isExternalModule(node) || compilerOptions.isolatedModules) { if (languageVersion >= ScriptTarget.ES6) { emitES6Module(node, startIndex); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 3bd4bdc7ac0..bf554384241 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -529,21 +529,21 @@ module ts { } function verifyCompilerOptions() { - if (options.separateCompilation) { + if (options.isolatedModules) { if (options.sourceMap) { - diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_sourceMap_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_sourceMap_cannot_be_specified_with_option_isolatedModules)); } if (options.declaration) { - diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_declaration_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_declaration_cannot_be_specified_with_option_isolatedModules)); } if (options.noEmitOnError) { - diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules)); } if (options.out) { - diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_out_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_out_cannot_be_specified_with_option_isolatedModules)); } } @@ -580,15 +580,15 @@ module ts { let languageVersion = options.target || ScriptTarget.ES3; let firstExternalModuleSourceFile = forEach(files, f => isExternalModule(f) ? f : undefined); - if (options.separateCompilation) { + if (options.isolatedModules) { if (!options.module && languageVersion < ScriptTarget.ES6) { - diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher)); + diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher)); } let firstNonExternalModuleSourceFile = forEach(files, f => !isExternalModule(f) && !isDeclarationFile(f) ? f : undefined); if (firstNonExternalModuleSourceFile) { let span = getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile); - diagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided)); + diagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided)); } } else if (firstExternalModuleSourceFile && languageVersion < ScriptTarget.ES6 && !options.module) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 86e680ca8b0..a6fa89846bb 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1676,7 +1676,7 @@ module ts { target?: ScriptTarget; version?: boolean; watch?: boolean; - separateCompilation?: boolean; + isolatedModules?: boolean; emitDecoratorMetadata?: boolean; /* @internal */ stripInternal?: boolean; [option: string]: string | number | boolean; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0bb0065d1b0..3ded0a7cfd9 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1438,7 +1438,7 @@ module ts { if ((isExternalModule(sourceFile) || !compilerOptions.out)) { // 1. in-browser single file compilation scenario // 2. non .js file - return compilerOptions.separateCompilation || !fileExtensionIs(sourceFile.fileName, ".js"); + return compilerOptions.isolatedModules || !fileExtensionIs(sourceFile.fileName, ".js"); } return false; } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 9ed515eb5b6..63eff36b30a 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -45,10 +45,10 @@ module Utils { export function getExecutionEnvironment() { if (typeof WScript !== "undefined" && typeof ActiveXObject === "function") { return ExecutionEnvironment.CScript; - } else if (typeof window !== "undefined") { + } else if (typeof window !== "undefined") { return ExecutionEnvironment.Browser; - } else { - return ExecutionEnvironment.Node; + } else { + return ExecutionEnvironment.Node; } } @@ -1092,8 +1092,8 @@ module Harness { options.preserveConstEnums = setting.value === 'true'; break; - case 'separatecompilation': - options.separateCompilation = setting.value === 'true'; + case 'isolatedmodules': + options.isolatedModules = setting.value === 'true'; break; case 'suppressimplicitanyindexerrors': @@ -1509,7 +1509,7 @@ module Harness { "noimplicitany", "noresolve", "newline", "normalizenewline", "emitbom", "errortruncation", "usecasesensitivefilenames", "preserveconstenums", "includebuiltfile", "suppressimplicitanyindexerrors", "stripinternal", - "separatecompilation", "inlinesourcemap", "maproot", "sourceroot", + "isolatedmodules", "inlinesourcemap", "maproot", "sourceroot", "inlinesources", "emitdecoratormetadata"]; function extractCompilerSettings(content: string): CompilerSetting[] { diff --git a/src/services/services.ts b/src/services/services.ts index bec00b9a66a..c805b0c7eea 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1760,13 +1760,13 @@ module ts { * This function will compile source text from 'input' argument using specified compiler options. * If not options are provided - it will use a set of default compiler options. * Extra compiler options that will unconditionally be used bu this function are: - * - separateCompilation = true + * - isolatedModules = true * - allowNonTsExtensions = true */ export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[]): string { let options = compilerOptions ? clone(compilerOptions) : getDefaultCompilerOptions(); - options.separateCompilation = true; + options.isolatedModules = true; // Filename can be non-ts file. options.allowNonTsExtensions = true; diff --git a/tests/baselines/reference/separateCompilationAmbientConstEnum.errors.txt b/tests/baselines/reference/separateCompilationAmbientConstEnum.errors.txt index 6ea2e445e29..ea55115e957 100644 --- a/tests/baselines/reference/separateCompilationAmbientConstEnum.errors.txt +++ b/tests/baselines/reference/separateCompilationAmbientConstEnum.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/separateCompilationAmbientConstEnum.ts(3,20): error TS1209: Ambient const enums are not allowed when the '--separateCompilation' flag is provided. +tests/cases/compiler/separateCompilationAmbientConstEnum.ts(3,20): error TS1209: Ambient const enums are not allowed when the '--isolatedModules' flag is provided. ==== tests/cases/compiler/separateCompilationAmbientConstEnum.ts (1 errors) ==== @@ -6,5 +6,5 @@ tests/cases/compiler/separateCompilationAmbientConstEnum.ts(3,20): error TS1209: declare const enum E { X = 1} ~ -!!! error TS1209: Ambient const enums are not allowed when the '--separateCompilation' flag is provided. +!!! error TS1209: Ambient const enums are not allowed when the '--isolatedModules' flag is provided. export var y; \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationDeclaration.errors.txt b/tests/baselines/reference/separateCompilationDeclaration.errors.txt index 8951184584c..107d917c751 100644 --- a/tests/baselines/reference/separateCompilationDeclaration.errors.txt +++ b/tests/baselines/reference/separateCompilationDeclaration.errors.txt @@ -1,7 +1,7 @@ -error TS5044: Option 'declaration' cannot be specified with option 'separateCompilation'. +error TS5044: Option 'declaration' cannot be specified with option 'isolatedModules'. -!!! error TS5044: Option 'declaration' cannot be specified with option 'separateCompilation'. +!!! error TS5044: Option 'declaration' cannot be specified with option 'isolatedModules'. ==== tests/cases/compiler/separateCompilationDeclaration.ts (0 errors) ==== export var x; \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationNoEmitOnError.errors.txt b/tests/baselines/reference/separateCompilationNoEmitOnError.errors.txt index 61d4f2d6d9e..ddb471cef49 100644 --- a/tests/baselines/reference/separateCompilationNoEmitOnError.errors.txt +++ b/tests/baselines/reference/separateCompilationNoEmitOnError.errors.txt @@ -1,7 +1,7 @@ -error TS5045: Option 'noEmitOnError' cannot be specified with option 'separateCompilation'. +error TS5045: Option 'noEmitOnError' cannot be specified with option 'isolatedModules'. -!!! error TS5045: Option 'noEmitOnError' cannot be specified with option 'separateCompilation'. +!!! error TS5045: Option 'noEmitOnError' cannot be specified with option 'isolatedModules'. ==== tests/cases/compiler/separateCompilationNoEmitOnError.ts (0 errors) ==== export var x; \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationNoExternalModule.errors.txt b/tests/baselines/reference/separateCompilationNoExternalModule.errors.txt index 71d7da73a80..7c242e90f12 100644 --- a/tests/baselines/reference/separateCompilationNoExternalModule.errors.txt +++ b/tests/baselines/reference/separateCompilationNoExternalModule.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/separateCompilationNoExternalModule.ts(2,1): error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +tests/cases/compiler/separateCompilationNoExternalModule.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. ==== tests/cases/compiler/separateCompilationNoExternalModule.ts (1 errors) ==== var x; ~~~ -!!! error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. \ No newline at end of file +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationOut.errors.txt b/tests/baselines/reference/separateCompilationOut.errors.txt index 9017809901f..8234ba94585 100644 --- a/tests/baselines/reference/separateCompilationOut.errors.txt +++ b/tests/baselines/reference/separateCompilationOut.errors.txt @@ -1,12 +1,12 @@ -error TS5046: Option 'out' cannot be specified with option 'separateCompilation'. -tests/cases/compiler/file2.ts(1,1): error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +error TS5046: Option 'out' cannot be specified with option 'isolatedModules'. +tests/cases/compiler/file2.ts(1,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. -!!! error TS5046: Option 'out' cannot be specified with option 'separateCompilation'. +!!! error TS5046: Option 'out' cannot be specified with option 'isolatedModules'. ==== tests/cases/compiler/file1.ts (0 errors) ==== export var x; ==== tests/cases/compiler/file2.ts (1 errors) ==== var y; ~~~ -!!! error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. \ No newline at end of file +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-AMD.errors.txt b/tests/baselines/reference/separateCompilationPlainFile-AMD.errors.txt index 6b80da30d33..329299f5130 100644 --- a/tests/baselines/reference/separateCompilationPlainFile-AMD.errors.txt +++ b/tests/baselines/reference/separateCompilationPlainFile-AMD.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/separateCompilationPlainFile-AMD.ts(2,1): error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +tests/cases/compiler/separateCompilationPlainFile-AMD.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. ==== tests/cases/compiler/separateCompilationPlainFile-AMD.ts (1 errors) ==== declare function run(a: number): void; ~~~~~~~ -!!! error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. run(1); \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-CommonJS.errors.txt b/tests/baselines/reference/separateCompilationPlainFile-CommonJS.errors.txt index 48a23a39653..e72a4a76b71 100644 --- a/tests/baselines/reference/separateCompilationPlainFile-CommonJS.errors.txt +++ b/tests/baselines/reference/separateCompilationPlainFile-CommonJS.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/separateCompilationPlainFile-CommonJS.ts(2,1): error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +tests/cases/compiler/separateCompilationPlainFile-CommonJS.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. ==== tests/cases/compiler/separateCompilationPlainFile-CommonJS.ts (1 errors) ==== declare function run(a: number): void; ~~~~~~~ -!!! error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. run(1); \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-ES6.errors.txt b/tests/baselines/reference/separateCompilationPlainFile-ES6.errors.txt index b0b059c73bd..602d41ce948 100644 --- a/tests/baselines/reference/separateCompilationPlainFile-ES6.errors.txt +++ b/tests/baselines/reference/separateCompilationPlainFile-ES6.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/separateCompilationPlainFile-ES6.ts(2,1): error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +tests/cases/compiler/separateCompilationPlainFile-ES6.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. ==== tests/cases/compiler/separateCompilationPlainFile-ES6.ts (1 errors) ==== declare function run(a: number): void; ~~~~~~~ -!!! error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. run(1); \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-System.errors.txt b/tests/baselines/reference/separateCompilationPlainFile-System.errors.txt index c3161c57275..a6d14edd61a 100644 --- a/tests/baselines/reference/separateCompilationPlainFile-System.errors.txt +++ b/tests/baselines/reference/separateCompilationPlainFile-System.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/separateCompilationPlainFile-System.ts(2,1): error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +tests/cases/compiler/separateCompilationPlainFile-System.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. ==== tests/cases/compiler/separateCompilationPlainFile-System.ts (1 errors) ==== declare function run(a: number): void; ~~~~~~~ -!!! error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. run(1); \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-UMD.errors.txt b/tests/baselines/reference/separateCompilationPlainFile-UMD.errors.txt index 6a0fb1ac8df..d15098a96c1 100644 --- a/tests/baselines/reference/separateCompilationPlainFile-UMD.errors.txt +++ b/tests/baselines/reference/separateCompilationPlainFile-UMD.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/separateCompilationPlainFile-UMD.ts(2,1): error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +tests/cases/compiler/separateCompilationPlainFile-UMD.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. ==== tests/cases/compiler/separateCompilationPlainFile-UMD.ts (1 errors) ==== declare function run(a: number): void; ~~~~~~~ -!!! error TS1208: Cannot compile namespaces when the '--separateCompilation' flag is provided. +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. run(1); \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationSourceMap.errors.txt b/tests/baselines/reference/separateCompilationSourceMap.errors.txt index 5274ef3921e..56fc5b5cb85 100644 --- a/tests/baselines/reference/separateCompilationSourceMap.errors.txt +++ b/tests/baselines/reference/separateCompilationSourceMap.errors.txt @@ -1,7 +1,7 @@ -error TS5043: Option 'sourceMap' cannot be specified with option 'separateCompilation'. +error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModules'. -!!! error TS5043: Option 'sourceMap' cannot be specified with option 'separateCompilation'. +!!! error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModules'. ==== tests/cases/compiler/separateCompilationSourceMap.ts (0 errors) ==== export var x; \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationUnspecifiedModule.errors.txt b/tests/baselines/reference/separateCompilationUnspecifiedModule.errors.txt index ab0fd7ffe9d..0691be32c7c 100644 --- a/tests/baselines/reference/separateCompilationUnspecifiedModule.errors.txt +++ b/tests/baselines/reference/separateCompilationUnspecifiedModule.errors.txt @@ -1,6 +1,6 @@ -error TS5047: Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher. +error TS5047: Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher. -!!! error TS5047: Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher. +!!! error TS5047: Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher. ==== tests/cases/compiler/separateCompilationUnspecifiedModule.ts (0 errors) ==== export var x; \ No newline at end of file diff --git a/tests/cases/compiler/separateCompilationAmbientConstEnum.ts b/tests/cases/compiler/separateCompilationAmbientConstEnum.ts index aaccfaaf02c..59fcdcd1fe4 100644 --- a/tests/cases/compiler/separateCompilationAmbientConstEnum.ts +++ b/tests/cases/compiler/separateCompilationAmbientConstEnum.ts @@ -1,4 +1,4 @@ -// @separateCompilation: true +// @isolatedModules: true // @target: es6 // @filename: file1.ts diff --git a/tests/cases/compiler/separateCompilationDeclaration.ts b/tests/cases/compiler/separateCompilationDeclaration.ts index 11003a19193..3d5e7db9b4f 100644 --- a/tests/cases/compiler/separateCompilationDeclaration.ts +++ b/tests/cases/compiler/separateCompilationDeclaration.ts @@ -1,4 +1,4 @@ -// @separateCompilation: true +// @isolatedModules: true // @declaration: true // @target: es6 diff --git a/tests/cases/compiler/separateCompilationES6.ts b/tests/cases/compiler/separateCompilationES6.ts index a2ac8c8d94e..12e8d8adb7f 100644 --- a/tests/cases/compiler/separateCompilationES6.ts +++ b/tests/cases/compiler/separateCompilationES6.ts @@ -1,4 +1,4 @@ -// @separateCompilation: true +// @isolatedModules: true // @target: es6 // @filename: file1.ts export var x; \ No newline at end of file diff --git a/tests/cases/compiler/separateCompilationImportExportElision.ts b/tests/cases/compiler/separateCompilationImportExportElision.ts index d7af74a1a69..e50a0f8eb88 100644 --- a/tests/cases/compiler/separateCompilationImportExportElision.ts +++ b/tests/cases/compiler/separateCompilationImportExportElision.ts @@ -1,4 +1,4 @@ -// @separateCompilation: true +// @isolatedModules: true // @target: es5 // @module: commonjs diff --git a/tests/cases/compiler/separateCompilationNoEmitOnError.ts b/tests/cases/compiler/separateCompilationNoEmitOnError.ts index fe0f59199f6..ce3085dbc3b 100644 --- a/tests/cases/compiler/separateCompilationNoEmitOnError.ts +++ b/tests/cases/compiler/separateCompilationNoEmitOnError.ts @@ -1,4 +1,4 @@ -// @separateCompilation: true +// @isolatedModules: true // @noEmitOnError:true // @target: es6 diff --git a/tests/cases/compiler/separateCompilationNoExternalModule.ts b/tests/cases/compiler/separateCompilationNoExternalModule.ts index e66ef27c005..37b61fcbc1a 100644 --- a/tests/cases/compiler/separateCompilationNoExternalModule.ts +++ b/tests/cases/compiler/separateCompilationNoExternalModule.ts @@ -1,4 +1,4 @@ -// @separateCompilation: true +// @isolatedModules: true // @target: es6 // @filename: file1.ts diff --git a/tests/cases/compiler/separateCompilationNonAmbientConstEnum.ts b/tests/cases/compiler/separateCompilationNonAmbientConstEnum.ts index 5f3054238d9..d5aae618d8f 100644 --- a/tests/cases/compiler/separateCompilationNonAmbientConstEnum.ts +++ b/tests/cases/compiler/separateCompilationNonAmbientConstEnum.ts @@ -1,4 +1,4 @@ -// @separateCompilation: true +// @isolatedModules: true // @target: es6 // @filename: file1.ts diff --git a/tests/cases/compiler/separateCompilationOut.ts b/tests/cases/compiler/separateCompilationOut.ts index 6c0a95f8ae5..c977a4b54da 100644 --- a/tests/cases/compiler/separateCompilationOut.ts +++ b/tests/cases/compiler/separateCompilationOut.ts @@ -1,4 +1,4 @@ -// @separateCompilation: true +// @isolatedModules: true // @out:all.js // @target: es6 diff --git a/tests/cases/compiler/separateCompilationPlainFile-AMD.ts b/tests/cases/compiler/separateCompilationPlainFile-AMD.ts index a1010ce3e8c..d28aea86250 100644 --- a/tests/cases/compiler/separateCompilationPlainFile-AMD.ts +++ b/tests/cases/compiler/separateCompilationPlainFile-AMD.ts @@ -1,6 +1,6 @@ // @target: es5 // @module: amd -// @separateCompilation: true +// @isolatedModules: true declare function run(a: number): void; run(1); diff --git a/tests/cases/compiler/separateCompilationPlainFile-CommonJS.ts b/tests/cases/compiler/separateCompilationPlainFile-CommonJS.ts index 532d97f09eb..6d07f10c4d0 100644 --- a/tests/cases/compiler/separateCompilationPlainFile-CommonJS.ts +++ b/tests/cases/compiler/separateCompilationPlainFile-CommonJS.ts @@ -1,6 +1,6 @@ // @target: es5 // @module: commonjs -// @separateCompilation: true +// @isolatedModules: true declare function run(a: number): void; run(1); diff --git a/tests/cases/compiler/separateCompilationPlainFile-ES6.ts b/tests/cases/compiler/separateCompilationPlainFile-ES6.ts index 20d4e8d79a2..051aa548149 100644 --- a/tests/cases/compiler/separateCompilationPlainFile-ES6.ts +++ b/tests/cases/compiler/separateCompilationPlainFile-ES6.ts @@ -1,5 +1,5 @@ // @target: es6 -// @separateCompilation: true +// @isolatedModules: true declare function run(a: number): void; run(1); diff --git a/tests/cases/compiler/separateCompilationPlainFile-System.ts b/tests/cases/compiler/separateCompilationPlainFile-System.ts index 69065718254..e16720596d9 100644 --- a/tests/cases/compiler/separateCompilationPlainFile-System.ts +++ b/tests/cases/compiler/separateCompilationPlainFile-System.ts @@ -1,6 +1,6 @@ // @target: es5 // @module: system -// @separateCompilation: true +// @isolatedModules: true declare function run(a: number): void; run(1); diff --git a/tests/cases/compiler/separateCompilationPlainFile-UMD.ts b/tests/cases/compiler/separateCompilationPlainFile-UMD.ts index 4ab45686c90..d452bbff96b 100644 --- a/tests/cases/compiler/separateCompilationPlainFile-UMD.ts +++ b/tests/cases/compiler/separateCompilationPlainFile-UMD.ts @@ -1,6 +1,6 @@ // @target: es5 // @module: umd -// @separateCompilation: true +// @isolatedModules: true declare function run(a: number): void; run(1); diff --git a/tests/cases/compiler/separateCompilationSourceMap.ts b/tests/cases/compiler/separateCompilationSourceMap.ts index 84c6290caf5..31dd4d9f0cf 100644 --- a/tests/cases/compiler/separateCompilationSourceMap.ts +++ b/tests/cases/compiler/separateCompilationSourceMap.ts @@ -1,4 +1,4 @@ -// @separateCompilation: true +// @isolatedModules: true // @sourceMap:true // @target: es6 diff --git a/tests/cases/compiler/separateCompilationSpecifiedModule.ts b/tests/cases/compiler/separateCompilationSpecifiedModule.ts index 6ba3a0d3bf4..0e72e6480b6 100644 --- a/tests/cases/compiler/separateCompilationSpecifiedModule.ts +++ b/tests/cases/compiler/separateCompilationSpecifiedModule.ts @@ -1,4 +1,4 @@ -// @separateCompilation: true +// @isolatedModules: true // @module: commonjs // @filename: file1.ts export var x; \ No newline at end of file diff --git a/tests/cases/compiler/separateCompilationUnspecifiedModule.ts b/tests/cases/compiler/separateCompilationUnspecifiedModule.ts index 38a3fd82868..2435f22e952 100644 --- a/tests/cases/compiler/separateCompilationUnspecifiedModule.ts +++ b/tests/cases/compiler/separateCompilationUnspecifiedModule.ts @@ -1,3 +1,3 @@ -// @separateCompilation: true +// @isolatedModules: true // @filename: file1.ts export var x; \ No newline at end of file diff --git a/tests/cases/compiler/separateCompilationWithDeclarationFile.ts b/tests/cases/compiler/separateCompilationWithDeclarationFile.ts index 121db1702a5..01e96b4ec2a 100644 --- a/tests/cases/compiler/separateCompilationWithDeclarationFile.ts +++ b/tests/cases/compiler/separateCompilationWithDeclarationFile.ts @@ -1,4 +1,4 @@ -// @separateCompilation: true +// @isolatedModules: true // @target: es6 // @filename: file1.d.ts diff --git a/tests/cases/compiler/systemModule10.ts b/tests/cases/compiler/systemModule10.ts index 49e99fb1c63..41aea2c8244 100644 --- a/tests/cases/compiler/systemModule10.ts +++ b/tests/cases/compiler/systemModule10.ts @@ -1,5 +1,5 @@ // @module: system -// @separateCompilation: true +// @isolatedModules: true import n, {x} from 'file1' import n2 = require('file2'); diff --git a/tests/cases/compiler/systemModule10_ES5.ts b/tests/cases/compiler/systemModule10_ES5.ts index 6468e4125d1..5e51b9152f8 100644 --- a/tests/cases/compiler/systemModule10_ES5.ts +++ b/tests/cases/compiler/systemModule10_ES5.ts @@ -1,6 +1,6 @@ // @target: es5 // @module: system -// @separateCompilation: true +// @isolatedModules: true import n, {x} from 'file1' import n2 = require('file2'); diff --git a/tests/cases/compiler/systemModule11.ts b/tests/cases/compiler/systemModule11.ts index 28e88688f87..15784b2f8c4 100644 --- a/tests/cases/compiler/systemModule11.ts +++ b/tests/cases/compiler/systemModule11.ts @@ -1,5 +1,5 @@ // @module: system -// @separateCompilation: true +// @isolatedModules: true // set of tests cases that checks generation of local storage for exported names diff --git a/tests/cases/compiler/systemModule9.ts b/tests/cases/compiler/systemModule9.ts index c6ff742b1bf..f124a1112c3 100644 --- a/tests/cases/compiler/systemModule9.ts +++ b/tests/cases/compiler/systemModule9.ts @@ -1,5 +1,5 @@ // @module: system -// @separateCompilation: true +// @isolatedModules: true import * as ns from 'file1'; import {a, b as c} from 'file2'; From 6057a918ecacd0cd62eaa389144a0839c82e4f2e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 18 May 2015 22:21:29 -0700 Subject: [PATCH 040/194] rename tests --- ...isolatedModulesAmbientConstEnum.errors.txt | 10 +++++++ .../isolatedModulesAmbientConstEnum.js | 8 ++++++ ... => isolatedModulesDeclaration.errors.txt} | 2 +- .../reference/isolatedModulesDeclaration.js | 10 +++++++ .../baselines/reference/isolatedModulesES6.js | 5 ++++ .../reference/isolatedModulesES6.symbols | 4 +++ .../reference/isolatedModulesES6.types | 4 +++ ...latedModulesImportExportElision.errors.txt | 28 +++++++++++++++++++ ... => isolatedModulesImportExportElision.js} | 4 +-- ...> isolatedModulesNoEmitOnError.errors.txt} | 2 +- ...isolatedModulesNoExternalModule.errors.txt | 8 ++++++ .../isolatedModulesNoExternalModule.js | 6 ++++ ... => isolatedModulesNonAmbientConstEnum.js} | 4 +-- ...isolatedModulesNonAmbientConstEnum.symbols | 15 ++++++++++ ... isolatedModulesNonAmbientConstEnum.types} | 2 +- ...rors.txt => isolatedModulesOut.errors.txt} | 0 ...ompilationOut.js => isolatedModulesOut.js} | 2 +- .../isolatedModulesPlainFile-AMD.errors.txt | 10 +++++++ ...AMD.js => isolatedModulesPlainFile-AMD.js} | 4 +-- ...olatedModulesPlainFile-CommonJS.errors.txt | 10 +++++++ .../isolatedModulesPlainFile-CommonJS.js | 8 ++++++ .../isolatedModulesPlainFile-ES6.errors.txt | 10 +++++++ .../reference/isolatedModulesPlainFile-ES6.js | 8 ++++++ ...isolatedModulesPlainFile-System.errors.txt | 10 +++++++ ....js => isolatedModulesPlainFile-System.js} | 4 +-- .../isolatedModulesPlainFile-UMD.errors.txt | 10 +++++++ ...UMD.js => isolatedModulesPlainFile-UMD.js} | 4 +-- ...xt => isolatedModulesSourceMap.errors.txt} | 2 +- .../reference/isolatedModulesSourceMap.js | 7 +++++ .../reference/isolatedModulesSourceMap.js.map | 2 ++ ...=> isolatedModulesSourceMap.sourcemap.txt} | 14 +++++----- .../isolatedModulesSpecifiedModule.js | 5 ++++ .../isolatedModulesSpecifiedModule.symbols | 4 +++ .../isolatedModulesSpecifiedModule.types | 4 +++ ...olatedModulesUnspecifiedModule.errors.txt} | 2 +- .../isolatedModulesUnspecifiedModule.js | 5 ++++ ... => isolatedModulesWithDeclarationFile.js} | 2 +- ...solatedModulesWithDeclarationFile.symbols} | 0 ... isolatedModulesWithDeclarationFile.types} | 0 ...rateCompilationAmbientConstEnum.errors.txt | 10 ------- .../separateCompilationAmbientConstEnum.js | 8 ------ .../separateCompilationDeclaration.js | 10 ------- .../reference/separateCompilationES6.js | 5 ---- .../reference/separateCompilationES6.symbols | 4 --- .../reference/separateCompilationES6.types | 4 --- ...eCompilationImportExportElision.errors.txt | 28 ------------------- ...rateCompilationNoExternalModule.errors.txt | 8 ------ .../separateCompilationNoExternalModule.js | 6 ---- ...rateCompilationNonAmbientConstEnum.symbols | 15 ---------- ...eparateCompilationPlainFile-AMD.errors.txt | 10 ------- ...teCompilationPlainFile-CommonJS.errors.txt | 10 ------- .../separateCompilationPlainFile-CommonJS.js | 8 ------ ...eparateCompilationPlainFile-ES6.errors.txt | 10 ------- .../separateCompilationPlainFile-ES6.js | 8 ------ ...rateCompilationPlainFile-System.errors.txt | 10 ------- ...eparateCompilationPlainFile-UMD.errors.txt | 10 ------- .../reference/separateCompilationSourceMap.js | 7 ----- .../separateCompilationSourceMap.js.map | 2 -- .../separateCompilationSpecifiedModule.js | 5 ---- ...separateCompilationSpecifiedModule.symbols | 4 --- .../separateCompilationSpecifiedModule.types | 4 --- .../separateCompilationUnspecifiedModule.js | 5 ---- ....ts => isolatedModulesAmbientConstEnum.ts} | 0 ...ation.ts => isolatedModulesDeclaration.ts} | 0 ...ompilationES6.ts => isolatedModulesES6.ts} | 0 ... => isolatedModulesImportExportElision.ts} | 0 ...ror.ts => isolatedModulesNoEmitOnError.ts} | 0 ....ts => isolatedModulesNoExternalModule.ts} | 0 ... => isolatedModulesNonAmbientConstEnum.ts} | 0 ...ompilationOut.ts => isolatedModulesOut.ts} | 0 ...AMD.ts => isolatedModulesPlainFile-AMD.ts} | 0 ...s => isolatedModulesPlainFile-CommonJS.ts} | 0 ...ES6.ts => isolatedModulesPlainFile-ES6.ts} | 0 ....ts => isolatedModulesPlainFile-System.ts} | 0 ...UMD.ts => isolatedModulesPlainFile-UMD.ts} | 0 ...urceMap.ts => isolatedModulesSourceMap.ts} | 0 ...e.ts => isolatedModulesSpecifiedModule.ts} | 0 ...ts => isolatedModulesUnspecifiedModule.ts} | 0 ... => isolatedModulesWithDeclarationFile.ts} | 0 79 files changed, 215 insertions(+), 215 deletions(-) create mode 100644 tests/baselines/reference/isolatedModulesAmbientConstEnum.errors.txt create mode 100644 tests/baselines/reference/isolatedModulesAmbientConstEnum.js rename tests/baselines/reference/{separateCompilationDeclaration.errors.txt => isolatedModulesDeclaration.errors.txt} (70%) create mode 100644 tests/baselines/reference/isolatedModulesDeclaration.js create mode 100644 tests/baselines/reference/isolatedModulesES6.js create mode 100644 tests/baselines/reference/isolatedModulesES6.symbols create mode 100644 tests/baselines/reference/isolatedModulesES6.types create mode 100644 tests/baselines/reference/isolatedModulesImportExportElision.errors.txt rename tests/baselines/reference/{separateCompilationImportExportElision.js => isolatedModulesImportExportElision.js} (86%) rename tests/baselines/reference/{separateCompilationNoEmitOnError.errors.txt => isolatedModulesNoEmitOnError.errors.txt} (70%) create mode 100644 tests/baselines/reference/isolatedModulesNoExternalModule.errors.txt create mode 100644 tests/baselines/reference/isolatedModulesNoExternalModule.js rename tests/baselines/reference/{separateCompilationNonAmbientConstEnum.js => isolatedModulesNonAmbientConstEnum.js} (58%) create mode 100644 tests/baselines/reference/isolatedModulesNonAmbientConstEnum.symbols rename tests/baselines/reference/{separateCompilationNonAmbientConstEnum.types => isolatedModulesNonAmbientConstEnum.types} (60%) rename tests/baselines/reference/{separateCompilationOut.errors.txt => isolatedModulesOut.errors.txt} (100%) rename tests/baselines/reference/{separateCompilationOut.js => isolatedModulesOut.js} (60%) create mode 100644 tests/baselines/reference/isolatedModulesPlainFile-AMD.errors.txt rename tests/baselines/reference/{separateCompilationPlainFile-AMD.js => isolatedModulesPlainFile-AMD.js} (57%) create mode 100644 tests/baselines/reference/isolatedModulesPlainFile-CommonJS.errors.txt create mode 100644 tests/baselines/reference/isolatedModulesPlainFile-CommonJS.js create mode 100644 tests/baselines/reference/isolatedModulesPlainFile-ES6.errors.txt create mode 100644 tests/baselines/reference/isolatedModulesPlainFile-ES6.js create mode 100644 tests/baselines/reference/isolatedModulesPlainFile-System.errors.txt rename tests/baselines/reference/{separateCompilationPlainFile-System.js => isolatedModulesPlainFile-System.js} (65%) create mode 100644 tests/baselines/reference/isolatedModulesPlainFile-UMD.errors.txt rename tests/baselines/reference/{separateCompilationPlainFile-UMD.js => isolatedModulesPlainFile-UMD.js} (80%) rename tests/baselines/reference/{separateCompilationSourceMap.errors.txt => isolatedModulesSourceMap.errors.txt} (71%) create mode 100644 tests/baselines/reference/isolatedModulesSourceMap.js create mode 100644 tests/baselines/reference/isolatedModulesSourceMap.js.map rename tests/baselines/reference/{separateCompilationSourceMap.sourcemap.txt => isolatedModulesSourceMap.sourcemap.txt} (61%) create mode 100644 tests/baselines/reference/isolatedModulesSpecifiedModule.js create mode 100644 tests/baselines/reference/isolatedModulesSpecifiedModule.symbols create mode 100644 tests/baselines/reference/isolatedModulesSpecifiedModule.types rename tests/baselines/reference/{separateCompilationUnspecifiedModule.errors.txt => isolatedModulesUnspecifiedModule.errors.txt} (77%) create mode 100644 tests/baselines/reference/isolatedModulesUnspecifiedModule.js rename tests/baselines/reference/{separateCompilationWithDeclarationFile.js => isolatedModulesWithDeclarationFile.js} (57%) rename tests/baselines/reference/{separateCompilationWithDeclarationFile.symbols => isolatedModulesWithDeclarationFile.symbols} (100%) rename tests/baselines/reference/{separateCompilationWithDeclarationFile.types => isolatedModulesWithDeclarationFile.types} (100%) delete mode 100644 tests/baselines/reference/separateCompilationAmbientConstEnum.errors.txt delete mode 100644 tests/baselines/reference/separateCompilationAmbientConstEnum.js delete mode 100644 tests/baselines/reference/separateCompilationDeclaration.js delete mode 100644 tests/baselines/reference/separateCompilationES6.js delete mode 100644 tests/baselines/reference/separateCompilationES6.symbols delete mode 100644 tests/baselines/reference/separateCompilationES6.types delete mode 100644 tests/baselines/reference/separateCompilationImportExportElision.errors.txt delete mode 100644 tests/baselines/reference/separateCompilationNoExternalModule.errors.txt delete mode 100644 tests/baselines/reference/separateCompilationNoExternalModule.js delete mode 100644 tests/baselines/reference/separateCompilationNonAmbientConstEnum.symbols delete mode 100644 tests/baselines/reference/separateCompilationPlainFile-AMD.errors.txt delete mode 100644 tests/baselines/reference/separateCompilationPlainFile-CommonJS.errors.txt delete mode 100644 tests/baselines/reference/separateCompilationPlainFile-CommonJS.js delete mode 100644 tests/baselines/reference/separateCompilationPlainFile-ES6.errors.txt delete mode 100644 tests/baselines/reference/separateCompilationPlainFile-ES6.js delete mode 100644 tests/baselines/reference/separateCompilationPlainFile-System.errors.txt delete mode 100644 tests/baselines/reference/separateCompilationPlainFile-UMD.errors.txt delete mode 100644 tests/baselines/reference/separateCompilationSourceMap.js delete mode 100644 tests/baselines/reference/separateCompilationSourceMap.js.map delete mode 100644 tests/baselines/reference/separateCompilationSpecifiedModule.js delete mode 100644 tests/baselines/reference/separateCompilationSpecifiedModule.symbols delete mode 100644 tests/baselines/reference/separateCompilationSpecifiedModule.types delete mode 100644 tests/baselines/reference/separateCompilationUnspecifiedModule.js rename tests/cases/compiler/{separateCompilationAmbientConstEnum.ts => isolatedModulesAmbientConstEnum.ts} (100%) rename tests/cases/compiler/{separateCompilationDeclaration.ts => isolatedModulesDeclaration.ts} (100%) rename tests/cases/compiler/{separateCompilationES6.ts => isolatedModulesES6.ts} (100%) rename tests/cases/compiler/{separateCompilationImportExportElision.ts => isolatedModulesImportExportElision.ts} (100%) rename tests/cases/compiler/{separateCompilationNoEmitOnError.ts => isolatedModulesNoEmitOnError.ts} (100%) rename tests/cases/compiler/{separateCompilationNoExternalModule.ts => isolatedModulesNoExternalModule.ts} (100%) rename tests/cases/compiler/{separateCompilationNonAmbientConstEnum.ts => isolatedModulesNonAmbientConstEnum.ts} (100%) rename tests/cases/compiler/{separateCompilationOut.ts => isolatedModulesOut.ts} (100%) rename tests/cases/compiler/{separateCompilationPlainFile-AMD.ts => isolatedModulesPlainFile-AMD.ts} (100%) rename tests/cases/compiler/{separateCompilationPlainFile-CommonJS.ts => isolatedModulesPlainFile-CommonJS.ts} (100%) rename tests/cases/compiler/{separateCompilationPlainFile-ES6.ts => isolatedModulesPlainFile-ES6.ts} (100%) rename tests/cases/compiler/{separateCompilationPlainFile-System.ts => isolatedModulesPlainFile-System.ts} (100%) rename tests/cases/compiler/{separateCompilationPlainFile-UMD.ts => isolatedModulesPlainFile-UMD.ts} (100%) rename tests/cases/compiler/{separateCompilationSourceMap.ts => isolatedModulesSourceMap.ts} (100%) rename tests/cases/compiler/{separateCompilationSpecifiedModule.ts => isolatedModulesSpecifiedModule.ts} (100%) rename tests/cases/compiler/{separateCompilationUnspecifiedModule.ts => isolatedModulesUnspecifiedModule.ts} (100%) rename tests/cases/compiler/{separateCompilationWithDeclarationFile.ts => isolatedModulesWithDeclarationFile.ts} (100%) diff --git a/tests/baselines/reference/isolatedModulesAmbientConstEnum.errors.txt b/tests/baselines/reference/isolatedModulesAmbientConstEnum.errors.txt new file mode 100644 index 00000000000..bb8a5202bc5 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesAmbientConstEnum.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/isolatedModulesAmbientConstEnum.ts(3,20): error TS1209: Ambient const enums are not allowed when the '--isolatedModules' flag is provided. + + +==== tests/cases/compiler/isolatedModulesAmbientConstEnum.ts (1 errors) ==== + + + declare const enum E { X = 1} + ~ +!!! error TS1209: Ambient const enums are not allowed when the '--isolatedModules' flag is provided. + export var y; \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesAmbientConstEnum.js b/tests/baselines/reference/isolatedModulesAmbientConstEnum.js new file mode 100644 index 00000000000..7742122b687 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesAmbientConstEnum.js @@ -0,0 +1,8 @@ +//// [isolatedModulesAmbientConstEnum.ts] + + +declare const enum E { X = 1} +export var y; + +//// [isolatedModulesAmbientConstEnum.js] +export var y; diff --git a/tests/baselines/reference/separateCompilationDeclaration.errors.txt b/tests/baselines/reference/isolatedModulesDeclaration.errors.txt similarity index 70% rename from tests/baselines/reference/separateCompilationDeclaration.errors.txt rename to tests/baselines/reference/isolatedModulesDeclaration.errors.txt index 107d917c751..de5cb97586c 100644 --- a/tests/baselines/reference/separateCompilationDeclaration.errors.txt +++ b/tests/baselines/reference/isolatedModulesDeclaration.errors.txt @@ -2,6 +2,6 @@ error TS5044: Option 'declaration' cannot be specified with option 'isolatedModu !!! error TS5044: Option 'declaration' cannot be specified with option 'isolatedModules'. -==== tests/cases/compiler/separateCompilationDeclaration.ts (0 errors) ==== +==== tests/cases/compiler/isolatedModulesDeclaration.ts (0 errors) ==== export var x; \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesDeclaration.js b/tests/baselines/reference/isolatedModulesDeclaration.js new file mode 100644 index 00000000000..12e6f23f92e --- /dev/null +++ b/tests/baselines/reference/isolatedModulesDeclaration.js @@ -0,0 +1,10 @@ +//// [isolatedModulesDeclaration.ts] + +export var x; + +//// [isolatedModulesDeclaration.js] +export var x; + + +//// [isolatedModulesDeclaration.d.ts] +export declare var x: any; diff --git a/tests/baselines/reference/isolatedModulesES6.js b/tests/baselines/reference/isolatedModulesES6.js new file mode 100644 index 00000000000..eb2ee3ee33a --- /dev/null +++ b/tests/baselines/reference/isolatedModulesES6.js @@ -0,0 +1,5 @@ +//// [isolatedModulesES6.ts] +export var x; + +//// [isolatedModulesES6.js] +export var x; diff --git a/tests/baselines/reference/isolatedModulesES6.symbols b/tests/baselines/reference/isolatedModulesES6.symbols new file mode 100644 index 00000000000..c705cbc5af8 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesES6.symbols @@ -0,0 +1,4 @@ +=== tests/cases/compiler/isolatedModulesES6.ts === +export var x; +>x : Symbol(x, Decl(isolatedModulesES6.ts, 0, 10)) + diff --git a/tests/baselines/reference/isolatedModulesES6.types b/tests/baselines/reference/isolatedModulesES6.types new file mode 100644 index 00000000000..898b9715ca4 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesES6.types @@ -0,0 +1,4 @@ +=== tests/cases/compiler/isolatedModulesES6.ts === +export var x; +>x : any + diff --git a/tests/baselines/reference/isolatedModulesImportExportElision.errors.txt b/tests/baselines/reference/isolatedModulesImportExportElision.errors.txt new file mode 100644 index 00000000000..8c6881a9bc1 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesImportExportElision.errors.txt @@ -0,0 +1,28 @@ +tests/cases/compiler/isolatedModulesImportExportElision.ts(2,17): error TS2307: Cannot find module 'module'. +tests/cases/compiler/isolatedModulesImportExportElision.ts(3,18): error TS2307: Cannot find module 'module'. +tests/cases/compiler/isolatedModulesImportExportElision.ts(4,21): error TS2307: Cannot find module 'module'. +tests/cases/compiler/isolatedModulesImportExportElision.ts(12,18): error TS2307: Cannot find module 'module'. + + +==== tests/cases/compiler/isolatedModulesImportExportElision.ts (4 errors) ==== + + import {c} from "module" + ~~~~~~~~ +!!! error TS2307: Cannot find module 'module'. + import {c2} from "module" + ~~~~~~~~ +!!! error TS2307: Cannot find module 'module'. + import * as ns from "module" + ~~~~~~~~ +!!! error TS2307: Cannot find module 'module'. + + class C extends c2.C { + } + + let x = new c(); + let y = ns.value; + + export {c1} from "module"; + ~~~~~~~~ +!!! error TS2307: Cannot find module 'module'. + export var z = x; \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationImportExportElision.js b/tests/baselines/reference/isolatedModulesImportExportElision.js similarity index 86% rename from tests/baselines/reference/separateCompilationImportExportElision.js rename to tests/baselines/reference/isolatedModulesImportExportElision.js index cfa57980249..ca3eee0ac2b 100644 --- a/tests/baselines/reference/separateCompilationImportExportElision.js +++ b/tests/baselines/reference/isolatedModulesImportExportElision.js @@ -1,4 +1,4 @@ -//// [separateCompilationImportExportElision.ts] +//// [isolatedModulesImportExportElision.ts] import {c} from "module" import {c2} from "module" @@ -13,7 +13,7 @@ let y = ns.value; export {c1} from "module"; export var z = x; -//// [separateCompilationImportExportElision.js] +//// [isolatedModulesImportExportElision.js] var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } diff --git a/tests/baselines/reference/separateCompilationNoEmitOnError.errors.txt b/tests/baselines/reference/isolatedModulesNoEmitOnError.errors.txt similarity index 70% rename from tests/baselines/reference/separateCompilationNoEmitOnError.errors.txt rename to tests/baselines/reference/isolatedModulesNoEmitOnError.errors.txt index ddb471cef49..68b2747cf6b 100644 --- a/tests/baselines/reference/separateCompilationNoEmitOnError.errors.txt +++ b/tests/baselines/reference/isolatedModulesNoEmitOnError.errors.txt @@ -2,6 +2,6 @@ error TS5045: Option 'noEmitOnError' cannot be specified with option 'isolatedMo !!! error TS5045: Option 'noEmitOnError' cannot be specified with option 'isolatedModules'. -==== tests/cases/compiler/separateCompilationNoEmitOnError.ts (0 errors) ==== +==== tests/cases/compiler/isolatedModulesNoEmitOnError.ts (0 errors) ==== export var x; \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesNoExternalModule.errors.txt b/tests/baselines/reference/isolatedModulesNoExternalModule.errors.txt new file mode 100644 index 00000000000..d00520a0618 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesNoExternalModule.errors.txt @@ -0,0 +1,8 @@ +tests/cases/compiler/isolatedModulesNoExternalModule.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + + +==== tests/cases/compiler/isolatedModulesNoExternalModule.ts (1 errors) ==== + + var x; + ~~~ +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesNoExternalModule.js b/tests/baselines/reference/isolatedModulesNoExternalModule.js new file mode 100644 index 00000000000..dd5d23a538c --- /dev/null +++ b/tests/baselines/reference/isolatedModulesNoExternalModule.js @@ -0,0 +1,6 @@ +//// [isolatedModulesNoExternalModule.ts] + +var x; + +//// [isolatedModulesNoExternalModule.js] +var x; diff --git a/tests/baselines/reference/separateCompilationNonAmbientConstEnum.js b/tests/baselines/reference/isolatedModulesNonAmbientConstEnum.js similarity index 58% rename from tests/baselines/reference/separateCompilationNonAmbientConstEnum.js rename to tests/baselines/reference/isolatedModulesNonAmbientConstEnum.js index 74096adca1f..efdba17dc93 100644 --- a/tests/baselines/reference/separateCompilationNonAmbientConstEnum.js +++ b/tests/baselines/reference/isolatedModulesNonAmbientConstEnum.js @@ -1,10 +1,10 @@ -//// [separateCompilationNonAmbientConstEnum.ts] +//// [isolatedModulesNonAmbientConstEnum.ts] const enum E { X = 100 }; var e = E.X; export var x; -//// [separateCompilationNonAmbientConstEnum.js] +//// [isolatedModulesNonAmbientConstEnum.js] var E; (function (E) { E[E["X"] = 100] = "X"; diff --git a/tests/baselines/reference/isolatedModulesNonAmbientConstEnum.symbols b/tests/baselines/reference/isolatedModulesNonAmbientConstEnum.symbols new file mode 100644 index 00000000000..5e30fd0b2ff --- /dev/null +++ b/tests/baselines/reference/isolatedModulesNonAmbientConstEnum.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/isolatedModulesNonAmbientConstEnum.ts === + +const enum E { X = 100 }; +>E : Symbol(E, Decl(isolatedModulesNonAmbientConstEnum.ts, 0, 0)) +>X : Symbol(E.X, Decl(isolatedModulesNonAmbientConstEnum.ts, 1, 14)) + +var e = E.X; +>e : Symbol(e, Decl(isolatedModulesNonAmbientConstEnum.ts, 2, 3)) +>E.X : Symbol(E.X, Decl(isolatedModulesNonAmbientConstEnum.ts, 1, 14)) +>E : Symbol(E, Decl(isolatedModulesNonAmbientConstEnum.ts, 0, 0)) +>X : Symbol(E.X, Decl(isolatedModulesNonAmbientConstEnum.ts, 1, 14)) + +export var x; +>x : Symbol(x, Decl(isolatedModulesNonAmbientConstEnum.ts, 3, 10)) + diff --git a/tests/baselines/reference/separateCompilationNonAmbientConstEnum.types b/tests/baselines/reference/isolatedModulesNonAmbientConstEnum.types similarity index 60% rename from tests/baselines/reference/separateCompilationNonAmbientConstEnum.types rename to tests/baselines/reference/isolatedModulesNonAmbientConstEnum.types index ce55b80f41d..d7e83b81070 100644 --- a/tests/baselines/reference/separateCompilationNonAmbientConstEnum.types +++ b/tests/baselines/reference/isolatedModulesNonAmbientConstEnum.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/separateCompilationNonAmbientConstEnum.ts === +=== tests/cases/compiler/isolatedModulesNonAmbientConstEnum.ts === const enum E { X = 100 }; >E : E diff --git a/tests/baselines/reference/separateCompilationOut.errors.txt b/tests/baselines/reference/isolatedModulesOut.errors.txt similarity index 100% rename from tests/baselines/reference/separateCompilationOut.errors.txt rename to tests/baselines/reference/isolatedModulesOut.errors.txt diff --git a/tests/baselines/reference/separateCompilationOut.js b/tests/baselines/reference/isolatedModulesOut.js similarity index 60% rename from tests/baselines/reference/separateCompilationOut.js rename to tests/baselines/reference/isolatedModulesOut.js index 67dd2dcfbfa..ca5eb2b7579 100644 --- a/tests/baselines/reference/separateCompilationOut.js +++ b/tests/baselines/reference/isolatedModulesOut.js @@ -1,4 +1,4 @@ -//// [tests/cases/compiler/separateCompilationOut.ts] //// +//// [tests/cases/compiler/isolatedModulesOut.ts] //// //// [file1.ts] diff --git a/tests/baselines/reference/isolatedModulesPlainFile-AMD.errors.txt b/tests/baselines/reference/isolatedModulesPlainFile-AMD.errors.txt new file mode 100644 index 00000000000..680070a73c8 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesPlainFile-AMD.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/isolatedModulesPlainFile-AMD.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + + +==== tests/cases/compiler/isolatedModulesPlainFile-AMD.ts (1 errors) ==== + + declare function run(a: number): void; + ~~~~~~~ +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + run(1); + \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-AMD.js b/tests/baselines/reference/isolatedModulesPlainFile-AMD.js similarity index 57% rename from tests/baselines/reference/separateCompilationPlainFile-AMD.js rename to tests/baselines/reference/isolatedModulesPlainFile-AMD.js index e3e9fc1eaeb..7f4f4219123 100644 --- a/tests/baselines/reference/separateCompilationPlainFile-AMD.js +++ b/tests/baselines/reference/isolatedModulesPlainFile-AMD.js @@ -1,10 +1,10 @@ -//// [separateCompilationPlainFile-AMD.ts] +//// [isolatedModulesPlainFile-AMD.ts] declare function run(a: number): void; run(1); -//// [separateCompilationPlainFile-AMD.js] +//// [isolatedModulesPlainFile-AMD.js] define(["require", "exports"], function (require, exports) { run(1); }); diff --git a/tests/baselines/reference/isolatedModulesPlainFile-CommonJS.errors.txt b/tests/baselines/reference/isolatedModulesPlainFile-CommonJS.errors.txt new file mode 100644 index 00000000000..d1f0ca3caad --- /dev/null +++ b/tests/baselines/reference/isolatedModulesPlainFile-CommonJS.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/isolatedModulesPlainFile-CommonJS.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + + +==== tests/cases/compiler/isolatedModulesPlainFile-CommonJS.ts (1 errors) ==== + + declare function run(a: number): void; + ~~~~~~~ +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + run(1); + \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesPlainFile-CommonJS.js b/tests/baselines/reference/isolatedModulesPlainFile-CommonJS.js new file mode 100644 index 00000000000..7026a7d9bed --- /dev/null +++ b/tests/baselines/reference/isolatedModulesPlainFile-CommonJS.js @@ -0,0 +1,8 @@ +//// [isolatedModulesPlainFile-CommonJS.ts] + +declare function run(a: number): void; +run(1); + + +//// [isolatedModulesPlainFile-CommonJS.js] +run(1); diff --git a/tests/baselines/reference/isolatedModulesPlainFile-ES6.errors.txt b/tests/baselines/reference/isolatedModulesPlainFile-ES6.errors.txt new file mode 100644 index 00000000000..d46fce22fd7 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesPlainFile-ES6.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/isolatedModulesPlainFile-ES6.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + + +==== tests/cases/compiler/isolatedModulesPlainFile-ES6.ts (1 errors) ==== + + declare function run(a: number): void; + ~~~~~~~ +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + run(1); + \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesPlainFile-ES6.js b/tests/baselines/reference/isolatedModulesPlainFile-ES6.js new file mode 100644 index 00000000000..245d3fe668f --- /dev/null +++ b/tests/baselines/reference/isolatedModulesPlainFile-ES6.js @@ -0,0 +1,8 @@ +//// [isolatedModulesPlainFile-ES6.ts] + +declare function run(a: number): void; +run(1); + + +//// [isolatedModulesPlainFile-ES6.js] +run(1); diff --git a/tests/baselines/reference/isolatedModulesPlainFile-System.errors.txt b/tests/baselines/reference/isolatedModulesPlainFile-System.errors.txt new file mode 100644 index 00000000000..fe1a2f80018 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesPlainFile-System.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/isolatedModulesPlainFile-System.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + + +==== tests/cases/compiler/isolatedModulesPlainFile-System.ts (1 errors) ==== + + declare function run(a: number): void; + ~~~~~~~ +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + run(1); + \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-System.js b/tests/baselines/reference/isolatedModulesPlainFile-System.js similarity index 65% rename from tests/baselines/reference/separateCompilationPlainFile-System.js rename to tests/baselines/reference/isolatedModulesPlainFile-System.js index c256ed7862a..b924a3b21f9 100644 --- a/tests/baselines/reference/separateCompilationPlainFile-System.js +++ b/tests/baselines/reference/isolatedModulesPlainFile-System.js @@ -1,10 +1,10 @@ -//// [separateCompilationPlainFile-System.ts] +//// [isolatedModulesPlainFile-System.ts] declare function run(a: number): void; run(1); -//// [separateCompilationPlainFile-System.js] +//// [isolatedModulesPlainFile-System.js] System.register([], function(exports_1) { return { setters:[], diff --git a/tests/baselines/reference/isolatedModulesPlainFile-UMD.errors.txt b/tests/baselines/reference/isolatedModulesPlainFile-UMD.errors.txt new file mode 100644 index 00000000000..24c5c86f8f8 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesPlainFile-UMD.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/isolatedModulesPlainFile-UMD.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + + +==== tests/cases/compiler/isolatedModulesPlainFile-UMD.ts (1 errors) ==== + + declare function run(a: number): void; + ~~~~~~~ +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + run(1); + \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-UMD.js b/tests/baselines/reference/isolatedModulesPlainFile-UMD.js similarity index 80% rename from tests/baselines/reference/separateCompilationPlainFile-UMD.js rename to tests/baselines/reference/isolatedModulesPlainFile-UMD.js index 6a145e7d239..0ed6e83a37f 100644 --- a/tests/baselines/reference/separateCompilationPlainFile-UMD.js +++ b/tests/baselines/reference/isolatedModulesPlainFile-UMD.js @@ -1,10 +1,10 @@ -//// [separateCompilationPlainFile-UMD.ts] +//// [isolatedModulesPlainFile-UMD.ts] declare function run(a: number): void; run(1); -//// [separateCompilationPlainFile-UMD.js] +//// [isolatedModulesPlainFile-UMD.js] (function (deps, factory) { if (typeof module === 'object' && typeof module.exports === 'object') { var v = factory(require, exports); if (v !== undefined) module.exports = v; diff --git a/tests/baselines/reference/separateCompilationSourceMap.errors.txt b/tests/baselines/reference/isolatedModulesSourceMap.errors.txt similarity index 71% rename from tests/baselines/reference/separateCompilationSourceMap.errors.txt rename to tests/baselines/reference/isolatedModulesSourceMap.errors.txt index 56fc5b5cb85..6383e85ecd5 100644 --- a/tests/baselines/reference/separateCompilationSourceMap.errors.txt +++ b/tests/baselines/reference/isolatedModulesSourceMap.errors.txt @@ -2,6 +2,6 @@ error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModule !!! error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModules'. -==== tests/cases/compiler/separateCompilationSourceMap.ts (0 errors) ==== +==== tests/cases/compiler/isolatedModulesSourceMap.ts (0 errors) ==== export var x; \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesSourceMap.js b/tests/baselines/reference/isolatedModulesSourceMap.js new file mode 100644 index 00000000000..ca6f4b4190e --- /dev/null +++ b/tests/baselines/reference/isolatedModulesSourceMap.js @@ -0,0 +1,7 @@ +//// [isolatedModulesSourceMap.ts] + +export var x; + +//// [isolatedModulesSourceMap.js] +export var x; +//# sourceMappingURL=isolatedModulesSourceMap.js.map \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesSourceMap.js.map b/tests/baselines/reference/isolatedModulesSourceMap.js.map new file mode 100644 index 00000000000..8e505dcda7a --- /dev/null +++ b/tests/baselines/reference/isolatedModulesSourceMap.js.map @@ -0,0 +1,2 @@ +//// [isolatedModulesSourceMap.js.map] +{"version":3,"file":"isolatedModulesSourceMap.js","sourceRoot":"","sources":["isolatedModulesSourceMap.ts"],"names":[],"mappings":"AACA,WAAW,CAAC,CAAC"} \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationSourceMap.sourcemap.txt b/tests/baselines/reference/isolatedModulesSourceMap.sourcemap.txt similarity index 61% rename from tests/baselines/reference/separateCompilationSourceMap.sourcemap.txt rename to tests/baselines/reference/isolatedModulesSourceMap.sourcemap.txt index 74e0d73d7e0..5c6b7659bc6 100644 --- a/tests/baselines/reference/separateCompilationSourceMap.sourcemap.txt +++ b/tests/baselines/reference/isolatedModulesSourceMap.sourcemap.txt @@ -1,19 +1,19 @@ =================================================================== -JsFile: separateCompilationSourceMap.js -mapUrl: separateCompilationSourceMap.js.map +JsFile: isolatedModulesSourceMap.js +mapUrl: isolatedModulesSourceMap.js.map sourceRoot: -sources: separateCompilationSourceMap.ts +sources: isolatedModulesSourceMap.ts =================================================================== ------------------------------------------------------------------- -emittedFile:tests/cases/compiler/separateCompilationSourceMap.js -sourceFile:separateCompilationSourceMap.ts +emittedFile:tests/cases/compiler/isolatedModulesSourceMap.js +sourceFile:isolatedModulesSourceMap.ts ------------------------------------------------------------------- >>>export var x; 1 > 2 >^^^^^^^^^^^ 3 > ^ 4 > ^ -5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> 1 > > 2 >export var @@ -24,4 +24,4 @@ sourceFile:separateCompilationSourceMap.ts 3 >Emitted(1, 13) Source(2, 13) + SourceIndex(0) 4 >Emitted(1, 14) Source(2, 14) + SourceIndex(0) --- ->>>//# sourceMappingURL=separateCompilationSourceMap.js.map \ No newline at end of file +>>>//# sourceMappingURL=isolatedModulesSourceMap.js.map \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesSpecifiedModule.js b/tests/baselines/reference/isolatedModulesSpecifiedModule.js new file mode 100644 index 00000000000..6e868360e71 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesSpecifiedModule.js @@ -0,0 +1,5 @@ +//// [isolatedModulesSpecifiedModule.ts] +export var x; + +//// [isolatedModulesSpecifiedModule.js] +exports.x; diff --git a/tests/baselines/reference/isolatedModulesSpecifiedModule.symbols b/tests/baselines/reference/isolatedModulesSpecifiedModule.symbols new file mode 100644 index 00000000000..91ede682d7c --- /dev/null +++ b/tests/baselines/reference/isolatedModulesSpecifiedModule.symbols @@ -0,0 +1,4 @@ +=== tests/cases/compiler/isolatedModulesSpecifiedModule.ts === +export var x; +>x : Symbol(x, Decl(isolatedModulesSpecifiedModule.ts, 0, 10)) + diff --git a/tests/baselines/reference/isolatedModulesSpecifiedModule.types b/tests/baselines/reference/isolatedModulesSpecifiedModule.types new file mode 100644 index 00000000000..8dee90a199f --- /dev/null +++ b/tests/baselines/reference/isolatedModulesSpecifiedModule.types @@ -0,0 +1,4 @@ +=== tests/cases/compiler/isolatedModulesSpecifiedModule.ts === +export var x; +>x : any + diff --git a/tests/baselines/reference/separateCompilationUnspecifiedModule.errors.txt b/tests/baselines/reference/isolatedModulesUnspecifiedModule.errors.txt similarity index 77% rename from tests/baselines/reference/separateCompilationUnspecifiedModule.errors.txt rename to tests/baselines/reference/isolatedModulesUnspecifiedModule.errors.txt index 0691be32c7c..7d290bcae44 100644 --- a/tests/baselines/reference/separateCompilationUnspecifiedModule.errors.txt +++ b/tests/baselines/reference/isolatedModulesUnspecifiedModule.errors.txt @@ -2,5 +2,5 @@ error TS5047: Option 'isolatedModules' can only be used when either option'--mod !!! error TS5047: Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher. -==== tests/cases/compiler/separateCompilationUnspecifiedModule.ts (0 errors) ==== +==== tests/cases/compiler/isolatedModulesUnspecifiedModule.ts (0 errors) ==== export var x; \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesUnspecifiedModule.js b/tests/baselines/reference/isolatedModulesUnspecifiedModule.js new file mode 100644 index 00000000000..104eda6c052 --- /dev/null +++ b/tests/baselines/reference/isolatedModulesUnspecifiedModule.js @@ -0,0 +1,5 @@ +//// [isolatedModulesUnspecifiedModule.ts] +export var x; + +//// [isolatedModulesUnspecifiedModule.js] +exports.x; diff --git a/tests/baselines/reference/separateCompilationWithDeclarationFile.js b/tests/baselines/reference/isolatedModulesWithDeclarationFile.js similarity index 57% rename from tests/baselines/reference/separateCompilationWithDeclarationFile.js rename to tests/baselines/reference/isolatedModulesWithDeclarationFile.js index 71d7ef41929..42d091b6108 100644 --- a/tests/baselines/reference/separateCompilationWithDeclarationFile.js +++ b/tests/baselines/reference/isolatedModulesWithDeclarationFile.js @@ -1,4 +1,4 @@ -//// [tests/cases/compiler/separateCompilationWithDeclarationFile.ts] //// +//// [tests/cases/compiler/isolatedModulesWithDeclarationFile.ts] //// //// [file1.d.ts] diff --git a/tests/baselines/reference/separateCompilationWithDeclarationFile.symbols b/tests/baselines/reference/isolatedModulesWithDeclarationFile.symbols similarity index 100% rename from tests/baselines/reference/separateCompilationWithDeclarationFile.symbols rename to tests/baselines/reference/isolatedModulesWithDeclarationFile.symbols diff --git a/tests/baselines/reference/separateCompilationWithDeclarationFile.types b/tests/baselines/reference/isolatedModulesWithDeclarationFile.types similarity index 100% rename from tests/baselines/reference/separateCompilationWithDeclarationFile.types rename to tests/baselines/reference/isolatedModulesWithDeclarationFile.types diff --git a/tests/baselines/reference/separateCompilationAmbientConstEnum.errors.txt b/tests/baselines/reference/separateCompilationAmbientConstEnum.errors.txt deleted file mode 100644 index ea55115e957..00000000000 --- a/tests/baselines/reference/separateCompilationAmbientConstEnum.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -tests/cases/compiler/separateCompilationAmbientConstEnum.ts(3,20): error TS1209: Ambient const enums are not allowed when the '--isolatedModules' flag is provided. - - -==== tests/cases/compiler/separateCompilationAmbientConstEnum.ts (1 errors) ==== - - - declare const enum E { X = 1} - ~ -!!! error TS1209: Ambient const enums are not allowed when the '--isolatedModules' flag is provided. - export var y; \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationAmbientConstEnum.js b/tests/baselines/reference/separateCompilationAmbientConstEnum.js deleted file mode 100644 index 5b3af0957e7..00000000000 --- a/tests/baselines/reference/separateCompilationAmbientConstEnum.js +++ /dev/null @@ -1,8 +0,0 @@ -//// [separateCompilationAmbientConstEnum.ts] - - -declare const enum E { X = 1} -export var y; - -//// [separateCompilationAmbientConstEnum.js] -export var y; diff --git a/tests/baselines/reference/separateCompilationDeclaration.js b/tests/baselines/reference/separateCompilationDeclaration.js deleted file mode 100644 index 33d64b088de..00000000000 --- a/tests/baselines/reference/separateCompilationDeclaration.js +++ /dev/null @@ -1,10 +0,0 @@ -//// [separateCompilationDeclaration.ts] - -export var x; - -//// [separateCompilationDeclaration.js] -export var x; - - -//// [separateCompilationDeclaration.d.ts] -export declare var x: any; diff --git a/tests/baselines/reference/separateCompilationES6.js b/tests/baselines/reference/separateCompilationES6.js deleted file mode 100644 index cf05e5590a8..00000000000 --- a/tests/baselines/reference/separateCompilationES6.js +++ /dev/null @@ -1,5 +0,0 @@ -//// [separateCompilationES6.ts] -export var x; - -//// [separateCompilationES6.js] -export var x; diff --git a/tests/baselines/reference/separateCompilationES6.symbols b/tests/baselines/reference/separateCompilationES6.symbols deleted file mode 100644 index 737d5e41365..00000000000 --- a/tests/baselines/reference/separateCompilationES6.symbols +++ /dev/null @@ -1,4 +0,0 @@ -=== tests/cases/compiler/separateCompilationES6.ts === -export var x; ->x : Symbol(x, Decl(separateCompilationES6.ts, 0, 10)) - diff --git a/tests/baselines/reference/separateCompilationES6.types b/tests/baselines/reference/separateCompilationES6.types deleted file mode 100644 index 70381906800..00000000000 --- a/tests/baselines/reference/separateCompilationES6.types +++ /dev/null @@ -1,4 +0,0 @@ -=== tests/cases/compiler/separateCompilationES6.ts === -export var x; ->x : any - diff --git a/tests/baselines/reference/separateCompilationImportExportElision.errors.txt b/tests/baselines/reference/separateCompilationImportExportElision.errors.txt deleted file mode 100644 index 0bac01d8134..00000000000 --- a/tests/baselines/reference/separateCompilationImportExportElision.errors.txt +++ /dev/null @@ -1,28 +0,0 @@ -tests/cases/compiler/separateCompilationImportExportElision.ts(2,17): error TS2307: Cannot find module 'module'. -tests/cases/compiler/separateCompilationImportExportElision.ts(3,18): error TS2307: Cannot find module 'module'. -tests/cases/compiler/separateCompilationImportExportElision.ts(4,21): error TS2307: Cannot find module 'module'. -tests/cases/compiler/separateCompilationImportExportElision.ts(12,18): error TS2307: Cannot find module 'module'. - - -==== tests/cases/compiler/separateCompilationImportExportElision.ts (4 errors) ==== - - import {c} from "module" - ~~~~~~~~ -!!! error TS2307: Cannot find module 'module'. - import {c2} from "module" - ~~~~~~~~ -!!! error TS2307: Cannot find module 'module'. - import * as ns from "module" - ~~~~~~~~ -!!! error TS2307: Cannot find module 'module'. - - class C extends c2.C { - } - - let x = new c(); - let y = ns.value; - - export {c1} from "module"; - ~~~~~~~~ -!!! error TS2307: Cannot find module 'module'. - export var z = x; \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationNoExternalModule.errors.txt b/tests/baselines/reference/separateCompilationNoExternalModule.errors.txt deleted file mode 100644 index 7c242e90f12..00000000000 --- a/tests/baselines/reference/separateCompilationNoExternalModule.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/compiler/separateCompilationNoExternalModule.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. - - -==== tests/cases/compiler/separateCompilationNoExternalModule.ts (1 errors) ==== - - var x; - ~~~ -!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationNoExternalModule.js b/tests/baselines/reference/separateCompilationNoExternalModule.js deleted file mode 100644 index 9ddc8bdef2c..00000000000 --- a/tests/baselines/reference/separateCompilationNoExternalModule.js +++ /dev/null @@ -1,6 +0,0 @@ -//// [separateCompilationNoExternalModule.ts] - -var x; - -//// [separateCompilationNoExternalModule.js] -var x; diff --git a/tests/baselines/reference/separateCompilationNonAmbientConstEnum.symbols b/tests/baselines/reference/separateCompilationNonAmbientConstEnum.symbols deleted file mode 100644 index da3f7ce6452..00000000000 --- a/tests/baselines/reference/separateCompilationNonAmbientConstEnum.symbols +++ /dev/null @@ -1,15 +0,0 @@ -=== tests/cases/compiler/separateCompilationNonAmbientConstEnum.ts === - -const enum E { X = 100 }; ->E : Symbol(E, Decl(separateCompilationNonAmbientConstEnum.ts, 0, 0)) ->X : Symbol(E.X, Decl(separateCompilationNonAmbientConstEnum.ts, 1, 14)) - -var e = E.X; ->e : Symbol(e, Decl(separateCompilationNonAmbientConstEnum.ts, 2, 3)) ->E.X : Symbol(E.X, Decl(separateCompilationNonAmbientConstEnum.ts, 1, 14)) ->E : Symbol(E, Decl(separateCompilationNonAmbientConstEnum.ts, 0, 0)) ->X : Symbol(E.X, Decl(separateCompilationNonAmbientConstEnum.ts, 1, 14)) - -export var x; ->x : Symbol(x, Decl(separateCompilationNonAmbientConstEnum.ts, 3, 10)) - diff --git a/tests/baselines/reference/separateCompilationPlainFile-AMD.errors.txt b/tests/baselines/reference/separateCompilationPlainFile-AMD.errors.txt deleted file mode 100644 index 329299f5130..00000000000 --- a/tests/baselines/reference/separateCompilationPlainFile-AMD.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -tests/cases/compiler/separateCompilationPlainFile-AMD.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. - - -==== tests/cases/compiler/separateCompilationPlainFile-AMD.ts (1 errors) ==== - - declare function run(a: number): void; - ~~~~~~~ -!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. - run(1); - \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-CommonJS.errors.txt b/tests/baselines/reference/separateCompilationPlainFile-CommonJS.errors.txt deleted file mode 100644 index e72a4a76b71..00000000000 --- a/tests/baselines/reference/separateCompilationPlainFile-CommonJS.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -tests/cases/compiler/separateCompilationPlainFile-CommonJS.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. - - -==== tests/cases/compiler/separateCompilationPlainFile-CommonJS.ts (1 errors) ==== - - declare function run(a: number): void; - ~~~~~~~ -!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. - run(1); - \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-CommonJS.js b/tests/baselines/reference/separateCompilationPlainFile-CommonJS.js deleted file mode 100644 index cd82cdf20a6..00000000000 --- a/tests/baselines/reference/separateCompilationPlainFile-CommonJS.js +++ /dev/null @@ -1,8 +0,0 @@ -//// [separateCompilationPlainFile-CommonJS.ts] - -declare function run(a: number): void; -run(1); - - -//// [separateCompilationPlainFile-CommonJS.js] -run(1); diff --git a/tests/baselines/reference/separateCompilationPlainFile-ES6.errors.txt b/tests/baselines/reference/separateCompilationPlainFile-ES6.errors.txt deleted file mode 100644 index 602d41ce948..00000000000 --- a/tests/baselines/reference/separateCompilationPlainFile-ES6.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -tests/cases/compiler/separateCompilationPlainFile-ES6.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. - - -==== tests/cases/compiler/separateCompilationPlainFile-ES6.ts (1 errors) ==== - - declare function run(a: number): void; - ~~~~~~~ -!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. - run(1); - \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-ES6.js b/tests/baselines/reference/separateCompilationPlainFile-ES6.js deleted file mode 100644 index 1cb6082f134..00000000000 --- a/tests/baselines/reference/separateCompilationPlainFile-ES6.js +++ /dev/null @@ -1,8 +0,0 @@ -//// [separateCompilationPlainFile-ES6.ts] - -declare function run(a: number): void; -run(1); - - -//// [separateCompilationPlainFile-ES6.js] -run(1); diff --git a/tests/baselines/reference/separateCompilationPlainFile-System.errors.txt b/tests/baselines/reference/separateCompilationPlainFile-System.errors.txt deleted file mode 100644 index a6d14edd61a..00000000000 --- a/tests/baselines/reference/separateCompilationPlainFile-System.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -tests/cases/compiler/separateCompilationPlainFile-System.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. - - -==== tests/cases/compiler/separateCompilationPlainFile-System.ts (1 errors) ==== - - declare function run(a: number): void; - ~~~~~~~ -!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. - run(1); - \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationPlainFile-UMD.errors.txt b/tests/baselines/reference/separateCompilationPlainFile-UMD.errors.txt deleted file mode 100644 index d15098a96c1..00000000000 --- a/tests/baselines/reference/separateCompilationPlainFile-UMD.errors.txt +++ /dev/null @@ -1,10 +0,0 @@ -tests/cases/compiler/separateCompilationPlainFile-UMD.ts(2,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. - - -==== tests/cases/compiler/separateCompilationPlainFile-UMD.ts (1 errors) ==== - - declare function run(a: number): void; - ~~~~~~~ -!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. - run(1); - \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationSourceMap.js b/tests/baselines/reference/separateCompilationSourceMap.js deleted file mode 100644 index 1e8f141eb47..00000000000 --- a/tests/baselines/reference/separateCompilationSourceMap.js +++ /dev/null @@ -1,7 +0,0 @@ -//// [separateCompilationSourceMap.ts] - -export var x; - -//// [separateCompilationSourceMap.js] -export var x; -//# sourceMappingURL=separateCompilationSourceMap.js.map \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationSourceMap.js.map b/tests/baselines/reference/separateCompilationSourceMap.js.map deleted file mode 100644 index 68c4e2c78db..00000000000 --- a/tests/baselines/reference/separateCompilationSourceMap.js.map +++ /dev/null @@ -1,2 +0,0 @@ -//// [separateCompilationSourceMap.js.map] -{"version":3,"file":"separateCompilationSourceMap.js","sourceRoot":"","sources":["separateCompilationSourceMap.ts"],"names":[],"mappings":"AACA,WAAW,CAAC,CAAC"} \ No newline at end of file diff --git a/tests/baselines/reference/separateCompilationSpecifiedModule.js b/tests/baselines/reference/separateCompilationSpecifiedModule.js deleted file mode 100644 index 5f3c7ceb39c..00000000000 --- a/tests/baselines/reference/separateCompilationSpecifiedModule.js +++ /dev/null @@ -1,5 +0,0 @@ -//// [separateCompilationSpecifiedModule.ts] -export var x; - -//// [separateCompilationSpecifiedModule.js] -exports.x; diff --git a/tests/baselines/reference/separateCompilationSpecifiedModule.symbols b/tests/baselines/reference/separateCompilationSpecifiedModule.symbols deleted file mode 100644 index a69b579b34d..00000000000 --- a/tests/baselines/reference/separateCompilationSpecifiedModule.symbols +++ /dev/null @@ -1,4 +0,0 @@ -=== tests/cases/compiler/separateCompilationSpecifiedModule.ts === -export var x; ->x : Symbol(x, Decl(separateCompilationSpecifiedModule.ts, 0, 10)) - diff --git a/tests/baselines/reference/separateCompilationSpecifiedModule.types b/tests/baselines/reference/separateCompilationSpecifiedModule.types deleted file mode 100644 index 497f63faf62..00000000000 --- a/tests/baselines/reference/separateCompilationSpecifiedModule.types +++ /dev/null @@ -1,4 +0,0 @@ -=== tests/cases/compiler/separateCompilationSpecifiedModule.ts === -export var x; ->x : any - diff --git a/tests/baselines/reference/separateCompilationUnspecifiedModule.js b/tests/baselines/reference/separateCompilationUnspecifiedModule.js deleted file mode 100644 index 0f2e5c71a87..00000000000 --- a/tests/baselines/reference/separateCompilationUnspecifiedModule.js +++ /dev/null @@ -1,5 +0,0 @@ -//// [separateCompilationUnspecifiedModule.ts] -export var x; - -//// [separateCompilationUnspecifiedModule.js] -exports.x; diff --git a/tests/cases/compiler/separateCompilationAmbientConstEnum.ts b/tests/cases/compiler/isolatedModulesAmbientConstEnum.ts similarity index 100% rename from tests/cases/compiler/separateCompilationAmbientConstEnum.ts rename to tests/cases/compiler/isolatedModulesAmbientConstEnum.ts diff --git a/tests/cases/compiler/separateCompilationDeclaration.ts b/tests/cases/compiler/isolatedModulesDeclaration.ts similarity index 100% rename from tests/cases/compiler/separateCompilationDeclaration.ts rename to tests/cases/compiler/isolatedModulesDeclaration.ts diff --git a/tests/cases/compiler/separateCompilationES6.ts b/tests/cases/compiler/isolatedModulesES6.ts similarity index 100% rename from tests/cases/compiler/separateCompilationES6.ts rename to tests/cases/compiler/isolatedModulesES6.ts diff --git a/tests/cases/compiler/separateCompilationImportExportElision.ts b/tests/cases/compiler/isolatedModulesImportExportElision.ts similarity index 100% rename from tests/cases/compiler/separateCompilationImportExportElision.ts rename to tests/cases/compiler/isolatedModulesImportExportElision.ts diff --git a/tests/cases/compiler/separateCompilationNoEmitOnError.ts b/tests/cases/compiler/isolatedModulesNoEmitOnError.ts similarity index 100% rename from tests/cases/compiler/separateCompilationNoEmitOnError.ts rename to tests/cases/compiler/isolatedModulesNoEmitOnError.ts diff --git a/tests/cases/compiler/separateCompilationNoExternalModule.ts b/tests/cases/compiler/isolatedModulesNoExternalModule.ts similarity index 100% rename from tests/cases/compiler/separateCompilationNoExternalModule.ts rename to tests/cases/compiler/isolatedModulesNoExternalModule.ts diff --git a/tests/cases/compiler/separateCompilationNonAmbientConstEnum.ts b/tests/cases/compiler/isolatedModulesNonAmbientConstEnum.ts similarity index 100% rename from tests/cases/compiler/separateCompilationNonAmbientConstEnum.ts rename to tests/cases/compiler/isolatedModulesNonAmbientConstEnum.ts diff --git a/tests/cases/compiler/separateCompilationOut.ts b/tests/cases/compiler/isolatedModulesOut.ts similarity index 100% rename from tests/cases/compiler/separateCompilationOut.ts rename to tests/cases/compiler/isolatedModulesOut.ts diff --git a/tests/cases/compiler/separateCompilationPlainFile-AMD.ts b/tests/cases/compiler/isolatedModulesPlainFile-AMD.ts similarity index 100% rename from tests/cases/compiler/separateCompilationPlainFile-AMD.ts rename to tests/cases/compiler/isolatedModulesPlainFile-AMD.ts diff --git a/tests/cases/compiler/separateCompilationPlainFile-CommonJS.ts b/tests/cases/compiler/isolatedModulesPlainFile-CommonJS.ts similarity index 100% rename from tests/cases/compiler/separateCompilationPlainFile-CommonJS.ts rename to tests/cases/compiler/isolatedModulesPlainFile-CommonJS.ts diff --git a/tests/cases/compiler/separateCompilationPlainFile-ES6.ts b/tests/cases/compiler/isolatedModulesPlainFile-ES6.ts similarity index 100% rename from tests/cases/compiler/separateCompilationPlainFile-ES6.ts rename to tests/cases/compiler/isolatedModulesPlainFile-ES6.ts diff --git a/tests/cases/compiler/separateCompilationPlainFile-System.ts b/tests/cases/compiler/isolatedModulesPlainFile-System.ts similarity index 100% rename from tests/cases/compiler/separateCompilationPlainFile-System.ts rename to tests/cases/compiler/isolatedModulesPlainFile-System.ts diff --git a/tests/cases/compiler/separateCompilationPlainFile-UMD.ts b/tests/cases/compiler/isolatedModulesPlainFile-UMD.ts similarity index 100% rename from tests/cases/compiler/separateCompilationPlainFile-UMD.ts rename to tests/cases/compiler/isolatedModulesPlainFile-UMD.ts diff --git a/tests/cases/compiler/separateCompilationSourceMap.ts b/tests/cases/compiler/isolatedModulesSourceMap.ts similarity index 100% rename from tests/cases/compiler/separateCompilationSourceMap.ts rename to tests/cases/compiler/isolatedModulesSourceMap.ts diff --git a/tests/cases/compiler/separateCompilationSpecifiedModule.ts b/tests/cases/compiler/isolatedModulesSpecifiedModule.ts similarity index 100% rename from tests/cases/compiler/separateCompilationSpecifiedModule.ts rename to tests/cases/compiler/isolatedModulesSpecifiedModule.ts diff --git a/tests/cases/compiler/separateCompilationUnspecifiedModule.ts b/tests/cases/compiler/isolatedModulesUnspecifiedModule.ts similarity index 100% rename from tests/cases/compiler/separateCompilationUnspecifiedModule.ts rename to tests/cases/compiler/isolatedModulesUnspecifiedModule.ts diff --git a/tests/cases/compiler/separateCompilationWithDeclarationFile.ts b/tests/cases/compiler/isolatedModulesWithDeclarationFile.ts similarity index 100% rename from tests/cases/compiler/separateCompilationWithDeclarationFile.ts rename to tests/cases/compiler/isolatedModulesWithDeclarationFile.ts From f5bcaa3bf88cf95c9b68f3dc2db476e766f99c89 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 12 May 2015 15:49:41 -0700 Subject: [PATCH 041/194] Emit [...a] as a.slice() to ensure a is copied --- src/compiler/emitter.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6d5146a6801..37e1f231bcf 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1366,7 +1366,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return true; } - function emitListWithSpread(elements: Expression[], multiLine: boolean, trailingComma: boolean) { + function emitListWithSpread(elements: Expression[], alwaysCopy: boolean, multiLine: boolean, trailingComma: boolean) { let pos = 0; let group = 0; let length = elements.length; @@ -1383,6 +1383,9 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { e = (e).expression; emitParenthesizedIf(e, /*parenthesized*/ group === 0 && needsParenthesisForPropertyAccessOrInvocation(e)); pos++; + if (pos === length && group === 0 && alwaysCopy) { + write(".slice()"); + } } else { let i = pos; @@ -1422,7 +1425,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { write("]"); } else { - emitListWithSpread(elements, /*multiLine*/(node.flags & NodeFlags.MultiLine) !== 0, + emitListWithSpread(elements, /*alwaysCopy*/ true, /*multiLine*/(node.flags & NodeFlags.MultiLine) !== 0, /*trailingComma*/ elements.hasTrailingComma); } } @@ -1847,7 +1850,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { write("void 0"); } write(", "); - emitListWithSpread(node.arguments, /*multiLine*/ false, /*trailingComma*/ false); + emitListWithSpread(node.arguments, /*alwaysCopy*/ false, /*multiLine*/ false, /*trailingComma*/ false); write(")"); } From a4294a686458039dd3fef5e5a3ebd2e01b4364bf Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 12 May 2015 15:51:20 -0700 Subject: [PATCH 042/194] Accepting new baselines --- tests/baselines/reference/arrayLiteralSpread.js | 6 +++--- tests/baselines/reference/arrayLiterals2ES5.js | 16 ++++++++-------- tests/baselines/reference/arrayLiterals3.js | 4 ++-- ...turingArrayBindingPatternAndAssignment1ES5.js | 2 +- ...ructuringArrayBindingPatternAndAssignment2.js | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/baselines/reference/arrayLiteralSpread.js b/tests/baselines/reference/arrayLiteralSpread.js index 73a60714526..5e4fcedf9d6 100644 --- a/tests/baselines/reference/arrayLiteralSpread.js +++ b/tests/baselines/reference/arrayLiteralSpread.js @@ -26,7 +26,7 @@ function f2() { //// [arrayLiteralSpread.js] function f0() { var a = [1, 2, 3]; - var a1 = a; + var a1 = a.slice(); var a2 = [1].concat(a); var a3 = [1, 2].concat(a); var a4 = a.concat([1]); @@ -41,6 +41,6 @@ function f1() { var b; } function f2() { - var a = []; - var b = [5]; + var a = [].slice().slice().slice().slice().slice(); + var b = [5].slice().slice().slice().slice().slice(); } diff --git a/tests/baselines/reference/arrayLiterals2ES5.js b/tests/baselines/reference/arrayLiterals2ES5.js index 0ff82e90970..689655fb302 100644 --- a/tests/baselines/reference/arrayLiterals2ES5.js +++ b/tests/baselines/reference/arrayLiterals2ES5.js @@ -93,12 +93,12 @@ var temp2 = [[1, 2, 3], ["hello", "string"]]; var temp3 = [undefined, null, undefined]; var temp4 = []; var d0 = [1, true].concat(temp); // has type (string|number|boolean)[] -var d1 = temp; // has type string[] -var d2 = temp1; -var d3 = temp1; +var d1 = temp.slice(); // has type string[] +var d2 = temp1.slice(); +var d3 = temp1.slice(); var d4 = temp.concat(temp1); -var d5 = temp3; -var d6 = temp4; -var d7 = temp1; -var d8 = [temp1]; -var d9 = [temp1].concat(["hello"]); +var d5 = temp3.slice(); +var d6 = temp4.slice(); +var d7 = temp1.slice().slice(); +var d8 = [temp1.slice()]; +var d9 = [temp1.slice()].concat(["hello"]); diff --git a/tests/baselines/reference/arrayLiterals3.js b/tests/baselines/reference/arrayLiterals3.js index 091c6148068..4769c069988 100644 --- a/tests/baselines/reference/arrayLiterals3.js +++ b/tests/baselines/reference/arrayLiterals3.js @@ -55,6 +55,6 @@ var _a = [1, 2, "string", true], b1 = _a[0], b2 = _a[1]; var temp = ["s", "t", "r"]; var temp1 = [1, 2, 3]; var temp2 = [[1, 2, 3], ["hello", "string"]]; -var c0 = temp2; // Error -var c1 = temp1; // Error cannot assign number[] to [number, number, number] +var c0 = temp2.slice(); // Error +var c1 = temp1.slice(); // Error cannot assign number[] to [number, number, number] var c2 = temp1.concat(temp); // Error cannot assign (number|string)[] to number[] diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.js b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.js index bf71064264a..4f071b5e5ec 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.js +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment1ES5.js @@ -88,7 +88,7 @@ var _e = foo(), b6 = _e[0], b7 = _e[1]; var b8 = foo().slice(0); // S is not a tuple- like type and the numeric index signature type of S is assignable to the target given in E. var temp = [1, 2, 3]; -var _f = temp, c0 = _f[0], c1 = _f[1]; +var _f = temp.slice(), c0 = _f[0], c1 = _f[1]; var c2 = [][0]; var _g = [[[]], [[[[]]]]], c3 = _g[0][0][0], c4 = _g[1][0][0][0][0]; var _h = [[1], true], c5 = _h[0][0], c6 = _h[1]; diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.js b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.js index fdbf47fd970..223090ea8ca 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.js +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.js @@ -50,8 +50,8 @@ var _c = bar(), _d = _c[0], b3 = _d === void 0 ? "string" : _d, b4 = _c[1], b5 = // V is an array assignment pattern, S is the type Any or an array-like type (section 3.3.2), and, for each assignment element E in V, // S is not a tuple- like type and the numeric index signature type of S is assignable to the target given in E. var temp = [1, 2, 3]; -var _e = temp, c0 = _e[0], c1 = _e[1]; // Error -var _f = temp, c2 = _f[0], c3 = _f[1]; // Error +var _e = temp.slice(), c0 = _e[0], c1 = _e[1]; // Error +var _f = temp.slice(), c2 = _f[0], c3 = _f[1]; // Error function foo(idx) { return { 2: true From de8b2fabb9f6b381ff271bb2a91f40f1c02a8561 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 12 May 2015 16:53:53 -0700 Subject: [PATCH 043/194] Optimize spread to not generate x.slice() when x is an array literal --- src/compiler/emitter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 37e1f231bcf..4c979486ff3 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1383,7 +1383,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { e = (e).expression; emitParenthesizedIf(e, /*parenthesized*/ group === 0 && needsParenthesisForPropertyAccessOrInvocation(e)); pos++; - if (pos === length && group === 0 && alwaysCopy) { + if (pos === length && group === 0 && alwaysCopy && e.kind !== SyntaxKind.ArrayLiteralExpression) { write(".slice()"); } } From b355412ef6311c0ca30c28842e31e1e2bea84080 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 12 May 2015 16:54:34 -0700 Subject: [PATCH 044/194] Accepting new baselines --- tests/baselines/reference/arrayLiteralSpread.js | 4 ++-- tests/baselines/reference/arrayLiterals2ES5.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/baselines/reference/arrayLiteralSpread.js b/tests/baselines/reference/arrayLiteralSpread.js index 5e4fcedf9d6..3561189671e 100644 --- a/tests/baselines/reference/arrayLiteralSpread.js +++ b/tests/baselines/reference/arrayLiteralSpread.js @@ -41,6 +41,6 @@ function f1() { var b; } function f2() { - var a = [].slice().slice().slice().slice().slice(); - var b = [5].slice().slice().slice().slice().slice(); + var a = []; + var b = [5]; } diff --git a/tests/baselines/reference/arrayLiterals2ES5.js b/tests/baselines/reference/arrayLiterals2ES5.js index 689655fb302..6a81ab465a2 100644 --- a/tests/baselines/reference/arrayLiterals2ES5.js +++ b/tests/baselines/reference/arrayLiterals2ES5.js @@ -99,6 +99,6 @@ var d3 = temp1.slice(); var d4 = temp.concat(temp1); var d5 = temp3.slice(); var d6 = temp4.slice(); -var d7 = temp1.slice().slice(); +var d7 = temp1.slice(); var d8 = [temp1.slice()]; var d9 = [temp1.slice()].concat(["hello"]); From 65735782990c1a18b86b8189f20576f1c682eacc Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 12 May 2015 22:59:29 -0700 Subject: [PATCH 045/194] handle triple slashes in url schema 'file' correctly --- src/compiler/core.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 9b987ba77c6..db47efa9670 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -459,6 +459,14 @@ module ts { if (path.charCodeAt(2) === CharacterCodes.slash) return 3; return 2; } + // Per RFC 1738'file' URI schema has a shape file:/// + // if is omitted then it is assumed that host value is'localhost', + // however slash after the omitted is not removed. + // file:///folder1/file1 - this is correct URI + // file://folder2/file2 - this is incorrect URI + if (path.lastIndexOf("file:///", 0) === 0) { + return "file:///".length; + } let idx = path.indexOf('://'); if (idx !== -1) return idx + 3 return 0; From 2a1df727debe18c98b6b2bc301f8d81690515521 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 15 May 2015 00:42:04 -0700 Subject: [PATCH 046/194] addressed PR feedback --- src/compiler/core.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index db47efa9670..c753f7ff42d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -459,16 +459,18 @@ module ts { if (path.charCodeAt(2) === CharacterCodes.slash) return 3; return 2; } - // Per RFC 1738'file' URI schema has a shape file:/// - // if is omitted then it is assumed that host value is'localhost', + // Per RFC 1738 'file' URI schema has the shape file:/// + // if is omitted then it is assumed that host value is 'localhost', // however slash after the omitted is not removed. - // file:///folder1/file1 - this is correct URI - // file://folder2/file2 - this is incorrect URI + // file:///folder1/file1 - this is a correct URI + // file://folder2/file2 - this is an incorrect URI if (path.lastIndexOf("file:///", 0) === 0) { return "file:///".length; } let idx = path.indexOf('://'); - if (idx !== -1) return idx + 3 + if (idx !== -1) { + return idx + "://".length; + } return 0; } From 87ed20bd57c1fd0acc561869b0b5ad604b2a96ee Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 11 May 2015 00:07:49 -0700 Subject: [PATCH 047/194] system: fix emit for exports of non-top level entities, fix emit for enums --- src/compiler/emitter.ts | 61 ++++++++++++++++--- .../systemModuleDeclarationMerging.js | 43 +++++++++++++ .../systemModuleDeclarationMerging.symbols | 23 +++++++ .../systemModuleDeclarationMerging.types | 23 +++++++ .../systemModuleNonTopLevelModuleMembers.js | 58 ++++++++++++++++++ ...stemModuleNonTopLevelModuleMembers.symbols | 33 ++++++++++ ...systemModuleNonTopLevelModuleMembers.types | 33 ++++++++++ .../systemModuleDeclarationMerging.ts | 11 ++++ .../systemModuleNonTopLevelModuleMembers.ts | 14 +++++ 9 files changed, 289 insertions(+), 10 deletions(-) create mode 100644 tests/baselines/reference/systemModuleDeclarationMerging.js create mode 100644 tests/baselines/reference/systemModuleDeclarationMerging.symbols create mode 100644 tests/baselines/reference/systemModuleDeclarationMerging.types create mode 100644 tests/baselines/reference/systemModuleNonTopLevelModuleMembers.js create mode 100644 tests/baselines/reference/systemModuleNonTopLevelModuleMembers.symbols create mode 100644 tests/baselines/reference/systemModuleNonTopLevelModuleMembers.types create mode 100644 tests/cases/compiler/systemModuleDeclarationMerging.ts create mode 100644 tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 4c979486ff3..9c6b4171890 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2642,7 +2642,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { writeLine(); emitStart(node); - if (compilerOptions.module === ModuleKind.System) { + // emit call to exported only for top level nodes + if (compilerOptions.module === ModuleKind.System && node.parent === currentSourceFile) { // emit export default as // export("default", ) write(`${exportFunctionForFile}("`); @@ -4406,7 +4407,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { emitModuleMemberName(node); write(" = {}));"); emitEnd(node); - if (!isES6ExportedDeclaration(node) && node.flags & NodeFlags.Export) { + if (!isES6ExportedDeclaration(node) && node.flags & NodeFlags.Export && !shouldHoistDeclarationInSystemJsModule(node)) { + // do not emit var if variable was already hoisted writeLine(); emitStart(node); write("var "); @@ -4417,6 +4419,15 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { write(";"); } if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) { + if (compilerOptions.module === ModuleKind.System && (node.flags & NodeFlags.Export)) { + // write the call to exported for enum + writeLine(); + write(`${exportFunctionForFile}("`); + emitDeclarationName(node); + write(`", `); + emitDeclarationName(node); + write(")"); + } emitExportMemberAssignments(node.name); } } @@ -5097,7 +5108,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { // in theory we should hoist only exported functions and its dependencies // in practice to simplify things we'll hoist all source level functions and variable declaration // including variables declarations for module and class declarations - let hoistedVars: (Identifier | ClassDeclaration | ModuleDeclaration)[]; + let hoistedVars: (Identifier | ClassDeclaration | ModuleDeclaration | EnumDeclaration)[]; let hoistedFunctionDeclarations: FunctionDeclaration[]; let exportedDeclarations: (Identifier | Declaration)[]; @@ -5106,13 +5117,30 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { if (hoistedVars) { writeLine(); write("var "); + let seen: Map = {}; for (let i = 0; i < hoistedVars.length; ++i) { let local = hoistedVars[i]; + let name = local.kind === SyntaxKind.Identifier + ? local + : (local).name; + + if (name) { + // do not emit duplicate entries (in case of declaration merging) in the list of hoisted variables + let text = unescapeIdentifier(name.text); + if (hasProperty(seen, text)) { + continue; + } + else { + seen[text] = text; + } + } + if (i !== 0) { write(", "); } - if (local.kind === SyntaxKind.ClassDeclaration || local.kind === SyntaxKind.ModuleDeclaration) { - emitDeclarationName(local); + + if (local.kind === SyntaxKind.ClassDeclaration || local.kind === SyntaxKind.ModuleDeclaration || local.kind === SyntaxKind.EnumDeclaration) { + emitDeclarationName(local); } else { emit(local); @@ -5156,7 +5184,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } if (node.kind === SyntaxKind.ClassDeclaration) { - // TODO: rename block scoped classes if (!hoistedVars) { hoistedVars = []; } @@ -5165,12 +5192,26 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return; } - if (node.kind === SyntaxKind.ModuleDeclaration && shouldEmitModuleDeclaration(node)) { - if (!hoistedVars) { - hoistedVars = []; + if (node.kind === SyntaxKind.EnumDeclaration) { + if (shouldEmitEnumDeclaration(node)) { + if (!hoistedVars) { + hoistedVars = []; + } + + hoistedVars.push(node); } - hoistedVars.push(node); + return; + } + + if (node.kind === SyntaxKind.ModuleDeclaration) { + if (shouldEmitModuleDeclaration(node)) { + if (!hoistedVars) { + hoistedVars = []; + } + + hoistedVars.push(node); + } return; } diff --git a/tests/baselines/reference/systemModuleDeclarationMerging.js b/tests/baselines/reference/systemModuleDeclarationMerging.js new file mode 100644 index 00000000000..b745ed04891 --- /dev/null +++ b/tests/baselines/reference/systemModuleDeclarationMerging.js @@ -0,0 +1,43 @@ +//// [systemModuleDeclarationMerging.ts] + +export function F() {} +export module F { var x; } + +export class C {} +export module C { var x; } + +export enum E {} +export module E { var x; } + +//// [systemModuleDeclarationMerging.js] +System.register([], function(exports_1) { + var F, C, E; + function F() { } + exports_1("F", F); + return { + setters:[], + execute: function() { + (function (F) { + var x; + })(F = F || (F = {})); + exports_1("F", F) + C = (function () { + function C() { + } + return C; + })(); + exports_1("C", C); + (function (C) { + var x; + })(C = C || (C = {})); + exports_1("C", C) + (function (E) { + })(E || (E = {})); + exports_1("E", E) + (function (E) { + var x; + })(E = E || (E = {})); + exports_1("E", E) + } + } +}); diff --git a/tests/baselines/reference/systemModuleDeclarationMerging.symbols b/tests/baselines/reference/systemModuleDeclarationMerging.symbols new file mode 100644 index 00000000000..8efce4022ba --- /dev/null +++ b/tests/baselines/reference/systemModuleDeclarationMerging.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/systemModuleDeclarationMerging.ts === + +export function F() {} +>F : Symbol(F, Decl(systemModuleDeclarationMerging.ts, 0, 0), Decl(systemModuleDeclarationMerging.ts, 1, 22)) + +export module F { var x; } +>F : Symbol(F, Decl(systemModuleDeclarationMerging.ts, 0, 0), Decl(systemModuleDeclarationMerging.ts, 1, 22)) +>x : Symbol(x, Decl(systemModuleDeclarationMerging.ts, 2, 21)) + +export class C {} +>C : Symbol(C, Decl(systemModuleDeclarationMerging.ts, 2, 26), Decl(systemModuleDeclarationMerging.ts, 4, 17)) + +export module C { var x; } +>C : Symbol(C, Decl(systemModuleDeclarationMerging.ts, 2, 26), Decl(systemModuleDeclarationMerging.ts, 4, 17)) +>x : Symbol(x, Decl(systemModuleDeclarationMerging.ts, 5, 21)) + +export enum E {} +>E : Symbol(E, Decl(systemModuleDeclarationMerging.ts, 5, 26), Decl(systemModuleDeclarationMerging.ts, 7, 16)) + +export module E { var x; } +>E : Symbol(E, Decl(systemModuleDeclarationMerging.ts, 5, 26), Decl(systemModuleDeclarationMerging.ts, 7, 16)) +>x : Symbol(x, Decl(systemModuleDeclarationMerging.ts, 8, 21)) + diff --git a/tests/baselines/reference/systemModuleDeclarationMerging.types b/tests/baselines/reference/systemModuleDeclarationMerging.types new file mode 100644 index 00000000000..20bf1e67f51 --- /dev/null +++ b/tests/baselines/reference/systemModuleDeclarationMerging.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/systemModuleDeclarationMerging.ts === + +export function F() {} +>F : typeof F + +export module F { var x; } +>F : typeof F +>x : any + +export class C {} +>C : C + +export module C { var x; } +>C : typeof C +>x : any + +export enum E {} +>E : E + +export module E { var x; } +>E : typeof E +>x : any + diff --git a/tests/baselines/reference/systemModuleNonTopLevelModuleMembers.js b/tests/baselines/reference/systemModuleNonTopLevelModuleMembers.js new file mode 100644 index 00000000000..87e96259bf1 --- /dev/null +++ b/tests/baselines/reference/systemModuleNonTopLevelModuleMembers.js @@ -0,0 +1,58 @@ +//// [systemModuleNonTopLevelModuleMembers.ts] + +export class TopLevelClass {} +export module TopLevelModule {var v;} +export function TopLevelFunction(): void {} +export enum TopLevelEnum {E} + +export module TopLevelModule2 { + export class NonTopLevelClass {} + export module NonTopLevelModule {var v;} + export function NonTopLevelFunction(): void {} + export enum NonTopLevelEnum {E} +} + +//// [systemModuleNonTopLevelModuleMembers.js] +System.register([], function(exports_1) { + var TopLevelClass, TopLevelModule, TopLevelEnum, TopLevelModule2; + function TopLevelFunction() { } + exports_1("TopLevelFunction", TopLevelFunction); + return { + setters:[], + execute: function() { + TopLevelClass = (function () { + function TopLevelClass() { + } + return TopLevelClass; + })(); + exports_1("TopLevelClass", TopLevelClass); + (function (TopLevelModule) { + var v; + })(TopLevelModule = TopLevelModule || (TopLevelModule = {})); + exports_1("TopLevelModule", TopLevelModule) + (function (TopLevelEnum) { + TopLevelEnum[TopLevelEnum["E"] = 0] = "E"; + })(TopLevelEnum || (TopLevelEnum = {})); + exports_1("TopLevelEnum", TopLevelEnum) + (function (TopLevelModule2) { + var NonTopLevelClass = (function () { + function NonTopLevelClass() { + } + return NonTopLevelClass; + })(); + TopLevelModule2.NonTopLevelClass = NonTopLevelClass; + var NonTopLevelModule; + (function (NonTopLevelModule) { + var v; + })(NonTopLevelModule = TopLevelModule2.NonTopLevelModule || (TopLevelModule2.NonTopLevelModule = {})); + function NonTopLevelFunction() { } + TopLevelModule2.NonTopLevelFunction = NonTopLevelFunction; + (function (NonTopLevelEnum) { + NonTopLevelEnum[NonTopLevelEnum["E"] = 0] = "E"; + })(TopLevelModule2.NonTopLevelEnum || (TopLevelModule2.NonTopLevelEnum = {})); + var NonTopLevelEnum = TopLevelModule2.NonTopLevelEnum; + })(TopLevelModule2 = TopLevelModule2 || (TopLevelModule2 = {})); + exports_1("TopLevelModule2", TopLevelModule2) + } + } +}); diff --git a/tests/baselines/reference/systemModuleNonTopLevelModuleMembers.symbols b/tests/baselines/reference/systemModuleNonTopLevelModuleMembers.symbols new file mode 100644 index 00000000000..e0b69c71a2f --- /dev/null +++ b/tests/baselines/reference/systemModuleNonTopLevelModuleMembers.symbols @@ -0,0 +1,33 @@ +=== tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts === + +export class TopLevelClass {} +>TopLevelClass : Symbol(TopLevelClass, Decl(systemModuleNonTopLevelModuleMembers.ts, 0, 0)) + +export module TopLevelModule {var v;} +>TopLevelModule : Symbol(TopLevelModule, Decl(systemModuleNonTopLevelModuleMembers.ts, 1, 29)) +>v : Symbol(v, Decl(systemModuleNonTopLevelModuleMembers.ts, 2, 33)) + +export function TopLevelFunction(): void {} +>TopLevelFunction : Symbol(TopLevelFunction, Decl(systemModuleNonTopLevelModuleMembers.ts, 2, 37)) + +export enum TopLevelEnum {E} +>TopLevelEnum : Symbol(TopLevelEnum, Decl(systemModuleNonTopLevelModuleMembers.ts, 3, 43)) +>E : Symbol(TopLevelEnum.E, Decl(systemModuleNonTopLevelModuleMembers.ts, 4, 26)) + +export module TopLevelModule2 { +>TopLevelModule2 : Symbol(TopLevelModule2, Decl(systemModuleNonTopLevelModuleMembers.ts, 4, 28)) + + export class NonTopLevelClass {} +>NonTopLevelClass : Symbol(NonTopLevelClass, Decl(systemModuleNonTopLevelModuleMembers.ts, 6, 31)) + + export module NonTopLevelModule {var v;} +>NonTopLevelModule : Symbol(NonTopLevelModule, Decl(systemModuleNonTopLevelModuleMembers.ts, 7, 36)) +>v : Symbol(v, Decl(systemModuleNonTopLevelModuleMembers.ts, 8, 40)) + + export function NonTopLevelFunction(): void {} +>NonTopLevelFunction : Symbol(NonTopLevelFunction, Decl(systemModuleNonTopLevelModuleMembers.ts, 8, 44)) + + export enum NonTopLevelEnum {E} +>NonTopLevelEnum : Symbol(NonTopLevelEnum, Decl(systemModuleNonTopLevelModuleMembers.ts, 9, 50)) +>E : Symbol(NonTopLevelEnum.E, Decl(systemModuleNonTopLevelModuleMembers.ts, 10, 33)) +} diff --git a/tests/baselines/reference/systemModuleNonTopLevelModuleMembers.types b/tests/baselines/reference/systemModuleNonTopLevelModuleMembers.types new file mode 100644 index 00000000000..ffe3d23f7a6 --- /dev/null +++ b/tests/baselines/reference/systemModuleNonTopLevelModuleMembers.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts === + +export class TopLevelClass {} +>TopLevelClass : TopLevelClass + +export module TopLevelModule {var v;} +>TopLevelModule : typeof TopLevelModule +>v : any + +export function TopLevelFunction(): void {} +>TopLevelFunction : () => void + +export enum TopLevelEnum {E} +>TopLevelEnum : TopLevelEnum +>E : TopLevelEnum + +export module TopLevelModule2 { +>TopLevelModule2 : typeof TopLevelModule2 + + export class NonTopLevelClass {} +>NonTopLevelClass : NonTopLevelClass + + export module NonTopLevelModule {var v;} +>NonTopLevelModule : typeof NonTopLevelModule +>v : any + + export function NonTopLevelFunction(): void {} +>NonTopLevelFunction : () => void + + export enum NonTopLevelEnum {E} +>NonTopLevelEnum : NonTopLevelEnum +>E : NonTopLevelEnum +} diff --git a/tests/cases/compiler/systemModuleDeclarationMerging.ts b/tests/cases/compiler/systemModuleDeclarationMerging.ts new file mode 100644 index 00000000000..45c59c5b5dc --- /dev/null +++ b/tests/cases/compiler/systemModuleDeclarationMerging.ts @@ -0,0 +1,11 @@ +// @module: system +// @separateCompilation: true + +export function F() {} +export module F { var x; } + +export class C {} +export module C { var x; } + +export enum E {} +export module E { var x; } \ No newline at end of file diff --git a/tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts b/tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts new file mode 100644 index 00000000000..756d430a2de --- /dev/null +++ b/tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts @@ -0,0 +1,14 @@ +// @module: system +// @separateCompilation: true + +export class TopLevelClass {} +export module TopLevelModule {var v;} +export function TopLevelFunction(): void {} +export enum TopLevelEnum {E} + +export module TopLevelModule2 { + export class NonTopLevelClass {} + export module NonTopLevelModule {var v;} + export function NonTopLevelFunction(): void {} + export enum NonTopLevelEnum {E} +} \ No newline at end of file From 546330ed7db0700fd3746f019a3f9817f0bef41c Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 11 May 2015 00:09:06 -0700 Subject: [PATCH 048/194] correct typos --- src/compiler/emitter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 9c6b4171890..d7996238f4c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2642,7 +2642,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { writeLine(); emitStart(node); - // emit call to exported only for top level nodes + // emit call to exporter only for top level nodes if (compilerOptions.module === ModuleKind.System && node.parent === currentSourceFile) { // emit export default as // export("default", ) @@ -4420,7 +4420,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) { if (compilerOptions.module === ModuleKind.System && (node.flags & NodeFlags.Export)) { - // write the call to exported for enum + // write the call to exporter for enum writeLine(); write(`${exportFunctionForFile}("`); emitDeclarationName(node); From c828bcb0c7eec0f10a47d1e838aba86a335a90c6 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 11 May 2015 14:17:34 -0700 Subject: [PATCH 049/194] addressed PR feedback --- src/compiler/emitter.ts | 19 +++--- .../reference/systemModuleConstEnums.js | 27 ++++++++ .../reference/systemModuleConstEnums.symbols | 35 ++++++++++ .../reference/systemModuleConstEnums.types | 37 ++++++++++ ...stemModuleConstEnumsSeparateCompilation.js | 37 ++++++++++ ...oduleConstEnumsSeparateCompilation.symbols | 35 ++++++++++ ...mModuleConstEnumsSeparateCompilation.types | 37 ++++++++++ .../reference/systemModuleExportDefault.js | 67 +++++++++++++++++++ .../systemModuleExportDefault.symbols | 16 +++++ .../reference/systemModuleExportDefault.types | 16 +++++ .../cases/compiler/systemModuleConstEnums.ts | 13 ++++ ...stemModuleConstEnumsSeparateCompilation.ts | 14 ++++ .../compiler/systemModuleExportDefault.ts | 14 ++++ 13 files changed, 359 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/systemModuleConstEnums.js create mode 100644 tests/baselines/reference/systemModuleConstEnums.symbols create mode 100644 tests/baselines/reference/systemModuleConstEnums.types create mode 100644 tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.js create mode 100644 tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.symbols create mode 100644 tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.types create mode 100644 tests/baselines/reference/systemModuleExportDefault.js create mode 100644 tests/baselines/reference/systemModuleExportDefault.symbols create mode 100644 tests/baselines/reference/systemModuleExportDefault.types create mode 100644 tests/cases/compiler/systemModuleConstEnums.ts create mode 100644 tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts create mode 100644 tests/cases/compiler/systemModuleExportDefault.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index d7996238f4c..71074c53d9c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4377,15 +4377,18 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return; } - if (!(node.flags & NodeFlags.Export) || isES6ExportedDeclaration(node)) { - emitStart(node); - if (isES6ExportedDeclaration(node)) { - write("export "); + if (!shouldHoistDeclarationInSystemJsModule(node)) { + // do not emit var if variable was already hoisted + if (!(node.flags & NodeFlags.Export) || isES6ExportedDeclaration(node)) { + emitStart(node); + if (isES6ExportedDeclaration(node)) { + write("export "); + } + write("var "); + emit(node.name); + emitEnd(node); + write(";"); } - write("var "); - emit(node.name); - emitEnd(node); - write(";"); } writeLine(); emitStart(node); diff --git a/tests/baselines/reference/systemModuleConstEnums.js b/tests/baselines/reference/systemModuleConstEnums.js new file mode 100644 index 00000000000..126e6266b2c --- /dev/null +++ b/tests/baselines/reference/systemModuleConstEnums.js @@ -0,0 +1,27 @@ +//// [systemModuleConstEnums.ts] + +declare function use(a: any); +const enum TopLevelConstEnum { X } + +export function foo() { + use(TopLevelConstEnum.X); + use(M.NonTopLevelConstEnum.X); +} + +module M { + export const enum NonTopLevelConstEnum { X } +} + +//// [systemModuleConstEnums.js] +System.register([], function(exports_1) { + function foo() { + use(0 /* X */); + use(0 /* X */); + } + exports_1("foo", foo); + return { + setters:[], + execute: function() { + } + } +}); diff --git a/tests/baselines/reference/systemModuleConstEnums.symbols b/tests/baselines/reference/systemModuleConstEnums.symbols new file mode 100644 index 00000000000..171f24628ec --- /dev/null +++ b/tests/baselines/reference/systemModuleConstEnums.symbols @@ -0,0 +1,35 @@ +=== tests/cases/compiler/systemModuleConstEnums.ts === + +declare function use(a: any); +>use : Symbol(use, Decl(systemModuleConstEnums.ts, 0, 0)) +>a : Symbol(a, Decl(systemModuleConstEnums.ts, 1, 21)) + +const enum TopLevelConstEnum { X } +>TopLevelConstEnum : Symbol(TopLevelConstEnum, Decl(systemModuleConstEnums.ts, 1, 29)) +>X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 2, 30)) + +export function foo() { +>foo : Symbol(foo, Decl(systemModuleConstEnums.ts, 2, 34)) + + use(TopLevelConstEnum.X); +>use : Symbol(use, Decl(systemModuleConstEnums.ts, 0, 0)) +>TopLevelConstEnum.X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 2, 30)) +>TopLevelConstEnum : Symbol(TopLevelConstEnum, Decl(systemModuleConstEnums.ts, 1, 29)) +>X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 2, 30)) + + use(M.NonTopLevelConstEnum.X); +>use : Symbol(use, Decl(systemModuleConstEnums.ts, 0, 0)) +>M.NonTopLevelConstEnum.X : Symbol(M.NonTopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 10, 44)) +>M.NonTopLevelConstEnum : Symbol(M.NonTopLevelConstEnum, Decl(systemModuleConstEnums.ts, 9, 10)) +>M : Symbol(M, Decl(systemModuleConstEnums.ts, 7, 1)) +>NonTopLevelConstEnum : Symbol(M.NonTopLevelConstEnum, Decl(systemModuleConstEnums.ts, 9, 10)) +>X : Symbol(M.NonTopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 10, 44)) +} + +module M { +>M : Symbol(M, Decl(systemModuleConstEnums.ts, 7, 1)) + + export const enum NonTopLevelConstEnum { X } +>NonTopLevelConstEnum : Symbol(NonTopLevelConstEnum, Decl(systemModuleConstEnums.ts, 9, 10)) +>X : Symbol(NonTopLevelConstEnum.X, Decl(systemModuleConstEnums.ts, 10, 44)) +} diff --git a/tests/baselines/reference/systemModuleConstEnums.types b/tests/baselines/reference/systemModuleConstEnums.types new file mode 100644 index 00000000000..193de0da3ab --- /dev/null +++ b/tests/baselines/reference/systemModuleConstEnums.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/systemModuleConstEnums.ts === + +declare function use(a: any); +>use : (a: any) => any +>a : any + +const enum TopLevelConstEnum { X } +>TopLevelConstEnum : TopLevelConstEnum +>X : TopLevelConstEnum + +export function foo() { +>foo : () => void + + use(TopLevelConstEnum.X); +>use(TopLevelConstEnum.X) : any +>use : (a: any) => any +>TopLevelConstEnum.X : TopLevelConstEnum +>TopLevelConstEnum : typeof TopLevelConstEnum +>X : TopLevelConstEnum + + use(M.NonTopLevelConstEnum.X); +>use(M.NonTopLevelConstEnum.X) : any +>use : (a: any) => any +>M.NonTopLevelConstEnum.X : M.NonTopLevelConstEnum +>M.NonTopLevelConstEnum : typeof M.NonTopLevelConstEnum +>M : typeof M +>NonTopLevelConstEnum : typeof M.NonTopLevelConstEnum +>X : M.NonTopLevelConstEnum +} + +module M { +>M : typeof M + + export const enum NonTopLevelConstEnum { X } +>NonTopLevelConstEnum : NonTopLevelConstEnum +>X : NonTopLevelConstEnum +} diff --git a/tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.js b/tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.js new file mode 100644 index 00000000000..381331a84db --- /dev/null +++ b/tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.js @@ -0,0 +1,37 @@ +//// [systemModuleConstEnumsSeparateCompilation.ts] + +declare function use(a: any); +const enum TopLevelConstEnum { X } + +export function foo() { + use(TopLevelConstEnum.X); + use(M.NonTopLevelConstEnum.X); +} + +module M { + export const enum NonTopLevelConstEnum { X } +} + +//// [systemModuleConstEnumsSeparateCompilation.js] +System.register([], function(exports_1) { + var TopLevelConstEnum, M; + function foo() { + use(TopLevelConstEnum.X); + use(M.NonTopLevelConstEnum.X); + } + exports_1("foo", foo); + return { + setters:[], + execute: function() { + (function (TopLevelConstEnum) { + TopLevelConstEnum[TopLevelConstEnum["X"] = 0] = "X"; + })(TopLevelConstEnum || (TopLevelConstEnum = {})); + (function (M) { + (function (NonTopLevelConstEnum) { + NonTopLevelConstEnum[NonTopLevelConstEnum["X"] = 0] = "X"; + })(M.NonTopLevelConstEnum || (M.NonTopLevelConstEnum = {})); + var NonTopLevelConstEnum = M.NonTopLevelConstEnum; + })(M || (M = {})); + } + } +}); diff --git a/tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.symbols b/tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.symbols new file mode 100644 index 00000000000..d57740b75e9 --- /dev/null +++ b/tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.symbols @@ -0,0 +1,35 @@ +=== tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts === + +declare function use(a: any); +>use : Symbol(use, Decl(systemModuleConstEnumsSeparateCompilation.ts, 0, 0)) +>a : Symbol(a, Decl(systemModuleConstEnumsSeparateCompilation.ts, 1, 21)) + +const enum TopLevelConstEnum { X } +>TopLevelConstEnum : Symbol(TopLevelConstEnum, Decl(systemModuleConstEnumsSeparateCompilation.ts, 1, 29)) +>X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 2, 30)) + +export function foo() { +>foo : Symbol(foo, Decl(systemModuleConstEnumsSeparateCompilation.ts, 2, 34)) + + use(TopLevelConstEnum.X); +>use : Symbol(use, Decl(systemModuleConstEnumsSeparateCompilation.ts, 0, 0)) +>TopLevelConstEnum.X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 2, 30)) +>TopLevelConstEnum : Symbol(TopLevelConstEnum, Decl(systemModuleConstEnumsSeparateCompilation.ts, 1, 29)) +>X : Symbol(TopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 2, 30)) + + use(M.NonTopLevelConstEnum.X); +>use : Symbol(use, Decl(systemModuleConstEnumsSeparateCompilation.ts, 0, 0)) +>M.NonTopLevelConstEnum.X : Symbol(M.NonTopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 10, 44)) +>M.NonTopLevelConstEnum : Symbol(M.NonTopLevelConstEnum, Decl(systemModuleConstEnumsSeparateCompilation.ts, 9, 10)) +>M : Symbol(M, Decl(systemModuleConstEnumsSeparateCompilation.ts, 7, 1)) +>NonTopLevelConstEnum : Symbol(M.NonTopLevelConstEnum, Decl(systemModuleConstEnumsSeparateCompilation.ts, 9, 10)) +>X : Symbol(M.NonTopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 10, 44)) +} + +module M { +>M : Symbol(M, Decl(systemModuleConstEnumsSeparateCompilation.ts, 7, 1)) + + export const enum NonTopLevelConstEnum { X } +>NonTopLevelConstEnum : Symbol(NonTopLevelConstEnum, Decl(systemModuleConstEnumsSeparateCompilation.ts, 9, 10)) +>X : Symbol(NonTopLevelConstEnum.X, Decl(systemModuleConstEnumsSeparateCompilation.ts, 10, 44)) +} diff --git a/tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.types b/tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.types new file mode 100644 index 00000000000..c3a352f66ec --- /dev/null +++ b/tests/baselines/reference/systemModuleConstEnumsSeparateCompilation.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts === + +declare function use(a: any); +>use : (a: any) => any +>a : any + +const enum TopLevelConstEnum { X } +>TopLevelConstEnum : TopLevelConstEnum +>X : TopLevelConstEnum + +export function foo() { +>foo : () => void + + use(TopLevelConstEnum.X); +>use(TopLevelConstEnum.X) : any +>use : (a: any) => any +>TopLevelConstEnum.X : TopLevelConstEnum +>TopLevelConstEnum : typeof TopLevelConstEnum +>X : TopLevelConstEnum + + use(M.NonTopLevelConstEnum.X); +>use(M.NonTopLevelConstEnum.X) : any +>use : (a: any) => any +>M.NonTopLevelConstEnum.X : M.NonTopLevelConstEnum +>M.NonTopLevelConstEnum : typeof M.NonTopLevelConstEnum +>M : typeof M +>NonTopLevelConstEnum : typeof M.NonTopLevelConstEnum +>X : M.NonTopLevelConstEnum +} + +module M { +>M : typeof M + + export const enum NonTopLevelConstEnum { X } +>NonTopLevelConstEnum : NonTopLevelConstEnum +>X : NonTopLevelConstEnum +} diff --git a/tests/baselines/reference/systemModuleExportDefault.js b/tests/baselines/reference/systemModuleExportDefault.js new file mode 100644 index 00000000000..4df3ec828c1 --- /dev/null +++ b/tests/baselines/reference/systemModuleExportDefault.js @@ -0,0 +1,67 @@ +//// [tests/cases/compiler/systemModuleExportDefault.ts] //// + +//// [file1.ts] + +export default function() {} + +//// [file2.ts] +export default function foo() {} + +//// [file3.ts] +export default class {} + +//// [file4.ts] +export default class C {} + + + +//// [file1.js] +System.register([], function(exports_1) { + function default_1() { } + exports_1("default", default_1); + return { + setters:[], + execute: function() { + } + } +}); +//// [file2.js] +System.register([], function(exports_1) { + function foo() { } + exports_1("default", foo); + return { + setters:[], + execute: function() { + } + } +}); +//// [file3.js] +System.register([], function(exports_1) { + var default_1; + return { + setters:[], + execute: function() { + default_1 = (function () { + function default_1() { + } + return default_1; + })(); + exports_1("default", default_1); + } + } +}); +//// [file4.js] +System.register([], function(exports_1) { + var C; + return { + setters:[], + execute: function() { + C = (function () { + function C() { + } + return C; + })(); + exports_1("default", C); + } + } +}); diff --git a/tests/baselines/reference/systemModuleExportDefault.symbols b/tests/baselines/reference/systemModuleExportDefault.symbols new file mode 100644 index 00000000000..d6e7cde9b71 --- /dev/null +++ b/tests/baselines/reference/systemModuleExportDefault.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/file1.ts === + +No type information for this code.export default function() {} +No type information for this code. +No type information for this code.=== tests/cases/compiler/file2.ts === +export default function foo() {} +>foo : Symbol(foo, Decl(file2.ts, 0, 0)) + +=== tests/cases/compiler/file3.ts === +export default class {} +No type information for this code. +No type information for this code.=== tests/cases/compiler/file4.ts === +export default class C {} +>C : Symbol(C, Decl(file4.ts, 0, 0)) + + diff --git a/tests/baselines/reference/systemModuleExportDefault.types b/tests/baselines/reference/systemModuleExportDefault.types new file mode 100644 index 00000000000..38b5abec8ed --- /dev/null +++ b/tests/baselines/reference/systemModuleExportDefault.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/file1.ts === + +No type information for this code.export default function() {} +No type information for this code. +No type information for this code.=== tests/cases/compiler/file2.ts === +export default function foo() {} +>foo : () => void + +=== tests/cases/compiler/file3.ts === +export default class {} +No type information for this code. +No type information for this code.=== tests/cases/compiler/file4.ts === +export default class C {} +>C : C + + diff --git a/tests/cases/compiler/systemModuleConstEnums.ts b/tests/cases/compiler/systemModuleConstEnums.ts new file mode 100644 index 00000000000..6ad7f31ef91 --- /dev/null +++ b/tests/cases/compiler/systemModuleConstEnums.ts @@ -0,0 +1,13 @@ +// @module: system + +declare function use(a: any); +const enum TopLevelConstEnum { X } + +export function foo() { + use(TopLevelConstEnum.X); + use(M.NonTopLevelConstEnum.X); +} + +module M { + export const enum NonTopLevelConstEnum { X } +} \ No newline at end of file diff --git a/tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts b/tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts new file mode 100644 index 00000000000..2fc4707b78e --- /dev/null +++ b/tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts @@ -0,0 +1,14 @@ +// @module: system +// @separateCompilation: true + +declare function use(a: any); +const enum TopLevelConstEnum { X } + +export function foo() { + use(TopLevelConstEnum.X); + use(M.NonTopLevelConstEnum.X); +} + +module M { + export const enum NonTopLevelConstEnum { X } +} \ No newline at end of file diff --git a/tests/cases/compiler/systemModuleExportDefault.ts b/tests/cases/compiler/systemModuleExportDefault.ts new file mode 100644 index 00000000000..102c03f0bcd --- /dev/null +++ b/tests/cases/compiler/systemModuleExportDefault.ts @@ -0,0 +1,14 @@ +// @module: system + +// @filename: file1.ts +export default function() {} + +// @filename: file2.ts +export default function foo() {} + +// @filename: file3.ts +export default class {} + +// @filename: file4.ts +export default class C {} + From 409dddc2f3f7c913b1a155c4283a3db1f11e3713 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Sun, 10 May 2015 22:23:12 -0700 Subject: [PATCH 050/194] do not hoist ambient declarations --- src/compiler/emitter.ts | 4 + .../systemModuleAmbientDeclarations.js | 84 +++++++++++++++++++ .../systemModuleAmbientDeclarations.symbols | 53 ++++++++++++ .../systemModuleAmbientDeclarations.types | 55 ++++++++++++ .../systemModuleAmbientDeclarations.ts | 28 +++++++ 5 files changed, 224 insertions(+) create mode 100644 tests/baselines/reference/systemModuleAmbientDeclarations.js create mode 100644 tests/baselines/reference/systemModuleAmbientDeclarations.symbols create mode 100644 tests/baselines/reference/systemModuleAmbientDeclarations.types create mode 100644 tests/cases/compiler/systemModuleAmbientDeclarations.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 4c979486ff3..38a84af6c05 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -5146,6 +5146,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return exportedDeclarations; function visit(node: Node): void { + if (node.flags & NodeFlags.Ambient) { + return; + } + if (node.kind === SyntaxKind.FunctionDeclaration) { if (!hoistedFunctionDeclarations) { hoistedFunctionDeclarations = []; diff --git a/tests/baselines/reference/systemModuleAmbientDeclarations.js b/tests/baselines/reference/systemModuleAmbientDeclarations.js new file mode 100644 index 00000000000..82c18cd7981 --- /dev/null +++ b/tests/baselines/reference/systemModuleAmbientDeclarations.js @@ -0,0 +1,84 @@ +//// [tests/cases/compiler/systemModuleAmbientDeclarations.ts] //// + +//// [file1.ts] + +declare class Promise { } +declare function Foo(): void; +declare class C {} +declare enum E {X = 1}; + +export var promise = Promise; +export var foo = Foo; +export var c = C; +export var e = E; + +//// [file2.ts] +export declare function foo(); + +//// [file3.ts] +export declare class C {} + +//// [file4.ts] +export declare var v: number; + +//// [file5.ts] +export declare enum E {X = 1} + +//// [file6.ts] +export declare module M { var v: number; } + + +//// [file1.js] +System.register([], function(exports_1) { + var promise, foo, c, e; + return { + setters:[], + execute: function() { + ; + exports_1("promise", promise = Promise); + exports_1("foo", foo = Foo); + exports_1("c", c = C); + exports_1("e", e = E); + } + } +}); +//// [file2.js] +System.register([], function(exports_1) { + return { + setters:[], + execute: function() { + } + } +}); +//// [file3.js] +System.register([], function(exports_1) { + return { + setters:[], + execute: function() { + } + } +}); +//// [file4.js] +System.register([], function(exports_1) { + return { + setters:[], + execute: function() { + } + } +}); +//// [file5.js] +System.register([], function(exports_1) { + return { + setters:[], + execute: function() { + } + } +}); +//// [file6.js] +System.register([], function(exports_1) { + return { + setters:[], + execute: function() { + } + } +}); diff --git a/tests/baselines/reference/systemModuleAmbientDeclarations.symbols b/tests/baselines/reference/systemModuleAmbientDeclarations.symbols new file mode 100644 index 00000000000..c2e8557270b --- /dev/null +++ b/tests/baselines/reference/systemModuleAmbientDeclarations.symbols @@ -0,0 +1,53 @@ +=== tests/cases/compiler/file1.ts === + +declare class Promise { } +>Promise : Symbol(Promise, Decl(file1.ts, 0, 0)) + +declare function Foo(): void; +>Foo : Symbol(Foo, Decl(file1.ts, 1, 25)) + +declare class C {} +>C : Symbol(C, Decl(file1.ts, 2, 29)) + +declare enum E {X = 1}; +>E : Symbol(E, Decl(file1.ts, 3, 18)) +>X : Symbol(E.X, Decl(file1.ts, 4, 16)) + +export var promise = Promise; +>promise : Symbol(promise, Decl(file1.ts, 6, 10)) +>Promise : Symbol(Promise, Decl(file1.ts, 0, 0)) + +export var foo = Foo; +>foo : Symbol(foo, Decl(file1.ts, 7, 10)) +>Foo : Symbol(Foo, Decl(file1.ts, 1, 25)) + +export var c = C; +>c : Symbol(c, Decl(file1.ts, 8, 10)) +>C : Symbol(C, Decl(file1.ts, 2, 29)) + +export var e = E; +>e : Symbol(e, Decl(file1.ts, 9, 10)) +>E : Symbol(E, Decl(file1.ts, 3, 18)) + +=== tests/cases/compiler/file2.ts === +export declare function foo(); +>foo : Symbol(foo, Decl(file2.ts, 0, 0)) + +=== tests/cases/compiler/file3.ts === +export declare class C {} +>C : Symbol(C, Decl(file3.ts, 0, 0)) + +=== tests/cases/compiler/file4.ts === +export declare var v: number; +>v : Symbol(v, Decl(file4.ts, 0, 18)) + +=== tests/cases/compiler/file5.ts === +export declare enum E {X = 1} +>E : Symbol(E, Decl(file5.ts, 0, 0)) +>X : Symbol(E.X, Decl(file5.ts, 0, 23)) + +=== tests/cases/compiler/file6.ts === +export declare module M { var v: number; } +>M : Symbol(M, Decl(file6.ts, 0, 0)) +>v : Symbol(v, Decl(file6.ts, 0, 29)) + diff --git a/tests/baselines/reference/systemModuleAmbientDeclarations.types b/tests/baselines/reference/systemModuleAmbientDeclarations.types new file mode 100644 index 00000000000..3633f922881 --- /dev/null +++ b/tests/baselines/reference/systemModuleAmbientDeclarations.types @@ -0,0 +1,55 @@ +=== tests/cases/compiler/file1.ts === + +declare class Promise { } +>Promise : Promise + +declare function Foo(): void; +>Foo : () => void + +declare class C {} +>C : C + +declare enum E {X = 1}; +>E : E +>X : E +>1 : number + +export var promise = Promise; +>promise : typeof Promise +>Promise : typeof Promise + +export var foo = Foo; +>foo : () => void +>Foo : () => void + +export var c = C; +>c : typeof C +>C : typeof C + +export var e = E; +>e : typeof E +>E : typeof E + +=== tests/cases/compiler/file2.ts === +export declare function foo(); +>foo : () => any + +=== tests/cases/compiler/file3.ts === +export declare class C {} +>C : C + +=== tests/cases/compiler/file4.ts === +export declare var v: number; +>v : number + +=== tests/cases/compiler/file5.ts === +export declare enum E {X = 1} +>E : E +>X : E +>1 : number + +=== tests/cases/compiler/file6.ts === +export declare module M { var v: number; } +>M : typeof M +>v : number + diff --git a/tests/cases/compiler/systemModuleAmbientDeclarations.ts b/tests/cases/compiler/systemModuleAmbientDeclarations.ts new file mode 100644 index 00000000000..05f78592780 --- /dev/null +++ b/tests/cases/compiler/systemModuleAmbientDeclarations.ts @@ -0,0 +1,28 @@ +// @module: system +// @separateCompilation: true + +// @filename: file1.ts +declare class Promise { } +declare function Foo(): void; +declare class C {} +declare enum E {X = 1}; + +export var promise = Promise; +export var foo = Foo; +export var c = C; +export var e = E; + +// @filename: file2.ts +export declare function foo(); + +// @filename: file3.ts +export declare class C {} + +// @filename: file4.ts +export declare var v: number; + +// @filename: file5.ts +export declare enum E {X = 1} + +// @filename: file6.ts +export declare module M { var v: number; } From fd5dfb63afff41ca1d79e056dbefd99e67a32d9a Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 11 May 2015 14:01:46 -0700 Subject: [PATCH 051/194] program should store file names with normalized slashes --- src/compiler/program.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 3bd4bdc7ac0..4ad82c069c2 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -238,7 +238,7 @@ module ts { } function getSourceFile(fileName: string) { - fileName = host.getCanonicalFileName(fileName); + fileName = host.getCanonicalFileName(normalizeSlashes(fileName)); return hasProperty(filesByName, fileName) ? filesByName[fileName] : undefined; } @@ -350,7 +350,7 @@ module ts { // Get source file from normalized fileName function findSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refStart?: number, refLength?: number): SourceFile { - let canonicalName = host.getCanonicalFileName(fileName); + let canonicalName = host.getCanonicalFileName(normalizeSlashes(fileName)); if (hasProperty(filesByName, canonicalName)) { // We've already looked for this file, use cached result return getSourceFileFromCache(fileName, canonicalName, /*useAbsolutePath*/ false); From 2252e3045c84aa5cc1b3900f7a6fae9a6c879929 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 12 May 2015 10:57:55 -0700 Subject: [PATCH 052/194] add optional 'getProjectVersion' method to perform fast up-to-date checks --- src/services/services.ts | 14 ++++++++++++++ src/services/shims.ts | 10 ++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/services/services.ts b/src/services/services.ts index bec00b9a66a..4374f3f3ea8 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -949,6 +949,7 @@ module ts { export interface LanguageServiceHost { getCompilationSettings(): CompilerOptions; getNewLine?(): string; + getProjectVersion?(): string; getScriptFileNames(): string[]; getScriptVersion(fileName: string): string; getScriptSnapshot(fileName: string): IScriptSnapshot; @@ -2353,6 +2354,7 @@ module ts { let syntaxTreeCache: SyntaxTreeCache = new SyntaxTreeCache(host); let ruleProvider: formatting.RulesProvider; let program: Program; + let lastProjectVersion: string; let useCaseSensitivefileNames = false; let cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); @@ -2392,6 +2394,18 @@ module ts { } function synchronizeHostData(): void { + // perform fast check if host supports it + if (host.getProjectVersion) { + let hostProjectVersion = host.getProjectVersion(); + if (hostProjectVersion) { + if (lastProjectVersion === hostProjectVersion) { + return; + } + + lastProjectVersion = hostProjectVersion; + } + } + // Get a fresh cache of the host information let hostCache = new HostCache(host, getCanonicalFileName); diff --git a/src/services/shims.ts b/src/services/shims.ts index dc19b8eb79b..795058243d9 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -55,6 +55,7 @@ module ts { getCurrentDirectory(): string; getDefaultLibFileName(options: string): string; getNewLine?(): string; + getProjectVersion?(): string; } /** Public interface of the the of a config service shim instance.*/ @@ -260,6 +261,15 @@ module ts { this.shimHost.error(s); } + public getProjectVersion(): string { + if (!this.shimHost.getProjectVersion) { + // shimmed host does not support getProjectVersion + return undefined; + } + + return this.shimHost.getProjectVersion(); + } + public getCompilationSettings(): CompilerOptions { var settingsJson = this.shimHost.getCompilationSettings(); if (settingsJson == null || settingsJson == "") { From 0b9dd9e2395c682dca2f0c742d6b4099b05d07c7 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 15 May 2015 14:28:02 -0700 Subject: [PATCH 053/194] during file update request only changed portion of the text from the host --- src/services/services.ts | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index bec00b9a66a..08eb1b7521f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1828,7 +1828,34 @@ module ts { if (version !== sourceFile.version) { // Once incremental parsing is ready, then just call into this function. if (!disableIncrementalParsing) { - let newSourceFile = updateSourceFile(sourceFile, scriptSnapshot.getText(0, scriptSnapshot.getLength()), textChangeRange, aggressiveChecks); + let newText: string; + + // grab the fragment from the beginning of the original text to the beginning of the span + let prefix = textChangeRange.span.start !== 0 + ? sourceFile.text.substr(0, textChangeRange.span.start) + : ""; + + // grab the fragment from the end of the span till the end of the original text + let suffix = textChangeRange.span.start + textChangeRange.span.length !== sourceFile.text.length + ? sourceFile.text.substr(textChangeRange.span.start + textChangeRange.span.length) + : ""; + + if (textChangeRange.newLength === 0) { + // edit was a deletion - just combine prefix and suffix + newText = prefix && suffix ? prefix + suffix : prefix || suffix; + } + else { + // it was actual edit, fetch the fragment of new text that correspond to new span + let changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); + // combine prefix, changed text and suffix + newText = prefix && suffix + ? prefix + changedText + suffix + : prefix + ? (prefix + changedText) + : (changedText + suffix); + } + + let newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later From 845820dfe953ce69c98d8aaeef437fff875ccfc0 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 15 May 2015 15:28:02 -0700 Subject: [PATCH 054/194] addressed PR feedback --- src/services/services.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 08eb1b7521f..b66ea095ca2 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1835,9 +1835,10 @@ module ts { ? sourceFile.text.substr(0, textChangeRange.span.start) : ""; + let textChangeRangeEnd = textChangeRange.span.start + textChangeRange.span.length; // grab the fragment from the end of the span till the end of the original text - let suffix = textChangeRange.span.start + textChangeRange.span.length !== sourceFile.text.length - ? sourceFile.text.substr(textChangeRange.span.start + textChangeRange.span.length) + let suffix = textChangeRangeEnd !== sourceFile.text.length + ? sourceFile.text.substr(textChangeRangeEnd) : ""; if (textChangeRange.newLength === 0) { From 1f35f194d23b7371b2eaa3b7d748211e5a7aad7d Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 15 May 2015 16:36:58 -0700 Subject: [PATCH 055/194] use textSpanEnd instead of handrolled version --- src/services/services.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index b66ea095ca2..f70cbd1e79c 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1835,11 +1835,10 @@ module ts { ? sourceFile.text.substr(0, textChangeRange.span.start) : ""; - let textChangeRangeEnd = textChangeRange.span.start + textChangeRange.span.length; // grab the fragment from the end of the span till the end of the original text - let suffix = textChangeRangeEnd !== sourceFile.text.length - ? sourceFile.text.substr(textChangeRangeEnd) - : ""; + let suffix = textSpanEnd(textChangeRange.span) !== sourceFile.text.length + ? sourceFile.text.substr(textSpanEnd(textChangeRange.span)) + : ""; if (textChangeRange.newLength === 0) { // edit was a deletion - just combine prefix and suffix From 3853489628fc00d341d01ca036625be7bff35cb4 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Tue, 19 May 2015 16:25:12 -0700 Subject: [PATCH 056/194] Update version to 1.5.3 for the VS 2015 release --- package.json | 2 +- src/compiler/program.ts | 2 +- src/services/shims.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 88d5db51f72..efa07c72e29 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "http://typescriptlang.org/", - "version": "1.5.2", + "version": "1.5.3", "licenses": [ { "type": "Apache License 2.0", diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 232a74107f7..32503de2566 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -8,7 +8,7 @@ module ts { /* @internal */ export let ioWriteTime = 0; /** The version of the TypeScript compiler release */ - export const version = "1.5.2"; + export const version = "1.5.3"; const carriageReturnLineFeed = "\r\n"; const lineFeed = "\n"; diff --git a/src/services/shims.ts b/src/services/shims.ts index 795058243d9..f5996e1bf04 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -989,4 +989,4 @@ module TypeScript.Services { } /* @internal */ -let toolsVersion = "1.4"; +let toolsVersion = "1.5"; From 635c7038724a415f31da64ec09deb2e5a9cdfe70 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Tue, 19 May 2015 18:07:21 -0700 Subject: [PATCH 057/194] Fix issue in the parsing of tsConfig file, this was fixed in master before, but never ported. The realizeDiagnosticS function already returns an array, no need to wrap again. The realizeDiagnostic (no S) function returns a single diagnostic. --- src/services/shims.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/shims.ts b/src/services/shims.ts index f5996e1bf04..d3f59737538 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -893,7 +893,7 @@ module ts { return { options: configFile.options, files: configFile.fileNames, - errors: [realizeDiagnostics(configFile.errors, '\r\n')] + errors: realizeDiagnostics(configFile.errors, '\r\n') }; }); } From 16d8d9eb0228f77b0715afec1ec9d9bca7cd4ce7 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 19 May 2015 16:17:12 -0700 Subject: [PATCH 058/194] Fix for #2971, adds missing logic in checkFunctionExpressionBodies --- src/compiler/checker.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d956ac189a5..d409d1ea2fa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10930,6 +10930,7 @@ module ts { break; case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: + forEach(node.decorators, checkFunctionExpressionBodies); forEach((node).parameters, checkFunctionExpressionBodies); if (isObjectLiteralMethod(node)) { checkFunctionExpressionOrObjectLiteralMethodBody(node); @@ -10944,6 +10945,7 @@ module ts { case SyntaxKind.WithStatement: checkFunctionExpressionBodies((node).expression); break; + case SyntaxKind.Decorator: case SyntaxKind.Parameter: case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: From e76f920e75f002041e1c53a3fda0fad1bf93c16e Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 19 May 2015 22:07:45 -0700 Subject: [PATCH 059/194] Added tests --- .../decoratorChecksFunctionBodies.errors.txt | 21 ++++++++ .../decoratorChecksFunctionBodies.js | 44 +++++++++++++++ ...ratorInstantiateModulesInFunctionBodies.js | 53 +++++++++++++++++++ ...InstantiateModulesInFunctionBodies.symbols | 34 ++++++++++++ ...orInstantiateModulesInFunctionBodies.types | 40 ++++++++++++++ .../class/decoratorChecksFunctionBodies.ts | 16 ++++++ ...ratorInstantiateModulesInFunctionBodies.ts | 22 ++++++++ 7 files changed, 230 insertions(+) create mode 100644 tests/baselines/reference/decoratorChecksFunctionBodies.errors.txt create mode 100644 tests/baselines/reference/decoratorChecksFunctionBodies.js create mode 100644 tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.js create mode 100644 tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.symbols create mode 100644 tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.types create mode 100644 tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts create mode 100644 tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts diff --git a/tests/baselines/reference/decoratorChecksFunctionBodies.errors.txt b/tests/baselines/reference/decoratorChecksFunctionBodies.errors.txt new file mode 100644 index 00000000000..c8166b538fd --- /dev/null +++ b/tests/baselines/reference/decoratorChecksFunctionBodies.errors.txt @@ -0,0 +1,21 @@ +tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts(9,14): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + + +==== tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts (1 errors) ==== + + // from #2971 + function func(s: string): void { + } + + class A { + @(x => { + var a = 3; + func(a); + ~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + return x; + }) + m() { + + } + } \ No newline at end of file diff --git a/tests/baselines/reference/decoratorChecksFunctionBodies.js b/tests/baselines/reference/decoratorChecksFunctionBodies.js new file mode 100644 index 00000000000..020bc775aea --- /dev/null +++ b/tests/baselines/reference/decoratorChecksFunctionBodies.js @@ -0,0 +1,44 @@ +//// [decoratorChecksFunctionBodies.ts] + +// from #2971 +function func(s: string): void { +} + +class A { + @(x => { + var a = 3; + func(a); + return x; + }) + m() { + + } +} + +//// [decoratorChecksFunctionBodies.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") return Reflect.decorate(decorators, target, key, desc); + switch (arguments.length) { + case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target); + case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0); + case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc); + } +}; +// from #2971 +function func(s) { +} +var A = (function () { + function A() { + } + A.prototype.m = function () { + }; + Object.defineProperty(A.prototype, "m", + __decorate([ + (function (x) { + var a = 3; + func(a); + return x; + }) + ], A.prototype, "m", Object.getOwnPropertyDescriptor(A.prototype, "m"))); + return A; +})(); diff --git a/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.js b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.js new file mode 100644 index 00000000000..313d77fa5ce --- /dev/null +++ b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.js @@ -0,0 +1,53 @@ +//// [tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts] //// + +//// [a.ts] + +// from #3108 +export var test = 'abc'; + +//// [b.ts] +import { test } from './a'; + +function filter(handler: any) { + return function (target: any) { + // ... + }; +} + +class Wat { + @filter(() => test == 'abc') + static whatever() { + // ... + } +} + +//// [a.js] +// from #3108 +exports.test = 'abc'; +//// [b.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") return Reflect.decorate(decorators, target, key, desc); + switch (arguments.length) { + case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target); + case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0); + case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc); + } +}; +var a_1 = require('./a'); +function filter(handler) { + return function (target) { + // ... + }; +} +var Wat = (function () { + function Wat() { + } + Wat.whatever = function () { + // ... + }; + Object.defineProperty(Wat, "whatever", + __decorate([ + filter(function () { return a_1.test == 'abc'; }) + ], Wat, "whatever", Object.getOwnPropertyDescriptor(Wat, "whatever"))); + return Wat; +})(); diff --git a/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.symbols b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.symbols new file mode 100644 index 00000000000..5088e740a57 --- /dev/null +++ b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.symbols @@ -0,0 +1,34 @@ +=== tests/cases/conformance/decorators/class/a.ts === + +// from #3108 +export var test = 'abc'; +>test : Symbol(test, Decl(a.ts, 2, 10)) + +=== tests/cases/conformance/decorators/class/b.ts === +import { test } from './a'; +>test : Symbol(test, Decl(b.ts, 0, 8)) + +function filter(handler: any) { +>filter : Symbol(filter, Decl(b.ts, 0, 27)) +>handler : Symbol(handler, Decl(b.ts, 2, 16)) + + return function (target: any) { +>target : Symbol(target, Decl(b.ts, 3, 21)) + + // ... + }; +} + +class Wat { +>Wat : Symbol(Wat, Decl(b.ts, 6, 1)) + + @filter(() => test == 'abc') +>filter : Symbol(filter, Decl(b.ts, 0, 27)) +>test : Symbol(test, Decl(b.ts, 0, 8)) + + static whatever() { +>whatever : Symbol(Wat.whatever, Decl(b.ts, 8, 11)) + + // ... + } +} diff --git a/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.types b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.types new file mode 100644 index 00000000000..18d993af9bb --- /dev/null +++ b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.types @@ -0,0 +1,40 @@ +=== tests/cases/conformance/decorators/class/a.ts === + +// from #3108 +export var test = 'abc'; +>test : string +>'abc' : string + +=== tests/cases/conformance/decorators/class/b.ts === +import { test } from './a'; +>test : string + +function filter(handler: any) { +>filter : (handler: any) => (target: any) => void +>handler : any + + return function (target: any) { +>function (target: any) { // ... } : (target: any) => void +>target : any + + // ... + }; +} + +class Wat { +>Wat : Wat + + @filter(() => test == 'abc') +>filter(() => test == 'abc') : (target: any) => void +>filter : (handler: any) => (target: any) => void +>() => test == 'abc' : () => boolean +>test == 'abc' : boolean +>test : string +>'abc' : string + + static whatever() { +>whatever : () => void + + // ... + } +} diff --git a/tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts b/tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts new file mode 100644 index 00000000000..31f5fe82551 --- /dev/null +++ b/tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts @@ -0,0 +1,16 @@ +// @target:es5 + +// from #2971 +function func(s: string): void { +} + +class A { + @(x => { + var a = 3; + func(a); + return x; + }) + m() { + + } +} \ No newline at end of file diff --git a/tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts b/tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts new file mode 100644 index 00000000000..7fa7ab8dd84 --- /dev/null +++ b/tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts @@ -0,0 +1,22 @@ +// @target:es5 +// @module:commonjs +// @filename: a.ts + +// from #3108 +export var test = 'abc'; + +// @filename: b.ts +import { test } from './a'; + +function filter(handler: any) { + return function (target: any) { + // ... + }; +} + +class Wat { + @filter(() => test == 'abc') + static whatever() { + // ... + } +} \ No newline at end of file From cfff30914ccedef1b3616c5eb5e6975f38e813ca Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 20 May 2015 10:24:19 -0700 Subject: [PATCH 060/194] Updated LKG --- bin/lib.core.es6.d.ts | 2 + bin/lib.es6.d.ts | 2 + bin/tsc.js | 208 ++++++++++++++-------- bin/tsserver.js | 290 +++++++++++++++++++----------- bin/typescript.d.ts | 3 +- bin/typescript.js | 343 ++++++++++++++++++++++++------------ bin/typescriptServices.d.ts | 3 +- bin/typescriptServices.js | 343 ++++++++++++++++++++++++------------ 8 files changed, 795 insertions(+), 399 deletions(-) diff --git a/bin/lib.core.es6.d.ts b/bin/lib.core.es6.d.ts index 902962cae51..86e2fa3ad70 100644 --- a/bin/lib.core.es6.d.ts +++ b/bin/lib.core.es6.d.ts @@ -4766,6 +4766,7 @@ interface PromiseLike { * @returns A Promise for the completion of which ever callback is executed. */ then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => TResult | PromiseLike): PromiseLike; + then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => void): PromiseLike; } /** @@ -4779,6 +4780,7 @@ interface Promise { * @returns A Promise for the completion of which ever callback is executed. */ then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => TResult | PromiseLike): Promise; + then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => void): Promise; /** * Attaches a callback for only the rejection of the Promise. diff --git a/bin/lib.es6.d.ts b/bin/lib.es6.d.ts index f839a3e3a0b..d6ca7245140 100644 --- a/bin/lib.es6.d.ts +++ b/bin/lib.es6.d.ts @@ -4766,6 +4766,7 @@ interface PromiseLike { * @returns A Promise for the completion of which ever callback is executed. */ then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => TResult | PromiseLike): PromiseLike; + then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => void): PromiseLike; } /** @@ -4779,6 +4780,7 @@ interface Promise { * @returns A Promise for the completion of which ever callback is executed. */ then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => TResult | PromiseLike): Promise; + then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => void): Promise; /** * Attaches a callback for only the rejection of the Promise. diff --git a/bin/tsc.js b/bin/tsc.js index ba5dd4f1d17..b14bf75a46b 100644 --- a/bin/tsc.js +++ b/bin/tsc.js @@ -431,9 +431,13 @@ var ts; return 3; return 2; } + if (path.lastIndexOf("file:///", 0) === 0) { + return "file:///".length; + } var idx = path.indexOf('://'); - if (idx !== -1) - return idx + 3; + if (idx !== -1) { + return idx + "://".length; + } return 0; } ts.getRootLength = getRootLength; @@ -1079,8 +1083,8 @@ var ts; Decorators_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1205, category: ts.DiagnosticCategory.Error, key: "Decorators are only available when targeting ECMAScript 5 and higher." }, Decorators_are_not_valid_here: { code: 1206, category: ts.DiagnosticCategory.Error, key: "Decorators are not valid here." }, Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: { code: 1207, category: ts.DiagnosticCategory.Error, key: "Decorators cannot be applied to multiple get/set accessors of the same name." }, - Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided: { code: 1208, category: ts.DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--separateCompilation' flag is provided." }, - Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided: { code: 1209, category: ts.DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--separateCompilation' flag is provided." }, + Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided: { code: 1208, category: ts.DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--isolatedModules' flag is provided." }, + Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided: { code: 1209, category: ts.DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--isolatedModules' flag is provided." }, Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: { code: 1210, category: ts.DiagnosticCategory.Error, key: "Invalid use of '{0}'. Class definitions are automatically in strict mode." }, A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: ts.DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" }, Identifier_expected_0_is_a_reserved_word_in_strict_mode: { code: 1212, category: ts.DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode" }, @@ -1363,11 +1367,11 @@ var ts; Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: ts.DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." }, Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: ts.DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." }, Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: ts.DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." }, - Option_sourceMap_cannot_be_specified_with_option_separateCompilation: { code: 5043, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'separateCompilation'." }, - Option_declaration_cannot_be_specified_with_option_separateCompilation: { code: 5044, category: ts.DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'separateCompilation'." }, - Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation: { code: 5045, category: ts.DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'separateCompilation'." }, - Option_out_cannot_be_specified_with_option_separateCompilation: { code: 5046, category: ts.DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'separateCompilation'." }, - Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: ts.DiagnosticCategory.Error, key: "Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." }, + Option_sourceMap_cannot_be_specified_with_option_isolatedModules: { code: 5043, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'isolatedModules'." }, + Option_declaration_cannot_be_specified_with_option_isolatedModules: { code: 5044, category: ts.DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'isolatedModules'." }, + Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules: { code: 5045, category: ts.DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'isolatedModules'." }, + Option_out_cannot_be_specified_with_option_isolatedModules: { code: 5046, category: ts.DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'isolatedModules'." }, + Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: ts.DiagnosticCategory.Error, key: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." }, Option_sourceMap_cannot_be_specified_with_option_inlineSourceMap: { code: 5048, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'inlineSourceMap'." }, Option_sourceRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5049, category: ts.DiagnosticCategory.Error, key: "Option 'sourceRoot' cannot be specified with option 'inlineSourceMap'." }, Option_mapRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5050, category: ts.DiagnosticCategory.Error, key: "Option 'mapRoot' cannot be specified with option 'inlineSourceMap'." }, @@ -4410,7 +4414,7 @@ var ts; function shouldEmitToOwnFile(sourceFile, compilerOptions) { if (!isDeclarationFile(sourceFile)) { if ((isExternalModule(sourceFile) || !compilerOptions.out)) { - return compilerOptions.separateCompilation || !ts.fileExtensionIs(sourceFile.fileName, ".js"); + return compilerOptions.isolatedModules || !ts.fileExtensionIs(sourceFile.fileName, ".js"); } return false; } @@ -9117,7 +9121,7 @@ var ts; var symbol = getSymbolOfNode(node); var target = resolveAlias(symbol); if (target) { - var markAlias = (target === unknownSymbol && compilerOptions.separateCompilation) || + var markAlias = (target === unknownSymbol && compilerOptions.isolatedModules) || (target !== unknownSymbol && (target.flags & 107455) && !isConstEnumOrConstEnumOnlyModule(target)); if (markAlias) { markAliasSymbolAsReferenced(symbol); @@ -10427,7 +10431,10 @@ var ts; function getTypeOfAlias(symbol) { var links = getSymbolLinks(symbol); if (!links.type) { - links.type = getTypeOfSymbol(resolveAlias(symbol)); + var targetSymbol = resolveAlias(symbol); + links.type = targetSymbol.flags & 107455 + ? getTypeOfSymbol(targetSymbol) + : unknownType; } return links.type; } @@ -11441,7 +11448,13 @@ var ts; } return false; } + var removeSubtypesStack = []; function removeSubtypes(types) { + var typeListId = getTypeListId(types); + if (removeSubtypesStack.lastIndexOf(typeListId) >= 0) { + return; + } + removeSubtypesStack.push(typeListId); var i = types.length; while (i > 0) { i--; @@ -11449,6 +11462,7 @@ var ts; types.splice(i, 1); } } + removeSubtypesStack.pop(); } function containsAnyType(types) { for (var _i = 0; _i < types.length; _i++) { @@ -13004,31 +13018,33 @@ var ts; if (!isTypeSubtypeOf(rightType, globalFunctionType)) { return type; } + var targetType; var prototypeProperty = getPropertyOfType(rightType, "prototype"); if (prototypeProperty) { - var targetType = getTypeOfSymbol(prototypeProperty); - if (targetType !== anyType) { - if (isTypeSubtypeOf(targetType, type)) { - return targetType; - } - if (type.flags & 16384) { - return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); })); - } + var prototypePropertyType = getTypeOfSymbol(prototypeProperty); + if (prototypePropertyType !== anyType) { + targetType = prototypePropertyType; } } - var constructSignatures; - if (rightType.flags & 2048) { - constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures; + if (!targetType) { + var constructSignatures; + if (rightType.flags & 2048) { + constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures; + } + else if (rightType.flags & 32768) { + constructSignatures = getSignaturesOfType(rightType, 1); + } + if (constructSignatures && constructSignatures.length) { + targetType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })); + } } - else if (rightType.flags & 32768) { - constructSignatures = getSignaturesOfType(rightType, 1); - } - if (constructSignatures && constructSignatures.length !== 0) { - var instanceType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })); + if (targetType) { + if (isTypeSubtypeOf(targetType, type)) { + return targetType; + } if (type.flags & 16384) { - return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, instanceType); })); + return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); })); } - return instanceType; } return type; } @@ -15529,7 +15545,7 @@ var ts; function checkTypeNodeAsExpression(node) { if (node && node.kind === 142) { var type = getTypeFromTypeNode(node); - var shouldCheckIfUnknownType = type === unknownType && compilerOptions.separateCompilation; + var shouldCheckIfUnknownType = type === unknownType && compilerOptions.isolatedModules; if (!type || (!shouldCheckIfUnknownType && type.flags & (1048703 | 132 | 258))) { return; } @@ -16362,7 +16378,7 @@ var ts; checkKindsOfPropertyMemberOverrides(type, baseType); } } - if (baseTypes.length || (baseTypeNode && compilerOptions.separateCompilation)) { + if (baseTypes.length || (baseTypeNode && compilerOptions.isolatedModules)) { checkExpressionOrQualifiedName(baseTypeNode.expression); } var implementedTypeNodes = ts.getClassImplementsHeritageClauseElements(node); @@ -16706,8 +16722,8 @@ var ts; checkExportsOnMergedDeclarations(node); computeEnumMemberValues(node); var enumIsConst = ts.isConst(node); - if (compilerOptions.separateCompilation && enumIsConst && ts.isInAmbientContext(node)) { - error(node.name, ts.Diagnostics.Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided); + if (compilerOptions.isolatedModules && enumIsConst && ts.isInAmbientContext(node)) { + error(node.name, ts.Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided); } var enumSymbol = getSymbolOfNode(node); var firstDeclaration = ts.getDeclarationOfKind(enumSymbol, node.kind); @@ -16779,7 +16795,7 @@ var ts; if (symbol.flags & 512 && symbol.declarations.length > 1 && !ts.isInAmbientContext(node) - && ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation)) { + && ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules)) { var firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol); if (firstNonAmbientClassOrFunc) { if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(firstNonAmbientClassOrFunc)) { @@ -17106,6 +17122,7 @@ var ts; break; case 135: case 134: + ts.forEach(node.decorators, checkFunctionExpressionBodies); ts.forEach(node.parameters, checkFunctionExpressionBodies); if (ts.isObjectLiteralMethod(node)) { checkFunctionExpressionOrObjectLiteralMethodBody(node); @@ -17120,6 +17137,7 @@ var ts; case 193: checkFunctionExpressionBodies(node.expression); break; + case 131: case 130: case 133: case 132: @@ -17701,7 +17719,7 @@ var ts; } function isAliasResolvedToValue(symbol) { var target = resolveAlias(symbol); - if (target === unknownSymbol && compilerOptions.separateCompilation) { + if (target === unknownSymbol && compilerOptions.isolatedModules) { return true; } return target !== unknownSymbol && target && target.flags & 107455 && !isConstEnumOrConstEnumOnlyModule(target); @@ -21259,7 +21277,7 @@ var ts; } return true; } - function emitListWithSpread(elements, multiLine, trailingComma) { + function emitListWithSpread(elements, alwaysCopy, multiLine, trailingComma) { var pos = 0; var group = 0; var length = elements.length; @@ -21275,6 +21293,9 @@ var ts; e = e.expression; emitParenthesizedIf(e, group === 0 && needsParenthesisForPropertyAccessOrInvocation(e)); pos++; + if (pos === length && group === 0 && alwaysCopy && e.kind !== 154) { + write(".slice()"); + } } else { var i = pos; @@ -21312,7 +21333,7 @@ var ts; write("]"); } else { - emitListWithSpread(elements, (node.flags & 512) !== 0, elements.hasTrailingComma); + emitListWithSpread(elements, true, (node.flags & 512) !== 0, elements.hasTrailingComma); } } function emitObjectLiteralBody(node, numElements) { @@ -21528,7 +21549,7 @@ var ts; } } function tryEmitConstantValue(node) { - if (compilerOptions.separateCompilation) { + if (compilerOptions.isolatedModules) { return false; } var constantValue = resolver.getConstantValue(node); @@ -21638,7 +21659,7 @@ var ts; write("void 0"); } write(", "); - emitListWithSpread(node.arguments, false, false); + emitListWithSpread(node.arguments, false, false, false); write(")"); } function emitCallExpression(node) { @@ -22266,7 +22287,7 @@ var ts; if (node.flags & 1) { writeLine(); emitStart(node); - if (compilerOptions.module === 4) { + if (compilerOptions.module === 4 && node.parent === currentSourceFile) { write(exportFunctionForFile + "(\""); if (node.flags & 256) { write("default"); @@ -23622,21 +23643,23 @@ var ts; } function shouldEmitEnumDeclaration(node) { var isConstEnum = ts.isConst(node); - return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.separateCompilation; + return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.isolatedModules; } function emitEnumDeclaration(node) { if (!shouldEmitEnumDeclaration(node)) { return; } - if (!(node.flags & 1) || isES6ExportedDeclaration(node)) { - emitStart(node); - if (isES6ExportedDeclaration(node)) { - write("export "); + if (!shouldHoistDeclarationInSystemJsModule(node)) { + if (!(node.flags & 1) || isES6ExportedDeclaration(node)) { + emitStart(node); + if (isES6ExportedDeclaration(node)) { + write("export "); + } + write("var "); + emit(node.name); + emitEnd(node); + write(";"); } - write("var "); - emit(node.name); - emitEnd(node); - write(";"); } writeLine(); emitStart(node); @@ -23658,7 +23681,7 @@ var ts; emitModuleMemberName(node); write(" = {}));"); emitEnd(node); - if (!isES6ExportedDeclaration(node) && node.flags & 1) { + if (!isES6ExportedDeclaration(node) && node.flags & 1 && !shouldHoistDeclarationInSystemJsModule(node)) { writeLine(); emitStart(node); write("var "); @@ -23669,6 +23692,14 @@ var ts; write(";"); } if (languageVersion < 2 && node.parent === currentSourceFile) { + if (compilerOptions.module === 4 && (node.flags & 1)) { + writeLine(); + write(exportFunctionForFile + "(\""); + emitDeclarationName(node); + write("\", "); + emitDeclarationName(node); + write(")"); + } emitExportMemberAssignments(node.name); } } @@ -23707,7 +23738,7 @@ var ts; } } function shouldEmitModuleDeclaration(node) { - return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation); + return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules); } function isModuleMergedWithES6Class(node) { return languageVersion === 2 && !!(resolver.getNodeCheckFlags(node) & 2048); @@ -24255,12 +24286,25 @@ var ts; if (hoistedVars) { writeLine(); write("var "); + var seen = {}; for (var i = 0; i < hoistedVars.length; ++i) { var local = hoistedVars[i]; + var name_21 = local.kind === 65 + ? local + : local.name; + if (name_21) { + var text = ts.unescapeIdentifier(name_21.text); + if (ts.hasProperty(seen, text)) { + continue; + } + else { + seen[text] = text; + } + } if (i !== 0) { write(", "); } - if (local.kind === 202 || local.kind === 206) { + if (local.kind === 202 || local.kind === 206 || local.kind === 205) { emitDeclarationName(local); } else { @@ -24291,6 +24335,9 @@ var ts; } return exportedDeclarations; function visit(node) { + if (node.flags & 2) { + return; + } if (node.kind === 201) { if (!hoistedFunctionDeclarations) { hoistedFunctionDeclarations = []; @@ -24305,24 +24352,35 @@ var ts; hoistedVars.push(node); return; } - if (node.kind === 206 && shouldEmitModuleDeclaration(node)) { - if (!hoistedVars) { - hoistedVars = []; + if (node.kind === 205) { + if (shouldEmitEnumDeclaration(node)) { + if (!hoistedVars) { + hoistedVars = []; + } + hoistedVars.push(node); + } + return; + } + if (node.kind === 206) { + if (shouldEmitModuleDeclaration(node)) { + if (!hoistedVars) { + hoistedVars = []; + } + hoistedVars.push(node); } - hoistedVars.push(node); return; } if (node.kind === 199 || node.kind === 153) { if (shouldHoistVariable(node, false)) { - var name_21 = node.name; - if (name_21.kind === 65) { + var name_22 = node.name; + if (name_22.kind === 65) { if (!hoistedVars) { hoistedVars = []; } - hoistedVars.push(name_21); + hoistedVars.push(name_22); } else { - ts.forEachChild(name_21, visit); + ts.forEachChild(name_22, visit); } } return; @@ -24636,7 +24694,7 @@ var ts; paramEmitted = true; } } - if (ts.isExternalModule(node) || compilerOptions.separateCompilation) { + if (ts.isExternalModule(node) || compilerOptions.isolatedModules) { if (languageVersion >= 2) { emitES6Module(node, startIndex); } @@ -24992,7 +25050,7 @@ var ts; ts.emitTime = 0; ts.ioReadTime = 0; ts.ioWriteTime = 0; - ts.version = "1.5.2"; + ts.version = "1.5.3"; var carriageReturnLineFeed = "\r\n"; var lineFeed = "\n"; function findConfigFile(searchPath) { @@ -25168,14 +25226,14 @@ var ts; if (options.noEmitOnError && getPreEmitDiagnostics(this).length > 0) { return { diagnostics: [], sourceMaps: undefined, emitSkipped: true }; } - var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile); + var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(options.out ? undefined : sourceFile); var start = new Date().getTime(); var emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile); ts.emitTime += new Date().getTime() - start; return emitResult; } function getSourceFile(fileName) { - fileName = host.getCanonicalFileName(fileName); + fileName = host.getCanonicalFileName(ts.normalizeSlashes(fileName)); return ts.hasProperty(filesByName, fileName) ? filesByName[fileName] : undefined; } function getDiagnosticsHelper(sourceFile, getDiagnostics) { @@ -25266,7 +25324,7 @@ var ts; } } function findSourceFile(fileName, isDefaultLib, refFile, refStart, refLength) { - var canonicalName = host.getCanonicalFileName(fileName); + var canonicalName = host.getCanonicalFileName(ts.normalizeSlashes(fileName)); if (ts.hasProperty(filesByName, canonicalName)) { return getSourceFileFromCache(fileName, canonicalName, false); } @@ -25409,18 +25467,18 @@ var ts; return allFilesBelongToPath; } function verifyCompilerOptions() { - if (options.separateCompilation) { + if (options.isolatedModules) { if (options.sourceMap) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_sourceMap_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_sourceMap_cannot_be_specified_with_option_isolatedModules)); } if (options.declaration) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_declaration_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_declaration_cannot_be_specified_with_option_isolatedModules)); } if (options.noEmitOnError) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules)); } if (options.out) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_out_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_out_cannot_be_specified_with_option_isolatedModules)); } } if (options.inlineSourceMap) { @@ -25450,14 +25508,14 @@ var ts; } var languageVersion = options.target || 0; var firstExternalModuleSourceFile = ts.forEach(files, function (f) { return ts.isExternalModule(f) ? f : undefined; }); - if (options.separateCompilation) { + if (options.isolatedModules) { if (!options.module && languageVersion < 2) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher)); } var firstNonExternalModuleSourceFile = ts.forEach(files, function (f) { return !ts.isExternalModule(f) && !ts.isDeclarationFile(f) ? f : undefined; }); if (firstNonExternalModuleSourceFile) { var span = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile); - diagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided)); + diagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided)); } } else if (firstExternalModuleSourceFile && languageVersion < 2 && !options.module) { @@ -25636,7 +25694,7 @@ var ts; paramType: ts.Diagnostics.LOCATION }, { - name: "separateCompilation", + name: "isolatedModules", type: "boolean" }, { diff --git a/bin/tsserver.js b/bin/tsserver.js index 2e4f2c16c75..9a67ba6eca6 100644 --- a/bin/tsserver.js +++ b/bin/tsserver.js @@ -431,9 +431,13 @@ var ts; return 3; return 2; } + if (path.lastIndexOf("file:///", 0) === 0) { + return "file:///".length; + } var idx = path.indexOf('://'); - if (idx !== -1) - return idx + 3; + if (idx !== -1) { + return idx + "://".length; + } return 0; } ts.getRootLength = getRootLength; @@ -1079,8 +1083,8 @@ var ts; Decorators_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1205, category: ts.DiagnosticCategory.Error, key: "Decorators are only available when targeting ECMAScript 5 and higher." }, Decorators_are_not_valid_here: { code: 1206, category: ts.DiagnosticCategory.Error, key: "Decorators are not valid here." }, Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: { code: 1207, category: ts.DiagnosticCategory.Error, key: "Decorators cannot be applied to multiple get/set accessors of the same name." }, - Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided: { code: 1208, category: ts.DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--separateCompilation' flag is provided." }, - Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided: { code: 1209, category: ts.DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--separateCompilation' flag is provided." }, + Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided: { code: 1208, category: ts.DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--isolatedModules' flag is provided." }, + Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided: { code: 1209, category: ts.DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--isolatedModules' flag is provided." }, Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: { code: 1210, category: ts.DiagnosticCategory.Error, key: "Invalid use of '{0}'. Class definitions are automatically in strict mode." }, A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: ts.DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" }, Identifier_expected_0_is_a_reserved_word_in_strict_mode: { code: 1212, category: ts.DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode" }, @@ -1363,11 +1367,11 @@ var ts; Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: ts.DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." }, Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: ts.DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." }, Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: ts.DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." }, - Option_sourceMap_cannot_be_specified_with_option_separateCompilation: { code: 5043, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'separateCompilation'." }, - Option_declaration_cannot_be_specified_with_option_separateCompilation: { code: 5044, category: ts.DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'separateCompilation'." }, - Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation: { code: 5045, category: ts.DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'separateCompilation'." }, - Option_out_cannot_be_specified_with_option_separateCompilation: { code: 5046, category: ts.DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'separateCompilation'." }, - Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: ts.DiagnosticCategory.Error, key: "Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." }, + Option_sourceMap_cannot_be_specified_with_option_isolatedModules: { code: 5043, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'isolatedModules'." }, + Option_declaration_cannot_be_specified_with_option_isolatedModules: { code: 5044, category: ts.DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'isolatedModules'." }, + Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules: { code: 5045, category: ts.DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'isolatedModules'." }, + Option_out_cannot_be_specified_with_option_isolatedModules: { code: 5046, category: ts.DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'isolatedModules'." }, + Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: ts.DiagnosticCategory.Error, key: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." }, Option_sourceMap_cannot_be_specified_with_option_inlineSourceMap: { code: 5048, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'inlineSourceMap'." }, Option_sourceRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5049, category: ts.DiagnosticCategory.Error, key: "Option 'sourceRoot' cannot be specified with option 'inlineSourceMap'." }, Option_mapRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5050, category: ts.DiagnosticCategory.Error, key: "Option 'mapRoot' cannot be specified with option 'inlineSourceMap'." }, @@ -2850,7 +2854,7 @@ var ts; paramType: ts.Diagnostics.LOCATION }, { - name: "separateCompilation", + name: "isolatedModules", type: "boolean" }, { @@ -4281,7 +4285,7 @@ var ts; function shouldEmitToOwnFile(sourceFile, compilerOptions) { if (!isDeclarationFile(sourceFile)) { if ((isExternalModule(sourceFile) || !compilerOptions.out)) { - return compilerOptions.separateCompilation || !ts.fileExtensionIs(sourceFile.fileName, ".js"); + return compilerOptions.isolatedModules || !ts.fileExtensionIs(sourceFile.fileName, ".js"); } return false; } @@ -9501,7 +9505,7 @@ var ts; var symbol = getSymbolOfNode(node); var target = resolveAlias(symbol); if (target) { - var markAlias = (target === unknownSymbol && compilerOptions.separateCompilation) || + var markAlias = (target === unknownSymbol && compilerOptions.isolatedModules) || (target !== unknownSymbol && (target.flags & 107455) && !isConstEnumOrConstEnumOnlyModule(target)); if (markAlias) { markAliasSymbolAsReferenced(symbol); @@ -10811,7 +10815,10 @@ var ts; function getTypeOfAlias(symbol) { var links = getSymbolLinks(symbol); if (!links.type) { - links.type = getTypeOfSymbol(resolveAlias(symbol)); + var targetSymbol = resolveAlias(symbol); + links.type = targetSymbol.flags & 107455 + ? getTypeOfSymbol(targetSymbol) + : unknownType; } return links.type; } @@ -11825,7 +11832,13 @@ var ts; } return false; } + var removeSubtypesStack = []; function removeSubtypes(types) { + var typeListId = getTypeListId(types); + if (removeSubtypesStack.lastIndexOf(typeListId) >= 0) { + return; + } + removeSubtypesStack.push(typeListId); var i = types.length; while (i > 0) { i--; @@ -11833,6 +11846,7 @@ var ts; types.splice(i, 1); } } + removeSubtypesStack.pop(); } function containsAnyType(types) { for (var _i = 0; _i < types.length; _i++) { @@ -13388,31 +13402,33 @@ var ts; if (!isTypeSubtypeOf(rightType, globalFunctionType)) { return type; } + var targetType; var prototypeProperty = getPropertyOfType(rightType, "prototype"); if (prototypeProperty) { - var targetType = getTypeOfSymbol(prototypeProperty); - if (targetType !== anyType) { - if (isTypeSubtypeOf(targetType, type)) { - return targetType; - } - if (type.flags & 16384) { - return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); })); - } + var prototypePropertyType = getTypeOfSymbol(prototypeProperty); + if (prototypePropertyType !== anyType) { + targetType = prototypePropertyType; } } - var constructSignatures; - if (rightType.flags & 2048) { - constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures; + if (!targetType) { + var constructSignatures; + if (rightType.flags & 2048) { + constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures; + } + else if (rightType.flags & 32768) { + constructSignatures = getSignaturesOfType(rightType, 1); + } + if (constructSignatures && constructSignatures.length) { + targetType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })); + } } - else if (rightType.flags & 32768) { - constructSignatures = getSignaturesOfType(rightType, 1); - } - if (constructSignatures && constructSignatures.length !== 0) { - var instanceType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })); + if (targetType) { + if (isTypeSubtypeOf(targetType, type)) { + return targetType; + } if (type.flags & 16384) { - return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, instanceType); })); + return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); })); } - return instanceType; } return type; } @@ -15913,7 +15929,7 @@ var ts; function checkTypeNodeAsExpression(node) { if (node && node.kind === 142) { var type = getTypeFromTypeNode(node); - var shouldCheckIfUnknownType = type === unknownType && compilerOptions.separateCompilation; + var shouldCheckIfUnknownType = type === unknownType && compilerOptions.isolatedModules; if (!type || (!shouldCheckIfUnknownType && type.flags & (1048703 | 132 | 258))) { return; } @@ -16746,7 +16762,7 @@ var ts; checkKindsOfPropertyMemberOverrides(type, baseType); } } - if (baseTypes.length || (baseTypeNode && compilerOptions.separateCompilation)) { + if (baseTypes.length || (baseTypeNode && compilerOptions.isolatedModules)) { checkExpressionOrQualifiedName(baseTypeNode.expression); } var implementedTypeNodes = ts.getClassImplementsHeritageClauseElements(node); @@ -17090,8 +17106,8 @@ var ts; checkExportsOnMergedDeclarations(node); computeEnumMemberValues(node); var enumIsConst = ts.isConst(node); - if (compilerOptions.separateCompilation && enumIsConst && ts.isInAmbientContext(node)) { - error(node.name, ts.Diagnostics.Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided); + if (compilerOptions.isolatedModules && enumIsConst && ts.isInAmbientContext(node)) { + error(node.name, ts.Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided); } var enumSymbol = getSymbolOfNode(node); var firstDeclaration = ts.getDeclarationOfKind(enumSymbol, node.kind); @@ -17163,7 +17179,7 @@ var ts; if (symbol.flags & 512 && symbol.declarations.length > 1 && !ts.isInAmbientContext(node) - && ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation)) { + && ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules)) { var firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol); if (firstNonAmbientClassOrFunc) { if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(firstNonAmbientClassOrFunc)) { @@ -17490,6 +17506,7 @@ var ts; break; case 135: case 134: + ts.forEach(node.decorators, checkFunctionExpressionBodies); ts.forEach(node.parameters, checkFunctionExpressionBodies); if (ts.isObjectLiteralMethod(node)) { checkFunctionExpressionOrObjectLiteralMethodBody(node); @@ -17504,6 +17521,7 @@ var ts; case 193: checkFunctionExpressionBodies(node.expression); break; + case 131: case 130: case 133: case 132: @@ -18085,7 +18103,7 @@ var ts; } function isAliasResolvedToValue(symbol) { var target = resolveAlias(symbol); - if (target === unknownSymbol && compilerOptions.separateCompilation) { + if (target === unknownSymbol && compilerOptions.isolatedModules) { return true; } return target !== unknownSymbol && target && target.flags & 107455 && !isConstEnumOrConstEnumOnlyModule(target); @@ -21643,7 +21661,7 @@ var ts; } return true; } - function emitListWithSpread(elements, multiLine, trailingComma) { + function emitListWithSpread(elements, alwaysCopy, multiLine, trailingComma) { var pos = 0; var group = 0; var length = elements.length; @@ -21659,6 +21677,9 @@ var ts; e = e.expression; emitParenthesizedIf(e, group === 0 && needsParenthesisForPropertyAccessOrInvocation(e)); pos++; + if (pos === length && group === 0 && alwaysCopy && e.kind !== 154) { + write(".slice()"); + } } else { var i = pos; @@ -21696,7 +21717,7 @@ var ts; write("]"); } else { - emitListWithSpread(elements, (node.flags & 512) !== 0, elements.hasTrailingComma); + emitListWithSpread(elements, true, (node.flags & 512) !== 0, elements.hasTrailingComma); } } function emitObjectLiteralBody(node, numElements) { @@ -21912,7 +21933,7 @@ var ts; } } function tryEmitConstantValue(node) { - if (compilerOptions.separateCompilation) { + if (compilerOptions.isolatedModules) { return false; } var constantValue = resolver.getConstantValue(node); @@ -22022,7 +22043,7 @@ var ts; write("void 0"); } write(", "); - emitListWithSpread(node.arguments, false, false); + emitListWithSpread(node.arguments, false, false, false); write(")"); } function emitCallExpression(node) { @@ -22650,7 +22671,7 @@ var ts; if (node.flags & 1) { writeLine(); emitStart(node); - if (compilerOptions.module === 4) { + if (compilerOptions.module === 4 && node.parent === currentSourceFile) { write(exportFunctionForFile + "(\""); if (node.flags & 256) { write("default"); @@ -24006,21 +24027,23 @@ var ts; } function shouldEmitEnumDeclaration(node) { var isConstEnum = ts.isConst(node); - return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.separateCompilation; + return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.isolatedModules; } function emitEnumDeclaration(node) { if (!shouldEmitEnumDeclaration(node)) { return; } - if (!(node.flags & 1) || isES6ExportedDeclaration(node)) { - emitStart(node); - if (isES6ExportedDeclaration(node)) { - write("export "); + if (!shouldHoistDeclarationInSystemJsModule(node)) { + if (!(node.flags & 1) || isES6ExportedDeclaration(node)) { + emitStart(node); + if (isES6ExportedDeclaration(node)) { + write("export "); + } + write("var "); + emit(node.name); + emitEnd(node); + write(";"); } - write("var "); - emit(node.name); - emitEnd(node); - write(";"); } writeLine(); emitStart(node); @@ -24042,7 +24065,7 @@ var ts; emitModuleMemberName(node); write(" = {}));"); emitEnd(node); - if (!isES6ExportedDeclaration(node) && node.flags & 1) { + if (!isES6ExportedDeclaration(node) && node.flags & 1 && !shouldHoistDeclarationInSystemJsModule(node)) { writeLine(); emitStart(node); write("var "); @@ -24053,6 +24076,14 @@ var ts; write(";"); } if (languageVersion < 2 && node.parent === currentSourceFile) { + if (compilerOptions.module === 4 && (node.flags & 1)) { + writeLine(); + write(exportFunctionForFile + "(\""); + emitDeclarationName(node); + write("\", "); + emitDeclarationName(node); + write(")"); + } emitExportMemberAssignments(node.name); } } @@ -24091,7 +24122,7 @@ var ts; } } function shouldEmitModuleDeclaration(node) { - return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation); + return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules); } function isModuleMergedWithES6Class(node) { return languageVersion === 2 && !!(resolver.getNodeCheckFlags(node) & 2048); @@ -24639,12 +24670,25 @@ var ts; if (hoistedVars) { writeLine(); write("var "); + var seen = {}; for (var i = 0; i < hoistedVars.length; ++i) { var local = hoistedVars[i]; + var name_21 = local.kind === 65 + ? local + : local.name; + if (name_21) { + var text = ts.unescapeIdentifier(name_21.text); + if (ts.hasProperty(seen, text)) { + continue; + } + else { + seen[text] = text; + } + } if (i !== 0) { write(", "); } - if (local.kind === 202 || local.kind === 206) { + if (local.kind === 202 || local.kind === 206 || local.kind === 205) { emitDeclarationName(local); } else { @@ -24675,6 +24719,9 @@ var ts; } return exportedDeclarations; function visit(node) { + if (node.flags & 2) { + return; + } if (node.kind === 201) { if (!hoistedFunctionDeclarations) { hoistedFunctionDeclarations = []; @@ -24689,24 +24736,35 @@ var ts; hoistedVars.push(node); return; } - if (node.kind === 206 && shouldEmitModuleDeclaration(node)) { - if (!hoistedVars) { - hoistedVars = []; + if (node.kind === 205) { + if (shouldEmitEnumDeclaration(node)) { + if (!hoistedVars) { + hoistedVars = []; + } + hoistedVars.push(node); + } + return; + } + if (node.kind === 206) { + if (shouldEmitModuleDeclaration(node)) { + if (!hoistedVars) { + hoistedVars = []; + } + hoistedVars.push(node); } - hoistedVars.push(node); return; } if (node.kind === 199 || node.kind === 153) { if (shouldHoistVariable(node, false)) { - var name_21 = node.name; - if (name_21.kind === 65) { + var name_22 = node.name; + if (name_22.kind === 65) { if (!hoistedVars) { hoistedVars = []; } - hoistedVars.push(name_21); + hoistedVars.push(name_22); } else { - ts.forEachChild(name_21, visit); + ts.forEachChild(name_22, visit); } } return; @@ -25020,7 +25078,7 @@ var ts; paramEmitted = true; } } - if (ts.isExternalModule(node) || compilerOptions.separateCompilation) { + if (ts.isExternalModule(node) || compilerOptions.isolatedModules) { if (languageVersion >= 2) { emitES6Module(node, startIndex); } @@ -25376,7 +25434,7 @@ var ts; ts.emitTime = 0; ts.ioReadTime = 0; ts.ioWriteTime = 0; - ts.version = "1.5.2"; + ts.version = "1.5.3"; var carriageReturnLineFeed = "\r\n"; var lineFeed = "\n"; function findConfigFile(searchPath) { @@ -25552,14 +25610,14 @@ var ts; if (options.noEmitOnError && getPreEmitDiagnostics(this).length > 0) { return { diagnostics: [], sourceMaps: undefined, emitSkipped: true }; } - var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile); + var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(options.out ? undefined : sourceFile); var start = new Date().getTime(); var emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile); ts.emitTime += new Date().getTime() - start; return emitResult; } function getSourceFile(fileName) { - fileName = host.getCanonicalFileName(fileName); + fileName = host.getCanonicalFileName(ts.normalizeSlashes(fileName)); return ts.hasProperty(filesByName, fileName) ? filesByName[fileName] : undefined; } function getDiagnosticsHelper(sourceFile, getDiagnostics) { @@ -25650,7 +25708,7 @@ var ts; } } function findSourceFile(fileName, isDefaultLib, refFile, refStart, refLength) { - var canonicalName = host.getCanonicalFileName(fileName); + var canonicalName = host.getCanonicalFileName(ts.normalizeSlashes(fileName)); if (ts.hasProperty(filesByName, canonicalName)) { return getSourceFileFromCache(fileName, canonicalName, false); } @@ -25793,18 +25851,18 @@ var ts; return allFilesBelongToPath; } function verifyCompilerOptions() { - if (options.separateCompilation) { + if (options.isolatedModules) { if (options.sourceMap) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_sourceMap_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_sourceMap_cannot_be_specified_with_option_isolatedModules)); } if (options.declaration) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_declaration_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_declaration_cannot_be_specified_with_option_isolatedModules)); } if (options.noEmitOnError) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules)); } if (options.out) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_out_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_out_cannot_be_specified_with_option_isolatedModules)); } } if (options.inlineSourceMap) { @@ -25834,14 +25892,14 @@ var ts; } var languageVersion = options.target || 0; var firstExternalModuleSourceFile = ts.forEach(files, function (f) { return ts.isExternalModule(f) ? f : undefined; }); - if (options.separateCompilation) { + if (options.isolatedModules) { if (!options.module && languageVersion < 2) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher)); } var firstNonExternalModuleSourceFile = ts.forEach(files, function (f) { return !ts.isExternalModule(f) && !ts.isDeclarationFile(f) ? f : undefined; }); if (firstNonExternalModuleSourceFile) { var span = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile); - diagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided)); + diagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided)); } } else if (firstExternalModuleSourceFile && languageVersion < 2 && !options.module) { @@ -26402,10 +26460,10 @@ var ts; ts.forEach(program.getSourceFiles(), function (sourceFile) { cancellationToken.throwIfCancellationRequested(); var nameToDeclarations = sourceFile.getNamedDeclarations(); - for (var name_22 in nameToDeclarations) { - var declarations = ts.getProperty(nameToDeclarations, name_22); + for (var name_23 in nameToDeclarations) { + var declarations = ts.getProperty(nameToDeclarations, name_23); if (declarations) { - var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_22); + var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_23); if (!matches) { continue; } @@ -26416,14 +26474,14 @@ var ts; if (!containers) { return undefined; } - matches = patternMatcher.getMatches(containers, name_22); + matches = patternMatcher.getMatches(containers, name_23); if (!matches) { continue; } } var fileName = sourceFile.fileName; var matchKind = bestMatchKind(matches); - rawItems.push({ name: name_22, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); + rawItems.push({ name: name_23, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); } } } @@ -26753,9 +26811,9 @@ var ts; case 199: case 153: var variableDeclarationNode; - var name_23; + var name_24; if (node.kind === 153) { - name_23 = node.name; + name_24 = node.name; variableDeclarationNode = node; while (variableDeclarationNode && variableDeclarationNode.kind !== 199) { variableDeclarationNode = variableDeclarationNode.parent; @@ -26765,16 +26823,16 @@ var ts; else { ts.Debug.assert(!ts.isBindingPattern(node.name)); variableDeclarationNode = node; - name_23 = node.name; + name_24 = node.name; } if (ts.isConst(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_23), ts.ScriptElementKind.constElement); + return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.constElement); } else if (ts.isLet(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_23), ts.ScriptElementKind.letElement); + return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.letElement); } else { - return createItem(node, getTextOfNode(name_23), ts.ScriptElementKind.variableElement); + return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.variableElement); } case 136: return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); @@ -28766,9 +28824,9 @@ var ts; } Rules.prototype.getRuleName = function (rule) { var o = this; - for (var name_24 in o) { - if (o[name_24] === rule) { - return name_24; + for (var name_25 in o) { + if (o[name_25] === rule) { + return name_25; } } throw new Error("Unknown rule"); @@ -31298,7 +31356,7 @@ var ts; } function transpile(input, compilerOptions, fileName, diagnostics) { var options = compilerOptions ? ts.clone(compilerOptions) : getDefaultCompilerOptions(); - options.separateCompilation = true; + options.isolatedModules = true; options.allowNonTsExtensions = true; var inputFileName = fileName || "module.ts"; var sourceFile = ts.createSourceFile(inputFileName, input, options.target); @@ -31339,7 +31397,25 @@ var ts; if (textChangeRange) { if (version !== sourceFile.version) { if (!ts.disableIncrementalParsing) { - var newSourceFile = ts.updateSourceFile(sourceFile, scriptSnapshot.getText(0, scriptSnapshot.getLength()), textChangeRange, aggressiveChecks); + var newText; + var prefix = textChangeRange.span.start !== 0 + ? sourceFile.text.substr(0, textChangeRange.span.start) + : ""; + var suffix = ts.textSpanEnd(textChangeRange.span) !== sourceFile.text.length + ? sourceFile.text.substr(ts.textSpanEnd(textChangeRange.span)) + : ""; + if (textChangeRange.newLength === 0) { + newText = prefix && suffix ? prefix + suffix : prefix || suffix; + } + else { + var changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); + newText = prefix && suffix + ? prefix + changedText + suffix + : prefix + ? (prefix + changedText) + : (changedText + suffix); + } + var newSourceFile = ts.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); newSourceFile.nameTable = undefined; return newSourceFile; @@ -31751,6 +31827,7 @@ var ts; var syntaxTreeCache = new SyntaxTreeCache(host); var ruleProvider; var program; + var lastProjectVersion; var useCaseSensitivefileNames = false; var cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); if (!ts.localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) { @@ -31780,6 +31857,15 @@ var ts; return ruleProvider; } function synchronizeHostData() { + if (host.getProjectVersion) { + var hostProjectVersion = host.getProjectVersion(); + if (hostProjectVersion) { + if (lastProjectVersion === hostProjectVersion) { + return; + } + lastProjectVersion = hostProjectVersion; + } + } var hostCache = new HostCache(host, getCanonicalFileName); if (programUpToDate()) { return; @@ -32451,10 +32537,10 @@ var ts; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; var nameTable = getNameTable(sourceFile); - for (var name_25 in nameTable) { - if (!allNames[name_25]) { - allNames[name_25] = name_25; - var displayName = getCompletionEntryDisplayName(name_25, target, true); + for (var name_26 in nameTable) { + if (!allNames[name_26]) { + allNames[name_26] = name_26; + var displayName = getCompletionEntryDisplayName(name_26, target, true); if (displayName) { var entry = { name: displayName, @@ -34133,17 +34219,17 @@ var ts; if (isNameOfPropertyAssignment(node)) { var objectLiteral = node.parent.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name_26 = node.text; + var name_27 = node.text; if (contextualType) { if (contextualType.flags & 16384) { - var unionProperty = contextualType.getProperty(name_26); + var unionProperty = contextualType.getProperty(name_27); if (unionProperty) { return [unionProperty]; } else { var result_4 = []; ts.forEach(contextualType.types, function (t) { - var symbol = t.getProperty(name_26); + var symbol = t.getProperty(name_27); if (symbol) { result_4.push(symbol); } @@ -34152,7 +34238,7 @@ var ts; } } else { - var symbol_1 = contextualType.getProperty(name_26); + var symbol_1 = contextualType.getProperty(name_27); if (symbol_1) { return [symbol_1]; } @@ -34529,10 +34615,10 @@ var ts; var kind = triviaScanner.scan(); var end = triviaScanner.getTextPos(); var width = end - start; + if (!ts.isTrivia(kind)) { + return; + } if (ts.textSpanIntersectsWith(span, start, width)) { - if (!ts.isTrivia(kind)) { - return; - } if (ts.isComment(kind)) { pushClassification(start, width, 1); continue; diff --git a/bin/typescript.d.ts b/bin/typescript.d.ts index 3e765a33f01..52a5cc8a96e 100644 --- a/bin/typescript.d.ts +++ b/bin/typescript.d.ts @@ -1114,7 +1114,7 @@ declare module "typescript" { target?: ScriptTarget; version?: boolean; watch?: boolean; - separateCompilation?: boolean; + isolatedModules?: boolean; emitDecoratorMetadata?: boolean; [option: string]: string | number | boolean; } @@ -1379,6 +1379,7 @@ declare module "typescript" { interface LanguageServiceHost { getCompilationSettings(): CompilerOptions; getNewLine?(): string; + getProjectVersion?(): string; getScriptFileNames(): string[]; getScriptVersion(fileName: string): string; getScriptSnapshot(fileName: string): IScriptSnapshot; diff --git a/bin/typescript.js b/bin/typescript.js index 4a17fb94c2c..940ce1e211f 100644 --- a/bin/typescript.js +++ b/bin/typescript.js @@ -1129,9 +1129,18 @@ var ts; return 3; return 2; } + // Per RFC 1738 'file' URI schema has the shape file:/// + // if is omitted then it is assumed that host value is 'localhost', + // however slash after the omitted is not removed. + // file:///folder1/file1 - this is a correct URI + // file://folder2/file2 - this is an incorrect URI + if (path.lastIndexOf("file:///", 0) === 0) { + return "file:///".length; + } var idx = path.indexOf('://'); - if (idx !== -1) - return idx + 3; + if (idx !== -1) { + return idx + "://".length; + } return 0; } ts.getRootLength = getRootLength; @@ -1822,8 +1831,8 @@ var ts; Decorators_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1205, category: ts.DiagnosticCategory.Error, key: "Decorators are only available when targeting ECMAScript 5 and higher." }, Decorators_are_not_valid_here: { code: 1206, category: ts.DiagnosticCategory.Error, key: "Decorators are not valid here." }, Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: { code: 1207, category: ts.DiagnosticCategory.Error, key: "Decorators cannot be applied to multiple get/set accessors of the same name." }, - Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided: { code: 1208, category: ts.DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--separateCompilation' flag is provided." }, - Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided: { code: 1209, category: ts.DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--separateCompilation' flag is provided." }, + Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided: { code: 1208, category: ts.DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--isolatedModules' flag is provided." }, + Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided: { code: 1209, category: ts.DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--isolatedModules' flag is provided." }, Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: { code: 1210, category: ts.DiagnosticCategory.Error, key: "Invalid use of '{0}'. Class definitions are automatically in strict mode." }, A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: ts.DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" }, Identifier_expected_0_is_a_reserved_word_in_strict_mode: { code: 1212, category: ts.DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode" }, @@ -2106,11 +2115,11 @@ var ts; Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: ts.DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." }, Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: ts.DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." }, Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: ts.DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." }, - Option_sourceMap_cannot_be_specified_with_option_separateCompilation: { code: 5043, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'separateCompilation'." }, - Option_declaration_cannot_be_specified_with_option_separateCompilation: { code: 5044, category: ts.DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'separateCompilation'." }, - Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation: { code: 5045, category: ts.DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'separateCompilation'." }, - Option_out_cannot_be_specified_with_option_separateCompilation: { code: 5046, category: ts.DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'separateCompilation'." }, - Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: ts.DiagnosticCategory.Error, key: "Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." }, + Option_sourceMap_cannot_be_specified_with_option_isolatedModules: { code: 5043, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'isolatedModules'." }, + Option_declaration_cannot_be_specified_with_option_isolatedModules: { code: 5044, category: ts.DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'isolatedModules'." }, + Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules: { code: 5045, category: ts.DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'isolatedModules'." }, + Option_out_cannot_be_specified_with_option_isolatedModules: { code: 5046, category: ts.DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'isolatedModules'." }, + Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: ts.DiagnosticCategory.Error, key: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." }, Option_sourceMap_cannot_be_specified_with_option_inlineSourceMap: { code: 5048, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'inlineSourceMap'." }, Option_sourceRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5049, category: ts.DiagnosticCategory.Error, key: "Option 'sourceRoot' cannot be specified with option 'inlineSourceMap'." }, Option_mapRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5050, category: ts.DiagnosticCategory.Error, key: "Option 'mapRoot' cannot be specified with option 'inlineSourceMap'." }, @@ -5468,7 +5477,7 @@ var ts; if ((isExternalModule(sourceFile) || !compilerOptions.out)) { // 1. in-browser single file compilation scenario // 2. non .js file - return compilerOptions.separateCompilation || !ts.fileExtensionIs(sourceFile.fileName, ".js"); + return compilerOptions.isolatedModules || !ts.fileExtensionIs(sourceFile.fileName, ".js"); } return false; } @@ -11418,7 +11427,7 @@ var ts; var symbol = getSymbolOfNode(node); var target = resolveAlias(symbol); if (target) { - var markAlias = (target === unknownSymbol && compilerOptions.separateCompilation) || + var markAlias = (target === unknownSymbol && compilerOptions.isolatedModules) || (target !== unknownSymbol && (target.flags & 107455 /* Value */) && !isConstEnumOrConstEnumOnlyModule(target)); if (markAlias) { markAliasSymbolAsReferenced(symbol); @@ -12945,7 +12954,15 @@ var ts; function getTypeOfAlias(symbol) { var links = getSymbolLinks(symbol); if (!links.type) { - links.type = getTypeOfSymbol(resolveAlias(symbol)); + var targetSymbol = resolveAlias(symbol); + // It only makes sense to get the type of a value symbol. If the result of resolving + // the alias is not a value, then it has no type. To get the type associated with a + // type symbol, call getDeclaredTypeOfSymbol. + // This check is important because without it, a call to getTypeOfSymbol could end + // up recursively calling getTypeOfAlias, causing a stack overflow. + links.type = targetSymbol.flags & 107455 /* Value */ + ? getTypeOfSymbol(targetSymbol) + : unknownType; } return links.type; } @@ -14021,7 +14038,17 @@ var ts; } return false; } + // Since removeSubtypes checks the subtype relation, and the subtype relation on a union + // may attempt to reduce a union, it is possible that removeSubtypes could be called + // recursively on the same set of types. The removeSubtypesStack is used to track which + // sets of types are currently undergoing subtype reduction. + var removeSubtypesStack = []; function removeSubtypes(types) { + var typeListId = getTypeListId(types); + if (removeSubtypesStack.lastIndexOf(typeListId) >= 0) { + return; + } + removeSubtypesStack.push(typeListId); var i = types.length; while (i > 0) { i--; @@ -14029,6 +14056,7 @@ var ts; types.splice(i, 1); } } + removeSubtypesStack.pop(); } function containsAnyType(types) { for (var _i = 0; _i < types.length; _i++) { @@ -15730,36 +15758,37 @@ var ts; if (!isTypeSubtypeOf(rightType, globalFunctionType)) { return type; } - // Target type is type of prototype property + var targetType; var prototypeProperty = getPropertyOfType(rightType, "prototype"); if (prototypeProperty) { - var targetType = getTypeOfSymbol(prototypeProperty); - if (targetType !== anyType) { - // Narrow to the target type if it's a subtype of the current type - if (isTypeSubtypeOf(targetType, type)) { - return targetType; - } - // If the current type is a union type, remove all constituents that aren't subtypes of the target. - if (type.flags & 16384 /* Union */) { - return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); })); - } + // Target type is type of the protoype property + var prototypePropertyType = getTypeOfSymbol(prototypeProperty); + if (prototypePropertyType !== anyType) { + targetType = prototypePropertyType; } } - // Target type is type of construct signature - var constructSignatures; - if (rightType.flags & 2048 /* Interface */) { - constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures; + if (!targetType) { + // Target type is type of construct signature + var constructSignatures; + if (rightType.flags & 2048 /* Interface */) { + constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures; + } + else if (rightType.flags & 32768 /* Anonymous */) { + constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */); + } + if (constructSignatures && constructSignatures.length) { + targetType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })); + } } - else if (rightType.flags & 32768 /* Anonymous */) { - constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */); - } - if (constructSignatures && constructSignatures.length !== 0) { - var instanceType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })); - // Pickup type from union types + if (targetType) { + // Narrow to the target type if it's a subtype of the current type + if (isTypeSubtypeOf(targetType, type)) { + return targetType; + } + // If the current type is a union type, remove all constituents that aren't subtypes of the target. if (type.flags & 16384 /* Union */) { - return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, instanceType); })); + return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); })); } - return instanceType; } return type; } @@ -18853,7 +18882,7 @@ var ts; // serialize the type metadata. if (node && node.kind === 142 /* TypeReference */) { var type = getTypeFromTypeNode(node); - var shouldCheckIfUnknownType = type === unknownType && compilerOptions.separateCompilation; + var shouldCheckIfUnknownType = type === unknownType && compilerOptions.isolatedModules; if (!type || (!shouldCheckIfUnknownType && type.flags & (1048703 /* Intrinsic */ | 132 /* NumberLike */ | 258 /* StringLike */))) { return; } @@ -19863,7 +19892,7 @@ var ts; checkKindsOfPropertyMemberOverrides(type, baseType); } } - if (baseTypes.length || (baseTypeNode && compilerOptions.separateCompilation)) { + if (baseTypes.length || (baseTypeNode && compilerOptions.isolatedModules)) { // Check that base type can be evaluated as expression checkExpressionOrQualifiedName(baseTypeNode.expression); } @@ -20232,8 +20261,8 @@ var ts; checkExportsOnMergedDeclarations(node); computeEnumMemberValues(node); var enumIsConst = ts.isConst(node); - if (compilerOptions.separateCompilation && enumIsConst && ts.isInAmbientContext(node)) { - error(node.name, ts.Diagnostics.Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided); + if (compilerOptions.isolatedModules && enumIsConst && ts.isInAmbientContext(node)) { + error(node.name, ts.Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided); } // Spec 2014 - Section 9.3: // It isn't possible for one enum declaration to continue the automatic numbering sequence of another, @@ -20315,7 +20344,7 @@ var ts; if (symbol.flags & 512 /* ValueModule */ && symbol.declarations.length > 1 && !ts.isInAmbientContext(node) - && ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation)) { + && ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules)) { var firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol); if (firstNonAmbientClassOrFunc) { if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(firstNonAmbientClassOrFunc)) { @@ -20666,6 +20695,7 @@ var ts; break; case 135 /* MethodDeclaration */: case 134 /* MethodSignature */: + ts.forEach(node.decorators, checkFunctionExpressionBodies); ts.forEach(node.parameters, checkFunctionExpressionBodies); if (ts.isObjectLiteralMethod(node)) { checkFunctionExpressionOrObjectLiteralMethodBody(node); @@ -20680,6 +20710,7 @@ var ts; case 193 /* WithStatement */: checkFunctionExpressionBodies(node.expression); break; + case 131 /* Decorator */: case 130 /* Parameter */: case 133 /* PropertyDeclaration */: case 132 /* PropertySignature */: @@ -21317,7 +21348,7 @@ var ts; } function isAliasResolvedToValue(symbol) { var target = resolveAlias(symbol); - if (target === unknownSymbol && compilerOptions.separateCompilation) { + if (target === unknownSymbol && compilerOptions.isolatedModules) { return true; } // const enums and modules that contain only const enums are not considered values from the emit perespective @@ -25321,7 +25352,7 @@ var ts; } return true; } - function emitListWithSpread(elements, multiLine, trailingComma) { + function emitListWithSpread(elements, alwaysCopy, multiLine, trailingComma) { var pos = 0; var group = 0; var length = elements.length; @@ -25338,6 +25369,9 @@ var ts; e = e.expression; emitParenthesizedIf(e, group === 0 && needsParenthesisForPropertyAccessOrInvocation(e)); pos++; + if (pos === length && group === 0 && alwaysCopy && e.kind !== 154 /* ArrayLiteralExpression */) { + write(".slice()"); + } } else { var i = pos; @@ -25375,7 +25409,7 @@ var ts; write("]"); } else { - emitListWithSpread(elements, (node.flags & 512 /* MultiLine */) !== 0, + emitListWithSpread(elements, true, (node.flags & 512 /* MultiLine */) !== 0, /*trailingComma*/ elements.hasTrailingComma); } } @@ -25627,7 +25661,7 @@ var ts; } } function tryEmitConstantValue(node) { - if (compilerOptions.separateCompilation) { + if (compilerOptions.isolatedModules) { // do not inline enum values in separate compilation mode return false; } @@ -25747,7 +25781,7 @@ var ts; write("void 0"); } write(", "); - emitListWithSpread(node.arguments, false, false); + emitListWithSpread(node.arguments, false, false, false); write(")"); } function emitCallExpression(node) { @@ -26451,7 +26485,8 @@ var ts; if (node.flags & 1 /* Export */) { writeLine(); emitStart(node); - if (compilerOptions.module === 4 /* System */) { + // emit call to exporter only for top level nodes + if (compilerOptions.module === 4 /* System */ && node.parent === currentSourceFile) { // emit export default as // export("default", ) write(exportFunctionForFile + "(\""); @@ -28021,22 +28056,25 @@ var ts; } function shouldEmitEnumDeclaration(node) { var isConstEnum = ts.isConst(node); - return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.separateCompilation; + return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.isolatedModules; } function emitEnumDeclaration(node) { // const enums are completely erased during compilation. if (!shouldEmitEnumDeclaration(node)) { return; } - if (!(node.flags & 1 /* Export */) || isES6ExportedDeclaration(node)) { - emitStart(node); - if (isES6ExportedDeclaration(node)) { - write("export "); + if (!shouldHoistDeclarationInSystemJsModule(node)) { + // do not emit var if variable was already hoisted + if (!(node.flags & 1 /* Export */) || isES6ExportedDeclaration(node)) { + emitStart(node); + if (isES6ExportedDeclaration(node)) { + write("export "); + } + write("var "); + emit(node.name); + emitEnd(node); + write(";"); } - write("var "); - emit(node.name); - emitEnd(node); - write(";"); } writeLine(); emitStart(node); @@ -28058,7 +28096,8 @@ var ts; emitModuleMemberName(node); write(" = {}));"); emitEnd(node); - if (!isES6ExportedDeclaration(node) && node.flags & 1 /* Export */) { + if (!isES6ExportedDeclaration(node) && node.flags & 1 /* Export */ && !shouldHoistDeclarationInSystemJsModule(node)) { + // do not emit var if variable was already hoisted writeLine(); emitStart(node); write("var "); @@ -28069,6 +28108,15 @@ var ts; write(";"); } if (languageVersion < 2 /* ES6 */ && node.parent === currentSourceFile) { + if (compilerOptions.module === 4 /* System */ && (node.flags & 1 /* Export */)) { + // write the call to exporter for enum + writeLine(); + write(exportFunctionForFile + "(\""); + emitDeclarationName(node); + write("\", "); + emitDeclarationName(node); + write(")"); + } emitExportMemberAssignments(node.name); } } @@ -28107,7 +28155,7 @@ var ts; } } function shouldEmitModuleDeclaration(node) { - return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation); + return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules); } function isModuleMergedWithES6Class(node) { return languageVersion === 2 /* ES6 */ && !!(resolver.getNodeCheckFlags(node) & 2048 /* LexicalModuleMergesWithClass */); @@ -28708,12 +28756,26 @@ var ts; if (hoistedVars) { writeLine(); write("var "); + var seen = {}; for (var i = 0; i < hoistedVars.length; ++i) { var local = hoistedVars[i]; + var name_21 = local.kind === 65 /* Identifier */ + ? local + : local.name; + if (name_21) { + // do not emit duplicate entries (in case of declaration merging) in the list of hoisted variables + var text = ts.unescapeIdentifier(name_21.text); + if (ts.hasProperty(seen, text)) { + continue; + } + else { + seen[text] = text; + } + } if (i !== 0) { write(", "); } - if (local.kind === 202 /* ClassDeclaration */ || local.kind === 206 /* ModuleDeclaration */) { + if (local.kind === 202 /* ClassDeclaration */ || local.kind === 206 /* ModuleDeclaration */ || local.kind === 205 /* EnumDeclaration */) { emitDeclarationName(local); } else { @@ -28744,6 +28806,9 @@ var ts; } return exportedDeclarations; function visit(node) { + if (node.flags & 2 /* Ambient */) { + return; + } if (node.kind === 201 /* FunctionDeclaration */) { if (!hoistedFunctionDeclarations) { hoistedFunctionDeclarations = []; @@ -28752,31 +28817,41 @@ var ts; return; } if (node.kind === 202 /* ClassDeclaration */) { - // TODO: rename block scoped classes if (!hoistedVars) { hoistedVars = []; } hoistedVars.push(node); return; } - if (node.kind === 206 /* ModuleDeclaration */ && shouldEmitModuleDeclaration(node)) { - if (!hoistedVars) { - hoistedVars = []; + if (node.kind === 205 /* EnumDeclaration */) { + if (shouldEmitEnumDeclaration(node)) { + if (!hoistedVars) { + hoistedVars = []; + } + hoistedVars.push(node); + } + return; + } + if (node.kind === 206 /* ModuleDeclaration */) { + if (shouldEmitModuleDeclaration(node)) { + if (!hoistedVars) { + hoistedVars = []; + } + hoistedVars.push(node); } - hoistedVars.push(node); return; } if (node.kind === 199 /* VariableDeclaration */ || node.kind === 153 /* BindingElement */) { if (shouldHoistVariable(node, false)) { - var name_21 = node.name; - if (name_21.kind === 65 /* Identifier */) { + var name_22 = node.name; + if (name_22.kind === 65 /* Identifier */) { if (!hoistedVars) { hoistedVars = []; } - hoistedVars.push(name_21); + hoistedVars.push(name_22); } else { - ts.forEachChild(name_21, visit); + ts.forEachChild(name_22, visit); } } return; @@ -29180,7 +29255,7 @@ var ts; paramEmitted = true; } } - if (ts.isExternalModule(node) || compilerOptions.separateCompilation) { + if (ts.isExternalModule(node) || compilerOptions.isolatedModules) { if (languageVersion >= 2 /* ES6 */) { emitES6Module(node, startIndex); } @@ -29571,7 +29646,7 @@ var ts; /* @internal */ ts.ioReadTime = 0; /* @internal */ ts.ioWriteTime = 0; /** The version of the TypeScript compiler release */ - ts.version = "1.5.2"; + ts.version = "1.5.3"; var carriageReturnLineFeed = "\r\n"; var lineFeed = "\n"; function findConfigFile(searchPath) { @@ -29755,14 +29830,19 @@ var ts; // Create the emit resolver outside of the "emitTime" tracking code below. That way // any cost associated with it (like type checking) are appropriate associated with // the type-checking counter. - var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile); + // + // If the -out option is specified, we should not pass the source file to getEmitResolver. + // This is because in the -out scenario all files need to be emitted, and therefore all + // files need to be type checked. And the way to specify that all files need to be type + // checked is to not pass the file to getEmitResolver. + var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(options.out ? undefined : sourceFile); var start = new Date().getTime(); var emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile); ts.emitTime += new Date().getTime() - start; return emitResult; } function getSourceFile(fileName) { - fileName = host.getCanonicalFileName(fileName); + fileName = host.getCanonicalFileName(ts.normalizeSlashes(fileName)); return ts.hasProperty(filesByName, fileName) ? filesByName[fileName] : undefined; } function getDiagnosticsHelper(sourceFile, getDiagnostics) { @@ -29855,7 +29935,7 @@ var ts; } // Get source file from normalized fileName function findSourceFile(fileName, isDefaultLib, refFile, refStart, refLength) { - var canonicalName = host.getCanonicalFileName(fileName); + var canonicalName = host.getCanonicalFileName(ts.normalizeSlashes(fileName)); if (ts.hasProperty(filesByName, canonicalName)) { // We've already looked for this file, use cached result return getSourceFileFromCache(fileName, canonicalName, false); @@ -30013,18 +30093,18 @@ var ts; return allFilesBelongToPath; } function verifyCompilerOptions() { - if (options.separateCompilation) { + if (options.isolatedModules) { if (options.sourceMap) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_sourceMap_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_sourceMap_cannot_be_specified_with_option_isolatedModules)); } if (options.declaration) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_declaration_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_declaration_cannot_be_specified_with_option_isolatedModules)); } if (options.noEmitOnError) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules)); } if (options.out) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_out_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_out_cannot_be_specified_with_option_isolatedModules)); } } if (options.inlineSourceMap) { @@ -30055,14 +30135,14 @@ var ts; } var languageVersion = options.target || 0 /* ES3 */; var firstExternalModuleSourceFile = ts.forEach(files, function (f) { return ts.isExternalModule(f) ? f : undefined; }); - if (options.separateCompilation) { + if (options.isolatedModules) { if (!options.module && languageVersion < 2 /* ES6 */) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher)); } var firstNonExternalModuleSourceFile = ts.forEach(files, function (f) { return !ts.isExternalModule(f) && !ts.isDeclarationFile(f) ? f : undefined; }); if (firstNonExternalModuleSourceFile) { var span = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile); - diagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided)); + diagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided)); } } else if (firstExternalModuleSourceFile && languageVersion < 2 /* ES6 */ && !options.module) { @@ -30251,7 +30331,7 @@ var ts; paramType: ts.Diagnostics.LOCATION }, { - name: "separateCompilation", + name: "isolatedModules", type: "boolean" }, { @@ -30684,12 +30764,12 @@ var ts; ts.forEach(program.getSourceFiles(), function (sourceFile) { cancellationToken.throwIfCancellationRequested(); var nameToDeclarations = sourceFile.getNamedDeclarations(); - for (var name_22 in nameToDeclarations) { - var declarations = ts.getProperty(nameToDeclarations, name_22); + for (var name_23 in nameToDeclarations) { + var declarations = ts.getProperty(nameToDeclarations, name_23); if (declarations) { // First do a quick check to see if the name of the declaration matches the // last portion of the (possibly) dotted name they're searching for. - var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_22); + var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_23); if (!matches) { continue; } @@ -30702,14 +30782,14 @@ var ts; if (!containers) { return undefined; } - matches = patternMatcher.getMatches(containers, name_22); + matches = patternMatcher.getMatches(containers, name_23); if (!matches) { continue; } } var fileName = sourceFile.fileName; var matchKind = bestMatchKind(matches); - rawItems.push({ name: name_22, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); + rawItems.push({ name: name_23, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); } } } @@ -31092,9 +31172,9 @@ var ts; case 199 /* VariableDeclaration */: case 153 /* BindingElement */: var variableDeclarationNode; - var name_23; + var name_24; if (node.kind === 153 /* BindingElement */) { - name_23 = node.name; + name_24 = node.name; variableDeclarationNode = node; // binding elements are added only for variable declarations // bubble up to the containing variable declaration @@ -31106,16 +31186,16 @@ var ts; else { ts.Debug.assert(!ts.isBindingPattern(node.name)); variableDeclarationNode = node; - name_23 = node.name; + name_24 = node.name; } if (ts.isConst(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_23), ts.ScriptElementKind.constElement); + return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.constElement); } else if (ts.isLet(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_23), ts.ScriptElementKind.letElement); + return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.letElement); } else { - return createItem(node, getTextOfNode(name_23), ts.ScriptElementKind.variableElement); + return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.variableElement); } case 136 /* Constructor */: return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); @@ -33702,9 +33782,9 @@ var ts; } Rules.prototype.getRuleName = function (rule) { var o = this; - for (var name_24 in o) { - if (o[name_24] === rule) { - return name_24; + for (var name_25 in o) { + if (o[name_25] === rule) { + return name_25; } } throw new Error("Unknown rule"); @@ -36592,12 +36672,12 @@ var ts; * This function will compile source text from 'input' argument using specified compiler options. * If not options are provided - it will use a set of default compiler options. * Extra compiler options that will unconditionally be used bu this function are: - * - separateCompilation = true + * - isolatedModules = true * - allowNonTsExtensions = true */ function transpile(input, compilerOptions, fileName, diagnostics) { var options = compilerOptions ? ts.clone(compilerOptions) : getDefaultCompilerOptions(); - options.separateCompilation = true; + options.isolatedModules = true; // Filename can be non-ts file. options.allowNonTsExtensions = true; // Parse @@ -36648,7 +36728,30 @@ var ts; if (version !== sourceFile.version) { // Once incremental parsing is ready, then just call into this function. if (!ts.disableIncrementalParsing) { - var newSourceFile = ts.updateSourceFile(sourceFile, scriptSnapshot.getText(0, scriptSnapshot.getLength()), textChangeRange, aggressiveChecks); + var newText; + // grab the fragment from the beginning of the original text to the beginning of the span + var prefix = textChangeRange.span.start !== 0 + ? sourceFile.text.substr(0, textChangeRange.span.start) + : ""; + // grab the fragment from the end of the span till the end of the original text + var suffix = ts.textSpanEnd(textChangeRange.span) !== sourceFile.text.length + ? sourceFile.text.substr(ts.textSpanEnd(textChangeRange.span)) + : ""; + if (textChangeRange.newLength === 0) { + // edit was a deletion - just combine prefix and suffix + newText = prefix && suffix ? prefix + suffix : prefix || suffix; + } + else { + // it was actual edit, fetch the fragment of new text that correspond to new span + var changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); + // combine prefix, changed text and suffix + newText = prefix && suffix + ? prefix + changedText + suffix + : prefix + ? (prefix + changedText) + : (changedText + suffix); + } + var newSourceFile = ts.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later @@ -37125,6 +37228,7 @@ var ts; var syntaxTreeCache = new SyntaxTreeCache(host); var ruleProvider; var program; + var lastProjectVersion; var useCaseSensitivefileNames = false; var cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); // Check if the localized messages json is set, otherwise query the host for it @@ -37156,6 +37260,16 @@ var ts; return ruleProvider; } function synchronizeHostData() { + // perform fast check if host supports it + if (host.getProjectVersion) { + var hostProjectVersion = host.getProjectVersion(); + if (hostProjectVersion) { + if (lastProjectVersion === hostProjectVersion) { + return; + } + lastProjectVersion = hostProjectVersion; + } + } // Get a fresh cache of the host information var hostCache = new HostCache(host, getCanonicalFileName); // If the program is already up-to-date, we can reuse it @@ -37954,10 +38068,10 @@ var ts; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; var nameTable = getNameTable(sourceFile); - for (var name_25 in nameTable) { - if (!allNames[name_25]) { - allNames[name_25] = name_25; - var displayName = getCompletionEntryDisplayName(name_25, target, true); + for (var name_26 in nameTable) { + if (!allNames[name_26]) { + allNames[name_26] = name_26; + var displayName = getCompletionEntryDisplayName(name_26, target, true); if (displayName) { var entry = { name: displayName, @@ -39839,19 +39953,19 @@ var ts; if (isNameOfPropertyAssignment(node)) { var objectLiteral = node.parent.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name_26 = node.text; + var name_27 = node.text; if (contextualType) { if (contextualType.flags & 16384 /* Union */) { // This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types) // if not, search the constituent types for the property - var unionProperty = contextualType.getProperty(name_26); + var unionProperty = contextualType.getProperty(name_27); if (unionProperty) { return [unionProperty]; } else { var result_4 = []; ts.forEach(contextualType.types, function (t) { - var symbol = t.getProperty(name_26); + var symbol = t.getProperty(name_27); if (symbol) { result_4.push(symbol); } @@ -39860,7 +39974,7 @@ var ts; } } else { - var symbol_1 = contextualType.getProperty(name_26); + var symbol_1 = contextualType.getProperty(name_27); if (symbol_1) { return [symbol_1]; } @@ -40280,10 +40394,12 @@ var ts; var kind = triviaScanner.scan(); var end = triviaScanner.getTextPos(); var width = end - start; + // The moment we get something that isn't trivia, then stop processing. + if (!ts.isTrivia(kind)) { + return; + } + // Only bother with the trivia if it at least intersects the span of interest. if (ts.textSpanIntersectsWith(span, start, width)) { - if (!ts.isTrivia(kind)) { - return; - } if (ts.isComment(kind)) { // Simple comment. Just add as is. pushClassification(start, width, 1 /* comment */); @@ -41726,6 +41842,13 @@ var ts; LanguageServiceShimHostAdapter.prototype.error = function (s) { this.shimHost.error(s); }; + LanguageServiceShimHostAdapter.prototype.getProjectVersion = function () { + if (!this.shimHost.getProjectVersion) { + // shimmed host does not support getProjectVersion + return undefined; + } + return this.shimHost.getProjectVersion(); + }; LanguageServiceShimHostAdapter.prototype.getCompilationSettings = function () { var settingsJson = this.shimHost.getCompilationSettings(); if (settingsJson == null || settingsJson == "") { @@ -42324,4 +42447,4 @@ var TypeScript; })(Services = TypeScript.Services || (TypeScript.Services = {})); })(TypeScript || (TypeScript = {})); /* @internal */ -var toolsVersion = "1.4"; +var toolsVersion = "1.5"; diff --git a/bin/typescriptServices.d.ts b/bin/typescriptServices.d.ts index 3114c56b789..7ccb2c2f27f 100644 --- a/bin/typescriptServices.d.ts +++ b/bin/typescriptServices.d.ts @@ -1114,7 +1114,7 @@ declare module ts { target?: ScriptTarget; version?: boolean; watch?: boolean; - separateCompilation?: boolean; + isolatedModules?: boolean; emitDecoratorMetadata?: boolean; [option: string]: string | number | boolean; } @@ -1379,6 +1379,7 @@ declare module ts { interface LanguageServiceHost { getCompilationSettings(): CompilerOptions; getNewLine?(): string; + getProjectVersion?(): string; getScriptFileNames(): string[]; getScriptVersion(fileName: string): string; getScriptSnapshot(fileName: string): IScriptSnapshot; diff --git a/bin/typescriptServices.js b/bin/typescriptServices.js index 4a17fb94c2c..940ce1e211f 100644 --- a/bin/typescriptServices.js +++ b/bin/typescriptServices.js @@ -1129,9 +1129,18 @@ var ts; return 3; return 2; } + // Per RFC 1738 'file' URI schema has the shape file:/// + // if is omitted then it is assumed that host value is 'localhost', + // however slash after the omitted is not removed. + // file:///folder1/file1 - this is a correct URI + // file://folder2/file2 - this is an incorrect URI + if (path.lastIndexOf("file:///", 0) === 0) { + return "file:///".length; + } var idx = path.indexOf('://'); - if (idx !== -1) - return idx + 3; + if (idx !== -1) { + return idx + "://".length; + } return 0; } ts.getRootLength = getRootLength; @@ -1822,8 +1831,8 @@ var ts; Decorators_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1205, category: ts.DiagnosticCategory.Error, key: "Decorators are only available when targeting ECMAScript 5 and higher." }, Decorators_are_not_valid_here: { code: 1206, category: ts.DiagnosticCategory.Error, key: "Decorators are not valid here." }, Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: { code: 1207, category: ts.DiagnosticCategory.Error, key: "Decorators cannot be applied to multiple get/set accessors of the same name." }, - Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided: { code: 1208, category: ts.DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--separateCompilation' flag is provided." }, - Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided: { code: 1209, category: ts.DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--separateCompilation' flag is provided." }, + Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided: { code: 1208, category: ts.DiagnosticCategory.Error, key: "Cannot compile namespaces when the '--isolatedModules' flag is provided." }, + Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided: { code: 1209, category: ts.DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--isolatedModules' flag is provided." }, Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: { code: 1210, category: ts.DiagnosticCategory.Error, key: "Invalid use of '{0}'. Class definitions are automatically in strict mode." }, A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: ts.DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" }, Identifier_expected_0_is_a_reserved_word_in_strict_mode: { code: 1212, category: ts.DiagnosticCategory.Error, key: "Identifier expected. '{0}' is a reserved word in strict mode" }, @@ -2106,11 +2115,11 @@ var ts; Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: ts.DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." }, Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: ts.DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." }, Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: ts.DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." }, - Option_sourceMap_cannot_be_specified_with_option_separateCompilation: { code: 5043, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'separateCompilation'." }, - Option_declaration_cannot_be_specified_with_option_separateCompilation: { code: 5044, category: ts.DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'separateCompilation'." }, - Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation: { code: 5045, category: ts.DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'separateCompilation'." }, - Option_out_cannot_be_specified_with_option_separateCompilation: { code: 5046, category: ts.DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'separateCompilation'." }, - Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: ts.DiagnosticCategory.Error, key: "Option 'separateCompilation' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." }, + Option_sourceMap_cannot_be_specified_with_option_isolatedModules: { code: 5043, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'isolatedModules'." }, + Option_declaration_cannot_be_specified_with_option_isolatedModules: { code: 5044, category: ts.DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'isolatedModules'." }, + Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules: { code: 5045, category: ts.DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'isolatedModules'." }, + Option_out_cannot_be_specified_with_option_isolatedModules: { code: 5046, category: ts.DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'isolatedModules'." }, + Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher: { code: 5047, category: ts.DiagnosticCategory.Error, key: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." }, Option_sourceMap_cannot_be_specified_with_option_inlineSourceMap: { code: 5048, category: ts.DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'inlineSourceMap'." }, Option_sourceRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5049, category: ts.DiagnosticCategory.Error, key: "Option 'sourceRoot' cannot be specified with option 'inlineSourceMap'." }, Option_mapRoot_cannot_be_specified_with_option_inlineSourceMap: { code: 5050, category: ts.DiagnosticCategory.Error, key: "Option 'mapRoot' cannot be specified with option 'inlineSourceMap'." }, @@ -5468,7 +5477,7 @@ var ts; if ((isExternalModule(sourceFile) || !compilerOptions.out)) { // 1. in-browser single file compilation scenario // 2. non .js file - return compilerOptions.separateCompilation || !ts.fileExtensionIs(sourceFile.fileName, ".js"); + return compilerOptions.isolatedModules || !ts.fileExtensionIs(sourceFile.fileName, ".js"); } return false; } @@ -11418,7 +11427,7 @@ var ts; var symbol = getSymbolOfNode(node); var target = resolveAlias(symbol); if (target) { - var markAlias = (target === unknownSymbol && compilerOptions.separateCompilation) || + var markAlias = (target === unknownSymbol && compilerOptions.isolatedModules) || (target !== unknownSymbol && (target.flags & 107455 /* Value */) && !isConstEnumOrConstEnumOnlyModule(target)); if (markAlias) { markAliasSymbolAsReferenced(symbol); @@ -12945,7 +12954,15 @@ var ts; function getTypeOfAlias(symbol) { var links = getSymbolLinks(symbol); if (!links.type) { - links.type = getTypeOfSymbol(resolveAlias(symbol)); + var targetSymbol = resolveAlias(symbol); + // It only makes sense to get the type of a value symbol. If the result of resolving + // the alias is not a value, then it has no type. To get the type associated with a + // type symbol, call getDeclaredTypeOfSymbol. + // This check is important because without it, a call to getTypeOfSymbol could end + // up recursively calling getTypeOfAlias, causing a stack overflow. + links.type = targetSymbol.flags & 107455 /* Value */ + ? getTypeOfSymbol(targetSymbol) + : unknownType; } return links.type; } @@ -14021,7 +14038,17 @@ var ts; } return false; } + // Since removeSubtypes checks the subtype relation, and the subtype relation on a union + // may attempt to reduce a union, it is possible that removeSubtypes could be called + // recursively on the same set of types. The removeSubtypesStack is used to track which + // sets of types are currently undergoing subtype reduction. + var removeSubtypesStack = []; function removeSubtypes(types) { + var typeListId = getTypeListId(types); + if (removeSubtypesStack.lastIndexOf(typeListId) >= 0) { + return; + } + removeSubtypesStack.push(typeListId); var i = types.length; while (i > 0) { i--; @@ -14029,6 +14056,7 @@ var ts; types.splice(i, 1); } } + removeSubtypesStack.pop(); } function containsAnyType(types) { for (var _i = 0; _i < types.length; _i++) { @@ -15730,36 +15758,37 @@ var ts; if (!isTypeSubtypeOf(rightType, globalFunctionType)) { return type; } - // Target type is type of prototype property + var targetType; var prototypeProperty = getPropertyOfType(rightType, "prototype"); if (prototypeProperty) { - var targetType = getTypeOfSymbol(prototypeProperty); - if (targetType !== anyType) { - // Narrow to the target type if it's a subtype of the current type - if (isTypeSubtypeOf(targetType, type)) { - return targetType; - } - // If the current type is a union type, remove all constituents that aren't subtypes of the target. - if (type.flags & 16384 /* Union */) { - return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); })); - } + // Target type is type of the protoype property + var prototypePropertyType = getTypeOfSymbol(prototypeProperty); + if (prototypePropertyType !== anyType) { + targetType = prototypePropertyType; } } - // Target type is type of construct signature - var constructSignatures; - if (rightType.flags & 2048 /* Interface */) { - constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures; + if (!targetType) { + // Target type is type of construct signature + var constructSignatures; + if (rightType.flags & 2048 /* Interface */) { + constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures; + } + else if (rightType.flags & 32768 /* Anonymous */) { + constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */); + } + if (constructSignatures && constructSignatures.length) { + targetType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })); + } } - else if (rightType.flags & 32768 /* Anonymous */) { - constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */); - } - if (constructSignatures && constructSignatures.length !== 0) { - var instanceType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })); - // Pickup type from union types + if (targetType) { + // Narrow to the target type if it's a subtype of the current type + if (isTypeSubtypeOf(targetType, type)) { + return targetType; + } + // If the current type is a union type, remove all constituents that aren't subtypes of the target. if (type.flags & 16384 /* Union */) { - return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, instanceType); })); + return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); })); } - return instanceType; } return type; } @@ -18853,7 +18882,7 @@ var ts; // serialize the type metadata. if (node && node.kind === 142 /* TypeReference */) { var type = getTypeFromTypeNode(node); - var shouldCheckIfUnknownType = type === unknownType && compilerOptions.separateCompilation; + var shouldCheckIfUnknownType = type === unknownType && compilerOptions.isolatedModules; if (!type || (!shouldCheckIfUnknownType && type.flags & (1048703 /* Intrinsic */ | 132 /* NumberLike */ | 258 /* StringLike */))) { return; } @@ -19863,7 +19892,7 @@ var ts; checkKindsOfPropertyMemberOverrides(type, baseType); } } - if (baseTypes.length || (baseTypeNode && compilerOptions.separateCompilation)) { + if (baseTypes.length || (baseTypeNode && compilerOptions.isolatedModules)) { // Check that base type can be evaluated as expression checkExpressionOrQualifiedName(baseTypeNode.expression); } @@ -20232,8 +20261,8 @@ var ts; checkExportsOnMergedDeclarations(node); computeEnumMemberValues(node); var enumIsConst = ts.isConst(node); - if (compilerOptions.separateCompilation && enumIsConst && ts.isInAmbientContext(node)) { - error(node.name, ts.Diagnostics.Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided); + if (compilerOptions.isolatedModules && enumIsConst && ts.isInAmbientContext(node)) { + error(node.name, ts.Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided); } // Spec 2014 - Section 9.3: // It isn't possible for one enum declaration to continue the automatic numbering sequence of another, @@ -20315,7 +20344,7 @@ var ts; if (symbol.flags & 512 /* ValueModule */ && symbol.declarations.length > 1 && !ts.isInAmbientContext(node) - && ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation)) { + && ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules)) { var firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol); if (firstNonAmbientClassOrFunc) { if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(firstNonAmbientClassOrFunc)) { @@ -20666,6 +20695,7 @@ var ts; break; case 135 /* MethodDeclaration */: case 134 /* MethodSignature */: + ts.forEach(node.decorators, checkFunctionExpressionBodies); ts.forEach(node.parameters, checkFunctionExpressionBodies); if (ts.isObjectLiteralMethod(node)) { checkFunctionExpressionOrObjectLiteralMethodBody(node); @@ -20680,6 +20710,7 @@ var ts; case 193 /* WithStatement */: checkFunctionExpressionBodies(node.expression); break; + case 131 /* Decorator */: case 130 /* Parameter */: case 133 /* PropertyDeclaration */: case 132 /* PropertySignature */: @@ -21317,7 +21348,7 @@ var ts; } function isAliasResolvedToValue(symbol) { var target = resolveAlias(symbol); - if (target === unknownSymbol && compilerOptions.separateCompilation) { + if (target === unknownSymbol && compilerOptions.isolatedModules) { return true; } // const enums and modules that contain only const enums are not considered values from the emit perespective @@ -25321,7 +25352,7 @@ var ts; } return true; } - function emitListWithSpread(elements, multiLine, trailingComma) { + function emitListWithSpread(elements, alwaysCopy, multiLine, trailingComma) { var pos = 0; var group = 0; var length = elements.length; @@ -25338,6 +25369,9 @@ var ts; e = e.expression; emitParenthesizedIf(e, group === 0 && needsParenthesisForPropertyAccessOrInvocation(e)); pos++; + if (pos === length && group === 0 && alwaysCopy && e.kind !== 154 /* ArrayLiteralExpression */) { + write(".slice()"); + } } else { var i = pos; @@ -25375,7 +25409,7 @@ var ts; write("]"); } else { - emitListWithSpread(elements, (node.flags & 512 /* MultiLine */) !== 0, + emitListWithSpread(elements, true, (node.flags & 512 /* MultiLine */) !== 0, /*trailingComma*/ elements.hasTrailingComma); } } @@ -25627,7 +25661,7 @@ var ts; } } function tryEmitConstantValue(node) { - if (compilerOptions.separateCompilation) { + if (compilerOptions.isolatedModules) { // do not inline enum values in separate compilation mode return false; } @@ -25747,7 +25781,7 @@ var ts; write("void 0"); } write(", "); - emitListWithSpread(node.arguments, false, false); + emitListWithSpread(node.arguments, false, false, false); write(")"); } function emitCallExpression(node) { @@ -26451,7 +26485,8 @@ var ts; if (node.flags & 1 /* Export */) { writeLine(); emitStart(node); - if (compilerOptions.module === 4 /* System */) { + // emit call to exporter only for top level nodes + if (compilerOptions.module === 4 /* System */ && node.parent === currentSourceFile) { // emit export default as // export("default", ) write(exportFunctionForFile + "(\""); @@ -28021,22 +28056,25 @@ var ts; } function shouldEmitEnumDeclaration(node) { var isConstEnum = ts.isConst(node); - return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.separateCompilation; + return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.isolatedModules; } function emitEnumDeclaration(node) { // const enums are completely erased during compilation. if (!shouldEmitEnumDeclaration(node)) { return; } - if (!(node.flags & 1 /* Export */) || isES6ExportedDeclaration(node)) { - emitStart(node); - if (isES6ExportedDeclaration(node)) { - write("export "); + if (!shouldHoistDeclarationInSystemJsModule(node)) { + // do not emit var if variable was already hoisted + if (!(node.flags & 1 /* Export */) || isES6ExportedDeclaration(node)) { + emitStart(node); + if (isES6ExportedDeclaration(node)) { + write("export "); + } + write("var "); + emit(node.name); + emitEnd(node); + write(";"); } - write("var "); - emit(node.name); - emitEnd(node); - write(";"); } writeLine(); emitStart(node); @@ -28058,7 +28096,8 @@ var ts; emitModuleMemberName(node); write(" = {}));"); emitEnd(node); - if (!isES6ExportedDeclaration(node) && node.flags & 1 /* Export */) { + if (!isES6ExportedDeclaration(node) && node.flags & 1 /* Export */ && !shouldHoistDeclarationInSystemJsModule(node)) { + // do not emit var if variable was already hoisted writeLine(); emitStart(node); write("var "); @@ -28069,6 +28108,15 @@ var ts; write(";"); } if (languageVersion < 2 /* ES6 */ && node.parent === currentSourceFile) { + if (compilerOptions.module === 4 /* System */ && (node.flags & 1 /* Export */)) { + // write the call to exporter for enum + writeLine(); + write(exportFunctionForFile + "(\""); + emitDeclarationName(node); + write("\", "); + emitDeclarationName(node); + write(")"); + } emitExportMemberAssignments(node.name); } } @@ -28107,7 +28155,7 @@ var ts; } } function shouldEmitModuleDeclaration(node) { - return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation); + return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules); } function isModuleMergedWithES6Class(node) { return languageVersion === 2 /* ES6 */ && !!(resolver.getNodeCheckFlags(node) & 2048 /* LexicalModuleMergesWithClass */); @@ -28708,12 +28756,26 @@ var ts; if (hoistedVars) { writeLine(); write("var "); + var seen = {}; for (var i = 0; i < hoistedVars.length; ++i) { var local = hoistedVars[i]; + var name_21 = local.kind === 65 /* Identifier */ + ? local + : local.name; + if (name_21) { + // do not emit duplicate entries (in case of declaration merging) in the list of hoisted variables + var text = ts.unescapeIdentifier(name_21.text); + if (ts.hasProperty(seen, text)) { + continue; + } + else { + seen[text] = text; + } + } if (i !== 0) { write(", "); } - if (local.kind === 202 /* ClassDeclaration */ || local.kind === 206 /* ModuleDeclaration */) { + if (local.kind === 202 /* ClassDeclaration */ || local.kind === 206 /* ModuleDeclaration */ || local.kind === 205 /* EnumDeclaration */) { emitDeclarationName(local); } else { @@ -28744,6 +28806,9 @@ var ts; } return exportedDeclarations; function visit(node) { + if (node.flags & 2 /* Ambient */) { + return; + } if (node.kind === 201 /* FunctionDeclaration */) { if (!hoistedFunctionDeclarations) { hoistedFunctionDeclarations = []; @@ -28752,31 +28817,41 @@ var ts; return; } if (node.kind === 202 /* ClassDeclaration */) { - // TODO: rename block scoped classes if (!hoistedVars) { hoistedVars = []; } hoistedVars.push(node); return; } - if (node.kind === 206 /* ModuleDeclaration */ && shouldEmitModuleDeclaration(node)) { - if (!hoistedVars) { - hoistedVars = []; + if (node.kind === 205 /* EnumDeclaration */) { + if (shouldEmitEnumDeclaration(node)) { + if (!hoistedVars) { + hoistedVars = []; + } + hoistedVars.push(node); + } + return; + } + if (node.kind === 206 /* ModuleDeclaration */) { + if (shouldEmitModuleDeclaration(node)) { + if (!hoistedVars) { + hoistedVars = []; + } + hoistedVars.push(node); } - hoistedVars.push(node); return; } if (node.kind === 199 /* VariableDeclaration */ || node.kind === 153 /* BindingElement */) { if (shouldHoistVariable(node, false)) { - var name_21 = node.name; - if (name_21.kind === 65 /* Identifier */) { + var name_22 = node.name; + if (name_22.kind === 65 /* Identifier */) { if (!hoistedVars) { hoistedVars = []; } - hoistedVars.push(name_21); + hoistedVars.push(name_22); } else { - ts.forEachChild(name_21, visit); + ts.forEachChild(name_22, visit); } } return; @@ -29180,7 +29255,7 @@ var ts; paramEmitted = true; } } - if (ts.isExternalModule(node) || compilerOptions.separateCompilation) { + if (ts.isExternalModule(node) || compilerOptions.isolatedModules) { if (languageVersion >= 2 /* ES6 */) { emitES6Module(node, startIndex); } @@ -29571,7 +29646,7 @@ var ts; /* @internal */ ts.ioReadTime = 0; /* @internal */ ts.ioWriteTime = 0; /** The version of the TypeScript compiler release */ - ts.version = "1.5.2"; + ts.version = "1.5.3"; var carriageReturnLineFeed = "\r\n"; var lineFeed = "\n"; function findConfigFile(searchPath) { @@ -29755,14 +29830,19 @@ var ts; // Create the emit resolver outside of the "emitTime" tracking code below. That way // any cost associated with it (like type checking) are appropriate associated with // the type-checking counter. - var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile); + // + // If the -out option is specified, we should not pass the source file to getEmitResolver. + // This is because in the -out scenario all files need to be emitted, and therefore all + // files need to be type checked. And the way to specify that all files need to be type + // checked is to not pass the file to getEmitResolver. + var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(options.out ? undefined : sourceFile); var start = new Date().getTime(); var emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile); ts.emitTime += new Date().getTime() - start; return emitResult; } function getSourceFile(fileName) { - fileName = host.getCanonicalFileName(fileName); + fileName = host.getCanonicalFileName(ts.normalizeSlashes(fileName)); return ts.hasProperty(filesByName, fileName) ? filesByName[fileName] : undefined; } function getDiagnosticsHelper(sourceFile, getDiagnostics) { @@ -29855,7 +29935,7 @@ var ts; } // Get source file from normalized fileName function findSourceFile(fileName, isDefaultLib, refFile, refStart, refLength) { - var canonicalName = host.getCanonicalFileName(fileName); + var canonicalName = host.getCanonicalFileName(ts.normalizeSlashes(fileName)); if (ts.hasProperty(filesByName, canonicalName)) { // We've already looked for this file, use cached result return getSourceFileFromCache(fileName, canonicalName, false); @@ -30013,18 +30093,18 @@ var ts; return allFilesBelongToPath; } function verifyCompilerOptions() { - if (options.separateCompilation) { + if (options.isolatedModules) { if (options.sourceMap) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_sourceMap_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_sourceMap_cannot_be_specified_with_option_isolatedModules)); } if (options.declaration) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_declaration_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_declaration_cannot_be_specified_with_option_isolatedModules)); } if (options.noEmitOnError) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules)); } if (options.out) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_out_cannot_be_specified_with_option_separateCompilation)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_out_cannot_be_specified_with_option_isolatedModules)); } } if (options.inlineSourceMap) { @@ -30055,14 +30135,14 @@ var ts; } var languageVersion = options.target || 0 /* ES3 */; var firstExternalModuleSourceFile = ts.forEach(files, function (f) { return ts.isExternalModule(f) ? f : undefined; }); - if (options.separateCompilation) { + if (options.isolatedModules) { if (!options.module && languageVersion < 2 /* ES6 */) { - diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_separateCompilation_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher)); + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher)); } var firstNonExternalModuleSourceFile = ts.forEach(files, function (f) { return !ts.isExternalModule(f) && !ts.isDeclarationFile(f) ? f : undefined; }); if (firstNonExternalModuleSourceFile) { var span = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile); - diagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_separateCompilation_flag_is_provided)); + diagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided)); } } else if (firstExternalModuleSourceFile && languageVersion < 2 /* ES6 */ && !options.module) { @@ -30251,7 +30331,7 @@ var ts; paramType: ts.Diagnostics.LOCATION }, { - name: "separateCompilation", + name: "isolatedModules", type: "boolean" }, { @@ -30684,12 +30764,12 @@ var ts; ts.forEach(program.getSourceFiles(), function (sourceFile) { cancellationToken.throwIfCancellationRequested(); var nameToDeclarations = sourceFile.getNamedDeclarations(); - for (var name_22 in nameToDeclarations) { - var declarations = ts.getProperty(nameToDeclarations, name_22); + for (var name_23 in nameToDeclarations) { + var declarations = ts.getProperty(nameToDeclarations, name_23); if (declarations) { // First do a quick check to see if the name of the declaration matches the // last portion of the (possibly) dotted name they're searching for. - var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_22); + var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_23); if (!matches) { continue; } @@ -30702,14 +30782,14 @@ var ts; if (!containers) { return undefined; } - matches = patternMatcher.getMatches(containers, name_22); + matches = patternMatcher.getMatches(containers, name_23); if (!matches) { continue; } } var fileName = sourceFile.fileName; var matchKind = bestMatchKind(matches); - rawItems.push({ name: name_22, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); + rawItems.push({ name: name_23, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); } } } @@ -31092,9 +31172,9 @@ var ts; case 199 /* VariableDeclaration */: case 153 /* BindingElement */: var variableDeclarationNode; - var name_23; + var name_24; if (node.kind === 153 /* BindingElement */) { - name_23 = node.name; + name_24 = node.name; variableDeclarationNode = node; // binding elements are added only for variable declarations // bubble up to the containing variable declaration @@ -31106,16 +31186,16 @@ var ts; else { ts.Debug.assert(!ts.isBindingPattern(node.name)); variableDeclarationNode = node; - name_23 = node.name; + name_24 = node.name; } if (ts.isConst(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_23), ts.ScriptElementKind.constElement); + return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.constElement); } else if (ts.isLet(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_23), ts.ScriptElementKind.letElement); + return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.letElement); } else { - return createItem(node, getTextOfNode(name_23), ts.ScriptElementKind.variableElement); + return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.variableElement); } case 136 /* Constructor */: return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); @@ -33702,9 +33782,9 @@ var ts; } Rules.prototype.getRuleName = function (rule) { var o = this; - for (var name_24 in o) { - if (o[name_24] === rule) { - return name_24; + for (var name_25 in o) { + if (o[name_25] === rule) { + return name_25; } } throw new Error("Unknown rule"); @@ -36592,12 +36672,12 @@ var ts; * This function will compile source text from 'input' argument using specified compiler options. * If not options are provided - it will use a set of default compiler options. * Extra compiler options that will unconditionally be used bu this function are: - * - separateCompilation = true + * - isolatedModules = true * - allowNonTsExtensions = true */ function transpile(input, compilerOptions, fileName, diagnostics) { var options = compilerOptions ? ts.clone(compilerOptions) : getDefaultCompilerOptions(); - options.separateCompilation = true; + options.isolatedModules = true; // Filename can be non-ts file. options.allowNonTsExtensions = true; // Parse @@ -36648,7 +36728,30 @@ var ts; if (version !== sourceFile.version) { // Once incremental parsing is ready, then just call into this function. if (!ts.disableIncrementalParsing) { - var newSourceFile = ts.updateSourceFile(sourceFile, scriptSnapshot.getText(0, scriptSnapshot.getLength()), textChangeRange, aggressiveChecks); + var newText; + // grab the fragment from the beginning of the original text to the beginning of the span + var prefix = textChangeRange.span.start !== 0 + ? sourceFile.text.substr(0, textChangeRange.span.start) + : ""; + // grab the fragment from the end of the span till the end of the original text + var suffix = ts.textSpanEnd(textChangeRange.span) !== sourceFile.text.length + ? sourceFile.text.substr(ts.textSpanEnd(textChangeRange.span)) + : ""; + if (textChangeRange.newLength === 0) { + // edit was a deletion - just combine prefix and suffix + newText = prefix && suffix ? prefix + suffix : prefix || suffix; + } + else { + // it was actual edit, fetch the fragment of new text that correspond to new span + var changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); + // combine prefix, changed text and suffix + newText = prefix && suffix + ? prefix + changedText + suffix + : prefix + ? (prefix + changedText) + : (changedText + suffix); + } + var newSourceFile = ts.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later @@ -37125,6 +37228,7 @@ var ts; var syntaxTreeCache = new SyntaxTreeCache(host); var ruleProvider; var program; + var lastProjectVersion; var useCaseSensitivefileNames = false; var cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); // Check if the localized messages json is set, otherwise query the host for it @@ -37156,6 +37260,16 @@ var ts; return ruleProvider; } function synchronizeHostData() { + // perform fast check if host supports it + if (host.getProjectVersion) { + var hostProjectVersion = host.getProjectVersion(); + if (hostProjectVersion) { + if (lastProjectVersion === hostProjectVersion) { + return; + } + lastProjectVersion = hostProjectVersion; + } + } // Get a fresh cache of the host information var hostCache = new HostCache(host, getCanonicalFileName); // If the program is already up-to-date, we can reuse it @@ -37954,10 +38068,10 @@ var ts; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; var nameTable = getNameTable(sourceFile); - for (var name_25 in nameTable) { - if (!allNames[name_25]) { - allNames[name_25] = name_25; - var displayName = getCompletionEntryDisplayName(name_25, target, true); + for (var name_26 in nameTable) { + if (!allNames[name_26]) { + allNames[name_26] = name_26; + var displayName = getCompletionEntryDisplayName(name_26, target, true); if (displayName) { var entry = { name: displayName, @@ -39839,19 +39953,19 @@ var ts; if (isNameOfPropertyAssignment(node)) { var objectLiteral = node.parent.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name_26 = node.text; + var name_27 = node.text; if (contextualType) { if (contextualType.flags & 16384 /* Union */) { // This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types) // if not, search the constituent types for the property - var unionProperty = contextualType.getProperty(name_26); + var unionProperty = contextualType.getProperty(name_27); if (unionProperty) { return [unionProperty]; } else { var result_4 = []; ts.forEach(contextualType.types, function (t) { - var symbol = t.getProperty(name_26); + var symbol = t.getProperty(name_27); if (symbol) { result_4.push(symbol); } @@ -39860,7 +39974,7 @@ var ts; } } else { - var symbol_1 = contextualType.getProperty(name_26); + var symbol_1 = contextualType.getProperty(name_27); if (symbol_1) { return [symbol_1]; } @@ -40280,10 +40394,12 @@ var ts; var kind = triviaScanner.scan(); var end = triviaScanner.getTextPos(); var width = end - start; + // The moment we get something that isn't trivia, then stop processing. + if (!ts.isTrivia(kind)) { + return; + } + // Only bother with the trivia if it at least intersects the span of interest. if (ts.textSpanIntersectsWith(span, start, width)) { - if (!ts.isTrivia(kind)) { - return; - } if (ts.isComment(kind)) { // Simple comment. Just add as is. pushClassification(start, width, 1 /* comment */); @@ -41726,6 +41842,13 @@ var ts; LanguageServiceShimHostAdapter.prototype.error = function (s) { this.shimHost.error(s); }; + LanguageServiceShimHostAdapter.prototype.getProjectVersion = function () { + if (!this.shimHost.getProjectVersion) { + // shimmed host does not support getProjectVersion + return undefined; + } + return this.shimHost.getProjectVersion(); + }; LanguageServiceShimHostAdapter.prototype.getCompilationSettings = function () { var settingsJson = this.shimHost.getCompilationSettings(); if (settingsJson == null || settingsJson == "") { @@ -42324,4 +42447,4 @@ var TypeScript; })(Services = TypeScript.Services || (TypeScript.Services = {})); })(TypeScript || (TypeScript = {})); /* @internal */ -var toolsVersion = "1.4"; +var toolsVersion = "1.5"; From 7887d6e396dea0537206518d3208949df4725f52 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Wed, 20 May 2015 12:02:52 -0700 Subject: [PATCH 061/194] Fix testcases for isolated modules. --- tests/cases/compiler/systemModuleAmbientDeclarations.ts | 2 +- .../cases/compiler/systemModuleConstEnumsSeparateCompilation.ts | 2 +- tests/cases/compiler/systemModuleDeclarationMerging.ts | 2 +- tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/cases/compiler/systemModuleAmbientDeclarations.ts b/tests/cases/compiler/systemModuleAmbientDeclarations.ts index 05f78592780..690d0c65c13 100644 --- a/tests/cases/compiler/systemModuleAmbientDeclarations.ts +++ b/tests/cases/compiler/systemModuleAmbientDeclarations.ts @@ -1,5 +1,5 @@ // @module: system -// @separateCompilation: true +// @isolatedModules: true // @filename: file1.ts declare class Promise { } diff --git a/tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts b/tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts index 2fc4707b78e..3813017639f 100644 --- a/tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts +++ b/tests/cases/compiler/systemModuleConstEnumsSeparateCompilation.ts @@ -1,5 +1,5 @@ // @module: system -// @separateCompilation: true +// @isolatedModules: true declare function use(a: any); const enum TopLevelConstEnum { X } diff --git a/tests/cases/compiler/systemModuleDeclarationMerging.ts b/tests/cases/compiler/systemModuleDeclarationMerging.ts index 45c59c5b5dc..ae8b3a8dd0b 100644 --- a/tests/cases/compiler/systemModuleDeclarationMerging.ts +++ b/tests/cases/compiler/systemModuleDeclarationMerging.ts @@ -1,5 +1,5 @@ // @module: system -// @separateCompilation: true +// @isolatedModules: true export function F() {} export module F { var x; } diff --git a/tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts b/tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts index 756d430a2de..b5617970339 100644 --- a/tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts +++ b/tests/cases/compiler/systemModuleNonTopLevelModuleMembers.ts @@ -1,5 +1,5 @@ // @module: system -// @separateCompilation: true +// @isolatedModules: true export class TopLevelClass {} export module TopLevelModule {var v;} From 711886e09994eda5bafa9383d92954242fc342c5 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Wed, 20 May 2015 13:44:02 -0700 Subject: [PATCH 062/194] update LKG --- bin/typescript.js | 2 +- bin/typescriptServices.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/typescript.js b/bin/typescript.js index 940ce1e211f..5f1053a72bd 100644 --- a/bin/typescript.js +++ b/bin/typescript.js @@ -42361,7 +42361,7 @@ var ts; return { options: configFile.options, files: configFile.fileNames, - errors: [realizeDiagnostics(configFile.errors, '\r\n')] + errors: realizeDiagnostics(configFile.errors, '\r\n') }; }); }; diff --git a/bin/typescriptServices.js b/bin/typescriptServices.js index 940ce1e211f..5f1053a72bd 100644 --- a/bin/typescriptServices.js +++ b/bin/typescriptServices.js @@ -42361,7 +42361,7 @@ var ts; return { options: configFile.options, files: configFile.fileNames, - errors: [realizeDiagnostics(configFile.errors, '\r\n')] + errors: realizeDiagnostics(configFile.errors, '\r\n') }; }); }; From e7eef830e13509baa479eabe0e75aaa4992927c1 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 26 May 2015 20:18:13 -0700 Subject: [PATCH 063/194] Fix #3245: ensure transpile diagnostics only include syntactic and compiler options diagnostics --- Jakefile.js | 3 +- src/compiler/program.ts | 15 ++++---- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 15 ++++++++ src/services/services.ts | 17 +++++++-- tests/cases/unittests/transpile.ts | 59 ++++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+), 12 deletions(-) create mode 100644 tests/cases/unittests/transpile.ts diff --git a/Jakefile.js b/Jakefile.js index cb53b479502..f27e61062f0 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -128,7 +128,8 @@ var harnessSources = [ "services/preProcessFile.ts", "services/patternMatcher.ts", "versionCache.ts", - "convertToBase64.ts" + "convertToBase64.ts", + "transpile.ts" ].map(function (f) { return path.join(unittestsDirectory, f); })).concat([ diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 32503de2566..4cccc881d40 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -10,9 +10,6 @@ module ts { /** The version of the TypeScript compiler release */ export const version = "1.5.3"; - const carriageReturnLineFeed = "\r\n"; - const lineFeed = "\n"; - export function findConfigFile(searchPath: string): string { var fileName = "tsconfig.json"; while (true) { @@ -94,10 +91,7 @@ module ts { } } - let newLine = - options.newLine === NewLineKind.CarriageReturnLineFeed ? carriageReturnLineFeed : - options.newLine === NewLineKind.LineFeed ? lineFeed : - sys.newLine; + const newLine = getNewLineCharacter(options); return { getSourceFile, @@ -175,6 +169,7 @@ module ts { getGlobalDiagnostics, getSemanticDiagnostics, getDeclarationDiagnostics, + getCompilerOptionsDiagnostics, getTypeChecker, getDiagnosticsProducingTypeChecker, getCommonSourceDirectory: () => commonSourceDirectory, @@ -291,6 +286,12 @@ module ts { } } + function getCompilerOptionsDiagnostics(): Diagnostic[]{ + let allDiagnostics: Diagnostic[] = []; + addRange(allDiagnostics, diagnostics.getGlobalDiagnostics()); + return sortAndDeduplicateDiagnostics(allDiagnostics); + } + function getGlobalDiagnostics(): Diagnostic[] { let typeChecker = getDiagnosticsProducingTypeChecker(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a6fa89846bb..7eec44eb2f2 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1064,6 +1064,7 @@ module ts { getGlobalDiagnostics(): Diagnostic[]; getSemanticDiagnostics(sourceFile?: SourceFile): Diagnostic[]; getDeclarationDiagnostics(sourceFile?: SourceFile): Diagnostic[]; + /* @internal */ getCompilerOptionsDiagnostics(): Diagnostic[]; /** * Gets a type checker that can be used to semantically analyze source fils in the program. diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 3ded0a7cfd9..3bb459ff99e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1774,6 +1774,21 @@ module ts { return result; } + + const carriageReturnLineFeed = "\r\n"; + const lineFeed = "\n"; + export function getNewLineCharacter(options: CompilerOptions): string { + if (options.newLine === NewLineKind.CarriageReturnLineFeed) { + return carriageReturnLineFeed; + } + else if (options.newLine === NewLineKind.LineFeed) { + return lineFeed; + } + else if (sys) { + return sys.newLine + } + return carriageReturnLineFeed; + } } module ts { diff --git a/src/services/services.ts b/src/services/services.ts index d5ba024cee5..ff1e627a241 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1772,15 +1772,24 @@ module ts { // Filename can be non-ts file. options.allowNonTsExtensions = true; + // We are not returning a lib file when asked, so pass this flag to + // avoid reporting a file not found error + options.noLib = true; + + // Similar to the library, we are not returning any refrenced files + options.noResolve = true; + // Parse - var inputFileName = fileName || "module.ts"; - var sourceFile = createSourceFile(inputFileName, input, options.target); + let inputFileName = fileName || "module.ts"; + let sourceFile = createSourceFile(inputFileName, input, options.target); // Store syntactic diagnostics if (diagnostics && sourceFile.parseDiagnostics) { diagnostics.push(...sourceFile.parseDiagnostics); } + let newLine = getNewLineCharacter(options); + // Output let outputText: string; @@ -1795,13 +1804,13 @@ module ts { useCaseSensitiveFileNames: () => false, getCanonicalFileName: fileName => fileName, getCurrentDirectory: () => "", - getNewLine: () => (sys && sys.newLine) || "\r\n" + getNewLine: () => newLine }; var program = createProgram([inputFileName], options, compilerHost); if (diagnostics) { - diagnostics.push(...program.getGlobalDiagnostics()); + diagnostics.push(...program.getCompilerOptionsDiagnostics()); } // Emit diff --git a/tests/cases/unittests/transpile.ts b/tests/cases/unittests/transpile.ts new file mode 100644 index 00000000000..32caad8d05c --- /dev/null +++ b/tests/cases/unittests/transpile.ts @@ -0,0 +1,59 @@ +/// + +module ts { + describe("Transpile", () => { + + function runTest(input: string, compilerOptions: ts.CompilerOptions = {}, expectedOutput?: string, expectedDiagnosticCodes: number[] = []): void { + let diagnostics: Diagnostic[] = []; + let result = transpile(input, compilerOptions, "file.ts", diagnostics); + + assert.equal(diagnostics.length, expectedDiagnosticCodes.length); + for (let diagnostic of diagnostics) { + assert.isTrue(expectedDiagnosticCodes.indexOf(diagnostic.code) >= 0, `Found an unexpected diagnostic: ${ diagnostic.code }`); + } + + if (expectedOutput !== undefined) { + assert.equal(result, expectedOutput); + } + } + + it("Generates correct compilerOptions diagnostics", () => { + // Expecting 5047: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." + runTest(`var x = 0;`, {}, /*expectedOutput*/ undefined, [5047]); + }); + + it("Generates no diagnostics with valid inputs", () => { + // No errors + runTest(`var x = 0;`, { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, []); + }); + + it("Generates no diagnostics for missing file references", () => { + runTest(`/// +var x = 0;`, + { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, []); + }); + + it("Generates no diagnostics for missing module imports", () => { + runTest(`import {a} from "module2";`, + { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, []); + }); + + it("Generates expected syntactic diagnostics", () => { + runTest(`a b`, + { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, [1005]); /// 1005: ';' Expected + }); + + it("Does not generate semantic diagnostics", () => { + runTest(`var x: string = 0;`, + { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, []); + }); + + it("Generates module output", () => { + runTest(`var x = 0;`, { module: ModuleKind.AMD }, `define(["require", "exports"], function (require, exports) {\r\n var x = 0;\r\n});\r\n`); + }); + + it("Uses correct newLine character", () => { + runTest(`var x = 0;`, { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed }, `var x = 0;\n`); + }); + }); +} From 2cbe14e1312296cdb1c8abfa0b81c6fb6932701e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 27 May 2015 10:20:01 -0700 Subject: [PATCH 064/194] Respond to code review comments --- src/compiler/program.ts | 2 +- src/services/services.ts | 9 ++++++--- tests/cases/unittests/transpile.ts | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 4cccc881d40..1db32b95954 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -286,7 +286,7 @@ module ts { } } - function getCompilerOptionsDiagnostics(): Diagnostic[]{ + function getCompilerOptionsDiagnostics(): Diagnostic[] { let allDiagnostics: Diagnostic[] = []; addRange(allDiagnostics, diagnostics.getGlobalDiagnostics()); return sortAndDeduplicateDiagnostics(allDiagnostics); diff --git a/src/services/services.ts b/src/services/services.ts index ff1e627a241..58155f2a691 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1763,6 +1763,8 @@ module ts { * Extra compiler options that will unconditionally be used bu this function are: * - isolatedModules = true * - allowNonTsExtensions = true + * - noLib = true + * - noResolve = true */ export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[]): string { let options = compilerOptions ? clone(compilerOptions) : getDefaultCompilerOptions(); @@ -1772,11 +1774,12 @@ module ts { // Filename can be non-ts file. options.allowNonTsExtensions = true; - // We are not returning a lib file when asked, so pass this flag to - // avoid reporting a file not found error + // We are not returning a sourceFile for lib file when asked by the program, + // so pass --noLib to avoid reporting a file not found error. options.noLib = true; - // Similar to the library, we are not returning any refrenced files + // We are not doing a full typecheck, we are not resolving the whole context, + // so pass --noResolve to avoid reporting missing file errors. options.noResolve = true; // Parse diff --git a/tests/cases/unittests/transpile.ts b/tests/cases/unittests/transpile.ts index 32caad8d05c..eca136649f2 100644 --- a/tests/cases/unittests/transpile.ts +++ b/tests/cases/unittests/transpile.ts @@ -7,10 +7,10 @@ module ts { let diagnostics: Diagnostic[] = []; let result = transpile(input, compilerOptions, "file.ts", diagnostics); - assert.equal(diagnostics.length, expectedDiagnosticCodes.length); - for (let diagnostic of diagnostics) { - assert.isTrue(expectedDiagnosticCodes.indexOf(diagnostic.code) >= 0, `Found an unexpected diagnostic: ${ diagnostic.code }`); + for (let i = 0; i < expectedDiagnosticCodes.length; i++) { + assert.equal(expectedDiagnosticCodes[i], diagnostics[i] && diagnostics[i].code, `Could not find expeced diagnostic.`); } + assert.equal(diagnostics.length, expectedDiagnosticCodes.length, "Resuting diagnostics count does not match expected"); if (expectedOutput !== undefined) { assert.equal(result, expectedOutput); From 456eedf43295e90bcb5cedeb4e84c66efc96aceb Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 14:56:30 -0700 Subject: [PATCH 065/194] Added tests. --- ...lassExpressionWithResolutionOfNamespaceOfSameName01.ts | 8 ++++++++ ...tionDeclarationWithResolutionOfTypeNamedArguments01.ts | 6 ++++++ ...functionDeclarationWithResolutionOfTypeOfSameName01.ts | 6 ++++++ ...ctionExpressionWithResolutionOfTypeNamedArguments01.ts | 6 ++++++ .../functionExpressionWithResolutionOfTypeOfSameName01.ts | 6 ++++++ 5 files changed, 32 insertions(+) create mode 100644 tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts create mode 100644 tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts create mode 100644 tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts create mode 100644 tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts create mode 100644 tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts diff --git a/tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts b/tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts new file mode 100644 index 00000000000..ce44c2bca43 --- /dev/null +++ b/tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts @@ -0,0 +1,8 @@ +namespace C { + export interface type { + } +} + +var x = class C { + prop: C.type; +} \ No newline at end of file diff --git a/tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts b/tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts new file mode 100644 index 00000000000..b9ceeb4740b --- /dev/null +++ b/tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts @@ -0,0 +1,6 @@ +interface arguments { +} + +function f() { + arguments; +} \ No newline at end of file diff --git a/tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts b/tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts new file mode 100644 index 00000000000..9dc0bf86943 --- /dev/null +++ b/tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts @@ -0,0 +1,6 @@ +interface f { +} + +function f() { + f; +} \ No newline at end of file diff --git a/tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts b/tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts new file mode 100644 index 00000000000..c1b99ee8f0e --- /dev/null +++ b/tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts @@ -0,0 +1,6 @@ +interface arguments { +} + +var x = function f() { + arguments; +} \ No newline at end of file diff --git a/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts b/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts new file mode 100644 index 00000000000..de4d0e3bb90 --- /dev/null +++ b/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts @@ -0,0 +1,6 @@ +interface f { +} + +var x = function f() { + f; +} \ No newline at end of file From ac152ed19d548dd418ddd15e563671e13f3f8504 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 15:03:54 -0700 Subject: [PATCH 066/194] Accepted baselines for the only test that was expected to pass. --- ...onDeclarationWithResolutionOfTypeOfSameName01.js | 12 ++++++++++++ ...larationWithResolutionOfTypeOfSameName01.symbols | 12 ++++++++++++ ...eclarationWithResolutionOfTypeOfSameName01.types | 13 +++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.js create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.symbols create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.types diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.js b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.js new file mode 100644 index 00000000000..6f5bb2cacf9 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.js @@ -0,0 +1,12 @@ +//// [functionDeclarationWithResolutionOfTypeOfSameName01.ts] +interface f { +} + +function f() { + f; +} + +//// [functionDeclarationWithResolutionOfTypeOfSameName01.js] +function f() { + f; +} diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.symbols b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.symbols new file mode 100644 index 00000000000..aa51fad0538 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts === +interface f { +>f : Symbol(f, Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 0, 0), Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 1, 1)) +} + +function f() { +>f : Symbol(f, Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 0, 0), Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 1, 1)) + + f; +>f : Symbol(f, Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 0, 0), Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 1, 1)) +>f : Symbol(f, Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 0, 0), Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 1, 1)) +} diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.types b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.types new file mode 100644 index 00000000000..1067b8989c8 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts === +interface f { +>f : f +} + +function f() { +>f : () => void + + f; +>f : f +>f : f +>f : () => void +} From 4088bc099c797ada14b0b2606d1e8d758324a413 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 15:04:34 -0700 Subject: [PATCH 067/194] Only resolve 'arguments' and function/class expression names if the meaning permits it. --- src/compiler/checker.ts | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d409d1ea2fa..8a833123dcb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -422,27 +422,33 @@ module ts { case SyntaxKind.SetAccessor: case SyntaxKind.FunctionDeclaration: case SyntaxKind.ArrowFunction: - if (name === "arguments") { - result = argumentsSymbol; - break loop; + if (meaning & SymbolFlags.Value) { + if (name === "arguments") { + result = argumentsSymbol; + break loop; + } } break; case SyntaxKind.FunctionExpression: - if (name === "arguments") { - result = argumentsSymbol; - break loop; - } - let functionName = (location).name; - if (functionName && name === functionName.text) { - result = location.symbol; - break loop; + if (meaning & SymbolFlags.Value) { + if (name === "arguments") { + result = argumentsSymbol; + break loop; + } + let functionName = (location).name; + if (functionName && name === functionName.text) { + result = location.symbol; + break loop; + } } break; case SyntaxKind.ClassExpression: - let className = (location).name; - if (className && name === className.text) { - result = location.symbol; - break loop; + if (meaning & (SymbolFlags.Value | SymbolFlags.Type)) { + let className = (location).name; + if (className && name === className.text) { + result = location.symbol; + break loop; + } } break; case SyntaxKind.Decorator: From 644dbf230fabd7bb85c5bd0bc359083b88bd8600 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 16:03:04 -0700 Subject: [PATCH 068/194] Don't use 'Value' or 'Type' as they have overlap. Instead test for the precice meaning. --- src/compiler/checker.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8a833123dcb..991e83150a3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -422,19 +422,18 @@ module ts { case SyntaxKind.SetAccessor: case SyntaxKind.FunctionDeclaration: case SyntaxKind.ArrowFunction: - if (meaning & SymbolFlags.Value) { - if (name === "arguments") { - result = argumentsSymbol; - break loop; - } + if (meaning & SymbolFlags.Variable && name === "arguments") { + result = argumentsSymbol; + break loop; } break; case SyntaxKind.FunctionExpression: - if (meaning & SymbolFlags.Value) { - if (name === "arguments") { - result = argumentsSymbol; - break loop; - } + if (meaning & SymbolFlags.Variable && name === "arguments") { + result = argumentsSymbol; + break loop; + } + + if (meaning & SymbolFlags.Function) { let functionName = (location).name; if (functionName && name === functionName.text) { result = location.symbol; @@ -443,7 +442,7 @@ module ts { } break; case SyntaxKind.ClassExpression: - if (meaning & (SymbolFlags.Value | SymbolFlags.Type)) { + if (meaning & SymbolFlags.Class) { let className = (location).name; if (className && name === className.text) { result = location.symbol; From 636347d86b7537c708b0478545dde85b2bd7eb6e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 16:03:27 -0700 Subject: [PATCH 069/194] Accepted baselines. --- ...hResolutionOfNamespaceOfSameName01.errors.txt | 14 ++++++++++++++ ...ssionWithResolutionOfNamespaceOfSameName01.js | 16 ++++++++++++++++ ...rationWithResolutionOfTypeNamedArguments01.js | 12 ++++++++++++ ...nWithResolutionOfTypeNamedArguments01.symbols | 12 ++++++++++++ ...ionWithResolutionOfTypeNamedArguments01.types | 13 +++++++++++++ ...essionWithResolutionOfTypeNamedArguments01.js | 12 ++++++++++++ ...nWithResolutionOfTypeNamedArguments01.symbols | 13 +++++++++++++ ...ionWithResolutionOfTypeNamedArguments01.types | 15 +++++++++++++++ ...ExpressionWithResolutionOfTypeOfSameName01.js | 12 ++++++++++++ ...ssionWithResolutionOfTypeOfSameName01.symbols | 13 +++++++++++++ ...ressionWithResolutionOfTypeOfSameName01.types | 15 +++++++++++++++ 11 files changed, 147 insertions(+) create mode 100644 tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.errors.txt create mode 100644 tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.js create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.js create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.symbols create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.types create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.js create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.symbols create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.types create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.js create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.symbols create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.types diff --git a/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.errors.txt b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.errors.txt new file mode 100644 index 00000000000..8edc1d8f74b --- /dev/null +++ b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts(6,15): error TS9003: 'class' expressions are not currently supported. + + +==== tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts (1 errors) ==== + namespace C { + export interface type { + } + } + + var x = class C { + ~ +!!! error TS9003: 'class' expressions are not currently supported. + prop: C.type; + } \ No newline at end of file diff --git a/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.js b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.js new file mode 100644 index 00000000000..7c9f25cdfe6 --- /dev/null +++ b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.js @@ -0,0 +1,16 @@ +//// [classExpressionWithResolutionOfNamespaceOfSameName01.ts] +namespace C { + export interface type { + } +} + +var x = class C { + prop: C.type; +} + +//// [classExpressionWithResolutionOfNamespaceOfSameName01.js] +var x = (function () { + function C() { + } + return C; +})(); diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.js b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.js new file mode 100644 index 00000000000..3659f3fd9f9 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.js @@ -0,0 +1,12 @@ +//// [functionDeclarationWithResolutionOfTypeNamedArguments01.ts] +interface arguments { +} + +function f() { + arguments; +} + +//// [functionDeclarationWithResolutionOfTypeNamedArguments01.js] +function f() { + arguments; +} diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.symbols b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.symbols new file mode 100644 index 00000000000..8a36f146001 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts === +interface arguments { +>arguments : Symbol(arguments, Decl(functionDeclarationWithResolutionOfTypeNamedArguments01.ts, 0, 0)) +} + +function f() { +>f : Symbol(f, Decl(functionDeclarationWithResolutionOfTypeNamedArguments01.ts, 1, 1)) + + arguments; +>arguments : Symbol(arguments, Decl(functionDeclarationWithResolutionOfTypeNamedArguments01.ts, 0, 0)) +>arguments : Symbol(arguments) +} diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.types b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.types new file mode 100644 index 00000000000..72dbbf8ec69 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts === +interface arguments { +>arguments : arguments +} + +function f() { +>f : () => void + + arguments; +>arguments : arguments +>arguments : arguments +>arguments : IArguments +} diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.js b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.js new file mode 100644 index 00000000000..43b38f2dd39 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.js @@ -0,0 +1,12 @@ +//// [functionExpressionWithResolutionOfTypeNamedArguments01.ts] +interface arguments { +} + +var x = function f() { + arguments; +} + +//// [functionExpressionWithResolutionOfTypeNamedArguments01.js] +var x = function f() { + arguments; +}; diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.symbols b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.symbols new file mode 100644 index 00000000000..d2455fd0106 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts === +interface arguments { +>arguments : Symbol(arguments, Decl(functionExpressionWithResolutionOfTypeNamedArguments01.ts, 0, 0)) +} + +var x = function f() { +>x : Symbol(x, Decl(functionExpressionWithResolutionOfTypeNamedArguments01.ts, 3, 3)) +>f : Symbol(f, Decl(functionExpressionWithResolutionOfTypeNamedArguments01.ts, 3, 7)) + + arguments; +>arguments : Symbol(arguments, Decl(functionExpressionWithResolutionOfTypeNamedArguments01.ts, 0, 0)) +>arguments : Symbol(arguments) +} diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.types b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.types new file mode 100644 index 00000000000..1a65010a4f6 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts === +interface arguments { +>arguments : arguments +} + +var x = function f() { +>x : () => void +>function f() { arguments;} : () => void +>f : () => void + + arguments; +>arguments : arguments +>arguments : arguments +>arguments : IArguments +} diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.js b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.js new file mode 100644 index 00000000000..c9af7ab3297 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.js @@ -0,0 +1,12 @@ +//// [functionExpressionWithResolutionOfTypeOfSameName01.ts] +interface f { +} + +var x = function f() { + f; +} + +//// [functionExpressionWithResolutionOfTypeOfSameName01.js] +var x = function f() { + f; +}; diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.symbols b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.symbols new file mode 100644 index 00000000000..cd2248c6018 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts === +interface f { +>f : Symbol(f, Decl(functionExpressionWithResolutionOfTypeOfSameName01.ts, 0, 0)) +} + +var x = function f() { +>x : Symbol(x, Decl(functionExpressionWithResolutionOfTypeOfSameName01.ts, 3, 3)) +>f : Symbol(f, Decl(functionExpressionWithResolutionOfTypeOfSameName01.ts, 3, 7)) + + f; +>f : Symbol(f, Decl(functionExpressionWithResolutionOfTypeOfSameName01.ts, 0, 0)) +>f : Symbol(f, Decl(functionExpressionWithResolutionOfTypeOfSameName01.ts, 3, 7)) +} diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.types b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.types new file mode 100644 index 00000000000..08b51f35226 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts === +interface f { +>f : f +} + +var x = function f() { +>x : () => void +>function f() { f;} : () => void +>f : () => void + + f; +>f : f +>f : f +>f : () => void +} From db313061ee1ba80fc263829f14f65dc26f8dc766 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 16:30:44 -0700 Subject: [PATCH 070/194] Added another test. --- .../functionExpressionWithResolutionOfTypeOfSameName02.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts diff --git a/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts b/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts new file mode 100644 index 00000000000..041195271fb --- /dev/null +++ b/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts @@ -0,0 +1,6 @@ +interface Foo { +} + +var x = function Foo() { + var x: Foo; +} \ No newline at end of file From acbff901da2b80b346ea1dcaae057ca854294265 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 16:34:39 -0700 Subject: [PATCH 071/194] Accepted baselines. --- ...onExpressionWithResolutionOfTypeOfSameName02.js | 12 ++++++++++++ ...ressionWithResolutionOfTypeOfSameName02.symbols | 13 +++++++++++++ ...xpressionWithResolutionOfTypeOfSameName02.types | 14 ++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.js create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.symbols create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.types diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.js b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.js new file mode 100644 index 00000000000..ada96c63a56 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.js @@ -0,0 +1,12 @@ +//// [functionExpressionWithResolutionOfTypeOfSameName02.ts] +interface Foo { +} + +var x = function Foo() { + var x: Foo; +} + +//// [functionExpressionWithResolutionOfTypeOfSameName02.js] +var x = function Foo() { + var x; +}; diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.symbols b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.symbols new file mode 100644 index 00000000000..89b46c99b4e --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts === +interface Foo { +>Foo : Symbol(Foo, Decl(functionExpressionWithResolutionOfTypeOfSameName02.ts, 0, 0)) +} + +var x = function Foo() { +>x : Symbol(x, Decl(functionExpressionWithResolutionOfTypeOfSameName02.ts, 3, 3)) +>Foo : Symbol(Foo, Decl(functionExpressionWithResolutionOfTypeOfSameName02.ts, 3, 7)) + + var x: Foo; +>x : Symbol(x, Decl(functionExpressionWithResolutionOfTypeOfSameName02.ts, 4, 7)) +>Foo : Symbol(Foo, Decl(functionExpressionWithResolutionOfTypeOfSameName02.ts, 0, 0)) +} diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.types b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.types new file mode 100644 index 00000000000..218276a95ea --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts === +interface Foo { +>Foo : Foo +} + +var x = function Foo() { +>x : () => void +>function Foo() { var x: Foo;} : () => void +>Foo : () => void + + var x: Foo; +>x : Foo +>Foo : Foo +} From 64c7f3d38be6822c5ee58f88e5782ef8867df3b8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 28 May 2015 14:45:43 -0700 Subject: [PATCH 072/194] Add syntactic classification for doc comments. --- src/compiler/parser.ts | 12 +- src/harness/harness.ts | 2 +- src/services/services.ts | 122 +++++++++++++++++- tests/cases/fourslash/fourslash.ts | 4 + .../syntacticClassificationsDocComment1.ts | 17 +++ 5 files changed, 143 insertions(+), 14 deletions(-) create mode 100644 tests/cases/fourslash/syntacticClassificationsDocComment1.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 28fd8184d7e..0595aa75959 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -363,9 +363,9 @@ module ts { } } - export function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes = false): SourceFile { + export function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes = false, includeDocComments = false): SourceFile { let start = new Date().getTime(); - let result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes); + let result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, includeDocComments); parseTime += new Date().getTime() - start; return result; @@ -493,10 +493,10 @@ module ts { // attached to the EOF token. let parseErrorBeforeNextFinishedNode: boolean = false; - export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean): SourceFile { + export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, includeDocComments?: boolean): SourceFile { initializeState(fileName, _sourceText, languageVersion, _syntaxCursor); - let result = parseSourceFileWorker(fileName, languageVersion, setParentNodes); + let result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, includeDocComments); clearState(); @@ -535,7 +535,7 @@ module ts { sourceText = undefined; } - function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean): SourceFile { + function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, includeDocComments: boolean): SourceFile { sourceFile = createSourceFile(fileName, languageVersion); // Prime the scanner. @@ -560,7 +560,7 @@ module ts { // If this is a javascript file, proactively see if we can get JSDoc comments for // relevant nodes in the file. We'll use these to provide typing informaion if they're // available. - if (isJavaScript(fileName)) { + if (includeDocComments || isJavaScript(fileName)) { addJSDocComments(); } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 90afab029eb..244c693ad12 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -167,7 +167,7 @@ module Utils { continue; } var child = (node)[childName]; - if (isNodeOrArray(child)) { + if (isNodeOrArray(child) && childName !== "jsDocComment") { assert.isFalse(childNodesAndArrays.indexOf(child) < 0, "Missing child when forEach'ing over node: " + (ts).SyntaxKind[node.kind] + "-" + childName); } diff --git a/src/services/services.ts b/src/services/services.ts index 1019c532192..8990a62f664 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1510,6 +1510,7 @@ module ts { public static typeParameterName = "type parameter name"; public static typeAliasName = "type alias name"; public static parameterName = "parameter name"; + public static docCommentTagName = "doc comment tag name"; } export const enum ClassificationType { @@ -1529,7 +1530,8 @@ module ts { moduleName = 14, typeParameterName = 15, typeAliasName = 16, - parameterName = 17 + parameterName = 17, + docCommentTagName = 18, } /// Language Service @@ -1813,7 +1815,8 @@ module ts { } export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile { - let sourceFile = createSourceFile(fileName, scriptSnapshot.getText(0, scriptSnapshot.getLength()), scriptTarget, setNodeParents); + let text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); + let sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents, /*includeDocComments:*/ true); setSourceFileFields(sourceFile, scriptSnapshot, version); // after full parsing we can use table with interned strings as name table sourceFile.nameTable = sourceFile.identifiers; @@ -2832,6 +2835,7 @@ module ts { let typeChecker = program.getTypeChecker(); let syntacticStart = new Date().getTime(); let sourceFile = getValidSourceFile(fileName); + let isJavaScriptFile = isJavaScript(fileName); let start = new Date().getTime(); let currentToken = getTokenAtPosition(sourceFile, position); @@ -2932,13 +2936,29 @@ module ts { } let type = typeChecker.getTypeAtLocation(node); + addTypeProperties(type); + } + + function addTypeProperties(type: Type) { if (type) { // Filter private properties - forEach(type.getApparentProperties(), symbol => { + for (let symbol of type.getApparentProperties()) { if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); } - }); + } + + if (isJavaScriptFile && type.flags & TypeFlags.Union) { + // In javascript files, for union types, we don't just get the members that + // the individual types have in common, we also include all the members that + // each individual type has. This is because we're going to add all identifiers + // anyways. So we might as well elevate the members that were at least part + // of the individual types to a higher status than since we know what they are. + let unionType = type; + for (let elementType of unionType.types) { + addTypeProperties(elementType); + } + } } } @@ -6031,6 +6051,7 @@ module ts { case ClassificationType.typeParameterName: return ClassificationTypeNames.typeParameterName; case ClassificationType.typeAliasName: return ClassificationTypeNames.typeAliasName; case ClassificationType.parameterName: return ClassificationTypeNames.parameterName; + case ClassificationType.docCommentTagName: return ClassificationTypeNames.docCommentTagName; } } @@ -6093,8 +6114,7 @@ module ts { // Only bother with the trivia if it at least intersects the span of interest. if (textSpanIntersectsWith(span, start, width)) { if (isComment(kind)) { - // Simple comment. Just add as is. - pushClassification(start, width, ClassificationType.comment); + classifyComment(token, kind, start, width); continue; } @@ -6118,6 +6138,90 @@ module ts { } } + function classifyComment(token: Node, kind: SyntaxKind, start: number, width: number) { + if (kind === SyntaxKind.MultiLineCommentTrivia) { + // See if this is a doc comment. If so, we'll classify certain portions of it + // specially. + let jsDocComment = parseIsolatedJSDocComment(sourceFile.text, start, width); + if (jsDocComment && jsDocComment.jsDocComment) { + jsDocComment.jsDocComment.parent = token; + classifyJSDocComment(jsDocComment.jsDocComment); + return; + } + } + + // Simple comment. Just add as is. + pushCommentRange(start, width); + } + + function pushCommentRange(start: number, width: number) { + pushClassification(start, width, ClassificationType.comment); + } + + function classifyJSDocComment(docComment: JSDocComment) { + let pos = docComment.pos; + + for (let tag of docComment.tags) { + if (tag.pos !== pos) { + pushCommentRange(pos, tag.pos - pos); + } + + pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, ClassificationType.punctuation); + pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, ClassificationType.docCommentTagName); + + pos = tag.tagName.end; + + switch (tag.kind) { + case SyntaxKind.JSDocParameterTag: + processJSDocParameterTag(tag); + break; + case SyntaxKind.JSDocTemplateTag: + processJSDocTemplateTag(tag); + break; + case SyntaxKind.JSDocTypeTag: + processElement((tag).typeExpression); + break; + case SyntaxKind.JSDocReturnTag: + processElement((tag).typeExpression); + break; + } + + pos = tag.end; + } + + if (pos !== docComment.end) { + pushCommentRange(pos, docComment.end - pos); + } + + return; + + function processJSDocParameterTag(tag: JSDocParameterTag) { + if (tag.preParameterName) { + pushCommentRange(pos, tag.preParameterName.pos - pos); + pushClassification(tag.preParameterName.pos, tag.preParameterName.end - tag.preParameterName.pos, ClassificationType.parameterName); + pos = tag.preParameterName.end; + } + + if (tag.typeExpression) { + pushCommentRange(pos, tag.typeExpression.pos - pos); + processElement(tag.typeExpression); + pos = tag.typeExpression.end; + } + + if (tag.postParameterName) { + pushCommentRange(pos, tag.postParameterName.pos - pos); + pushClassification(tag.postParameterName.pos, tag.postParameterName.end - tag.postParameterName.pos, ClassificationType.parameterName); + pos = tag.postParameterName.end; + } + } + } + + function processJSDocTemplateTag(tag: JSDocTemplateTag) { + for (let child of tag.getChildren()) { + processElement(child); + } + } + function classifyDisabledMergeCode(text: string, start: number, end: number) { // Classify the line that the ======= marker is on as a comment. Then just lex // all further tokens and add them to the result. @@ -6251,9 +6355,13 @@ module ts { } function processElement(element: Node) { + if (!element) { + return; + } + // Ignore nodes that don't intersect the original span to classify. if (textSpanIntersectsWith(span, element.getFullStart(), element.getFullWidth())) { - let children = element.getChildren(); + let children = element.getChildren(sourceFile); for (let child of children) { if (isToken(child)) { classifyToken(child); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 9c6fd814d9f..0d98c6e4869 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -639,6 +639,10 @@ module FourSlashInterface { return getClassification("punctuation", text, position); } + export function docCommentTagName(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } { + return getClassification("docCommentTagName", text, position); + } + export function className(text: string, position?: number): { classificationType: string; text: string; textSpan?: TextSpan } { return getClassification("className", text, position); } diff --git a/tests/cases/fourslash/syntacticClassificationsDocComment1.ts b/tests/cases/fourslash/syntacticClassificationsDocComment1.ts new file mode 100644 index 00000000000..fe812b4c780 --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsDocComment1.ts @@ -0,0 +1,17 @@ +/// + +//// /** @type {number} */ +//// var v; + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("/** "), + c.punctuation("@"), + c.docCommentTagName("type"), + c.punctuation("{"), + c.keyword("number"), + c.punctuation("}"), + c.comment(" */"), + c.keyword("var"), + c.text("v"), + c.punctuation(";")); From caddec902a8d72f8a273bae09cbd46f5de792d81 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 28 May 2015 14:58:22 -0700 Subject: [PATCH 073/194] Remove uneeded code. --- src/compiler/parser.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 0595aa75959..bbc76c73b66 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2,8 +2,6 @@ /// module ts { - export var throwOnJSDocErrors = false; - let nodeConstructors = new Array Node>(SyntaxKind.Count); /* @internal */ export let parseTime = 0; @@ -5049,13 +5047,6 @@ module ts { return finishNode(result); } - function setError(message: DiagnosticMessage) { - parseErrorAtCurrentToken(message); - if (throwOnJSDocErrors) { - throw new Error(message.key); - } - } - function parseJSDocTopLevelType(): JSDocType { var type = parseJSDocType(); if (token === SyntaxKind.BarToken) { From 0f3584e9cc5fbdd9ed9b556a24b9893ddb3d7565 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 28 May 2015 15:04:08 -0700 Subject: [PATCH 074/194] Removing unnecessary code. --- src/compiler/parser.ts | 12 ++++++------ src/services/services.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index bbc76c73b66..f53c0799c9f 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -361,9 +361,9 @@ module ts { } } - export function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes = false, includeDocComments = false): SourceFile { + export function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes = false): SourceFile { let start = new Date().getTime(); - let result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, includeDocComments); + let result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes); parseTime += new Date().getTime() - start; return result; @@ -491,10 +491,10 @@ module ts { // attached to the EOF token. let parseErrorBeforeNextFinishedNode: boolean = false; - export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, includeDocComments?: boolean): SourceFile { + export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean): SourceFile { initializeState(fileName, _sourceText, languageVersion, _syntaxCursor); - let result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, includeDocComments); + let result = parseSourceFileWorker(fileName, languageVersion, setParentNodes); clearState(); @@ -533,7 +533,7 @@ module ts { sourceText = undefined; } - function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, includeDocComments: boolean): SourceFile { + function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean): SourceFile { sourceFile = createSourceFile(fileName, languageVersion); // Prime the scanner. @@ -558,7 +558,7 @@ module ts { // If this is a javascript file, proactively see if we can get JSDoc comments for // relevant nodes in the file. We'll use these to provide typing informaion if they're // available. - if (includeDocComments || isJavaScript(fileName)) { + if (isJavaScript(fileName)) { addJSDocComments(); } diff --git a/src/services/services.ts b/src/services/services.ts index 8990a62f664..350a7049728 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1816,7 +1816,7 @@ module ts { export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile { let text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); - let sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents, /*includeDocComments:*/ true); + let sourceFile = createSourceFile(fileName, text, scriptTarget, setNodeParents); setSourceFileFields(sourceFile, scriptSnapshot, version); // after full parsing we can use table with interned strings as name table sourceFile.nameTable = sourceFile.identifiers; From 26103b8548cd03f23810ac8b70a01d046e4473f2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 28 May 2015 15:18:39 -0700 Subject: [PATCH 075/194] Remove unnecessary code. --- src/harness/harness.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 244c693ad12..90afab029eb 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -167,7 +167,7 @@ module Utils { continue; } var child = (node)[childName]; - if (isNodeOrArray(child) && childName !== "jsDocComment") { + if (isNodeOrArray(child)) { assert.isFalse(childNodesAndArrays.indexOf(child) < 0, "Missing child when forEach'ing over node: " + (ts).SyntaxKind[node.kind] + "-" + childName); } From c597bd63fcee789e2c3d525928db36e28c2e292d Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Fri, 29 May 2015 17:20:41 -0700 Subject: [PATCH 076/194] Add APIs to provide project info for a given file Return the path of the config file and the file name list of the project (optionally). This is helpful in differentiate the build command behavior for loose files and configured projects in sublime. --- src/server/editorServices.ts | 5 +++++ src/server/protocol.d.ts | 22 ++++++++++++++++++++++ src/server/session.ts | 24 ++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 9c87a20c851..bc9e685825c 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -305,6 +305,11 @@ module ts.server { return this.projectService.openFile(filename, false); } + getFileNameList() { + let sourceFiles = this.program.getSourceFiles(); + return sourceFiles.map(sourceFile => sourceFile.fileName); + } + getSourceFile(info: ScriptInfo) { return this.filenameToSourceFile[info.fileName]; } diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index b95d5e99864..f857595069d 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -87,6 +87,28 @@ declare module ts.server.protocol { file: string; } + /** + * Arguments for ProjectInfo messages. + */ + export interface ProjectInfoRequestArgs { + /** + * The file for the request (absolute pathname required). + */ + file: string; + /** + * Indicate if the file name list of the project is needed + */ + needFileNameList: boolean; + } + + /** + * Response message for "projectInfo" request + */ + export interface ProjectInfo { + configFileName: string; + fileNameList?: string[]; + } + /** * Request whose sole parameter is a file name. */ diff --git a/src/server/session.ts b/src/server/session.ts index baf0a085ad4..4a779be0787 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -96,8 +96,9 @@ module ts.server { export var Reload = "reload"; export var Rename = "rename"; export var Saveto = "saveto"; - export var SignatureHelp = "signatureHelp"; - export var TypeDefinition = "typeDefinition"; + export var SignatureHelp = "signatureHelp"; + export var TypeDefinition = "typeDefinition"; + export var ProjectInfo = "projectInfo"; export var Unknown = "unknown"; } @@ -338,6 +339,20 @@ module ts.server { }); } + getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo { + fileName = ts.normalizePath(fileName) + let project = this.projectService.getProjectForFile(fileName) + + let projectInfo: protocol.ProjectInfo = { + configFileName: project.projectFilename + } + + if (needFileNameList) { + projectInfo.fileNameList = project.getFileNameList(); + } + return projectInfo; + } + getRenameLocations(line: number, offset: number, fileName: string,findInComments: boolean, findInStrings: boolean): protocol.RenameResponseBody { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); @@ -951,6 +966,11 @@ module ts.server { response = this.getOccurrences(line, offset, fileName); break; } + case CommandNames.ProjectInfo: { + var { file, needFileNameList } = request.arguments; + response = this.getProjectInfo(file, needFileNameList); + break; + } default: { this.projectService.log("Unrecognized JSON command: " + message); this.output(undefined, CommandNames.Unknown, request.seq, "Unrecognized JSON command: " + request.command); From 321cfab2d7d9a56f95233f1cc3f22042fdbf4c90 Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Fri, 29 May 2015 18:03:41 -0700 Subject: [PATCH 077/194] CR feedback --- src/server/protocol.d.ts | 4 +-- src/server/session.ts | 56 ++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index f857595069d..6df5b420243 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -88,7 +88,7 @@ declare module ts.server.protocol { } /** - * Arguments for ProjectInfo messages. + * Arguments for ProjectInfoResponse messages. */ export interface ProjectInfoRequestArgs { /** @@ -104,7 +104,7 @@ declare module ts.server.protocol { /** * Response message for "projectInfo" request */ - export interface ProjectInfo { + export interface ProjectInfoResponse { configFileName: string; fileNameList?: string[]; } diff --git a/src/server/session.ts b/src/server/session.ts index 4a779be0787..621edd35f4f 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -76,30 +76,30 @@ module ts.server { } export module CommandNames { - export var Brace = "brace"; - export var Change = "change"; - export var Close = "close"; - export var Completions = "completions"; - export var CompletionDetails = "completionEntryDetails"; - export var Configure = "configure"; - export var Definition = "definition"; - export var Exit = "exit"; - export var Format = "format"; - export var Formatonkey = "formatonkey"; - export var Geterr = "geterr"; - export var NavBar = "navbar"; - export var Navto = "navto"; - export var Occurrences = "occurrences"; - export var Open = "open"; - export var Quickinfo = "quickinfo"; - export var References = "references"; - export var Reload = "reload"; - export var Rename = "rename"; - export var Saveto = "saveto"; - export var SignatureHelp = "signatureHelp"; - export var TypeDefinition = "typeDefinition"; - export var ProjectInfo = "projectInfo"; - export var Unknown = "unknown"; + export const Brace = "brace"; + export const Change = "change"; + export const Close = "close"; + export const Completions = "completions"; + export const CompletionDetails = "completionEntryDetails"; + export const Configure = "configure"; + export const Definition = "definition"; + export const Exit = "exit"; + export const Format = "format"; + export const Formatonkey = "formatonkey"; + export const Geterr = "geterr"; + export const NavBar = "navbar"; + export const Navto = "navto"; + export const Occurrences = "occurrences"; + export const Open = "open"; + export const Quickinfo = "quickinfo"; + export const References = "references"; + export const Reload = "reload"; + export const Rename = "rename"; + export const Saveto = "saveto"; + export const SignatureHelp = "signatureHelp"; + export const TypeDefinition = "typeDefinition"; + export const ProjectInfo = "projectInfo"; + export const Unknown = "unknown"; } module Errors { @@ -339,18 +339,18 @@ module ts.server { }); } - getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo { + getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfoResponse { fileName = ts.normalizePath(fileName) let project = this.projectService.getProjectForFile(fileName) - let projectInfo: protocol.ProjectInfo = { + let projectInfoResponse: protocol.ProjectInfoResponse = { configFileName: project.projectFilename } if (needFileNameList) { - projectInfo.fileNameList = project.getFileNameList(); + projectInfoResponse.fileNameList = project.getFileNameList(); } - return projectInfo; + return projectInfoResponse; } getRenameLocations(line: number, offset: number, fileName: string,findInComments: boolean, findInStrings: boolean): protocol.RenameResponseBody { From 413176b2a1a54babdd94d8baa51d996d62cee1a7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 30 May 2015 16:37:03 -0700 Subject: [PATCH 078/194] Use symbols instead of types in infinite instantiation detection --- src/compiler/checker.ts | 123 +++++++++++++++++++++------------------- src/compiler/types.ts | 11 ++-- 2 files changed, 70 insertions(+), 64 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 76ec977491e..7c640598e69 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1472,7 +1472,7 @@ module ts { return appendParentTypeArgumentsAndSymbolName(symbol); } - function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, typeStack?: Type[]) { + function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) { let globalFlagsToPass = globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike; return writeType(type, globalFlags); @@ -1557,49 +1557,54 @@ module ts { } function writeAnonymousType(type: ObjectType, flags: TypeFormatFlags) { - // Always use 'typeof T' for type of class, enum, and module objects - if (type.symbol && type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) { - writeTypeofSymbol(type, flags); - } - // Use 'typeof T' for types of functions and methods that circularly reference themselves - else if (shouldWriteTypeOfFunctionSymbol()) { - writeTypeofSymbol(type, flags); - } - else if (typeStack && contains(typeStack, type)) { - // If type is an anonymous type literal in a type alias declaration, use type alias name - let typeAlias = getTypeAliasForTypeLiteral(type); - if (typeAlias) { - // The specified symbol flags need to be reinterpreted as type flags - buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags); + let symbol = type.symbol; + if (symbol) { + // Always use 'typeof T' for type of class, enum, and module objects + if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) { + writeTypeofSymbol(type, flags); + } + else if (shouldWriteTypeOfFunctionSymbol()) { + writeTypeofSymbol(type, flags); + } + else if (contains(symbolStack, symbol)) { + // If type is an anonymous type literal in a type alias declaration, use type alias name + let typeAlias = getTypeAliasForTypeLiteral(type); + if (typeAlias) { + // The specified symbol flags need to be reinterpreted as type flags + buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags); + } + else { + // Recursive usage, use any + writeKeyword(writer, SyntaxKind.AnyKeyword); + } } else { - // Recursive usage, use any - writeKeyword(writer, SyntaxKind.AnyKeyword); + // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead + // of types allows us to catch circular references to instantiations of the same anonymous type + if (!symbolStack) { + symbolStack = []; + } + symbolStack.push(symbol); + writeLiteralType(type, flags); + symbolStack.pop(); } } else { - if (!typeStack) { - typeStack = []; - } - typeStack.push(type); + // Anonymous types with no symbol are never circular writeLiteralType(type, flags); - typeStack.pop(); } function shouldWriteTypeOfFunctionSymbol() { - if (type.symbol) { - let isStaticMethodSymbol = !!(type.symbol.flags & SymbolFlags.Method && // typeof static method - ts.forEach(type.symbol.declarations, declaration => declaration.flags & NodeFlags.Static)); - let isNonLocalFunctionSymbol = !!(type.symbol.flags & SymbolFlags.Function) && - (type.symbol.parent || // is exported function symbol - ts.forEach(type.symbol.declarations, declaration => - declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); - - if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { - // typeof is allowed only for static/non local functions - return !!(flags & TypeFormatFlags.UseTypeOfFunction) || // use typeof if format flags specify it - (typeStack && contains(typeStack, type)); // it is type of the symbol uses itself recursively - } + let isStaticMethodSymbol = !!(symbol.flags & SymbolFlags.Method && // typeof static method + forEach(symbol.declarations, declaration => declaration.flags & NodeFlags.Static)); + let isNonLocalFunctionSymbol = !!(symbol.flags & SymbolFlags.Function) && + (symbol.parent || // is exported function symbol + forEach(symbol.declarations, declaration => + declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); + if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { + // typeof is allowed only for static/non local functions + return !!(flags & TypeFormatFlags.UseTypeOfFunction) || // use typeof if format flags specify it + (contains(symbolStack, symbol)); // it is type of the symbol uses itself recursively } } } @@ -1634,7 +1639,7 @@ module ts { if (flags & TypeFormatFlags.InElementType) { writePunctuation(writer, SyntaxKind.OpenParenToken); } - buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, typeStack); + buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, symbolStack); if (flags & TypeFormatFlags.InElementType) { writePunctuation(writer, SyntaxKind.CloseParenToken); } @@ -1646,7 +1651,7 @@ module ts { } writeKeyword(writer, SyntaxKind.NewKeyword); writeSpace(writer); - buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, typeStack); + buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, symbolStack); if (flags & TypeFormatFlags.InElementType) { writePunctuation(writer, SyntaxKind.CloseParenToken); } @@ -1658,7 +1663,7 @@ module ts { writer.writeLine(); writer.increaseIndent(); for (let signature of resolved.callSignatures) { - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, typeStack); + buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, symbolStack); writePunctuation(writer, SyntaxKind.SemicolonToken); writer.writeLine(); } @@ -1666,7 +1671,7 @@ module ts { writeKeyword(writer, SyntaxKind.NewKeyword); writeSpace(writer); - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, typeStack); + buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, symbolStack); writePunctuation(writer, SyntaxKind.SemicolonToken); writer.writeLine(); } @@ -1707,7 +1712,7 @@ module ts { if (p.flags & SymbolFlags.Optional) { writePunctuation(writer, SyntaxKind.QuestionToken); } - buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, typeStack); + buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, symbolStack); writePunctuation(writer, SyntaxKind.SemicolonToken); writer.writeLine(); } @@ -1736,18 +1741,18 @@ module ts { } } - function buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { appendSymbolNameOnly(tp.symbol, writer); let constraint = getConstraintOfTypeParameter(tp); if (constraint) { writeSpace(writer); writeKeyword(writer, SyntaxKind.ExtendsKeyword); writeSpace(writer); - buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, typeStack); + buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack); } } - function buildParameterDisplay(p: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildParameterDisplay(p: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { if (hasDotDotDotToken(p.valueDeclaration)) { writePunctuation(writer, SyntaxKind.DotDotDotToken); } @@ -1758,10 +1763,10 @@ module ts { writePunctuation(writer, SyntaxKind.ColonToken); writeSpace(writer); - buildTypeDisplay(getTypeOfSymbol(p), writer, enclosingDeclaration, flags, typeStack); + buildTypeDisplay(getTypeOfSymbol(p), writer, enclosingDeclaration, flags, symbolStack); } - function buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { if (typeParameters && typeParameters.length) { writePunctuation(writer, SyntaxKind.LessThanToken); for (let i = 0; i < typeParameters.length; i++) { @@ -1769,13 +1774,13 @@ module ts { writePunctuation(writer, SyntaxKind.CommaToken); writeSpace(writer); } - buildTypeParameterDisplay(typeParameters[i], writer, enclosingDeclaration, flags, typeStack); + buildTypeParameterDisplay(typeParameters[i], writer, enclosingDeclaration, flags, symbolStack); } writePunctuation(writer, SyntaxKind.GreaterThanToken); } } - function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { if (typeParameters && typeParameters.length) { writePunctuation(writer, SyntaxKind.LessThanToken); for (let i = 0; i < typeParameters.length; i++) { @@ -1789,19 +1794,19 @@ module ts { } } - function buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { writePunctuation(writer, SyntaxKind.OpenParenToken); for (let i = 0; i < parameters.length; i++) { if (i > 0) { writePunctuation(writer, SyntaxKind.CommaToken); writeSpace(writer); } - buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, typeStack); + buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, symbolStack); } writePunctuation(writer, SyntaxKind.CloseParenToken); } - function buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { if (flags & TypeFormatFlags.WriteArrowStyleSignature) { writeSpace(writer); writePunctuation(writer, SyntaxKind.EqualsGreaterThanToken); @@ -1810,21 +1815,21 @@ module ts { writePunctuation(writer, SyntaxKind.ColonToken); } writeSpace(writer); - buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags, typeStack); + buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags, symbolStack); } - function buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { + function buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { if (signature.target && (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature)) { // Instantiated signature, write type arguments instead // This is achieved by passing in the mapper separately buildDisplayForTypeArgumentsAndDelimiters(signature.target.typeParameters, signature.mapper, writer, enclosingDeclaration); } else { - buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, typeStack); + buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, symbolStack); } - buildDisplayForParametersAndDelimiters(signature.parameters, writer, enclosingDeclaration, flags, typeStack); - buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, typeStack); + buildDisplayForParametersAndDelimiters(signature.parameters, writer, enclosingDeclaration, flags, symbolStack); + buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack); } return _displayBuilder || (_displayBuilder = { @@ -3889,7 +3894,7 @@ module ts { mapper.mappings = {}; } // Instantiate the given type using the given mapper and cache the result - let result = createObjectType(TypeFlags.Anonymous, type.symbol); + let result = createObjectType(TypeFlags.Anonymous | TypeFlags.Instantiated, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); result.members = createSymbolTable(result.properties); result.callSignatures = instantiateList(getSignaturesOfType(type, SignatureKind.Call), mapper, instantiateSignature); @@ -4313,12 +4318,12 @@ module ts { // Effectively, we will generate a false positive when two types are structurally equal to at least 10 levels, but unequal at // some level beyond that. function isDeeplyNestedGeneric(type: ObjectType, stack: ObjectType[]): boolean { - if (type.flags & TypeFlags.Reference && depth >= 10) { - let target = (type).target; + if (type.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && depth >= 10) { + let symbol = type.symbol; let count = 0; for (let i = 0; i < depth; i++) { let t = stack[i]; - if (t.flags & TypeFlags.Reference && (t).target === target) { + if (t.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && t.symbol === symbol) { count++; if (count >= 10) return true; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3d52d096b03..a6ab19d4296 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1582,14 +1582,15 @@ module ts { Tuple = 0x00002000, // Tuple Union = 0x00004000, // Union Anonymous = 0x00008000, // Anonymous + Instantiated = 0x00010000, // Instantiated anonymous type /* @internal */ - FromSignature = 0x00010000, // Created for signature assignment check - ObjectLiteral = 0x00020000, // Originates in an object literal + FromSignature = 0x00020000, // Created for signature assignment check + ObjectLiteral = 0x00040000, // Originates in an object literal /* @internal */ - ContainsUndefinedOrNull = 0x00040000, // Type is or contains Undefined or Null type + ContainsUndefinedOrNull = 0x00080000, // Type is or contains Undefined or Null type /* @internal */ - ContainsObjectLiteral = 0x00080000, // Type is or contains object literal type - ESSymbol = 0x00100000, // Type of symbol primitive introduced in ES6 + ContainsObjectLiteral = 0x00100000, // Type is or contains object literal type + ESSymbol = 0x00200000, // Type of symbol primitive introduced in ES6 /* @internal */ Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null, From 46e0ba82cec8e97e1e0be137e94d1d2fcef31381 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 30 May 2015 17:25:44 -0700 Subject: [PATCH 079/194] Remove old (and insufficient) instantiation caching --- src/compiler/checker.ts | 14 +------------- src/compiler/types.ts | 1 - 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7c640598e69..c180d8425f2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3882,18 +3882,7 @@ module ts { } function instantiateAnonymousType(type: ObjectType, mapper: TypeMapper): ObjectType { - // If this type has already been instantiated using this mapper, returned the cached result. This guards against - // infinite instantiations of cyclic types, e.g. "var x: { a: T, b: typeof x };" - if (mapper.mappings) { - let cached = mapper.mappings[type.id]; - if (cached) { - return cached; - } - } - else { - mapper.mappings = {}; - } - // Instantiate the given type using the given mapper and cache the result + // Mark the anonymous type as instantiated such that our infinite instantiation detection logic can recognize it let result = createObjectType(TypeFlags.Anonymous | TypeFlags.Instantiated, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); result.members = createSymbolTable(result.properties); @@ -3903,7 +3892,6 @@ module ts { let numberIndexType = getIndexTypeOfType(type, IndexKind.Number); if (stringIndexType) result.stringIndexType = instantiateType(stringIndexType, mapper); if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper); - mapper.mappings[type.id] = result; return result; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a6ab19d4296..2d1175df080 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1730,7 +1730,6 @@ module ts { /* @internal */ export interface TypeMapper { (t: TypeParameter): Type; - mappings?: Map; // Type mapping cache } /* @internal */ From e336e3ad0aa6e983d380dcd9bbd107b157a5bfba Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 30 May 2015 18:09:13 -0700 Subject: [PATCH 080/194] Adding regression test --- .../cyclicGenericTypeInstantiation.js | 37 ++++++++++++ .../cyclicGenericTypeInstantiation.symbols | 55 +++++++++++++++++ .../cyclicGenericTypeInstantiation.types | 60 +++++++++++++++++++ .../cyclicGenericTypeInstantiation.ts | 20 +++++++ 4 files changed, 172 insertions(+) create mode 100644 tests/baselines/reference/cyclicGenericTypeInstantiation.js create mode 100644 tests/baselines/reference/cyclicGenericTypeInstantiation.symbols create mode 100644 tests/baselines/reference/cyclicGenericTypeInstantiation.types create mode 100644 tests/cases/compiler/cyclicGenericTypeInstantiation.ts diff --git a/tests/baselines/reference/cyclicGenericTypeInstantiation.js b/tests/baselines/reference/cyclicGenericTypeInstantiation.js new file mode 100644 index 00000000000..10f52e10d89 --- /dev/null +++ b/tests/baselines/reference/cyclicGenericTypeInstantiation.js @@ -0,0 +1,37 @@ +//// [cyclicGenericTypeInstantiation.ts] +function foo() { + var z = foo(); + var y: { + y2: typeof z + }; + return y; +} + + +function bar() { + var z = bar(); + var y: { + y2: typeof z; + } + return y; +} + +var a = foo(); +var b = bar(); +a = b; + + +//// [cyclicGenericTypeInstantiation.js] +function foo() { + var z = foo(); + var y; + return y; +} +function bar() { + var z = bar(); + var y; + return y; +} +var a = foo(); +var b = bar(); +a = b; diff --git a/tests/baselines/reference/cyclicGenericTypeInstantiation.symbols b/tests/baselines/reference/cyclicGenericTypeInstantiation.symbols new file mode 100644 index 00000000000..a6566b86839 --- /dev/null +++ b/tests/baselines/reference/cyclicGenericTypeInstantiation.symbols @@ -0,0 +1,55 @@ +=== tests/cases/compiler/cyclicGenericTypeInstantiation.ts === +function foo() { +>foo : Symbol(foo, Decl(cyclicGenericTypeInstantiation.ts, 0, 0)) +>T : Symbol(T, Decl(cyclicGenericTypeInstantiation.ts, 0, 13)) + + var z = foo(); +>z : Symbol(z, Decl(cyclicGenericTypeInstantiation.ts, 1, 7)) +>foo : Symbol(foo, Decl(cyclicGenericTypeInstantiation.ts, 0, 0)) +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 2, 7)) + + var y: { +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 2, 7)) + + y2: typeof z +>y2 : Symbol(y2, Decl(cyclicGenericTypeInstantiation.ts, 2, 12)) +>z : Symbol(z, Decl(cyclicGenericTypeInstantiation.ts, 1, 7)) + + }; + return y; +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 2, 7)) +} + + +function bar() { +>bar : Symbol(bar, Decl(cyclicGenericTypeInstantiation.ts, 6, 1)) +>T : Symbol(T, Decl(cyclicGenericTypeInstantiation.ts, 9, 13)) + + var z = bar(); +>z : Symbol(z, Decl(cyclicGenericTypeInstantiation.ts, 10, 7)) +>bar : Symbol(bar, Decl(cyclicGenericTypeInstantiation.ts, 6, 1)) +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 11, 7)) + + var y: { +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 11, 7)) + + y2: typeof z; +>y2 : Symbol(y2, Decl(cyclicGenericTypeInstantiation.ts, 11, 12)) +>z : Symbol(z, Decl(cyclicGenericTypeInstantiation.ts, 10, 7)) + } + return y; +>y : Symbol(y, Decl(cyclicGenericTypeInstantiation.ts, 11, 7)) +} + +var a = foo(); +>a : Symbol(a, Decl(cyclicGenericTypeInstantiation.ts, 17, 3)) +>foo : Symbol(foo, Decl(cyclicGenericTypeInstantiation.ts, 0, 0)) + +var b = bar(); +>b : Symbol(b, Decl(cyclicGenericTypeInstantiation.ts, 18, 3)) +>bar : Symbol(bar, Decl(cyclicGenericTypeInstantiation.ts, 6, 1)) + +a = b; +>a : Symbol(a, Decl(cyclicGenericTypeInstantiation.ts, 17, 3)) +>b : Symbol(b, Decl(cyclicGenericTypeInstantiation.ts, 18, 3)) + diff --git a/tests/baselines/reference/cyclicGenericTypeInstantiation.types b/tests/baselines/reference/cyclicGenericTypeInstantiation.types new file mode 100644 index 00000000000..69b0955b22f --- /dev/null +++ b/tests/baselines/reference/cyclicGenericTypeInstantiation.types @@ -0,0 +1,60 @@ +=== tests/cases/compiler/cyclicGenericTypeInstantiation.ts === +function foo() { +>foo : () => { y2: any; } +>T : T + + var z = foo(); +>z : { y2: any; } +>foo() : { y2: any; } +>foo : () => { y2: any; } +>y : { y2: any; } + + var y: { +>y : { y2: any; } + + y2: typeof z +>y2 : { y2: any; } +>z : { y2: any; } + + }; + return y; +>y : { y2: any; } +} + + +function bar() { +>bar : () => { y2: any; } +>T : T + + var z = bar(); +>z : { y2: any; } +>bar() : { y2: any; } +>bar : () => { y2: any; } +>y : { y2: any; } + + var y: { +>y : { y2: any; } + + y2: typeof z; +>y2 : { y2: any; } +>z : { y2: any; } + } + return y; +>y : { y2: any; } +} + +var a = foo(); +>a : { y2: any; } +>foo() : { y2: any; } +>foo : () => { y2: any; } + +var b = bar(); +>b : { y2: any; } +>bar() : { y2: any; } +>bar : () => { y2: any; } + +a = b; +>a = b : { y2: any; } +>a : { y2: any; } +>b : { y2: any; } + diff --git a/tests/cases/compiler/cyclicGenericTypeInstantiation.ts b/tests/cases/compiler/cyclicGenericTypeInstantiation.ts new file mode 100644 index 00000000000..070cc44a63a --- /dev/null +++ b/tests/cases/compiler/cyclicGenericTypeInstantiation.ts @@ -0,0 +1,20 @@ +function foo() { + var z = foo(); + var y: { + y2: typeof z + }; + return y; +} + + +function bar() { + var z = bar(); + var y: { + y2: typeof z; + } + return y; +} + +var a = foo(); +var b = bar(); +a = b; From 386eeee8561ad11cf4900615f3cc91627b5a17bb Mon Sep 17 00:00:00 2001 From: Micah Zoltu Date: Sun, 31 May 2015 15:45:41 -0700 Subject: [PATCH 081/194] Never normalize end-of-lines on clone/commit. --- .gitattributes | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 74f5f4a6409..811a89b5493 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ -*.js linguist-language=TypeScript \ No newline at end of file +*.js linguist-language=TypeScript +* -text From f516ebd0e046c26dc7cb290215d1035f6ef837bf Mon Sep 17 00:00:00 2001 From: Oleksandr Chekhovskyi Date: Wed, 27 May 2015 10:28:45 +0200 Subject: [PATCH 082/194] Follow symlinks when enumerating files in a directory --- src/compiler/sys.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index f9daf52c5f2..1a7d9de47a1 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -231,7 +231,7 @@ module ts { var directories: string[] = []; for (let current of files) { var name = combinePaths(path, current); - var stat = _fs.lstatSync(name); + var stat = _fs.statSync(name); if (stat.isFile()) { if (!extension || fileExtensionIs(name, extension)) { result.push(name); From 62ba36908bceed22a52cee3269223189397cbab5 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 1 Jun 2015 15:01:24 -0700 Subject: [PATCH 083/194] Added experimentalDecorators flag --- src/compiler/checker.ts | 4 ++++ src/compiler/commandLineParser.ts | 8 +++++++- .../diagnosticInformationMap.generated.ts | 4 ++++ src/compiler/diagnosticMessages.json | 17 ++++++++++++++++- src/compiler/program.ts | 5 +++++ src/compiler/types.ts | 1 + src/harness/harness.ts | 6 +++++- .../compiler/classExpressionWithDecorator1.ts | 1 + tests/cases/compiler/noEmitHelpers2.ts | 1 + .../compiler/sourceMapValidationDecorators.ts | 1 + .../class/accessor/decoratorOnClassAccessor1.ts | 1 + .../class/accessor/decoratorOnClassAccessor2.ts | 1 + .../class/accessor/decoratorOnClassAccessor3.ts | 1 + .../class/accessor/decoratorOnClassAccessor4.ts | 1 + .../class/accessor/decoratorOnClassAccessor5.ts | 1 + .../class/accessor/decoratorOnClassAccessor6.ts | 1 + .../constructor/decoratorOnClassConstructor1.ts | 1 + .../decoratorOnClassConstructorParameter1.ts | 1 + .../decoratorOnClassConstructorParameter4.ts | 1 + .../class/decoratedClassFromExternalModule.ts | 1 + .../class/decoratorChecksFunctionBodies.ts | 1 + ...coratorInstantiateModulesInFunctionBodies.ts | 1 + .../decorators/class/decoratorOnClass1.ts | 1 + .../decorators/class/decoratorOnClass2.ts | 1 + .../decorators/class/decoratorOnClass3.ts | 1 + .../decorators/class/decoratorOnClass4.ts | 1 + .../decorators/class/decoratorOnClass5.ts | 1 + .../decorators/class/decoratorOnClass8.ts | 1 + .../class/method/decoratorOnClassMethod1.ts | 1 + .../class/method/decoratorOnClassMethod10.ts | 1 + .../class/method/decoratorOnClassMethod11.ts | 1 + .../class/method/decoratorOnClassMethod12.ts | 1 + .../class/method/decoratorOnClassMethod13.ts | 1 + .../class/method/decoratorOnClassMethod2.ts | 1 + .../class/method/decoratorOnClassMethod3.ts | 1 + .../class/method/decoratorOnClassMethod4.ts | 1 + .../class/method/decoratorOnClassMethod5.ts | 1 + .../class/method/decoratorOnClassMethod6.ts | 1 + .../class/method/decoratorOnClassMethod7.ts | 1 + .../class/method/decoratorOnClassMethod8.ts | 1 + .../decoratorOnClassMethodParameter1.ts | 1 + .../class/property/decoratorOnClassProperty1.ts | 1 + .../property/decoratorOnClassProperty10.ts | 1 + .../property/decoratorOnClassProperty11.ts | 1 + .../class/property/decoratorOnClassProperty2.ts | 1 + .../class/property/decoratorOnClassProperty3.ts | 1 + .../class/property/decoratorOnClassProperty6.ts | 1 + .../class/property/decoratorOnClassProperty7.ts | 1 + .../decorators/missingDecoratorType.ts | 6 +++--- 49 files changed, 86 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d409d1ea2fa..85cde0c9551 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8942,6 +8942,10 @@ module ts { if (!nodeCanBeDecorated(node)) { return; } + + if (!compilerOptions.experimentalDecorators) { + error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning); + } if (compilerOptions.emitDecoratorMetadata) { // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator. diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 64784590024..351f1caec94 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -188,10 +188,16 @@ module ts { type: "boolean", description: Diagnostics.Watch_input_files, }, + { + name: "experimentalDecorators", + type: "boolean", + description: Diagnostics.Enables_experimental_support_for_ES7_decorators + }, { name: "emitDecoratorMetadata", type: "boolean", - experimental: true + experimental: true, + description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators } ]; diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 8dd6ea6dc55..a42ce1b2338 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -174,6 +174,7 @@ module ts { Type_expected_0_is_a_reserved_word_in_strict_mode: { code: 1215, category: DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode" }, Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." }, Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." }, + Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, @@ -507,6 +508,9 @@ module ts { Specifies_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: { code: 6060, category: DiagnosticCategory.Message, key: "Specifies the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)." }, NEWLINE: { code: 6061, category: DiagnosticCategory.Message, key: "NEWLINE" }, Argument_for_newLine_option_must_be_CRLF_or_LF: { code: 6062, category: DiagnosticCategory.Error, key: "Argument for '--newLine' option must be 'CRLF' or 'LF'." }, + Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified: { code: 6064, category: DiagnosticCategory.Error, key: "Option 'experimentalDecorators' must also be specified when option 'emitDecoratorMetadata' is specified." }, + Enables_experimental_support_for_ES7_decorators: { code: 6065, category: DiagnosticCategory.Message, key: "Enables experimental support for ES7 decorators." }, + Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 416936e741b..0ad8fc68528 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -683,6 +683,10 @@ "category": "Error", "code": 1218 }, + "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning.": { + "category": "Error", + "code": 1219 + }, "Duplicate identifier '{0}'.": { "category": "Error", @@ -2018,7 +2022,18 @@ "category": "Error", "code": 6062 }, - + "Option 'experimentalDecorators' must also be specified when option 'emitDecoratorMetadata' is specified.": { + "category": "Error", + "code": 6064 + }, + "Enables experimental support for ES7 decorators.": { + "category": "Message", + "code": 6065 + }, + "Enables experimental support for emitting type metadata for decorators.": { + "category": "Message", + "code": 6066 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 32503de2566..9e0e250c987 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -635,6 +635,11 @@ module ts { diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_noEmit_cannot_be_specified_with_option_declaration)); } } + + if (options.emitDecoratorMetadata && + !options.experimentalDecorators) { + diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified)); + } } } } \ No newline at end of file diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a6fa89846bb..848b51d721b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1677,6 +1677,7 @@ module ts { version?: boolean; watch?: boolean; isolatedModules?: boolean; + experimentalDecorators?: boolean; emitDecoratorMetadata?: boolean; /* @internal */ stripInternal?: boolean; [option: string]: string | number | boolean; diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 63eff36b30a..f64fa57a41a 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -998,6 +998,10 @@ module Harness { options.target = setting.value; } break; + + case 'experimentaldecorators': + options.experimentalDecorators = setting.value === 'true'; + break; case 'emitdecoratormetadata': options.emitDecoratorMetadata = setting.value === 'true'; @@ -1510,7 +1514,7 @@ module Harness { "errortruncation", "usecasesensitivefilenames", "preserveconstenums", "includebuiltfile", "suppressimplicitanyindexerrors", "stripinternal", "isolatedmodules", "inlinesourcemap", "maproot", "sourceroot", - "inlinesources", "emitdecoratormetadata"]; + "inlinesources", "emitdecoratormetadata", "experimentaldecorators"]; function extractCompilerSettings(content: string): CompilerSetting[] { diff --git a/tests/cases/compiler/classExpressionWithDecorator1.ts b/tests/cases/compiler/classExpressionWithDecorator1.ts index 74b49456a36..67e9c8aa6ce 100644 --- a/tests/cases/compiler/classExpressionWithDecorator1.ts +++ b/tests/cases/compiler/classExpressionWithDecorator1.ts @@ -1 +1,2 @@ +// @experimentaldecorators: true var v = @decorate class C { static p = 1 }; \ No newline at end of file diff --git a/tests/cases/compiler/noEmitHelpers2.ts b/tests/cases/compiler/noEmitHelpers2.ts index df71f4fae82..ccc17f7066e 100644 --- a/tests/cases/compiler/noEmitHelpers2.ts +++ b/tests/cases/compiler/noEmitHelpers2.ts @@ -1,4 +1,5 @@ // @noemithelpers: true +// @experimentaldecorators: true // @emitdecoratormetadata: true // @target: es5 diff --git a/tests/cases/compiler/sourceMapValidationDecorators.ts b/tests/cases/compiler/sourceMapValidationDecorators.ts index c8bd16be80f..898d3f729b2 100644 --- a/tests/cases/compiler/sourceMapValidationDecorators.ts +++ b/tests/cases/compiler/sourceMapValidationDecorators.ts @@ -1,5 +1,6 @@ // @sourcemap: true // @target: es5 +// @experimentaldecorators: true declare function ClassDecorator1(target: Function): void; declare function ClassDecorator2(x: number): (target: Function) => void; declare function PropertyDecorator1(target: Object, key: string | symbol, descriptor?: PropertyDescriptor): void; diff --git a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor1.ts b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor1.ts index 7e80e9e637d..19abd8231d6 100644 --- a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor1.ts +++ b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor1.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor2.ts b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor2.ts index bbe58e72eb9..5250b42929c 100644 --- a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor2.ts +++ b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor2.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor3.ts b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor3.ts index bd1ce41bb12..4d7ccc6a825 100644 --- a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor3.ts +++ b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor3.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor4.ts b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor4.ts index 72259e5d212..35c15ae7a6f 100644 --- a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor4.ts +++ b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor4.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor5.ts b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor5.ts index ba5f82ab0ce..b32dd98ed2a 100644 --- a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor5.ts +++ b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor5.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor6.ts b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor6.ts index 686127858b0..ffbd2713621 100644 --- a/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor6.ts +++ b/tests/cases/conformance/decorators/class/accessor/decoratorOnClassAccessor6.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/constructor/decoratorOnClassConstructor1.ts b/tests/cases/conformance/decorators/class/constructor/decoratorOnClassConstructor1.ts index 4a39536e30b..b9ee9295744 100644 --- a/tests/cases/conformance/decorators/class/constructor/decoratorOnClassConstructor1.ts +++ b/tests/cases/conformance/decorators/class/constructor/decoratorOnClassConstructor1.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/constructor/parameter/decoratorOnClassConstructorParameter1.ts b/tests/cases/conformance/decorators/class/constructor/parameter/decoratorOnClassConstructorParameter1.ts index 3f4baabac7c..dbfd38c7896 100644 --- a/tests/cases/conformance/decorators/class/constructor/parameter/decoratorOnClassConstructorParameter1.ts +++ b/tests/cases/conformance/decorators/class/constructor/parameter/decoratorOnClassConstructorParameter1.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(target: Function, propertyKey: string | symbol, parameterIndex: number): void; class C { diff --git a/tests/cases/conformance/decorators/class/constructor/parameter/decoratorOnClassConstructorParameter4.ts b/tests/cases/conformance/decorators/class/constructor/parameter/decoratorOnClassConstructorParameter4.ts index e58771fbebb..4e0373ff5d1 100644 --- a/tests/cases/conformance/decorators/class/constructor/parameter/decoratorOnClassConstructorParameter4.ts +++ b/tests/cases/conformance/decorators/class/constructor/parameter/decoratorOnClassConstructorParameter4.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(target: Function, propertyKey: string | symbol, parameterIndex: number): void; class C { diff --git a/tests/cases/conformance/decorators/class/decoratedClassFromExternalModule.ts b/tests/cases/conformance/decorators/class/decoratedClassFromExternalModule.ts index cb622265b44..95f8bf4ab97 100644 --- a/tests/cases/conformance/decorators/class/decoratedClassFromExternalModule.ts +++ b/tests/cases/conformance/decorators/class/decoratedClassFromExternalModule.ts @@ -1,4 +1,5 @@ // @target: es6 +// @experimentaldecorators: true // @Filename: decorated.ts function decorate() { } diff --git a/tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts b/tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts index 31f5fe82551..b1cbd1a679c 100644 --- a/tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts +++ b/tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true // from #2971 function func(s: string): void { diff --git a/tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts b/tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts index 7fa7ab8dd84..9163ed0c384 100644 --- a/tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts +++ b/tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts @@ -1,5 +1,6 @@ // @target:es5 // @module:commonjs +// @experimentaldecorators: true // @filename: a.ts // from #3108 diff --git a/tests/cases/conformance/decorators/class/decoratorOnClass1.ts b/tests/cases/conformance/decorators/class/decoratorOnClass1.ts index 1d3c87e7a6a..c1a729f56f3 100644 --- a/tests/cases/conformance/decorators/class/decoratorOnClass1.ts +++ b/tests/cases/conformance/decorators/class/decoratorOnClass1.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(target: T): T; @dec diff --git a/tests/cases/conformance/decorators/class/decoratorOnClass2.ts b/tests/cases/conformance/decorators/class/decoratorOnClass2.ts index c82b9fe04a7..062ef391205 100644 --- a/tests/cases/conformance/decorators/class/decoratorOnClass2.ts +++ b/tests/cases/conformance/decorators/class/decoratorOnClass2.ts @@ -1,5 +1,6 @@ // @target:es5 // @module: commonjs +// @experimentaldecorators: true declare function dec(target: T): T; @dec diff --git a/tests/cases/conformance/decorators/class/decoratorOnClass3.ts b/tests/cases/conformance/decorators/class/decoratorOnClass3.ts index cf778380356..e410eaa1b07 100644 --- a/tests/cases/conformance/decorators/class/decoratorOnClass3.ts +++ b/tests/cases/conformance/decorators/class/decoratorOnClass3.ts @@ -1,5 +1,6 @@ // @target:es5 // @module: commonjs +// @experimentaldecorators: true declare function dec(target: T): T; export diff --git a/tests/cases/conformance/decorators/class/decoratorOnClass4.ts b/tests/cases/conformance/decorators/class/decoratorOnClass4.ts index e365df091fc..bebf595a170 100644 --- a/tests/cases/conformance/decorators/class/decoratorOnClass4.ts +++ b/tests/cases/conformance/decorators/class/decoratorOnClass4.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(): (target: T) => T; @dec() diff --git a/tests/cases/conformance/decorators/class/decoratorOnClass5.ts b/tests/cases/conformance/decorators/class/decoratorOnClass5.ts index e365df091fc..bebf595a170 100644 --- a/tests/cases/conformance/decorators/class/decoratorOnClass5.ts +++ b/tests/cases/conformance/decorators/class/decoratorOnClass5.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(): (target: T) => T; @dec() diff --git a/tests/cases/conformance/decorators/class/decoratorOnClass8.ts b/tests/cases/conformance/decorators/class/decoratorOnClass8.ts index a7227964180..bade386a56b 100644 --- a/tests/cases/conformance/decorators/class/decoratorOnClass8.ts +++ b/tests/cases/conformance/decorators/class/decoratorOnClass8.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(): (target: Function, paramIndex: number) => void; @dec() diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod1.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod1.ts index 7216be210f1..418ace9a0dc 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod1.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod1.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod10.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod10.ts index 03f75f16552..c4658cc6405 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod10.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod10.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(target: Function, paramIndex: number): void; class C { diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod11.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod11.ts index 6f80fa00bca..058f8134880 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod11.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod11.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true module M { class C { decorator(target: Object, key: string): void { } diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod12.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod12.ts index a9a2607c39b..9af80e32c46 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod12.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod12.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true module M { class S { decorator(target: Object, key: string): void { } diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod13.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod13.ts index df0b847e99d..f41481d4ad0 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod13.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod13.ts @@ -1,4 +1,5 @@ // @target: ES6 +// @experimentaldecorators: true declare function dec(): (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod2.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod2.ts index 7b7f089e4d4..8305ed1a448 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod2.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod2.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod3.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod3.ts index aa80151cf83..b951bd5c8c9 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod3.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod3.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod4.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod4.ts index 92b35ae6189..3d3ff2c8785 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod4.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod4.ts @@ -1,4 +1,5 @@ // @target: ES6 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod5.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod5.ts index cd891b4231b..d91d4331ce0 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod5.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod5.ts @@ -1,4 +1,5 @@ // @target: ES6 +// @experimentaldecorators: true declare function dec(): (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod6.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod6.ts index a1fa7005892..b3cd6ee75d4 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod6.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod6.ts @@ -1,4 +1,5 @@ // @target: ES6 +// @experimentaldecorators: true declare function dec(): (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod7.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod7.ts index 4bf86aa4995..16915e9aaab 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod7.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod7.ts @@ -1,4 +1,5 @@ // @target: ES6 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod8.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod8.ts index 9bd2c192c2d..73f58809420 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod8.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod8.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(target: T): T; class C { diff --git a/tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter1.ts b/tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter1.ts index e525933fb6a..18a7fff6dd0 100644 --- a/tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter1.ts +++ b/tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter1.ts @@ -1,4 +1,5 @@ // @target:es5 +// @experimentaldecorators: true declare function dec(target: Function, propertyKey: string | symbol, parameterIndex: number): void; class C { diff --git a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty1.ts b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty1.ts index 0d8fd82225d..026949fb5b8 100644 --- a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty1.ts +++ b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty1.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string): void; class C { diff --git a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty10.ts b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty10.ts index 4be77035692..2b10c0aec08 100644 --- a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty10.ts +++ b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty10.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(): (target: any, propertyKey: string) => void; class C { diff --git a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts index 60ea10189e2..eb720b20dff 100644 --- a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts +++ b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(): (target: any, propertyKey: string) => void; class C { diff --git a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty2.ts b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty2.ts index dc2886e7dbd..01af3e6ee81 100644 --- a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty2.ts +++ b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty2.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string): void; class C { diff --git a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty3.ts b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty3.ts index cf58b4b71ec..55fd6fe93e1 100644 --- a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty3.ts +++ b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty3.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(target: any, propertyKey: string): void; class C { diff --git a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty6.ts b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty6.ts index 1dd184419af..412a592ece1 100644 --- a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty6.ts +++ b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty6.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(target: Function): void; class C { diff --git a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty7.ts b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty7.ts index d82ca6eb2eb..0e11e103ce7 100644 --- a/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty7.ts +++ b/tests/cases/conformance/decorators/class/property/decoratorOnClassProperty7.ts @@ -1,4 +1,5 @@ // @target: ES5 +// @experimentaldecorators: true declare function dec(target: Function, propertyKey: string | symbol, paramIndex: number): void; class C { diff --git a/tests/cases/conformance/decorators/missingDecoratorType.ts b/tests/cases/conformance/decorators/missingDecoratorType.ts index 1407e00b7a3..905edaf0756 100644 --- a/tests/cases/conformance/decorators/missingDecoratorType.ts +++ b/tests/cases/conformance/decorators/missingDecoratorType.ts @@ -1,4 +1,5 @@ -// @target: ES5 +// @target: ES5 +// @experimentaldecorators: true // @noLib: true // @Filename: a.ts @@ -11,8 +12,7 @@ interface Function { } interface RegExp { } interface IArguments { } -// @Filename: b.ts -/// +// @Filename: b.ts declare var dec: any; @dec From 69094b5693656c2a230875532b9a20caeb1d0013 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 1 Jun 2015 15:35:42 -0700 Subject: [PATCH 084/194] Updated LKG --- bin/tsc.js | 19 ++++++++++++++++++- bin/tsserver.js | 19 ++++++++++++++++++- bin/typescript.d.ts | 1 + bin/typescript.js | 19 ++++++++++++++++++- bin/typescriptServices.d.ts | 1 + bin/typescriptServices.js | 19 ++++++++++++++++++- 6 files changed, 74 insertions(+), 4 deletions(-) diff --git a/bin/tsc.js b/bin/tsc.js index b14bf75a46b..8c1542d6c7b 100644 --- a/bin/tsc.js +++ b/bin/tsc.js @@ -1092,6 +1092,7 @@ var ts; Type_expected_0_is_a_reserved_word_in_strict_mode: { code: 1215, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode" }, Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." }, Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: ts.DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." }, + Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: ts.DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." }, Duplicate_identifier_0: { code: 2300, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: ts.DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: ts.DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, @@ -1425,6 +1426,9 @@ var ts; Specifies_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: { code: 6060, category: ts.DiagnosticCategory.Message, key: "Specifies the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)." }, NEWLINE: { code: 6061, category: ts.DiagnosticCategory.Message, key: "NEWLINE" }, Argument_for_newLine_option_must_be_CRLF_or_LF: { code: 6062, category: ts.DiagnosticCategory.Error, key: "Argument for '--newLine' option must be 'CRLF' or 'LF'." }, + Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified: { code: 6064, category: ts.DiagnosticCategory.Error, key: "Option 'experimentalDecorators' must also be specified when option 'emitDecoratorMetadata' is specified." }, + Enables_experimental_support_for_ES7_decorators: { code: 6065, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 decorators." }, + Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -15586,6 +15590,9 @@ var ts; if (!ts.nodeCanBeDecorated(node)) { return; } + if (!compilerOptions.experimentalDecorators) { + error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning); + } if (compilerOptions.emitDecoratorMetadata) { switch (node.kind) { case 202: @@ -25547,6 +25554,10 @@ var ts; diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmit_cannot_be_specified_with_option_declaration)); } } + if (options.emitDecoratorMetadata && + !options.experimentalDecorators) { + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified)); + } } } ts.createProgram = createProgram; @@ -25740,10 +25751,16 @@ var ts; type: "boolean", description: ts.Diagnostics.Watch_input_files }, + { + name: "experimentalDecorators", + type: "boolean", + description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators + }, { name: "emitDecoratorMetadata", type: "boolean", - experimental: true + experimental: true, + description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators } ]; function parseCommandLine(commandLine) { diff --git a/bin/tsserver.js b/bin/tsserver.js index 9a67ba6eca6..4f175eee95b 100644 --- a/bin/tsserver.js +++ b/bin/tsserver.js @@ -1092,6 +1092,7 @@ var ts; Type_expected_0_is_a_reserved_word_in_strict_mode: { code: 1215, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode" }, Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." }, Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: ts.DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." }, + Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: ts.DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." }, Duplicate_identifier_0: { code: 2300, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: ts.DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: ts.DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, @@ -1425,6 +1426,9 @@ var ts; Specifies_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: { code: 6060, category: ts.DiagnosticCategory.Message, key: "Specifies the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)." }, NEWLINE: { code: 6061, category: ts.DiagnosticCategory.Message, key: "NEWLINE" }, Argument_for_newLine_option_must_be_CRLF_or_LF: { code: 6062, category: ts.DiagnosticCategory.Error, key: "Argument for '--newLine' option must be 'CRLF' or 'LF'." }, + Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified: { code: 6064, category: ts.DiagnosticCategory.Error, key: "Option 'experimentalDecorators' must also be specified when option 'emitDecoratorMetadata' is specified." }, + Enables_experimental_support_for_ES7_decorators: { code: 6065, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 decorators." }, + Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -2900,10 +2904,16 @@ var ts; type: "boolean", description: ts.Diagnostics.Watch_input_files }, + { + name: "experimentalDecorators", + type: "boolean", + description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators + }, { name: "emitDecoratorMetadata", type: "boolean", - experimental: true + experimental: true, + description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators } ]; function parseCommandLine(commandLine) { @@ -15970,6 +15980,9 @@ var ts; if (!ts.nodeCanBeDecorated(node)) { return; } + if (!compilerOptions.experimentalDecorators) { + error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning); + } if (compilerOptions.emitDecoratorMetadata) { switch (node.kind) { case 202: @@ -25931,6 +25944,10 @@ var ts; diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmit_cannot_be_specified_with_option_declaration)); } } + if (options.emitDecoratorMetadata && + !options.experimentalDecorators) { + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified)); + } } } ts.createProgram = createProgram; diff --git a/bin/typescript.d.ts b/bin/typescript.d.ts index 52a5cc8a96e..50f5c1ade22 100644 --- a/bin/typescript.d.ts +++ b/bin/typescript.d.ts @@ -1115,6 +1115,7 @@ declare module "typescript" { version?: boolean; watch?: boolean; isolatedModules?: boolean; + experimentalDecorators?: boolean; emitDecoratorMetadata?: boolean; [option: string]: string | number | boolean; } diff --git a/bin/typescript.js b/bin/typescript.js index 5f1053a72bd..a60814cc7fd 100644 --- a/bin/typescript.js +++ b/bin/typescript.js @@ -1840,6 +1840,7 @@ var ts; Type_expected_0_is_a_reserved_word_in_strict_mode: { code: 1215, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode" }, Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." }, Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: ts.DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." }, + Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: ts.DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." }, Duplicate_identifier_0: { code: 2300, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: ts.DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: ts.DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, @@ -2173,6 +2174,9 @@ var ts; Specifies_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: { code: 6060, category: ts.DiagnosticCategory.Message, key: "Specifies the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)." }, NEWLINE: { code: 6061, category: ts.DiagnosticCategory.Message, key: "NEWLINE" }, Argument_for_newLine_option_must_be_CRLF_or_LF: { code: 6062, category: ts.DiagnosticCategory.Error, key: "Argument for '--newLine' option must be 'CRLF' or 'LF'." }, + Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified: { code: 6064, category: ts.DiagnosticCategory.Error, key: "Option 'experimentalDecorators' must also be specified when option 'emitDecoratorMetadata' is specified." }, + Enables_experimental_support_for_ES7_decorators: { code: 6065, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 decorators." }, + Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -18932,6 +18936,9 @@ var ts; if (!ts.nodeCanBeDecorated(node)) { return; } + if (!compilerOptions.experimentalDecorators) { + error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning); + } if (compilerOptions.emitDecoratorMetadata) { // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator. switch (node.kind) { @@ -30183,6 +30190,10 @@ var ts; diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmit_cannot_be_specified_with_option_declaration)); } } + if (options.emitDecoratorMetadata && + !options.experimentalDecorators) { + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified)); + } } } ts.createProgram = createProgram; @@ -30377,10 +30388,16 @@ var ts; type: "boolean", description: ts.Diagnostics.Watch_input_files }, + { + name: "experimentalDecorators", + type: "boolean", + description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators + }, { name: "emitDecoratorMetadata", type: "boolean", - experimental: true + experimental: true, + description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators } ]; function parseCommandLine(commandLine) { diff --git a/bin/typescriptServices.d.ts b/bin/typescriptServices.d.ts index 7ccb2c2f27f..558504fcede 100644 --- a/bin/typescriptServices.d.ts +++ b/bin/typescriptServices.d.ts @@ -1115,6 +1115,7 @@ declare module ts { version?: boolean; watch?: boolean; isolatedModules?: boolean; + experimentalDecorators?: boolean; emitDecoratorMetadata?: boolean; [option: string]: string | number | boolean; } diff --git a/bin/typescriptServices.js b/bin/typescriptServices.js index 5f1053a72bd..a60814cc7fd 100644 --- a/bin/typescriptServices.js +++ b/bin/typescriptServices.js @@ -1840,6 +1840,7 @@ var ts; Type_expected_0_is_a_reserved_word_in_strict_mode: { code: 1215, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode" }, Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." }, Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: ts.DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." }, + Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: ts.DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." }, Duplicate_identifier_0: { code: 2300, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: ts.DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: ts.DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, @@ -2173,6 +2174,9 @@ var ts; Specifies_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: { code: 6060, category: ts.DiagnosticCategory.Message, key: "Specifies the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)." }, NEWLINE: { code: 6061, category: ts.DiagnosticCategory.Message, key: "NEWLINE" }, Argument_for_newLine_option_must_be_CRLF_or_LF: { code: 6062, category: ts.DiagnosticCategory.Error, key: "Argument for '--newLine' option must be 'CRLF' or 'LF'." }, + Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified: { code: 6064, category: ts.DiagnosticCategory.Error, key: "Option 'experimentalDecorators' must also be specified when option 'emitDecoratorMetadata' is specified." }, + Enables_experimental_support_for_ES7_decorators: { code: 6065, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 decorators." }, + Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." }, Variable_0_implicitly_has_an_1_type: { code: 7005, category: ts.DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." }, Parameter_0_implicitly_has_an_1_type: { code: 7006, category: ts.DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." }, Member_0_implicitly_has_an_1_type: { code: 7008, category: ts.DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." }, @@ -18932,6 +18936,9 @@ var ts; if (!ts.nodeCanBeDecorated(node)) { return; } + if (!compilerOptions.experimentalDecorators) { + error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning); + } if (compilerOptions.emitDecoratorMetadata) { // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator. switch (node.kind) { @@ -30183,6 +30190,10 @@ var ts; diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_noEmit_cannot_be_specified_with_option_declaration)); } } + if (options.emitDecoratorMetadata && + !options.experimentalDecorators) { + diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified)); + } } } ts.createProgram = createProgram; @@ -30377,10 +30388,16 @@ var ts; type: "boolean", description: ts.Diagnostics.Watch_input_files }, + { + name: "experimentalDecorators", + type: "boolean", + description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators + }, { name: "emitDecoratorMetadata", type: "boolean", - experimental: true + experimental: true, + description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators } ]; function parseCommandLine(commandLine) { From 22e493d0d3f10697696ce6924c69dbc7e307ac7c Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 1 Jun 2015 16:08:58 -0700 Subject: [PATCH 085/194] clean hostCache to avoid extending lifetime of script snapshots --- src/services/services.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/services/services.ts b/src/services/services.ts index 1019c532192..4e441e40d87 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2475,6 +2475,10 @@ module ts { } } + // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point. + // It needs to be cleared to allow all collected snapshots to be released + hostCache = undefined; + program = newProgram; // Make sure all the nodes in the program are both bound, and have their parent @@ -2483,6 +2487,7 @@ module ts { return; function getOrCreateSourceFile(fileName: string): SourceFile { + Debug.assert(hostCache !== undefined); // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. From 6ef162dbbcc4e4795ff16525548676311ad1f9de Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 1 Jun 2015 17:40:44 -0700 Subject: [PATCH 086/194] Update LKG --- bin/lib.core.es6.d.ts | 13 +- bin/lib.d.ts | 16 +- bin/lib.dom.d.ts | 16 +- bin/lib.es6.d.ts | 29 +- bin/lib.webworker.d.ts | 16 +- bin/tsc.js | 2162 ++++++++++++++++++++-------- bin/tsserver.js | 2287 +++++++++++++++++++++--------- bin/typescript.d.ts | 116 +- bin/typescript.js | 2653 +++++++++++++++++++++++++---------- bin/typescriptServices.d.ts | 116 +- bin/typescriptServices.js | 2653 +++++++++++++++++++++++++---------- 11 files changed, 7336 insertions(+), 2741 deletions(-) diff --git a/bin/lib.core.es6.d.ts b/bin/lib.core.es6.d.ts index 86e2fa3ad70..1213967b972 100644 --- a/bin/lib.core.es6.d.ts +++ b/bin/lib.core.es6.d.ts @@ -1502,6 +1502,11 @@ interface Array { copyWithin(target: number, start: number, end?: number): T[]; } +interface IArguments { + /** Iterator */ + [Symbol.iterator](): IterableIterator; +} + interface ArrayConstructor { /** * Creates an array from an array-like object. @@ -1686,14 +1691,6 @@ interface GeneratorFunctionConstructor { } declare var GeneratorFunction: GeneratorFunctionConstructor; -interface Generator extends IterableIterator { - next(value?: any): IteratorResult; - throw(exception: any): IteratorResult; - return(value: T): IteratorResult; - [Symbol.iterator](): Generator; - [Symbol.toStringTag]: string; -} - interface Math { /** * Returns the number of leading zero bits in the 32-bit binary representation of a number. diff --git a/bin/lib.d.ts b/bin/lib.d.ts index e583f1ac783..7497c306161 100644 --- a/bin/lib.d.ts +++ b/bin/lib.d.ts @@ -3552,10 +3552,10 @@ declare module Intl { resolvedOptions(): ResolvedNumberFormatOptions; } var NumberFormat: { - new (locales?: string[], options?: NumberFormatOptions): Collator; - new (locale?: string, options?: NumberFormatOptions): Collator; - (locales?: string[], options?: NumberFormatOptions): Collator; - (locale?: string, options?: NumberFormatOptions): Collator; + new (locales?: string[], options?: NumberFormatOptions): NumberFormat; + new (locale?: string, options?: NumberFormatOptions): NumberFormat; + (locales?: string[], options?: NumberFormatOptions): NumberFormat; + (locale?: string, options?: NumberFormatOptions): NumberFormat; supportedLocalesOf(locales: string[], options?: NumberFormatOptions): string[]; supportedLocalesOf(locale: string, options?: NumberFormatOptions): string[]; } @@ -3597,10 +3597,10 @@ declare module Intl { resolvedOptions(): ResolvedDateTimeFormatOptions; } var DateTimeFormat: { - new (locales?: string[], options?: DateTimeFormatOptions): Collator; - new (locale?: string, options?: DateTimeFormatOptions): Collator; - (locales?: string[], options?: DateTimeFormatOptions): Collator; - (locale?: string, options?: DateTimeFormatOptions): Collator; + new (locales?: string[], options?: DateTimeFormatOptions): DateTimeFormat; + new (locale?: string, options?: DateTimeFormatOptions): DateTimeFormat; + (locales?: string[], options?: DateTimeFormatOptions): DateTimeFormat; + (locale?: string, options?: DateTimeFormatOptions): DateTimeFormat; supportedLocalesOf(locales: string[], options?: DateTimeFormatOptions): string[]; supportedLocalesOf(locale: string, options?: DateTimeFormatOptions): string[]; } diff --git a/bin/lib.dom.d.ts b/bin/lib.dom.d.ts index 142486a1662..1df0e2f736c 100644 --- a/bin/lib.dom.d.ts +++ b/bin/lib.dom.d.ts @@ -2382,10 +2382,10 @@ declare module Intl { resolvedOptions(): ResolvedNumberFormatOptions; } var NumberFormat: { - new (locales?: string[], options?: NumberFormatOptions): Collator; - new (locale?: string, options?: NumberFormatOptions): Collator; - (locales?: string[], options?: NumberFormatOptions): Collator; - (locale?: string, options?: NumberFormatOptions): Collator; + new (locales?: string[], options?: NumberFormatOptions): NumberFormat; + new (locale?: string, options?: NumberFormatOptions): NumberFormat; + (locales?: string[], options?: NumberFormatOptions): NumberFormat; + (locale?: string, options?: NumberFormatOptions): NumberFormat; supportedLocalesOf(locales: string[], options?: NumberFormatOptions): string[]; supportedLocalesOf(locale: string, options?: NumberFormatOptions): string[]; } @@ -2427,10 +2427,10 @@ declare module Intl { resolvedOptions(): ResolvedDateTimeFormatOptions; } var DateTimeFormat: { - new (locales?: string[], options?: DateTimeFormatOptions): Collator; - new (locale?: string, options?: DateTimeFormatOptions): Collator; - (locales?: string[], options?: DateTimeFormatOptions): Collator; - (locale?: string, options?: DateTimeFormatOptions): Collator; + new (locales?: string[], options?: DateTimeFormatOptions): DateTimeFormat; + new (locale?: string, options?: DateTimeFormatOptions): DateTimeFormat; + (locales?: string[], options?: DateTimeFormatOptions): DateTimeFormat; + (locale?: string, options?: DateTimeFormatOptions): DateTimeFormat; supportedLocalesOf(locales: string[], options?: DateTimeFormatOptions): string[]; supportedLocalesOf(locale: string, options?: DateTimeFormatOptions): string[]; } diff --git a/bin/lib.es6.d.ts b/bin/lib.es6.d.ts index d6ca7245140..b91bd34cf5d 100644 --- a/bin/lib.es6.d.ts +++ b/bin/lib.es6.d.ts @@ -1502,6 +1502,11 @@ interface Array { copyWithin(target: number, start: number, end?: number): T[]; } +interface IArguments { + /** Iterator */ + [Symbol.iterator](): IterableIterator; +} + interface ArrayConstructor { /** * Creates an array from an array-like object. @@ -1686,14 +1691,6 @@ interface GeneratorFunctionConstructor { } declare var GeneratorFunction: GeneratorFunctionConstructor; -interface Generator extends IterableIterator { - next(value?: any): IteratorResult; - throw(exception: any): IteratorResult; - return(value: T): IteratorResult; - [Symbol.iterator](): Generator; - [Symbol.toStringTag]: string; -} - interface Math { /** * Returns the number of leading zero bits in the 32-bit binary representation of a number. @@ -4933,10 +4930,10 @@ declare module Intl { resolvedOptions(): ResolvedNumberFormatOptions; } var NumberFormat: { - new (locales?: string[], options?: NumberFormatOptions): Collator; - new (locale?: string, options?: NumberFormatOptions): Collator; - (locales?: string[], options?: NumberFormatOptions): Collator; - (locale?: string, options?: NumberFormatOptions): Collator; + new (locales?: string[], options?: NumberFormatOptions): NumberFormat; + new (locale?: string, options?: NumberFormatOptions): NumberFormat; + (locales?: string[], options?: NumberFormatOptions): NumberFormat; + (locale?: string, options?: NumberFormatOptions): NumberFormat; supportedLocalesOf(locales: string[], options?: NumberFormatOptions): string[]; supportedLocalesOf(locale: string, options?: NumberFormatOptions): string[]; } @@ -4978,10 +4975,10 @@ declare module Intl { resolvedOptions(): ResolvedDateTimeFormatOptions; } var DateTimeFormat: { - new (locales?: string[], options?: DateTimeFormatOptions): Collator; - new (locale?: string, options?: DateTimeFormatOptions): Collator; - (locales?: string[], options?: DateTimeFormatOptions): Collator; - (locale?: string, options?: DateTimeFormatOptions): Collator; + new (locales?: string[], options?: DateTimeFormatOptions): DateTimeFormat; + new (locale?: string, options?: DateTimeFormatOptions): DateTimeFormat; + (locales?: string[], options?: DateTimeFormatOptions): DateTimeFormat; + (locale?: string, options?: DateTimeFormatOptions): DateTimeFormat; supportedLocalesOf(locales: string[], options?: DateTimeFormatOptions): string[]; supportedLocalesOf(locale: string, options?: DateTimeFormatOptions): string[]; } diff --git a/bin/lib.webworker.d.ts b/bin/lib.webworker.d.ts index 1704e07f75a..79eac80a8fd 100644 --- a/bin/lib.webworker.d.ts +++ b/bin/lib.webworker.d.ts @@ -2382,10 +2382,10 @@ declare module Intl { resolvedOptions(): ResolvedNumberFormatOptions; } var NumberFormat: { - new (locales?: string[], options?: NumberFormatOptions): Collator; - new (locale?: string, options?: NumberFormatOptions): Collator; - (locales?: string[], options?: NumberFormatOptions): Collator; - (locale?: string, options?: NumberFormatOptions): Collator; + new (locales?: string[], options?: NumberFormatOptions): NumberFormat; + new (locale?: string, options?: NumberFormatOptions): NumberFormat; + (locales?: string[], options?: NumberFormatOptions): NumberFormat; + (locale?: string, options?: NumberFormatOptions): NumberFormat; supportedLocalesOf(locales: string[], options?: NumberFormatOptions): string[]; supportedLocalesOf(locale: string, options?: NumberFormatOptions): string[]; } @@ -2427,10 +2427,10 @@ declare module Intl { resolvedOptions(): ResolvedDateTimeFormatOptions; } var DateTimeFormat: { - new (locales?: string[], options?: DateTimeFormatOptions): Collator; - new (locale?: string, options?: DateTimeFormatOptions): Collator; - (locales?: string[], options?: DateTimeFormatOptions): Collator; - (locale?: string, options?: DateTimeFormatOptions): Collator; + new (locales?: string[], options?: DateTimeFormatOptions): DateTimeFormat; + new (locale?: string, options?: DateTimeFormatOptions): DateTimeFormat; + (locales?: string[], options?: DateTimeFormatOptions): DateTimeFormat; + (locale?: string, options?: DateTimeFormatOptions): DateTimeFormat; supportedLocalesOf(locales: string[], options?: DateTimeFormatOptions): string[]; supportedLocalesOf(locale: string, options?: DateTimeFormatOptions): string[]; } diff --git a/bin/tsc.js b/bin/tsc.js index a73a566ef56..3e08d6f7723 100644 --- a/bin/tsc.js +++ b/bin/tsc.js @@ -145,6 +145,16 @@ var ts; } } ts.addRange = addRange; + function rangeEquals(array1, array2, pos, end) { + while (pos < end) { + if (array1[pos] !== array2[pos]) { + return false; + } + pos++; + } + return true; + } + ts.rangeEquals = rangeEquals; function lastOrUndefined(array) { if (array.length === 0) { return undefined; @@ -301,8 +311,10 @@ var ts; var end = start + length; Debug.assert(start >= 0, "start must be non-negative, is " + start); Debug.assert(length >= 0, "length must be non-negative, is " + length); - Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); - Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + if (file) { + Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); + Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + } var text = getLocaleSpecificMessage(message.key); if (arguments.length > 4) { text = formatStringFromArgs(text, arguments, 4); @@ -837,7 +849,7 @@ var ts; for (var _i = 0; _i < files.length; _i++) { var current = files[_i]; var name = ts.combinePaths(path, current); - var stat = _fs.lstatSync(name); + var stat = _fs.statSync(name); if (stat.isFile()) { if (!extension || ts.fileExtensionIs(name, extension)) { result.push(name); @@ -1039,7 +1051,7 @@ var ts; Unterminated_template_literal: { code: 1160, category: ts.DiagnosticCategory.Error, key: "Unterminated template literal." }, Unterminated_regular_expression_literal: { code: 1161, category: ts.DiagnosticCategory.Error, key: "Unterminated regular expression literal." }, An_object_member_cannot_be_declared_optional: { code: 1162, category: ts.DiagnosticCategory.Error, key: "An object member cannot be declared optional." }, - yield_expression_must_be_contained_within_a_generator_declaration: { code: 1163, category: ts.DiagnosticCategory.Error, key: "'yield' expression must be contained_within a generator declaration." }, + A_yield_expression_is_only_allowed_in_a_generator_body: { code: 1163, category: ts.DiagnosticCategory.Error, key: "A 'yield' expression is only allowed in a generator body." }, Computed_property_names_are_not_allowed_in_enums: { code: 1164, category: ts.DiagnosticCategory.Error, key: "Computed property names are not allowed in enums." }, A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol: { code: 1165, category: ts.DiagnosticCategory.Error, key: "A computed property name in an ambient context must directly refer to a built-in symbol." }, A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol: { code: 1166, category: ts.DiagnosticCategory.Error, key: "A computed property name in a class property declaration must directly refer to a built-in symbol." }, @@ -1094,6 +1106,10 @@ var ts; Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." }, Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: ts.DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." }, Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: ts.DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." }, + Generators_are_only_available_when_targeting_ECMAScript_6_or_higher: { code: 1220, category: ts.DiagnosticCategory.Error, key: "Generators are only available when targeting ECMAScript 6 or higher." }, + Generators_are_not_allowed_in_an_ambient_context: { code: 1221, category: ts.DiagnosticCategory.Error, key: "Generators are not allowed in an ambient context." }, + An_overload_signature_cannot_be_declared_as_a_generator: { code: 1222, category: ts.DiagnosticCategory.Error, key: "An overload signature cannot be declared as a generator." }, + _0_tag_already_specified: { code: 1223, category: ts.DiagnosticCategory.Error, key: "'{0}' tag already specified." }, Duplicate_identifier_0: { code: 2300, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: ts.DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: ts.DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, @@ -1254,7 +1270,7 @@ var ts; The_0_operator_cannot_be_applied_to_type_symbol: { code: 2469, category: ts.DiagnosticCategory.Error, key: "The '{0}' operator cannot be applied to type 'symbol'." }, Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: { code: 2470, category: ts.DiagnosticCategory.Error, key: "'Symbol' reference does not refer to the global Symbol constructor object." }, A_computed_property_name_of_the_form_0_must_be_of_type_symbol: { code: 2471, category: ts.DiagnosticCategory.Error, key: "A computed property name of the form '{0}' must be of type 'symbol'." }, - Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher: { code: 2472, category: ts.DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher." }, + Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: { code: 2472, category: ts.DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher." }, Enum_declarations_must_all_be_const_or_non_const: { code: 2473, category: ts.DiagnosticCategory.Error, key: "Enum declarations must all be const or non-const." }, In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 2474, category: ts.DiagnosticCategory.Error, key: "In 'const' enum declarations member initializer must be constant expression." }, const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: { code: 2475, category: ts.DiagnosticCategory.Error, key: "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment." }, @@ -1285,6 +1301,8 @@ var ts; A_rest_element_cannot_contain_a_binding_pattern: { code: 2501, category: ts.DiagnosticCategory.Error, key: "A rest element cannot contain a binding pattern." }, _0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: { code: 2502, category: ts.DiagnosticCategory.Error, key: "'{0}' is referenced directly or indirectly in its own type annotation." }, Cannot_find_namespace_0: { code: 2503, category: ts.DiagnosticCategory.Error, key: "Cannot find namespace '{0}'." }, + No_best_common_type_exists_among_yield_expressions: { code: 2504, category: ts.DiagnosticCategory.Error, key: "No best common type exists among yield expressions." }, + A_generator_cannot_have_a_void_type_annotation: { code: 2505, category: ts.DiagnosticCategory.Error, key: "A generator cannot have a 'void' type annotation." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, @@ -1445,6 +1463,7 @@ var ts; _0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: ts.DiagnosticCategory.Error, key: "'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer." }, _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7023, category: ts.DiagnosticCategory.Error, key: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: ts.DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, + Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: ts.DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." }, You_cannot_rename_this_element: { code: 8000, category: ts.DiagnosticCategory.Error, key: "You cannot rename this element." }, You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: ts.DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." }, import_can_only_be_used_in_a_ts_file: { code: 8002, category: ts.DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." }, @@ -1458,16 +1477,12 @@ var ts; types_can_only_be_used_in_a_ts_file: { code: 8010, category: ts.DiagnosticCategory.Error, key: "'types' can only be used in a .ts file." }, type_arguments_can_only_be_used_in_a_ts_file: { code: 8011, category: ts.DiagnosticCategory.Error, key: "'type arguments' can only be used in a .ts file." }, parameter_modifiers_can_only_be_used_in_a_ts_file: { code: 8012, category: ts.DiagnosticCategory.Error, key: "'parameter modifiers' can only be used in a .ts file." }, - can_only_be_used_in_a_ts_file: { code: 8013, category: ts.DiagnosticCategory.Error, key: "'?' can only be used in a .ts file." }, property_declarations_can_only_be_used_in_a_ts_file: { code: 8014, category: ts.DiagnosticCategory.Error, key: "'property declarations' can only be used in a .ts file." }, enum_declarations_can_only_be_used_in_a_ts_file: { code: 8015, category: ts.DiagnosticCategory.Error, key: "'enum declarations' can only be used in a .ts file." }, type_assertion_expressions_can_only_be_used_in_a_ts_file: { code: 8016, category: ts.DiagnosticCategory.Error, key: "'type assertion expressions' can only be used in a .ts file." }, decorators_can_only_be_used_in_a_ts_file: { code: 8017, category: ts.DiagnosticCategory.Error, key: "'decorators' can only be used in a .ts file." }, - yield_expressions_are_not_currently_supported: { code: 9000, category: ts.DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." }, - Generators_are_not_currently_supported: { code: 9001, category: ts.DiagnosticCategory.Error, key: "Generators are not currently supported." }, Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: ts.DiagnosticCategory.Error, key: "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses." }, - class_expressions_are_not_currently_supported: { code: 9003, category: ts.DiagnosticCategory.Error, key: "'class' expressions are not currently supported." }, - class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration: { code: 9004, category: ts.DiagnosticCategory.Error, key: "'class' declarations are only supported directly inside a module or as a top level declaration." } + class_expressions_are_not_currently_supported: { code: 9003, category: ts.DiagnosticCategory.Error, key: "'class' expressions are not currently supported." } }; })(ts || (ts = {})); /// @@ -3140,17 +3155,17 @@ var ts; bindBlockScopedDeclaration(node, 32, 899583); break; case 203: - bindDeclaration(node, 64, 792992, false); + bindBlockScopedDeclaration(node, 64, 792992); break; case 204: - bindDeclaration(node, 524288, 793056, false); + bindBlockScopedDeclaration(node, 524288, 793056); break; case 205: if (ts.isConst(node)) { - bindDeclaration(node, 128, 899967, false); + bindBlockScopedDeclaration(node, 128, 899967); } else { - bindDeclaration(node, 256, 899327, false); + bindBlockScopedDeclaration(node, 256, 899327); } break; case 206: @@ -3281,17 +3296,17 @@ var ts; ts.getFullWidth = getFullWidth; function containsParseError(node) { aggregateChildData(node); - return (node.parserContextFlags & 64) !== 0; + return (node.parserContextFlags & 128) !== 0; } ts.containsParseError = containsParseError; function aggregateChildData(node) { - if (!(node.parserContextFlags & 128)) { + if (!(node.parserContextFlags & 256)) { var thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & 32) !== 0) || ts.forEachChild(node, containsParseError); if (thisNodeOrAnySubNodesHasError) { - node.parserContextFlags |= 64; + node.parserContextFlags |= 128; } - node.parserContextFlags |= 128; + node.parserContextFlags |= 256; } } function getSourceFileOfNode(node) { @@ -3534,6 +3549,75 @@ var ts; } ts.getJsDocComments = getJsDocComments; ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; + function isTypeNode(node) { + if (142 <= node.kind && node.kind <= 150) { + return true; + } + switch (node.kind) { + case 112: + case 120: + case 122: + case 113: + case 123: + return true; + case 99: + return node.parent.kind !== 167; + case 8: + return node.parent.kind === 130; + case 177: + return true; + case 65: + if (node.parent.kind === 127 && node.parent.right === node) { + node = node.parent; + } + else if (node.parent.kind === 156 && node.parent.name === node) { + node = node.parent; + } + case 127: + case 156: + ts.Debug.assert(node.kind === 65 || node.kind === 127 || node.kind === 156, "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'."); + var parent_1 = node.parent; + if (parent_1.kind === 145) { + return false; + } + if (142 <= parent_1.kind && parent_1.kind <= 150) { + return true; + } + switch (parent_1.kind) { + case 177: + return true; + case 129: + return node === parent_1.constraint; + case 133: + case 132: + case 130: + case 199: + return node === parent_1.type; + case 201: + case 163: + case 164: + case 136: + case 135: + case 134: + case 137: + case 138: + return node === parent_1.type; + case 139: + case 140: + case 141: + return node === parent_1.type; + case 161: + return node === parent_1.type; + case 158: + case 159: + return parent_1.typeArguments && ts.indexOf(parent_1.typeArguments, node) >= 0; + case 160: + return false; + } + } + return false; + } + ts.isTypeNode = isTypeNode; function forEachReturnStatement(body, visitor) { return traverse(body); function traverse(node) { @@ -3560,6 +3644,37 @@ var ts; } } ts.forEachReturnStatement = forEachReturnStatement; + function forEachYieldExpression(body, visitor) { + return traverse(body); + function traverse(node) { + switch (node.kind) { + case 173: + visitor(node); + var operand = node.expression; + if (operand) { + traverse(operand); + } + case 205: + case 203: + case 206: + case 204: + case 202: + return; + default: + if (isFunctionLike(node)) { + var name_3 = node.name; + if (name_3 && name_3.kind === 128) { + traverse(name_3.expression); + return; + } + } + else if (!isTypeNode(node)) { + ts.forEachChild(node, traverse); + } + } + } + } + ts.forEachYieldExpression = forEachYieldExpression; function isVariableLike(node) { if (node) { switch (node.kind) { @@ -3588,6 +3703,12 @@ var ts; return false; } ts.isAccessor = isAccessor; + function isClassLike(node) { + if (node) { + return node.kind === 202 || node.kind === 175; + } + } + ts.isClassLike = isClassLike; function isFunctionLike(node) { if (node) { switch (node.kind) { @@ -3804,6 +3925,7 @@ var ts; case 172: case 10: case 176: + case 173: return true; case 127: while (node.parent.kind === 127) { @@ -3816,8 +3938,8 @@ var ts; } case 7: case 8: - var parent_1 = node.parent; - switch (parent_1.kind) { + var parent_2 = node.parent; + switch (parent_2.kind) { case 199: case 130: case 133: @@ -3825,7 +3947,7 @@ var ts; case 227: case 225: case 153: - return parent_1.initializer === node; + return parent_2.initializer === node; case 183: case 184: case 185: @@ -3836,27 +3958,27 @@ var ts; case 221: case 196: case 194: - return parent_1.expression === node; + return parent_2.expression === node; case 187: - var forStatement = parent_1; + var forStatement = parent_2; return (forStatement.initializer === node && forStatement.initializer.kind !== 200) || forStatement.condition === node || forStatement.incrementor === node; case 188: case 189: - var forInStatement = parent_1; + var forInStatement = parent_2; return (forInStatement.initializer === node && forInStatement.initializer.kind !== 200) || forInStatement.expression === node; case 161: - return node === parent_1.expression; + return node === parent_2.expression; case 178: - return node === parent_1.expression; + return node === parent_2.expression; case 128: - return node === parent_1.expression; + return node === parent_2.expression; case 131: return true; default: - if (isExpression(parent_1)) { + if (isExpression(parent_2)) { return true; } } @@ -3924,6 +4046,72 @@ var ts; return s.parameters.length > 0 && ts.lastOrUndefined(s.parameters).dotDotDotToken !== undefined; } ts.hasRestParameters = hasRestParameters; + function isJSDocConstructSignature(node) { + return node.kind === 241 && + node.parameters.length > 0 && + node.parameters[0].type.kind === 243; + } + ts.isJSDocConstructSignature = isJSDocConstructSignature; + function getJSDocTag(node, kind) { + if (node && node.jsDocComment) { + for (var _i = 0, _a = node.jsDocComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.kind === kind) { + return tag; + } + } + } + } + function getJSDocTypeTag(node) { + return getJSDocTag(node, 249); + } + ts.getJSDocTypeTag = getJSDocTypeTag; + function getJSDocReturnTag(node) { + return getJSDocTag(node, 248); + } + ts.getJSDocReturnTag = getJSDocReturnTag; + function getJSDocTemplateTag(node) { + return getJSDocTag(node, 250); + } + ts.getJSDocTemplateTag = getJSDocTemplateTag; + function getCorrespondingJSDocParameterTag(parameter) { + if (parameter.name && parameter.name.kind === 65) { + var parameterName = parameter.name.text; + var docComment = parameter.parent.jsDocComment; + if (docComment) { + return ts.forEach(docComment.tags, function (t) { + if (t.kind === 247) { + var parameterTag = t; + var name_4 = parameterTag.preParameterName || parameterTag.postParameterName; + if (name_4.text === parameterName) { + return t; + } + } + }); + } + } + } + ts.getCorrespondingJSDocParameterTag = getCorrespondingJSDocParameterTag; + function hasRestParameter(s) { + return isRestParameter(ts.lastOrUndefined(s.parameters)); + } + ts.hasRestParameter = hasRestParameter; + function isRestParameter(node) { + if (node) { + if (node.parserContextFlags & 64) { + if (node.type && node.type.kind === 242) { + return true; + } + var paramTag = getCorrespondingJSDocParameterTag(node); + if (paramTag && paramTag.typeExpression) { + return paramTag.typeExpression.type.kind === 242; + } + } + return node.dotDotDotToken !== undefined; + } + return false; + } + ts.isRestParameter = isRestParameter; function isLiteralKind(kind) { return 7 <= kind && kind <= 10; } @@ -4647,6 +4835,10 @@ var ts; return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & 256) ? symbol.valueDeclaration.localSymbol : undefined; } ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault; + function isJavaScript(fileName) { + return ts.fileExtensionIs(fileName, ".js"); + } + ts.isJavaScript = isJavaScript; function getExpandedCharCodes(input) { var output = []; var length = input.length; @@ -4817,12 +5009,23 @@ var ts; return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), newEndN - oldStartN); } ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions; + function getTypeParameterOwner(d) { + if (d && d.kind === 129) { + for (var current = d; current; current = current.parent) { + if (ts.isFunctionLike(current) || ts.isClassLike(current) || current.kind === 203) { + return current; + } + } + } + } + ts.getTypeParameterOwner = getTypeParameterOwner; })(ts || (ts = {})); /// /// var ts; (function (ts) { - var nodeConstructors = new Array(230); + ts.throwOnJSDocErrors = false; + var nodeConstructors = new Array(252); ts.parseTime = 0; function getNodeConstructor(kind) { return nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind)); @@ -5125,6 +5328,49 @@ var ts; return visitNode(cbNode, node.expression); case 219: return visitNodes(cbNodes, node.decorators); + case 229: + return visitNode(cbNode, node.type); + case 233: + return visitNodes(cbNodes, node.types); + case 234: + return visitNodes(cbNodes, node.types); + case 232: + return visitNode(cbNode, node.elementType); + case 236: + return visitNode(cbNode, node.type); + case 235: + return visitNode(cbNode, node.type); + case 237: + return visitNodes(cbNodes, node.members); + case 239: + return visitNode(cbNode, node.name) || + visitNodes(cbNodes, node.typeArguments); + case 240: + return visitNode(cbNode, node.type); + case 241: + return visitNodes(cbNodes, node.parameters) || + visitNode(cbNode, node.type); + case 242: + return visitNode(cbNode, node.type); + case 243: + return visitNode(cbNode, node.type); + case 244: + return visitNode(cbNode, node.type); + case 238: + return visitNode(cbNode, node.name) || + visitNode(cbNode, node.type); + case 245: + return visitNodes(cbNodes, node.tags); + case 247: + return visitNode(cbNode, node.preParameterName) || + visitNode(cbNode, node.typeExpression) || + visitNode(cbNode, node.postParameterName); + case 248: + return visitNode(cbNode, node.typeExpression); + case 249: + return visitNode(cbNode, node.typeExpression); + case 250: + return visitNodes(cbNodes, node.typeParameters); } } ts.forEachChild = forEachChild; @@ -5140,11 +5386,20 @@ var ts; return IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); } ts.updateSourceFile = updateSourceFile; + function parseIsolatedJSDocComment(content, start, length) { + return Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length); + } + ts.parseIsolatedJSDocComment = parseIsolatedJSDocComment; + function parseJSDocTypeExpressionForTests(content, start, length) { + return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length); + } + ts.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests; var Parser; (function (Parser) { var scanner = ts.createScanner(2, true); var disallowInAndDecoratorContext = 2 | 16; var sourceFile; + var parseDiagnostics; var syntaxCursor; var token; var sourceText; @@ -5152,21 +5407,40 @@ var ts; var identifiers; var identifierCount; var parsingContext; - var contextFlags = 0; + var contextFlags; var parseErrorBeforeNextFinishedNode = false; function parseSourceFile(fileName, _sourceText, languageVersion, _syntaxCursor, setParentNodes) { + initializeState(fileName, _sourceText, languageVersion, _syntaxCursor); + var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes); + clearState(); + return result; + } + Parser.parseSourceFile = parseSourceFile; + function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor) { sourceText = _sourceText; syntaxCursor = _syntaxCursor; + parseDiagnostics = []; parsingContext = 0; identifiers = {}; identifierCount = 0; nodeCount = 0; - contextFlags = 0; + contextFlags = ts.isJavaScript(fileName) ? 64 : 0; parseErrorBeforeNextFinishedNode = false; - createSourceFile(fileName, languageVersion); scanner.setText(sourceText); scanner.setOnError(scanError); scanner.setScriptTarget(languageVersion); + } + function clearState() { + scanner.setText(""); + scanner.setOnError(undefined); + parseDiagnostics = undefined; + sourceFile = undefined; + identifiers = undefined; + syntaxCursor = undefined; + sourceText = undefined; + } + function parseSourceFileWorker(fileName, languageVersion, setParentNodes) { + sourceFile = createSourceFile(fileName, languageVersion); token = nextToken(); processReferenceComments(sourceFile); sourceFile.statements = parseList(0, true, parseSourceElement); @@ -5176,20 +5450,40 @@ var ts; sourceFile.nodeCount = nodeCount; sourceFile.identifierCount = identifierCount; sourceFile.identifiers = identifiers; + sourceFile.parseDiagnostics = parseDiagnostics; if (setParentNodes) { fixupParentReferences(sourceFile); } - syntaxCursor = undefined; - scanner.setText(""); - scanner.setOnError(undefined); - var result = sourceFile; - sourceFile = undefined; - identifiers = undefined; - syntaxCursor = undefined; - sourceText = undefined; - return result; + if (ts.isJavaScript(fileName)) { + addJSDocComments(); + } + return sourceFile; + } + function addJSDocComments() { + forEachChild(sourceFile, visit); + return; + function visit(node) { + switch (node.kind) { + case 181: + case 201: + case 130: + addJSDocComment(node); + } + forEachChild(node, visit); + } + } + function addJSDocComment(node) { + var comments = ts.getLeadingCommentRangesOfNode(node, sourceFile); + if (comments) { + for (var _i = 0; _i < comments.length; _i++) { + var comment = comments[_i]; + var jsDocComment = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); + if (jsDocComment) { + node.jsDocComment = jsDocComment; + } + } + } } - Parser.parseSourceFile = parseSourceFile; function fixupParentReferences(sourceFile) { // normally parent references are set during binding. However, for clients that only need // a syntax tree, and no semantic features, then the binding process is an unnecessary @@ -5208,16 +5502,17 @@ var ts; } } } + Parser.fixupParentReferences = fixupParentReferences; function createSourceFile(fileName, languageVersion) { - sourceFile = createNode(228, 0); + var sourceFile = createNode(228, 0); sourceFile.pos = 0; sourceFile.end = sourceText.length; sourceFile.text = sourceText; - sourceFile.parseDiagnostics = []; sourceFile.bindDiagnostics = []; sourceFile.languageVersion = languageVersion; sourceFile.fileName = ts.normalizePath(fileName); sourceFile.flags = ts.fileExtensionIs(sourceFile.fileName, ".d.ts") ? 2048 : 0; + return sourceFile; } function setContextFlag(val, flag) { if (val) { @@ -5318,9 +5613,9 @@ var ts; parseErrorAtPosition(start, length, message, arg0); } function parseErrorAtPosition(start, length, message, arg0) { - var lastError = ts.lastOrUndefined(sourceFile.parseDiagnostics); + var lastError = ts.lastOrUndefined(parseDiagnostics); if (!lastError || start !== lastError.start) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0)); } parseErrorBeforeNextFinishedNode = true; } @@ -5351,7 +5646,7 @@ var ts; } function speculationHelper(callback, isLookAhead) { var saveToken = token; - var saveParseDiagnosticsLength = sourceFile.parseDiagnostics.length; + var saveParseDiagnosticsLength = parseDiagnostics.length; var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; var saveContextFlags = contextFlags; var result = isLookAhead @@ -5360,7 +5655,7 @@ var ts; ts.Debug.assert(saveContextFlags === contextFlags); if (!result || isLookAhead) { token = saveToken; - sourceFile.parseDiagnostics.length = saveParseDiagnosticsLength; + parseDiagnostics.length = saveParseDiagnosticsLength; parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; } return result; @@ -5442,8 +5737,8 @@ var ts; node.end = pos; return node; } - function finishNode(node) { - node.end = scanner.getStartPos(); + function finishNode(node, end) { + node.end = end === undefined ? scanner.getStartPos() : end; if (contextFlags) { node.parserContextFlags = contextFlags; } @@ -5492,15 +5787,24 @@ var ts; token === 8 || token === 7; } - function parsePropertyName() { + function parsePropertyNameWorker(allowComputedPropertyNames) { if (token === 8 || token === 7) { return parseLiteralNode(true); } - if (token === 18) { + if (allowComputedPropertyNames && token === 18) { return parseComputedPropertyName(); } return parseIdentifierName(); } + function parsePropertyName() { + return parsePropertyNameWorker(true); + } + function parseSimplePropertyName() { + return parsePropertyNameWorker(false); + } + function isSimplePropertyName() { + return token === 8 || token === 7 || isIdentifierOrKeyword(); + } function parseComputedPropertyName() { var node = createNode(128); parseExpected(18); @@ -5556,10 +5860,10 @@ var ts; switch (parsingContext) { case 0: case 1: - return isSourceElement(inErrorRecovery); + return !(token === 22 && inErrorRecovery) && isStartOfModuleElement(); case 2: case 4: - return isStartOfStatement(inErrorRecovery); + return !(token === 22 && inErrorRecovery) && isStartOfStatement(); case 3: return token === 67 || token === 73; case 5: @@ -5600,6 +5904,12 @@ var ts; return isHeritageClause(); case 20: return isIdentifierOrKeyword(); + case 21: + case 22: + case 24: + return JSDocParser.isJSDocType(); + case 23: + return isSimplePropertyName(); } ts.Debug.fail("Non-exhaustive case in 'isListElement'."); } @@ -5661,6 +5971,14 @@ var ts; return token === 25 || token === 16; case 19: return token === 14 || token === 15; + case 21: + return token === 17 || token === 51 || token === 15; + case 22: + return token === 25 || token === 15; + case 24: + return token === 19 || token === 15; + case 23: + return token === 15; } } function isVariableDeclaratorListTerminator() { @@ -5676,7 +5994,7 @@ var ts; return false; } function isInSomeParsingContext() { - for (var kind = 0; kind < 21; kind++) { + for (var kind = 0; kind < 25; kind++) { if (parsingContext & (1 << kind)) { if (isListElement(kind, true) || isListTerminator(kind)) { return true; @@ -5697,7 +6015,7 @@ var ts; result.push(element); if (checkForStrictMode && !inStrictModeContext()) { if (ts.isPrologueDirective(element)) { - if (isUseStrictPrologueDirective(sourceFile, element)) { + if (isUseStrictPrologueDirective(element)) { setStrictModeContext(true); checkForStrictMode = false; } @@ -5717,9 +6035,9 @@ var ts; parsingContext = saveParsingContext; return result; } - function isUseStrictPrologueDirective(sourceFile, node) { + function isUseStrictPrologueDirective(node) { ts.Debug.assert(ts.isPrologueDirective(node)); - var nodeText = ts.getSourceTextOfNodeFromSourceFile(sourceFile, node.expression); + var nodeText = ts.getTextOfNodeFromSourceText(sourceText, node.expression); return nodeText === '"use strict"' || nodeText === "'use strict'"; } function parseListElement(parsingContext, parseElement) { @@ -5920,6 +6238,10 @@ var ts; case 18: return ts.Diagnostics.Type_expected; case 19: return ts.Diagnostics.Unexpected_token_expected; case 20: return ts.Diagnostics.Identifier_expected; + case 21: return ts.Diagnostics.Parameter_declaration_expected; + case 22: return ts.Diagnostics.Type_argument_expected; + case 24: return ts.Diagnostics.Type_expected; + case 23: return ts.Diagnostics.Property_assignment_expected; } } ; @@ -6568,11 +6890,6 @@ var ts; nextToken(); return !scanner.hasPrecedingLineBreak() && isIdentifier(); } - function nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine() { - nextToken(); - return !scanner.hasPrecedingLineBreak() && - (isIdentifier() || token === 14 || token === 18); - } function parseYieldExpression() { var node = createNode(173); nextToken(); @@ -6681,10 +6998,11 @@ var ts; if (token === 14) { return parseFunctionBlock(false, false); } - if (isStartOfStatement(true) && - !isStartOfExpressionStatement() && + if (token !== 22 && token !== 83 && - token !== 69) { + token !== 69 && + isStartOfStatement() && + !isStartOfExpressionStatement()) { return parseFunctionBlock(false, true); } return parseAssignmentExpressionOrHigher(); @@ -7327,21 +7645,68 @@ var ts; return finishNode(expressionStatement); } } - function isStartOfStatement(inErrorRecovery) { - if (ts.isModifier(token)) { - var result = lookAhead(parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers); - if (result) { - return true; + function isIdentifierOrKeyword() { + return token >= 65; + } + function nextTokenIsIdentifierOrKeywordOnSameLine() { + nextToken(); + return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak(); + } + function parseDeclarationFlags() { + while (true) { + switch (token) { + case 98: + case 104: + case 70: + case 83: + case 69: + case 77: + return 1; + case 103: + case 124: + nextToken(); + return isIdentifierOrKeyword() ? 1 : 0; + case 117: + case 118: + nextToken(); + return isIdentifierOrKeyword() || token === 8 ? 2 : 0; + case 85: + nextToken(); + return token === 8 || token === 35 || + token === 14 || isIdentifierOrKeyword() ? + 2 : 0; + case 78: + nextToken(); + if (token === 53 || token === 35 || + token === 14 || token === 73) { + return 2; + } + continue; + case 115: + case 108: + case 106: + case 107: + case 109: + nextToken(); + continue; + default: + return 0; } } + } + function getDeclarationFlags() { + return lookAhead(parseDeclarationFlags); + } + function getStatementFlags() { switch (token) { + case 52: case 22: - return !inErrorRecovery; case 14: case 98: case 104: case 83: case 69: + case 77: case 84: case 75: case 100: @@ -7356,50 +7721,67 @@ var ts; case 72: case 68: case 81: - return true; + return 1; case 70: - var isConstEnum = lookAhead(nextTokenIsEnumKeyword); - return !isConstEnum; + case 78: + case 85: + return getDeclarationFlags(); + case 115: case 103: case 117: case 118: - case 77: case 124: - if (isDeclarationStart()) { - return false; - } + return getDeclarationFlags() || 1; case 108: case 106: case 107: case 109: - if (lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine)) { - return false; - } + return getDeclarationFlags() || + (lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? 0 : 1); default: - return isStartOfExpression(); + return isStartOfExpression() ? 1 : 0; } } - function nextTokenIsEnumKeyword() { - nextToken(); - return token === 77; + function isStartOfStatement() { + return (getStatementFlags() & 1) !== 0; } - function nextTokenIsIdentifierOrKeywordOnSameLine() { + function isStartOfModuleElement() { + return (getStatementFlags() & 3) !== 0; + } + function nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine() { nextToken(); - return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak(); + return !scanner.hasPrecedingLineBreak() && + (isIdentifier() || token === 14 || token === 18); + } + function isLetDeclaration() { + return inStrictModeContext() || lookAhead(nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine); } function parseStatement() { + return parseModuleElementOfKind(1); + } + function parseModuleElement() { + return parseModuleElementOfKind(3); + } + function parseSourceElement() { + return parseModuleElementOfKind(3); + } + function parseModuleElementOfKind(flags) { switch (token) { + case 22: + return parseEmptyStatement(); case 14: return parseBlock(false, false); case 98: - case 70: return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + case 104: + if (isLetDeclaration()) { + return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + } + break; case 83: return parseFunctionDeclaration(scanner.getStartPos(), undefined, undefined); case 69: return parseClassDeclaration(scanner.getStartPos(), undefined, undefined); - case 22: - return parseEmptyStatement(); case 84: return parseIfStatement(); case 75: @@ -7426,44 +7808,66 @@ var ts; return parseTryStatement(); case 72: return parseDebuggerStatement(); - case 104: - if (isLetDeclaration()) { - return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + case 52: + return parseDeclaration(); + case 70: + case 115: + case 77: + case 78: + case 85: + case 103: + case 117: + case 118: + case 106: + case 107: + case 108: + case 109: + case 124: + if (getDeclarationFlags() & flags) { + return parseDeclaration(); } - default: - if (ts.isModifier(token) || token === 52) { - var result = tryParse(parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers); - if (result) { - return result; - } - } - return parseExpressionOrLabeledStatement(); + break; } + return parseExpressionOrLabeledStatement(); } - function parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers() { - var start = scanner.getStartPos(); + function parseDeclaration() { + var fullStart = getNodePos(); var decorators = parseDecorators(); var modifiers = parseModifiers(); switch (token) { - case 70: - var nextTokenIsEnum = lookAhead(nextTokenIsEnumKeyword); - if (nextTokenIsEnum) { - return undefined; - } - return parseVariableStatement(start, decorators, modifiers); - case 104: - if (!isLetDeclaration()) { - return undefined; - } - return parseVariableStatement(start, decorators, modifiers); case 98: - return parseVariableStatement(start, decorators, modifiers); + case 104: + case 70: + return parseVariableStatement(fullStart, decorators, modifiers); case 83: - return parseFunctionDeclaration(start, decorators, modifiers); + return parseFunctionDeclaration(fullStart, decorators, modifiers); case 69: - return parseClassDeclaration(start, decorators, modifiers); + return parseClassDeclaration(fullStart, decorators, modifiers); + case 103: + return parseInterfaceDeclaration(fullStart, decorators, modifiers); + case 124: + return parseTypeAliasDeclaration(fullStart, decorators, modifiers); + case 77: + return parseEnumDeclaration(fullStart, decorators, modifiers); + case 117: + case 118: + return parseModuleDeclaration(fullStart, decorators, modifiers); + case 85: + return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers); + case 78: + nextToken(); + return token === 73 || token === 53 ? + parseExportAssignment(fullStart, decorators, modifiers) : + parseExportDeclaration(fullStart, decorators, modifiers); + default: + if (decorators) { + var node = createMissingNode(219, true, ts.Diagnostics.Declaration_expected); + node.pos = fullStart; + node.decorators = decorators; + setModifiers(node, modifiers); + return finishNode(node); + } } - return undefined; } function parseFunctionBlockOrSemicolon(isGenerator, diagnosticMessage) { if (token !== 14 && canParseSemicolon()) { @@ -7607,7 +8011,9 @@ var ts; property.name = name; property.questionToken = questionToken; property.type = parseTypeAnnotation(); - property.initializer = allowInAnd(parseNonParameterInitializer); + property.initializer = modifiers && modifiers.flags & 128 + ? allowInAnd(parseNonParameterInitializer) + : doOutsideOfContext(4 | 2, parseNonParameterInitializer); parseSemicolon(); return finishNode(property); } @@ -7753,8 +8159,8 @@ var ts; return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers); } if (decorators) { - var name_3 = createMissingNode(65, true, ts.Diagnostics.Declaration_expected); - return parsePropertyDeclaration(fullStart, decorators, modifiers, name_3, undefined); + var name_5 = createMissingNode(65, true, ts.Diagnostics.Declaration_expected); + return parsePropertyDeclaration(fullStart, decorators, modifiers, name_5, undefined); } ts.Debug.fail("Should not have attempted to parse class member declaration."); } @@ -8061,125 +8467,6 @@ var ts; parseSemicolon(); return finishNode(node); } - function isLetDeclaration() { - return inStrictModeContext() || lookAhead(nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine); - } - function isDeclarationStart(followsModifier) { - switch (token) { - case 98: - case 70: - case 83: - return true; - case 104: - return isLetDeclaration(); - case 69: - case 103: - case 77: - case 124: - return lookAhead(nextTokenIsIdentifierOrKeyword); - case 85: - return lookAhead(nextTokenCanFollowImportKeyword); - case 117: - case 118: - return lookAhead(nextTokenIsIdentifierOrKeywordOrStringLiteral); - case 78: - return lookAhead(nextTokenCanFollowExportKeyword); - case 115: - case 108: - case 106: - case 107: - case 109: - return lookAhead(nextTokenIsDeclarationStart); - case 52: - return !followsModifier; - } - } - function isIdentifierOrKeyword() { - return token >= 65; - } - function nextTokenIsIdentifierOrKeyword() { - nextToken(); - return isIdentifierOrKeyword(); - } - function nextTokenIsIdentifierOrKeywordOrStringLiteral() { - nextToken(); - return isIdentifierOrKeyword() || token === 8; - } - function nextTokenCanFollowImportKeyword() { - nextToken(); - return isIdentifierOrKeyword() || token === 8 || - token === 35 || token === 14; - } - function nextTokenCanFollowExportKeyword() { - nextToken(); - return token === 53 || token === 35 || - token === 14 || token === 73 || isDeclarationStart(true); - } - function nextTokenIsDeclarationStart() { - nextToken(); - return isDeclarationStart(true); - } - function nextTokenIsAsKeyword() { - return nextToken() === 111; - } - function parseDeclaration() { - var fullStart = getNodePos(); - var decorators = parseDecorators(); - var modifiers = parseModifiers(); - if (token === 78) { - nextToken(); - if (token === 73 || token === 53) { - return parseExportAssignment(fullStart, decorators, modifiers); - } - if (token === 35 || token === 14) { - return parseExportDeclaration(fullStart, decorators, modifiers); - } - } - switch (token) { - case 98: - case 104: - case 70: - return parseVariableStatement(fullStart, decorators, modifiers); - case 83: - return parseFunctionDeclaration(fullStart, decorators, modifiers); - case 69: - return parseClassDeclaration(fullStart, decorators, modifiers); - case 103: - return parseInterfaceDeclaration(fullStart, decorators, modifiers); - case 124: - return parseTypeAliasDeclaration(fullStart, decorators, modifiers); - case 77: - return parseEnumDeclaration(fullStart, decorators, modifiers); - case 117: - case 118: - return parseModuleDeclaration(fullStart, decorators, modifiers); - case 85: - return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers); - default: - if (decorators) { - var node = createMissingNode(219, true, ts.Diagnostics.Declaration_expected); - node.pos = fullStart; - node.decorators = decorators; - setModifiers(node, modifiers); - return finishNode(node); - } - ts.Debug.fail("Mismatch between isDeclarationStart and parseDeclaration"); - } - } - function isSourceElement(inErrorRecovery) { - return isDeclarationStart() || isStartOfStatement(inErrorRecovery); - } - function parseSourceElement() { - return parseSourceElementOrModuleElement(); - } - function parseModuleElement() { - return parseSourceElementOrModuleElement(); - } - function parseSourceElementOrModuleElement() { - return isDeclarationStart() - ? parseDeclaration() - : parseStatement(); - } function processReferenceComments(sourceFile) { var triviaScanner = ts.createScanner(sourceFile.languageVersion, false, sourceText); var referencedFiles = []; @@ -8204,7 +8491,7 @@ var ts; referencedFiles.push(fileReference); } if (diagnosticMessage) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); } } else { @@ -8212,7 +8499,7 @@ var ts; var amdModuleNameMatchResult = amdModuleNameRegEx.exec(comment); if (amdModuleNameMatchResult) { if (amdModuleName) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); } amdModuleName = amdModuleNameMatchResult[2]; } @@ -8245,6 +8532,520 @@ var ts; : undefined; }); } + var JSDocParser; + (function (JSDocParser) { + function isJSDocType() { + switch (token) { + case 35: + case 50: + case 16: + case 18: + case 46: + case 14: + case 83: + case 21: + case 88: + case 93: + return true; + } + return isIdentifierOrKeyword(); + } + JSDocParser.isJSDocType = isJSDocType; + function parseJSDocTypeExpressionForTests(content, start, length) { + initializeState("file.js", content, 2, undefined); + var jsDocTypeExpression = parseJSDocTypeExpression(start, length); + var diagnostics = parseDiagnostics; + clearState(); + return jsDocTypeExpression ? { jsDocTypeExpression: jsDocTypeExpression, diagnostics: diagnostics } : undefined; + } + JSDocParser.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests; + function parseJSDocTypeExpression(start, length) { + scanner.setText(sourceText, start, length); + token = nextToken(); + var result = createNode(229); + parseExpected(14); + result.type = parseJSDocTopLevelType(); + parseExpected(15); + fixupParentReferences(result); + return finishNode(result); + } + JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression; + function setError(message) { + parseErrorAtCurrentToken(message); + if (ts.throwOnJSDocErrors) { + throw new Error(message.key); + } + } + function parseJSDocTopLevelType() { + var type = parseJSDocType(); + if (token === 44) { + var unionType = createNode(233, type.pos); + unionType.types = parseJSDocTypeList(type); + type = finishNode(unionType); + } + if (token === 53) { + var optionalType = createNode(240, type.pos); + nextToken(); + optionalType.type = type; + type = finishNode(optionalType); + } + return type; + } + function parseJSDocType() { + var type = parseBasicTypeExpression(); + while (true) { + if (token === 18) { + var arrayType = createNode(232, type.pos); + arrayType.elementType = type; + nextToken(); + parseExpected(19); + type = finishNode(arrayType); + } + else if (token === 50) { + var nullableType = createNode(235, type.pos); + nullableType.type = type; + nextToken(); + type = finishNode(nullableType); + } + else if (token === 46) { + var nonNullableType = createNode(236, type.pos); + nonNullableType.type = type; + nextToken(); + type = finishNode(nonNullableType); + } + else { + break; + } + } + return type; + } + function parseBasicTypeExpression() { + switch (token) { + case 35: + return parseJSDocAllType(); + case 50: + return parseJSDocUnknownOrNullableType(); + case 16: + return parseJSDocUnionType(); + case 18: + return parseJSDocTupleType(); + case 46: + return parseJSDocNonNullableType(); + case 14: + return parseJSDocRecordType(); + case 83: + return parseJSDocFunctionType(); + case 21: + return parseJSDocVariadicType(); + case 88: + return parseJSDocConstructorType(); + case 93: + return parseJSDocThisType(); + case 112: + case 122: + case 120: + case 113: + case 123: + case 99: + return parseTokenNode(); + } + return parseJSDocTypeReference(); + } + function parseJSDocThisType() { + var result = createNode(244); + nextToken(); + parseExpected(51); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocConstructorType() { + var result = createNode(243); + nextToken(); + parseExpected(51); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocVariadicType() { + var result = createNode(242); + nextToken(); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocFunctionType() { + var result = createNode(241); + nextToken(); + parseExpected(16); + result.parameters = parseDelimitedList(21, parseJSDocParameter); + checkForTrailingComma(result.parameters); + parseExpected(17); + if (token === 51) { + nextToken(); + result.type = parseJSDocType(); + } + return finishNode(result); + } + function parseJSDocParameter() { + var parameter = createNode(130); + parameter.type = parseJSDocType(); + return finishNode(parameter); + } + function parseJSDocOptionalType(type) { + var result = createNode(240, type.pos); + nextToken(); + result.type = type; + return finishNode(result); + } + function parseJSDocTypeReference() { + var result = createNode(239); + result.name = parseSimplePropertyName(); + while (parseOptional(20)) { + if (token === 24) { + result.typeArguments = parseTypeArguments(); + break; + } + else { + result.name = parseQualifiedName(result.name); + } + } + return finishNode(result); + } + function parseTypeArguments() { + nextToken(); + var typeArguments = parseDelimitedList(22, parseJSDocType); + checkForTrailingComma(typeArguments); + checkForEmptyTypeArgumentList(typeArguments); + parseExpected(25); + return typeArguments; + } + function checkForEmptyTypeArgumentList(typeArguments) { + if (parseDiagnostics.length === 0 && typeArguments && typeArguments.length === 0) { + var start = typeArguments.pos - "<".length; + var end = ts.skipTrivia(sourceText, typeArguments.end) + ">".length; + return parseErrorAtPosition(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty); + } + } + function parseQualifiedName(left) { + var result = createNode(127, left.pos); + result.left = left; + result.right = parseIdentifierName(); + return finishNode(result); + } + function parseJSDocRecordType() { + var result = createNode(237); + nextToken(); + result.members = parseDelimitedList(23, parseJSDocRecordMember); + checkForTrailingComma(result.members); + parseExpected(15); + return finishNode(result); + } + function parseJSDocRecordMember() { + var result = createNode(238); + result.name = parseSimplePropertyName(); + if (token === 51) { + nextToken(); + result.type = parseJSDocType(); + } + return finishNode(result); + } + function parseJSDocNonNullableType() { + var result = createNode(236); + nextToken(); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocTupleType() { + var result = createNode(234); + nextToken(); + result.types = parseDelimitedList(24, parseJSDocType); + checkForTrailingComma(result.types); + parseExpected(19); + return finishNode(result); + } + function checkForTrailingComma(list) { + if (parseDiagnostics.length === 0 && list.hasTrailingComma) { + var start = list.end - ",".length; + parseErrorAtPosition(start, ",".length, ts.Diagnostics.Trailing_comma_not_allowed); + } + } + function parseJSDocUnionType() { + var result = createNode(233); + nextToken(); + result.types = parseJSDocTypeList(parseJSDocType()); + parseExpected(17); + return finishNode(result); + } + function parseJSDocTypeList(firstType) { + ts.Debug.assert(!!firstType); + var types = []; + types.pos = firstType.pos; + types.push(firstType); + while (parseOptional(44)) { + types.push(parseJSDocType()); + } + types.end = scanner.getStartPos(); + return types; + } + function parseJSDocAllType() { + var result = createNode(230); + nextToken(); + return finishNode(result); + } + function parseJSDocUnknownOrNullableType() { + var pos = scanner.getStartPos(); + nextToken(); + if (token === 23 || + token === 15 || + token === 17 || + token === 25 || + token === 53 || + token === 44) { + var result = createNode(231, pos); + return finishNode(result); + } + else { + var result = createNode(235, pos); + result.type = parseJSDocType(); + return finishNode(result); + } + } + function parseIsolatedJSDocComment(content, start, length) { + initializeState("file.js", content, 2, undefined); + var jsDocComment = parseJSDocComment(undefined, start, length); + var diagnostics = parseDiagnostics; + clearState(); + return jsDocComment ? { jsDocComment: jsDocComment, diagnostics: diagnostics } : undefined; + } + JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment; + function parseJSDocComment(parent, start, length) { + var comment = parseJSDocCommentWorker(start, length); + if (comment) { + fixupParentReferences(comment); + comment.parent = parent; + } + return comment; + } + JSDocParser.parseJSDocComment = parseJSDocComment; + function parseJSDocCommentWorker(start, length) { + var content = sourceText; + start = start || 0; + var end = length === undefined ? content.length : start + length; + length = end - start; + ts.Debug.assert(start >= 0); + ts.Debug.assert(start <= end); + ts.Debug.assert(end <= content.length); + var tags; + var pos; + if (length >= "/** */".length) { + if (content.charCodeAt(start) === 47 && + content.charCodeAt(start + 1) === 42 && + content.charCodeAt(start + 2) === 42 && + content.charCodeAt(start + 3) !== 42) { + var canParseTag = true; + var seenAsterisk = true; + for (pos = start + "/**".length; pos < end;) { + var ch = content.charCodeAt(pos); + pos++; + if (ch === 64 && canParseTag) { + parseTag(); + canParseTag = false; + continue; + } + if (ts.isLineBreak(ch)) { + canParseTag = true; + seenAsterisk = false; + continue; + } + if (ts.isWhiteSpace(ch)) { + continue; + } + if (ch === 42) { + if (seenAsterisk) { + canParseTag = false; + } + seenAsterisk = true; + continue; + } + canParseTag = false; + } + } + } + return createJSDocComment(); + function createJSDocComment() { + if (!tags) { + return undefined; + } + var result = createNode(245, start); + result.tags = tags; + return finishNode(result, end); + } + function skipWhitespace() { + while (pos < end && ts.isWhiteSpace(content.charCodeAt(pos))) { + pos++; + } + } + function parseTag() { + ts.Debug.assert(content.charCodeAt(pos - 1) === 64); + var atToken = createNode(52, pos - 1); + atToken.end = pos; + var startPos = pos; + var tagName = scanIdentifier(); + if (!tagName) { + return; + } + var tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName); + addTag(tag); + } + function handleTag(atToken, tagName) { + if (tagName) { + switch (tagName.text) { + case "param": + return handleParamTag(atToken, tagName); + case "return": + case "returns": + return handleReturnTag(atToken, tagName); + case "template": + return handleTemplateTag(atToken, tagName); + case "type": + return handleTypeTag(atToken, tagName); + } + } + return undefined; + } + function handleUnknownTag(atToken, tagName) { + var result = createNode(246, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + return finishNode(result, pos); + } + function addTag(tag) { + if (tag) { + if (!tags) { + tags = []; + tags.pos = tag.pos; + } + tags.push(tag); + tags.end = tag.end; + } + } + function tryParseTypeExpression() { + skipWhitespace(); + if (content.charCodeAt(pos) !== 123) { + return undefined; + } + var typeExpression = parseJSDocTypeExpression(pos, end - pos); + pos = typeExpression.end; + return typeExpression; + } + function handleParamTag(atToken, tagName) { + var typeExpression = tryParseTypeExpression(); + skipWhitespace(); + var name; + var isBracketed; + if (content.charCodeAt(pos) === 91) { + pos++; + skipWhitespace(); + name = scanIdentifier(); + isBracketed = true; + } + else { + name = scanIdentifier(); + } + if (!name) { + parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); + return undefined; + } + var preName, postName; + if (typeExpression) { + postName = name; + } + else { + preName = name; + } + if (!typeExpression) { + typeExpression = tryParseTypeExpression(); + } + var result = createNode(247, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.preParameterName = preName; + result.typeExpression = typeExpression; + result.postParameterName = postName; + result.isBracketed = isBracketed; + return finishNode(result, pos); + } + function handleReturnTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 248; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var result = createNode(248, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeExpression = tryParseTypeExpression(); + return finishNode(result, pos); + } + function handleTypeTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 249; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var result = createNode(249, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeExpression = tryParseTypeExpression(); + return finishNode(result, pos); + } + function handleTemplateTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 250; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var typeParameters = []; + typeParameters.pos = pos; + while (true) { + skipWhitespace(); + var startPos = pos; + var name_6 = scanIdentifier(); + if (!name_6) { + parseErrorAtPosition(startPos, 0, ts.Diagnostics.Identifier_expected); + return undefined; + } + var typeParameter = createNode(129, name_6.pos); + typeParameter.name = name_6; + finishNode(typeParameter, pos); + typeParameters.push(typeParameter); + skipWhitespace(); + if (content.charCodeAt(pos) !== 44) { + break; + } + pos++; + } + typeParameters.end = pos; + var result = createNode(250, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeParameters = typeParameters; + return finishNode(result, pos); + } + function scanIdentifier() { + var startPos = pos; + for (; pos < end; pos++) { + var ch = content.charCodeAt(pos); + if (pos === startPos && ts.isIdentifierStart(ch, 2)) { + continue; + } + else if (pos > startPos && ts.isIdentifierPart(ch, 2)) { + continue; + } + break; + } + if (startPos === pos) { + return undefined; + } + var result = createNode(65, startPos); + result.text = content.substring(startPos, pos); + return finishNode(result, pos); + } + } + JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker; + })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {})); })(Parser || (Parser = {})); var IncrementalParser; (function (IncrementalParser) { @@ -8285,7 +9086,12 @@ var ts; if (aggressiveChecks && shouldCheckNode(node)) { var text = oldText.substring(node.pos, node.end); } - node._children = undefined; + if (node._children) { + node._children = undefined; + } + if (node.jsDocComment) { + node.jsDocComment = undefined; + } node.pos += delta; node.end += delta; if (aggressiveChecks && shouldCheckNode(node)) { @@ -8601,13 +9407,15 @@ var ts; var undefinedType = createIntrinsicType(32 | 262144, "undefined"); var nullType = createIntrinsicType(64 | 262144, "null"); var unknownType = createIntrinsicType(1, "unknown"); + var circularType = createIntrinsicType(1, "__circular__"); var emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + var emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + emptyGenericType.instantiations = {}; var anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); var noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); var anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, false, false); var unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false); var globals = {}; - var globalArraySymbol; var globalESSymbolConstructorSymbol; var globalObjectType; var globalFunctionType; @@ -8619,6 +9427,8 @@ var ts; var globalTemplateStringsArrayType; var globalESSymbolType; var globalIterableType; + var globalIteratorType; + var globalIterableIteratorType; var anyArrayType; var getGlobalClassDecoratorType; var getGlobalParameterDecoratorType; @@ -8835,7 +9645,13 @@ var ts; loop: while (location) { if (location.locals && !isGlobalSourceFile(location)) { if (result = getSymbol(location.locals, name, meaning)) { - break loop; + if (!(meaning & 793056) || + !(result.flags & (793056 & ~262144)) || + !ts.isFunctionLike(location) || + lastLocation === location.body) { + break loop; + } + result = undefined; } } switch (location.kind) { @@ -9067,15 +9883,15 @@ var ts; var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier); var targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier); if (targetSymbol) { - var name_4 = specifier.propertyName || specifier.name; - if (name_4.text) { - var symbolFromModule = getExportOfModule(targetSymbol, name_4.text); - var symbolFromVariable = getPropertyOfVariable(targetSymbol, name_4.text); + var name_7 = specifier.propertyName || specifier.name; + if (name_7.text) { + var symbolFromModule = getExportOfModule(targetSymbol, name_7.text); + var symbolFromVariable = getPropertyOfVariable(targetSymbol, name_7.text); var symbol = symbolFromModule && symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { - error(name_4, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name_4)); + error(name_7, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name_7)); } return symbol; } @@ -9723,17 +10539,46 @@ var ts; writeType(types[i], union ? 64 : 0); } } + function writeSymbolTypeReference(symbol, typeArguments, pos, end) { + if (!isReservedMemberName(symbol.name)) { + buildSymbolDisplay(symbol, writer, enclosingDeclaration, 793056); + } + if (pos < end) { + writePunctuation(writer, 24); + writeType(typeArguments[pos++], 0); + while (pos < end) { + writePunctuation(writer, 23); + writeSpace(writer); + writeType(typeArguments[pos++], 0); + } + writePunctuation(writer, 25); + } + } function writeTypeReference(type, flags) { + var typeArguments = type.typeArguments; if (type.target === globalArrayType && !(flags & 1)) { - writeType(type.typeArguments[0], 64); + writeType(typeArguments[0], 64); writePunctuation(writer, 18); writePunctuation(writer, 19); } else { - buildSymbolDisplay(type.target.symbol, writer, enclosingDeclaration, 793056); - writePunctuation(writer, 24); - writeTypeList(type.typeArguments, false); - writePunctuation(writer, 25); + var outerTypeParameters = type.target.outerTypeParameters; + var i = 0; + if (outerTypeParameters) { + var length_1 = outerTypeParameters.length; + while (i < length_1) { + var start = i; + var parent_3 = getParentSymbolOfTypeParameter(outerTypeParameters[i]); + do { + i++; + } while (i < length_1 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent_3); + if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) { + writeSymbolTypeReference(parent_3, typeArguments, start, i); + writePunctuation(writer, 20); + } + } + } + writeSymbolTypeReference(type.symbol, typeArguments, i, typeArguments.length); } } function writeTupleType(type) { @@ -9912,7 +10757,7 @@ var ts; function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); if (targetSymbol.flags & 32 || targetSymbol.flags & 64) { - buildDisplayForTypeParametersAndDelimiters(getTypeParametersOfClassOrInterface(symbol), writer, enclosingDeclaraiton, flags); + buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterface(symbol), writer, enclosingDeclaraiton, flags); } } function buildTypeParameterDisplay(tp, writer, enclosingDeclaration, flags, typeStack) { @@ -10075,12 +10920,12 @@ var ts; case 201: case 205: case 209: - var parent_2 = getDeclarationContainer(node); + var parent_4 = getDeclarationContainer(node); if (!(ts.getCombinedNodeFlags(node) & 1) && - !(node.kind !== 209 && parent_2.kind !== 228 && ts.isInAmbientContext(parent_2))) { - return isGlobalSourceFile(parent_2); + !(node.kind !== 209 && parent_4.kind !== 228 && ts.isInAmbientContext(parent_4))) { + return isGlobalSourceFile(parent_4); } - return isDeclarationVisible(parent_2); + return isDeclarationVisible(parent_4); case 133: case 132: case 137: @@ -10201,12 +11046,12 @@ var ts; } var type; if (pattern.kind === 151) { - var name_5 = declaration.propertyName || declaration.name; - type = getTypeOfPropertyOfType(parentType, name_5.text) || - isNumericLiteralName(name_5.text) && getIndexTypeOfType(parentType, 1) || + var name_8 = declaration.propertyName || declaration.name; + type = getTypeOfPropertyOfType(parentType, name_8.text) || + isNumericLiteralName(name_8.text) && getIndexTypeOfType(parentType, 1) || getIndexTypeOfType(parentType, 0); if (!type) { - error(name_5, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_5)); + error(name_8, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_8)); return unknownType; } } @@ -10484,26 +11329,55 @@ var ts; return target === checkBase || ts.forEach(getBaseTypes(target), check); } } - function getTypeParametersOfClassOrInterface(symbol) { - var result; - ts.forEach(symbol.declarations, function (node) { - if (node.kind === 203 || node.kind === 202) { - var declaration = node; - if (declaration.typeParameters && declaration.typeParameters.length) { - ts.forEach(declaration.typeParameters, function (node) { - var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node)); - if (!result) { - result = [tp]; - } - else if (!ts.contains(result, tp)) { - result.push(tp); - } - }); + function appendTypeParameters(typeParameters, declarations) { + for (var _i = 0; _i < declarations.length; _i++) { + var declaration = declarations[_i]; + var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); + if (!typeParameters) { + typeParameters = [tp]; + } + else if (!ts.contains(typeParameters, tp)) { + typeParameters.push(tp); + } + } + return typeParameters; + } + function appendOuterTypeParameters(typeParameters, node) { + while (true) { + node = node.parent; + if (!node) { + return typeParameters; + } + if (node.kind === 202 || node.kind === 201 || + node.kind === 163 || node.kind === 135 || + node.kind === 164) { + var declarations = node.typeParameters; + if (declarations) { + return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations); } } - }); + } + } + function getOuterTypeParametersOfClassOrInterface(symbol) { + var kind = symbol.flags & 32 ? 202 : 203; + return appendOuterTypeParameters(undefined, ts.getDeclarationOfKind(symbol, kind)); + } + function getLocalTypeParametersOfClassOrInterface(symbol) { + var result; + for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { + var node = _a[_i]; + if (node.kind === 203 || node.kind === 202) { + var declaration = node; + if (declaration.typeParameters) { + result = appendTypeParameters(result, declaration.typeParameters); + } + } + } return result; } + function getTypeParametersOfClassOrInterface(symbol) { + return ts.concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterface(symbol)); + } function getBaseTypes(type) { var typeWithBaseTypes = type; if (!typeWithBaseTypes.baseTypes) { @@ -10570,10 +11444,13 @@ var ts; if (!links.declaredType) { var kind = symbol.flags & 32 ? 1024 : 2048; var type = links.declaredType = createObjectType(kind, symbol); - var typeParameters = getTypeParametersOfClassOrInterface(symbol); - if (typeParameters) { + var outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol); + var localTypeParameters = getLocalTypeParametersOfClassOrInterface(symbol); + if (outerTypeParameters || localTypeParameters) { type.flags |= 4096; - type.typeParameters = typeParameters; + type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters); + type.outerTypeParameters = outerTypeParameters; + type.localTypeParameters = localTypeParameters; type.instantiations = {}; type.instantiations[getTypeListId(type.typeParameters)] = type; type.target = type; @@ -10749,12 +11626,12 @@ var ts; return ts.map(baseSignatures, function (baseSignature) { var signature = baseType.flags & 4096 ? getSignatureInstantiation(baseSignature, baseType.typeArguments) : cloneSignature(baseSignature); - signature.typeParameters = classType.typeParameters; + signature.typeParameters = classType.localTypeParameters; signature.resolvedReturnType = classType; return signature; }); } - return [createSignature(undefined, classType.typeParameters, emptyArray, classType, 0, false, false)]; + return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, 0, false, false)]; } function createTupleTypeMemberSymbols(memberTypes) { var members = {}; @@ -11060,7 +11937,7 @@ var ts; var links = getNodeLinks(declaration); if (!links.resolvedSignature) { var classType = declaration.kind === 136 ? getDeclaredTypeOfClassOrInterface(declaration.parent.symbol) : undefined; - var typeParameters = classType ? classType.typeParameters : + var typeParameters = classType ? classType.localTypeParameters : declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) : undefined; var parameters = []; var hasStringLiterals = false; @@ -11238,6 +12115,9 @@ var ts; } return type.constraint === noConstraintType ? undefined : type.constraint; } + function getParentSymbolOfTypeParameter(typeParameter) { + return getSymbolOfNode(ts.getDeclarationOfKind(typeParameter.symbol, 129).parent); + } function getTypeListId(types) { switch (types.length) { case 1: @@ -11324,12 +12204,16 @@ var ts; else { type = getDeclaredTypeOfSymbol(symbol); if (type.flags & (1024 | 2048) && type.flags & 4096) { - var typeParameters = type.typeParameters; - if (node.typeArguments && node.typeArguments.length === typeParameters.length) { - type = createTypeReference(type, ts.map(node.typeArguments, getTypeFromTypeNode)); + var localTypeParameters = type.localTypeParameters; + var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; + var typeArgCount = node.typeArguments ? node.typeArguments.length : 0; + if (typeArgCount === expectedTypeArgCount) { + if (typeArgCount) { + type = createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(node.typeArguments, getTypeFromTypeNode))); + } } else { - error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1), typeParameters.length); + error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1), expectedTypeArgCount); type = undefined; } } @@ -11367,16 +12251,16 @@ var ts; } } if (!symbol) { - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } var type = getDeclaredTypeOfSymbol(symbol); if (!(type.flags & 48128)) { error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, symbol.name); - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } if ((type.typeParameters ? type.typeParameters.length : 0) !== arity) { error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbol.name, arity); - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } return type; } @@ -11396,12 +12280,17 @@ var ts; function getGlobalESSymbolConstructorSymbol() { return globalESSymbolConstructorSymbol || (globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol")); } + function createTypeFromGenericGlobalType(genericGlobalType, elementType) { + return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, [elementType]) : emptyObjectType; + } function createIterableType(elementType) { - return globalIterableType !== emptyObjectType ? createTypeReference(globalIterableType, [elementType]) : emptyObjectType; + return createTypeFromGenericGlobalType(globalIterableType, elementType); + } + function createIterableIteratorType(elementType) { + return createTypeFromGenericGlobalType(globalIterableIteratorType, elementType); } function createArrayType(elementType) { - var arrayType = globalArrayType || getDeclaredTypeOfSymbol(globalArraySymbol); - return arrayType !== emptyObjectType ? createTypeReference(arrayType, [elementType]) : emptyObjectType; + return createTypeFromGenericGlobalType(globalArrayType, elementType); } function getTypeFromArrayTypeNode(node) { var links = getNodeLinks(node); @@ -11456,13 +12345,7 @@ var ts; } return false; } - var removeSubtypesStack = []; function removeSubtypes(types) { - var typeListId = getTypeListId(types); - if (removeSubtypesStack.lastIndexOf(typeListId) >= 0) { - return; - } - removeSubtypesStack.push(typeListId); var i = types.length; while (i > 0) { i--; @@ -11470,7 +12353,6 @@ var ts; types.splice(i, 1); } } - removeSubtypesStack.pop(); } function containsAnyType(types) { for (var _i = 0; _i < types.length; _i++) { @@ -11520,7 +12402,14 @@ var ts; } function getReducedTypeOfUnionType(type) { if (!type.reducedType) { - type.reducedType = getUnionType(type.types, false); + type.reducedType = circularType; + var reducedType = getUnionType(type.types, false); + if (type.reducedType === circularType) { + type.reducedType = reducedType; + } + } + else if (type.reducedType === circularType) { + type.reducedType = type; } return type.reducedType; } @@ -11704,6 +12593,15 @@ var ts; return result; } function instantiateAnonymousType(type, mapper) { + if (mapper.mappings) { + var cached = mapper.mappings[type.id]; + if (cached) { + return cached; + } + } + else { + mapper.mappings = {}; + } var result = createObjectType(32768, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); result.members = createSymbolTable(result.properties); @@ -11715,6 +12613,7 @@ var ts; result.stringIndexType = instantiateType(stringIndexType, mapper); if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper); + mapper.mappings[type.id] = result; return result; } function instantiateType(type, mapper) { @@ -11723,7 +12622,7 @@ var ts; return mapper(type); } if (type.flags & 32768) { - return type.symbol && type.symbol.flags & (16 | 8192 | 2048 | 4096) ? + return type.symbol && type.symbol.flags & (16 | 8192 | 32 | 2048 | 4096) ? instantiateAnonymousType(type, mapper) : type; } if (type.flags & 4096) { @@ -12900,10 +13799,10 @@ var ts; } function resolveLocation(node) { var containerNodes = []; - for (var parent_3 = node.parent; parent_3; parent_3 = parent_3.parent) { - if ((ts.isExpression(parent_3) || ts.isObjectLiteralMethod(node)) && - isContextSensitive(parent_3)) { - containerNodes.unshift(parent_3); + for (var parent_5 = node.parent; parent_5; parent_5 = parent_5.parent) { + if ((ts.isExpression(parent_5) || ts.isObjectLiteralMethod(node)) && + isContextSensitive(parent_5)) { + containerNodes.unshift(parent_5); } } ts.forEach(containerNodes, function (node) { getTypeOfNode(node); }); @@ -13308,18 +14207,36 @@ var ts; return undefined; } function getContextualTypeForReturnExpression(node) { + var func = ts.getContainingFunction(node); + if (func && !func.asteriskToken) { + return getContextualReturnType(func); + } + return undefined; + } + function getContextualTypeForYieldOperand(node) { var func = ts.getContainingFunction(node); if (func) { - if (func.type || func.kind === 136 || func.kind === 137 && getSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(func.symbol, 138))) { - return getReturnTypeOfSignature(getSignatureFromDeclaration(func)); - } - var signature = getContextualSignatureForFunctionLikeDeclaration(func); - if (signature) { - return getReturnTypeOfSignature(signature); + var contextualReturnType = getContextualReturnType(func); + if (contextualReturnType) { + return node.asteriskToken + ? contextualReturnType + : getElementTypeOfIterableIterator(contextualReturnType); } } return undefined; } + function getContextualReturnType(functionDecl) { + if (functionDecl.type || + functionDecl.kind === 136 || + functionDecl.kind === 137 && getSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(functionDecl.symbol, 138))) { + return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl)); + } + var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); + if (signature) { + return getReturnTypeOfSignature(signature); + } + return undefined; + } function getContextualTypeForArgument(callTarget, arg) { var args = getEffectiveCallArguments(callTarget); var argIndex = ts.indexOf(args, arg); @@ -13421,7 +14338,7 @@ var ts; var index = ts.indexOf(arrayLiteral.elements, node); return getTypeOfPropertyOfContextualType(type, "" + index) || getIndexTypeOfContextualType(type, 1) - || (languageVersion >= 2 ? checkIteratedType(type, undefined) : undefined); + || (languageVersion >= 2 ? getElementTypeOfIterable(type, undefined) : undefined); } return undefined; } @@ -13447,6 +14364,8 @@ var ts; case 164: case 192: return getContextualTypeForReturnExpression(node); + case 173: + return getContextualTypeForYieldOperand(parent); case 158: case 159: return getContextualTypeForArgument(parent, node); @@ -13481,7 +14400,9 @@ var ts; return node.kind === 163 || node.kind === 164; } function getContextualSignatureForFunctionLikeDeclaration(node) { - return isFunctionExpressionOrArrowFunction(node) ? getContextualSignature(node) : undefined; + return isFunctionExpressionOrArrowFunction(node) || ts.isObjectLiteralMethod(node) + ? getContextualSignature(node) + : undefined; } function getContextualSignature(node) { ts.Debug.assert(node.kind !== 135 || ts.isObjectLiteralMethod(node)); @@ -13556,7 +14477,7 @@ var ts; if (inDestructuringPattern && e.kind === 174) { var restArrayType = checkExpression(e.expression, contextualMapper); var restElementType = getIndexTypeOfType(restArrayType, 1) || - (languageVersion >= 2 ? checkIteratedType(restArrayType, undefined) : undefined); + (languageVersion >= 2 ? getElementTypeOfIterable(restArrayType, undefined) : undefined); if (restElementType) { elementTypes.push(restElementType); } @@ -13779,15 +14700,15 @@ var ts; return unknownType; } if (node.argumentExpression) { - var name_6 = getPropertyNameForIndexedAccess(node.argumentExpression, indexType); - if (name_6 !== undefined) { - var prop = getPropertyOfType(objectType, name_6); + var name_9 = getPropertyNameForIndexedAccess(node.argumentExpression, indexType); + if (name_9 !== undefined) { + var prop = getPropertyOfType(objectType, name_9); if (prop) { getNodeLinks(node).resolvedSymbol = prop; return getTypeOfSymbol(prop); } else if (isConstEnum) { - error(node.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_const_enum_1, name_6, symbolToString(objectType.symbol)); + error(node.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_const_enum_1, name_9, symbolToString(objectType.symbol)); return unknownType; } } @@ -13877,19 +14798,19 @@ var ts; for (var _i = 0; _i < signatures.length; _i++) { var signature = signatures[_i]; var symbol = signature.declaration && getSymbolOfNode(signature.declaration); - var parent_4 = signature.declaration && signature.declaration.parent; + var parent_6 = signature.declaration && signature.declaration.parent; if (!lastSymbol || symbol === lastSymbol) { - if (lastParent && parent_4 === lastParent) { + if (lastParent && parent_6 === lastParent) { index++; } else { - lastParent = parent_4; + lastParent = parent_6; index = cutoffIndex; } } else { index = cutoffIndex = result.length; - lastParent = parent_4; + lastParent = parent_6; } lastSymbol = symbol; if (signature.hasStringLiterals) { @@ -14228,10 +15149,10 @@ var ts; return resolveCall(node, callSignatures, candidatesOutArray); } function resolveNewExpression(node, candidatesOutArray) { - if (node.arguments && languageVersion < 2) { + if (node.arguments && languageVersion < 1) { var spreadIndex = getSpreadArgumentIndex(node.arguments); if (spreadIndex >= 0) { - error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher); + error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher); } } var expressionType = checkExpression(node.expression); @@ -14357,14 +15278,37 @@ var ts; type = checkExpressionCached(func.body, contextualMapper); } else { - var types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper); - if (types.length === 0) { - return voidType; + var types; + var funcIsGenerator = !!func.asteriskToken; + if (funcIsGenerator) { + types = checkAndAggregateYieldOperandTypes(func.body, contextualMapper); + if (types.length === 0) { + var iterableIteratorAny = createIterableIteratorType(anyType); + if (compilerOptions.noImplicitAny) { + error(func.asteriskToken, ts.Diagnostics.Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type, typeToString(iterableIteratorAny)); + } + return iterableIteratorAny; + } + } + else { + types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper); + if (types.length === 0) { + return voidType; + } } type = contextualSignature ? getUnionType(types) : getCommonSupertype(types); if (!type) { - error(func, ts.Diagnostics.No_best_common_type_exists_among_return_expressions); - return unknownType; + if (funcIsGenerator) { + error(func, ts.Diagnostics.No_best_common_type_exists_among_yield_expressions); + return createIterableIteratorType(unknownType); + } + else { + error(func, ts.Diagnostics.No_best_common_type_exists_among_return_expressions); + return unknownType; + } + } + if (funcIsGenerator) { + type = createIterableIteratorType(type); } } if (!contextualSignature) { @@ -14372,6 +15316,22 @@ var ts; } return getWidenedType(type); } + function checkAndAggregateYieldOperandTypes(body, contextualMapper) { + var aggregatedTypes = []; + ts.forEachYieldExpression(body, function (yieldExpression) { + var expr = yieldExpression.expression; + if (expr) { + var type = checkExpressionCached(expr, contextualMapper); + if (yieldExpression.asteriskToken) { + type = checkElementTypeOfIterable(type, yieldExpression.expression); + } + if (!ts.contains(aggregatedTypes, type)) { + aggregatedTypes.push(type); + } + } + }); + return aggregatedTypes; + } function checkAndAggregateReturnExpressionTypes(body, contextualMapper) { var aggregatedTypes = []; ts.forEachReturnStatement(body, function (returnStatement) { @@ -14507,8 +15467,8 @@ var ts; var index = n.argumentExpression; var symbol = findSymbol(n.expression); if (symbol && index && index.kind === 8) { - var name_7 = index.text; - var prop = getPropertyOfType(getTypeOfSymbol(symbol), name_7); + var name_10 = index.text; + var prop = getPropertyOfType(getTypeOfSymbol(symbol), name_10); return prop && (prop.flags & 3) !== 0 && (getDeclarationFlagsFromSymbol(prop) & 8192) !== 0; } return false; @@ -14639,16 +15599,16 @@ var ts; for (var _i = 0; _i < properties.length; _i++) { var p = properties[_i]; if (p.kind === 225 || p.kind === 226) { - var name_8 = p.name; + var name_11 = p.name; var type = sourceType.flags & 1 ? sourceType : - getTypeOfPropertyOfType(sourceType, name_8.text) || - isNumericLiteralName(name_8.text) && getIndexTypeOfType(sourceType, 1) || + getTypeOfPropertyOfType(sourceType, name_11.text) || + isNumericLiteralName(name_11.text) && getIndexTypeOfType(sourceType, 1) || getIndexTypeOfType(sourceType, 0); if (type) { - checkDestructuringAssignment(p.initializer || name_8, type); + checkDestructuringAssignment(p.initializer || name_11, type); } else { - error(name_8, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), ts.declarationNameToString(name_8)); + error(name_11, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), ts.declarationNameToString(name_11)); } } else { @@ -14863,13 +15823,46 @@ var ts; error(node, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(node.operatorToken.kind), typeToString(leftType), typeToString(rightType)); } } + function isYieldExpressionInClass(node) { + var current = node; + var parent = node.parent; + while (parent) { + if (ts.isFunctionLike(parent) && current === parent.body) { + return false; + } + else if (current.kind === 202 || current.kind === 175) { + return true; + } + current = parent; + parent = parent.parent; + } + return false; + } function checkYieldExpression(node) { - if (!(node.parserContextFlags & 4)) { - grammarErrorOnFirstToken(node, ts.Diagnostics.yield_expression_must_be_contained_within_a_generator_declaration); + if (!(node.parserContextFlags & 4) || isYieldExpressionInClass(node)) { + grammarErrorOnFirstToken(node, ts.Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body); } - else { - grammarErrorOnFirstToken(node, ts.Diagnostics.yield_expressions_are_not_currently_supported); + if (node.expression) { + var func = ts.getContainingFunction(node); + if (func && func.asteriskToken) { + var expressionType = checkExpressionCached(node.expression, undefined); + var expressionElementType; + var nodeIsYieldStar = !!node.asteriskToken; + if (nodeIsYieldStar) { + expressionElementType = checkElementTypeOfIterable(expressionType, node.expression); + } + if (func.type) { + var signatureElementType = getElementTypeOfIterableIterator(getTypeFromTypeNode(func.type)) || anyType; + if (nodeIsYieldStar) { + checkTypeAssignableTo(expressionElementType, signatureElementType, node.expression, undefined); + } + else { + checkTypeAssignableTo(expressionType, signatureElementType, node.expression, undefined); + } + } + } } + return anyType; } function checkConditionalExpression(node, contextualMapper) { checkExpression(node.condition); @@ -15016,8 +16009,7 @@ var ts; case 176: return undefinedType; case 173: - checkYieldExpression(node); - return unknownType; + return checkYieldExpression(node); } return unknownType; } @@ -15055,6 +16047,14 @@ var ts; error(node, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type); } } + function isSyntacticallyValidGenerator(node) { + if (!node.asteriskToken || !node.body) { + return false; + } + return node.kind === 135 || + node.kind === 201 || + node.kind === 163; + } function checkSignatureDeclaration(node) { if (node.kind === 141) { checkGrammarIndexSignature(node); @@ -15081,6 +16081,19 @@ var ts; break; } } + if (node.type) { + if (languageVersion >= 2 && isSyntacticallyValidGenerator(node)) { + var returnType = getTypeFromTypeNode(node.type); + if (returnType === voidType) { + error(node.type, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation); + } + else { + var generatorElementType = getElementTypeOfIterableIterator(returnType) || anyType; + var iterableIteratorInstantiation = createIterableIteratorType(generatorElementType); + checkTypeAssignableTo(iterableIteratorInstantiation, returnType, node.type); + } + } + } } checkSpecializedSignatureDeclaration(node); } @@ -15624,7 +16637,6 @@ var ts; function checkFunctionDeclaration(node) { if (produceDiagnostics) { checkFunctionLikeDeclaration(node) || - checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarFunctionName(node.name) || checkGrammarForGenerator(node); checkCollisionWithCapturedSuperVariable(node, node.name); @@ -15656,8 +16668,13 @@ var ts; if (node.type && !isAccessor(node.kind) && !node.asteriskToken) { checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } - if (compilerOptions.noImplicitAny && ts.nodeIsMissing(node.body) && !node.type && !isPrivateWithinAmbient(node)) { - reportImplicitAnyError(node, anyType); + if (produceDiagnostics && !node.type) { + if (compilerOptions.noImplicitAny && ts.nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) { + reportImplicitAnyError(node, anyType); + } + if (node.asteriskToken && ts.nodeIsPresent(node.body)) { + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } } } function checkBlock(node) { @@ -15778,8 +16795,8 @@ var ts; container.kind === 206 || container.kind === 228); if (!namesShareScope) { - var name_9 = symbolToString(localDeclarationSymbol); - error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name_9, name_9); + var name_12 = symbolToString(localDeclarationSymbol); + error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name_12, name_12); } } } @@ -15872,7 +16889,7 @@ var ts; return checkVariableLikeDeclaration(node); } function checkVariableStatement(node) { - checkGrammarDecorators(node) || checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node); + checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node); ts.forEach(node.declarationList.declarations, checkSourceElement); } function checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) { @@ -15995,7 +17012,7 @@ var ts; return inputType; } if (languageVersion >= 2) { - return checkIteratedType(inputType, errorNode) || anyType; + return checkElementTypeOfIterable(inputType, errorNode); } if (allowStringInput) { return checkElementTypeOfArrayOrString(inputType, errorNode); @@ -16009,84 +17026,85 @@ var ts; error(errorNode, ts.Diagnostics.Type_0_is_not_an_array_type, typeToString(inputType)); return unknownType; } - function checkIteratedType(iterable, errorNode) { - ts.Debug.assert(languageVersion >= 2); - var iteratedType = getIteratedType(iterable, errorNode); - if (errorNode && iteratedType) { - checkTypeAssignableTo(iterable, createIterableType(iteratedType), errorNode); + function checkElementTypeOfIterable(iterable, errorNode) { + var elementType = getElementTypeOfIterable(iterable, errorNode); + if (errorNode && elementType) { + checkTypeAssignableTo(iterable, createIterableType(elementType), errorNode); } - return iteratedType; - function getIteratedType(iterable, errorNode) { - // We want to treat type as an iterable, and get the type it is an iterable of. The iterable - // must have the following structure (annotated with the names of the variables below): - // - // { // iterable - // [Symbol.iterator]: { // iteratorFunction - // (): { // iterator - // next: { // iteratorNextFunction - // (): { // iteratorNextResult - // value: T // iteratorNextValue - // } - // } - // } - // } - // } - // - // T is the type we are after. At every level that involves analyzing return types - // of signatures, we union the return types of all the signatures. - // - // Another thing to note is that at any step of this process, we could run into a dead end, - // meaning either the property is missing, or we run into the anyType. If either of these things - // happens, we return undefined to signal that we could not find the iterated type. If a property - // is missing, and the previous step did not result in 'any', then we also give an error if the - // caller requested it. Then the caller can decide what to do in the case where there is no iterated - // type. This is different from returning anyType, because that would signify that we have matched the - // whole pattern and that T (above) is 'any'. - if (allConstituentTypesHaveKind(iterable, 1)) { - return undefined; - } - if ((iterable.flags & 4096) && iterable.target === globalIterableType) { - return iterable.typeArguments[0]; - } - var iteratorFunction = getTypeOfPropertyOfType(iterable, ts.getPropertyNameForKnownSymbolName("iterator")); - if (iteratorFunction && allConstituentTypesHaveKind(iteratorFunction, 1)) { - return undefined; - } - var iteratorFunctionSignatures = iteratorFunction ? getSignaturesOfType(iteratorFunction, 0) : emptyArray; - if (iteratorFunctionSignatures.length === 0) { - if (errorNode) { - error(errorNode, ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator); - } - return undefined; - } - var iterator = getUnionType(ts.map(iteratorFunctionSignatures, getReturnTypeOfSignature)); - if (allConstituentTypesHaveKind(iterator, 1)) { - return undefined; - } - var iteratorNextFunction = getTypeOfPropertyOfType(iterator, "next"); - if (iteratorNextFunction && allConstituentTypesHaveKind(iteratorNextFunction, 1)) { - return undefined; - } - var iteratorNextFunctionSignatures = iteratorNextFunction ? getSignaturesOfType(iteratorNextFunction, 0) : emptyArray; - if (iteratorNextFunctionSignatures.length === 0) { - if (errorNode) { - error(errorNode, ts.Diagnostics.An_iterator_must_have_a_next_method); - } - return undefined; - } - var iteratorNextResult = getUnionType(ts.map(iteratorNextFunctionSignatures, getReturnTypeOfSignature)); - if (allConstituentTypesHaveKind(iteratorNextResult, 1)) { - return undefined; - } - var iteratorNextValue = getTypeOfPropertyOfType(iteratorNextResult, "value"); - if (!iteratorNextValue) { - if (errorNode) { - error(errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property); - } - return undefined; - } - return iteratorNextValue; + return elementType || anyType; + } + function getElementTypeOfIterable(type, errorNode) { + if (type.flags & 1) { + return undefined; } + var typeAsIterable = type; + if (!typeAsIterable.iterableElementType) { + if ((type.flags & 4096) && type.target === globalIterableType) { + typeAsIterable.iterableElementType = type.typeArguments[0]; + } + else { + var iteratorFunction = getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("iterator")); + if (iteratorFunction && iteratorFunction.flags & 1) { + return undefined; + } + var iteratorFunctionSignatures = iteratorFunction ? getSignaturesOfType(iteratorFunction, 0) : emptyArray; + if (iteratorFunctionSignatures.length === 0) { + if (errorNode) { + error(errorNode, ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator); + } + return undefined; + } + typeAsIterable.iterableElementType = getElementTypeOfIterator(getUnionType(ts.map(iteratorFunctionSignatures, getReturnTypeOfSignature)), errorNode); + } + } + return typeAsIterable.iterableElementType; + } + function getElementTypeOfIterator(type, errorNode) { + if (type.flags & 1) { + return undefined; + } + var typeAsIterator = type; + if (!typeAsIterator.iteratorElementType) { + if ((type.flags & 4096) && type.target === globalIteratorType) { + typeAsIterator.iteratorElementType = type.typeArguments[0]; + } + else { + var iteratorNextFunction = getTypeOfPropertyOfType(type, "next"); + if (iteratorNextFunction && iteratorNextFunction.flags & 1) { + return undefined; + } + var iteratorNextFunctionSignatures = iteratorNextFunction ? getSignaturesOfType(iteratorNextFunction, 0) : emptyArray; + if (iteratorNextFunctionSignatures.length === 0) { + if (errorNode) { + error(errorNode, ts.Diagnostics.An_iterator_must_have_a_next_method); + } + return undefined; + } + var iteratorNextResult = getUnionType(ts.map(iteratorNextFunctionSignatures, getReturnTypeOfSignature)); + if (iteratorNextResult.flags & 1) { + return undefined; + } + var iteratorNextValue = getTypeOfPropertyOfType(iteratorNextResult, "value"); + if (!iteratorNextValue) { + if (errorNode) { + error(errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property); + } + return undefined; + } + typeAsIterator.iteratorElementType = iteratorNextValue; + } + } + return typeAsIterator.iteratorElementType; + } + function getElementTypeOfIterableIterator(type) { + if (type.flags & 1) { + return undefined; + } + if ((type.flags & 4096) && type.target === globalIterableIteratorType) { + return type.typeArguments[0]; + } + return getElementTypeOfIterable(type, undefined) || + getElementTypeOfIterator(type, undefined); } function checkElementTypeOfArrayOrString(arrayOrStringType, errorNode) { ts.Debug.assert(languageVersion < 2); @@ -16138,19 +17156,20 @@ var ts; if (func) { var returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func)); var exprType = checkExpressionCached(node.expression); + if (func.asteriskToken) { + return; + } if (func.kind === 138) { error(node.expression, ts.Diagnostics.Setters_cannot_return_a_value); } - else { - if (func.kind === 136) { - if (!isTypeAssignableTo(exprType, returnType)) { - error(node.expression, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); - } - } - else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) { - checkTypeAssignableTo(exprType, returnType, node.expression, undefined); + else if (func.kind === 136) { + if (!isTypeAssignableTo(exprType, returnType)) { + error(node.expression, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } + else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) { + checkTypeAssignableTo(exprType, returnType, node.expression, undefined); + } } } } @@ -16344,9 +17363,6 @@ var ts; } function checkClassDeclaration(node) { checkGrammarDeclarationNameInStrictMode(node); - if (node.parent.kind !== 207 && node.parent.kind !== 228) { - grammarErrorOnNode(node, ts.Diagnostics.class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration); - } if (!node.name && !(node.flags & 256)) { grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } @@ -17386,74 +18402,6 @@ var ts; } return node.parent && node.parent.kind === 177; } - function isTypeNode(node) { - if (142 <= node.kind && node.kind <= 150) { - return true; - } - switch (node.kind) { - case 112: - case 120: - case 122: - case 113: - case 123: - return true; - case 99: - return node.parent.kind !== 167; - case 8: - return node.parent.kind === 130; - case 177: - return true; - case 65: - if (node.parent.kind === 127 && node.parent.right === node) { - node = node.parent; - } - else if (node.parent.kind === 156 && node.parent.name === node) { - node = node.parent; - } - case 127: - case 156: - ts.Debug.assert(node.kind === 65 || node.kind === 127 || node.kind === 156, "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'."); - var parent_5 = node.parent; - if (parent_5.kind === 145) { - return false; - } - if (142 <= parent_5.kind && parent_5.kind <= 150) { - return true; - } - switch (parent_5.kind) { - case 177: - return true; - case 129: - return node === parent_5.constraint; - case 133: - case 132: - case 130: - case 199: - return node === parent_5.type; - case 201: - case 163: - case 164: - case 136: - case 135: - case 134: - case 137: - case 138: - return node === parent_5.type; - case 139: - case 140: - case 141: - return node === parent_5.type; - case 161: - return node === parent_5.type; - case 158: - case 159: - return parent_5.typeArguments && ts.indexOf(parent_5.typeArguments, node) >= 0; - case 160: - return false; - } - } - return false; - } function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide) { while (nodeOnRightSide.parent.kind === 127) { nodeOnRightSide = nodeOnRightSide.parent; @@ -17578,7 +18526,7 @@ var ts; if (isInsideWithStatementBody(node)) { return unknownType; } - if (isTypeNode(node)) { + if (ts.isTypeNode(node)) { return getTypeFromTypeNode(node); } if (ts.isExpression(node)) { @@ -17628,9 +18576,9 @@ var ts; function getRootSymbols(symbol) { if (symbol.flags & 268435456) { var symbols = []; - var name_10 = symbol.name; + var name_13 = symbol.name; ts.forEach(getSymbolLinks(symbol).unionType.types, function (t) { - symbols.push(getPropertyOfType(t, name_10)); + symbols.push(getPropertyOfType(t, name_13)); }); return symbols; } @@ -18008,8 +18956,7 @@ var ts; getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments"); getSymbolLinks(unknownSymbol).type = unknownType; globals[undefinedSymbol.name] = undefinedSymbol; - globalArraySymbol = getGlobalTypeSymbol("Array"); - globalArrayType = getTypeOfGlobalSymbol(globalArraySymbol, 1); + globalArrayType = getGlobalType("Array", 1); globalObjectType = getGlobalType("Object"); globalFunctionType = getGlobalType("Function"); globalStringType = getGlobalType("String"); @@ -18025,11 +18972,16 @@ var ts; globalESSymbolType = getGlobalType("Symbol"); globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol"); globalIterableType = getGlobalType("Iterable", 1); + globalIteratorType = getGlobalType("Iterator", 1); + globalIterableIteratorType = getGlobalType("IterableIterator", 1); } else { globalTemplateStringsArrayType = unknownType; globalESSymbolType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); globalESSymbolConstructorSymbol = undefined; + globalIterableType = emptyGenericType; + globalIteratorType = emptyGenericType; + globalIterableIteratorType = emptyGenericType; } anyArrayType = createArrayType(anyType); } @@ -18049,20 +19001,20 @@ var ts; if (impotClause.namedBindings) { var nameBindings = impotClause.namedBindings; if (nameBindings.kind === 212) { - var name_11 = nameBindings.name; - if (isReservedWordInStrictMode(name_11)) { - var nameText = ts.declarationNameToString(name_11); - return grammarErrorOnNode(name_11, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); + var name_14 = nameBindings.name; + if (isReservedWordInStrictMode(name_14)) { + var nameText = ts.declarationNameToString(name_14); + return grammarErrorOnNode(name_14, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); } } else if (nameBindings.kind === 213) { var reportError = false; for (var _i = 0, _a = nameBindings.elements; _i < _a.length; _i++) { var element = _a[_i]; - var name_12 = element.name; - if (isReservedWordInStrictMode(name_12)) { - var nameText = ts.declarationNameToString(name_12); - reportError = reportError || grammarErrorOnNode(name_12, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); + var name_15 = element.name; + if (isReservedWordInStrictMode(name_15)) { + var nameText = ts.declarationNameToString(name_15); + reportError = reportError || grammarErrorOnNode(name_15, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); } } return reportError; @@ -18160,19 +19112,28 @@ var ts; case 135: case 134: case 141: - case 202: - case 203: case 206: - case 205: - case 181: - case 201: - case 204: case 210: case 209: case 216: case 215: case 130: break; + case 202: + case 203: + case 181: + case 201: + case 204: + if (node.modifiers && node.parent.kind !== 207 && node.parent.kind !== 228) { + return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here); + } + break; + case 205: + if (node.modifiers && (node.modifiers.length > 1 || node.modifiers[0].kind !== 70) && + node.parent.kind !== 207 && node.parent.kind !== 228) { + return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here); + } + break; default: return false; } @@ -18270,9 +19231,6 @@ var ts; else if ((node.kind === 210 || node.kind === 209) && flags & 2) { return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_declare_modifier_cannot_be_used_with_an_import_declaration, "declare"); } - else if (node.kind === 203 && flags & 2) { - return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_declare_modifier_cannot_be_used_with_an_interface_declaration, "declare"); - } else if (node.kind === 130 && (flags & 112) && ts.isBindingPattern(node.name)) { return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_may_not_be_a_binding_pattern); } @@ -18484,7 +19442,18 @@ var ts; } function checkGrammarForGenerator(node) { if (node.asteriskToken) { - return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_currently_supported); + ts.Debug.assert(node.kind === 201 || + node.kind === 163 || + node.kind === 135); + if (ts.isInAmbientContext(node)) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_allowed_in_an_ambient_context); + } + if (!node.body) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator); + } + if (languageVersion < 2) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_only_available_when_targeting_ECMAScript_6_or_higher); + } } } function checkGrammarFunctionName(name) { @@ -18504,17 +19473,17 @@ var ts; var inStrictMode = (node.parserContextFlags & 1) !== 0; for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var prop = _a[_i]; - var name_13 = prop.name; + var name_16 = prop.name; if (prop.kind === 176 || - name_13.kind === 128) { - checkGrammarComputedPropertyName(name_13); + name_16.kind === 128) { + checkGrammarComputedPropertyName(name_16); continue; } var currentKind = void 0; if (prop.kind === 225 || prop.kind === 226) { checkGrammarForInvalidQuestionMark(prop, prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional); - if (name_13.kind === 7) { - checkGrammarNumericLiteral(name_13); + if (name_16.kind === 7) { + checkGrammarNumericLiteral(name_16); } currentKind = Property; } @@ -18530,26 +19499,26 @@ var ts; else { ts.Debug.fail("Unexpected syntax kind:" + prop.kind); } - if (!ts.hasProperty(seen, name_13.text)) { - seen[name_13.text] = currentKind; + if (!ts.hasProperty(seen, name_16.text)) { + seen[name_16.text] = currentKind; } else { - var existingKind = seen[name_13.text]; + var existingKind = seen[name_16.text]; if (currentKind === Property && existingKind === Property) { if (inStrictMode) { - grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode); + grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode); } } else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { - seen[name_13.text] = currentKind | existingKind; + seen[name_16.text] = currentKind | existingKind; } else { - return grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); + return grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); } } else { - return grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name); + return grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name); } } } @@ -19328,9 +20297,9 @@ var ts; } var count = 0; while (true) { - var name_14 = baseName + "_" + (++count); - if (!ts.hasProperty(currentSourceFile.identifiers, name_14)) { - return name_14; + var name_17 = baseName + "_" + (++count); + if (!ts.hasProperty(currentSourceFile.identifiers, name_17)) { + return name_17; } } } @@ -20414,9 +21383,9 @@ var ts; var count = tempFlags & 268435455; tempFlags++; if (count !== 8 && count !== 13) { - var name_15 = count < 26 ? "_" + String.fromCharCode(97 + count) : "_" + (count - 26); - if (isUniqueName(name_15)) { - return name_15; + var name_18 = count < 26 ? "_" + String.fromCharCode(97 + count) : "_" + (count - 26); + if (isUniqueName(name_18)) { + return name_18; } } } @@ -20444,8 +21413,8 @@ var ts; } function generateNameForModuleOrEnum(node) { if (node.name.kind === 65) { - var name_16 = node.name.text; - assignGeneratedName(node, isUniqueLocalName(name_16, node) ? name_16 : makeUniqueName(name_16)); + var name_19 = node.name.text; + assignGeneratedName(node, isUniqueLocalName(name_19, node) ? name_19 : makeUniqueName(name_19)); } } function generateNameForImportOrExportDeclaration(node) { @@ -20631,8 +21600,8 @@ var ts; if (scopeName) { var parentIndex = getSourceMapNameIndex(); if (parentIndex !== -1) { - var name_17 = node.name; - if (!name_17 || name_17.kind !== 128) { + var name_20 = node.name; + if (!name_20 || name_20.kind !== 128) { scopeName = "." + scopeName; } scopeName = sourceMapData.sourceMapNames[parentIndex] + scopeName; @@ -20659,9 +21628,9 @@ var ts; node.kind === 202 || node.kind === 205) { if (node.name) { - var name_18 = node.name; - scopeName = name_18.kind === 128 - ? ts.getTextOfNode(name_18) + var name_21 = node.name; + scopeName = name_21.kind === 128 + ? ts.getTextOfNode(name_21) : node.name.text; } recordScopeNameStart(scopeName); @@ -21282,15 +22251,15 @@ var ts; } return true; } - function emitListWithSpread(elements, alwaysCopy, multiLine, trailingComma) { + function emitListWithSpread(elements, needsUniqueCopy, multiLine, trailingComma, useConcat) { var pos = 0; var group = 0; var length = elements.length; while (pos < length) { - if (group === 1) { + if (group === 1 && useConcat) { write(".concat("); } - else if (group > 1) { + else if (group > 0) { write(", "); } var e = elements[pos]; @@ -21298,7 +22267,7 @@ var ts; e = e.expression; emitParenthesizedIf(e, group === 0 && needsParenthesisForPropertyAccessOrInvocation(e)); pos++; - if (pos === length && group === 0 && alwaysCopy && e.kind !== 154) { + if (pos === length && group === 0 && needsUniqueCopy && e.kind !== 154) { write(".slice()"); } } @@ -21321,7 +22290,9 @@ var ts; group++; } if (group > 1) { - write(")"); + if (useConcat) { + write(")"); + } } } function isSpreadElementExpression(node) { @@ -21338,7 +22309,7 @@ var ts; write("]"); } else { - emitListWithSpread(elements, true, (node.flags & 512) !== 0, elements.hasTrailingComma); + emitListWithSpread(elements, true, (node.flags & 512) !== 0, elements.hasTrailingComma, true); } } function emitObjectLiteralBody(node, numElements) { @@ -21664,7 +22635,7 @@ var ts; write("void 0"); } write(", "); - emitListWithSpread(node.arguments, false, false, false); + emitListWithSpread(node.arguments, false, false, false, true); write(")"); } function emitCallExpression(node) { @@ -21698,11 +22669,25 @@ var ts; } function emitNewExpression(node) { write("new "); - emit(node.expression); - if (node.arguments) { + if (languageVersion === 1 && + node.arguments && + hasSpreadElement(node.arguments)) { write("("); - emitCommaList(node.arguments); - write(")"); + var target = emitCallTarget(node.expression); + write(".bind.apply("); + emit(target); + write(", [void 0].concat("); + emitListWithSpread(node.arguments, false, false, false, false); + write(")))"); + write("()"); + } + else { + emit(node.expression); + if (node.arguments) { + write("("); + emitCommaList(node.arguments); + write(")"); + } } } function emitTaggedTemplateExpression(node) { @@ -22654,15 +23639,30 @@ var ts; ts.forEach(node.declarationList.declarations, emitExportVariableAssignments); } } + function shouldEmitLeadingAndTrailingCommentsForVariableStatement(node) { + if (!(node.flags & 1)) { + return true; + } + if (isES6ExportedDeclaration(node)) { + return true; + } + for (var _a = 0, _b = node.declarationList.declarations; _a < _b.length; _a++) { + var declaration = _b[_a]; + if (declaration.initializer) { + return true; + } + } + return false; + } function emitParameter(node) { if (languageVersion < 2) { if (ts.isBindingPattern(node.name)) { - var name_19 = createTempVariable(0); + var name_22 = createTempVariable(0); if (!tempParameters) { tempParameters = []; } - tempParameters.push(name_19); - emit(name_19); + tempParameters.push(name_22); + emit(name_22); } else { emit(node.name); @@ -24122,8 +25122,8 @@ var ts; else { for (var _c = 0, _d = node.exportClause.elements; _c < _d.length; _c++) { var specifier = _d[_c]; - var name_20 = (specifier.propertyName || specifier.name).text; - (exportSpecifiers[name_20] || (exportSpecifiers[name_20] = [])).push(specifier); + var name_23 = (specifier.propertyName || specifier.name).text; + (exportSpecifiers[name_23] || (exportSpecifiers[name_23] = [])).push(specifier); } } break; @@ -24296,11 +25296,11 @@ var ts; var seen = {}; for (var i = 0; i < hoistedVars.length; ++i) { var local = hoistedVars[i]; - var name_21 = local.kind === 65 + var name_24 = local.kind === 65 ? local : local.name; - if (name_21) { - var text = ts.unescapeIdentifier(name_21.text); + if (name_24) { + var text = ts.unescapeIdentifier(name_24.text); if (ts.hasProperty(seen, text)) { continue; } @@ -24379,15 +25379,15 @@ var ts; } if (node.kind === 199 || node.kind === 153) { if (shouldHoistVariable(node, false)) { - var name_22 = node.name; - if (name_22.kind === 65) { + var name_25 = node.name; + if (name_25.kind === 65) { if (!hoistedVars) { hoistedVars = []; } - hoistedVars.push(name_22); + hoistedVars.push(name_25); } else { - ts.forEachChild(name_22, visit); + ts.forEachChild(name_25, visit); } } return; @@ -24754,6 +25754,8 @@ var ts; case 204: case 215: return false; + case 181: + return shouldEmitLeadingAndTrailingCommentsForVariableStatement(node); case 206: return shouldEmitModuleDeclaration(node); case 205: diff --git a/bin/tsserver.js b/bin/tsserver.js index 49c7b69b302..5795b1e7e36 100644 --- a/bin/tsserver.js +++ b/bin/tsserver.js @@ -145,6 +145,16 @@ var ts; } } ts.addRange = addRange; + function rangeEquals(array1, array2, pos, end) { + while (pos < end) { + if (array1[pos] !== array2[pos]) { + return false; + } + pos++; + } + return true; + } + ts.rangeEquals = rangeEquals; function lastOrUndefined(array) { if (array.length === 0) { return undefined; @@ -301,8 +311,10 @@ var ts; var end = start + length; Debug.assert(start >= 0, "start must be non-negative, is " + start); Debug.assert(length >= 0, "length must be non-negative, is " + length); - Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); - Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + if (file) { + Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); + Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + } var text = getLocaleSpecificMessage(message.key); if (arguments.length > 4) { text = formatStringFromArgs(text, arguments, 4); @@ -837,7 +849,7 @@ var ts; for (var _i = 0; _i < files.length; _i++) { var current = files[_i]; var name = ts.combinePaths(path, current); - var stat = _fs.lstatSync(name); + var stat = _fs.statSync(name); if (stat.isFile()) { if (!extension || ts.fileExtensionIs(name, extension)) { result.push(name); @@ -1039,7 +1051,7 @@ var ts; Unterminated_template_literal: { code: 1160, category: ts.DiagnosticCategory.Error, key: "Unterminated template literal." }, Unterminated_regular_expression_literal: { code: 1161, category: ts.DiagnosticCategory.Error, key: "Unterminated regular expression literal." }, An_object_member_cannot_be_declared_optional: { code: 1162, category: ts.DiagnosticCategory.Error, key: "An object member cannot be declared optional." }, - yield_expression_must_be_contained_within_a_generator_declaration: { code: 1163, category: ts.DiagnosticCategory.Error, key: "'yield' expression must be contained_within a generator declaration." }, + A_yield_expression_is_only_allowed_in_a_generator_body: { code: 1163, category: ts.DiagnosticCategory.Error, key: "A 'yield' expression is only allowed in a generator body." }, Computed_property_names_are_not_allowed_in_enums: { code: 1164, category: ts.DiagnosticCategory.Error, key: "Computed property names are not allowed in enums." }, A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol: { code: 1165, category: ts.DiagnosticCategory.Error, key: "A computed property name in an ambient context must directly refer to a built-in symbol." }, A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol: { code: 1166, category: ts.DiagnosticCategory.Error, key: "A computed property name in a class property declaration must directly refer to a built-in symbol." }, @@ -1094,6 +1106,10 @@ var ts; Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." }, Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: ts.DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." }, Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: ts.DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." }, + Generators_are_only_available_when_targeting_ECMAScript_6_or_higher: { code: 1220, category: ts.DiagnosticCategory.Error, key: "Generators are only available when targeting ECMAScript 6 or higher." }, + Generators_are_not_allowed_in_an_ambient_context: { code: 1221, category: ts.DiagnosticCategory.Error, key: "Generators are not allowed in an ambient context." }, + An_overload_signature_cannot_be_declared_as_a_generator: { code: 1222, category: ts.DiagnosticCategory.Error, key: "An overload signature cannot be declared as a generator." }, + _0_tag_already_specified: { code: 1223, category: ts.DiagnosticCategory.Error, key: "'{0}' tag already specified." }, Duplicate_identifier_0: { code: 2300, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: ts.DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: ts.DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, @@ -1254,7 +1270,7 @@ var ts; The_0_operator_cannot_be_applied_to_type_symbol: { code: 2469, category: ts.DiagnosticCategory.Error, key: "The '{0}' operator cannot be applied to type 'symbol'." }, Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: { code: 2470, category: ts.DiagnosticCategory.Error, key: "'Symbol' reference does not refer to the global Symbol constructor object." }, A_computed_property_name_of_the_form_0_must_be_of_type_symbol: { code: 2471, category: ts.DiagnosticCategory.Error, key: "A computed property name of the form '{0}' must be of type 'symbol'." }, - Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher: { code: 2472, category: ts.DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher." }, + Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: { code: 2472, category: ts.DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher." }, Enum_declarations_must_all_be_const_or_non_const: { code: 2473, category: ts.DiagnosticCategory.Error, key: "Enum declarations must all be const or non-const." }, In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 2474, category: ts.DiagnosticCategory.Error, key: "In 'const' enum declarations member initializer must be constant expression." }, const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: { code: 2475, category: ts.DiagnosticCategory.Error, key: "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment." }, @@ -1285,6 +1301,8 @@ var ts; A_rest_element_cannot_contain_a_binding_pattern: { code: 2501, category: ts.DiagnosticCategory.Error, key: "A rest element cannot contain a binding pattern." }, _0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: { code: 2502, category: ts.DiagnosticCategory.Error, key: "'{0}' is referenced directly or indirectly in its own type annotation." }, Cannot_find_namespace_0: { code: 2503, category: ts.DiagnosticCategory.Error, key: "Cannot find namespace '{0}'." }, + No_best_common_type_exists_among_yield_expressions: { code: 2504, category: ts.DiagnosticCategory.Error, key: "No best common type exists among yield expressions." }, + A_generator_cannot_have_a_void_type_annotation: { code: 2505, category: ts.DiagnosticCategory.Error, key: "A generator cannot have a 'void' type annotation." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, @@ -1445,6 +1463,7 @@ var ts; _0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: ts.DiagnosticCategory.Error, key: "'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer." }, _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7023, category: ts.DiagnosticCategory.Error, key: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: ts.DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, + Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: ts.DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." }, You_cannot_rename_this_element: { code: 8000, category: ts.DiagnosticCategory.Error, key: "You cannot rename this element." }, You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: ts.DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." }, import_can_only_be_used_in_a_ts_file: { code: 8002, category: ts.DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." }, @@ -1458,16 +1477,12 @@ var ts; types_can_only_be_used_in_a_ts_file: { code: 8010, category: ts.DiagnosticCategory.Error, key: "'types' can only be used in a .ts file." }, type_arguments_can_only_be_used_in_a_ts_file: { code: 8011, category: ts.DiagnosticCategory.Error, key: "'type arguments' can only be used in a .ts file." }, parameter_modifiers_can_only_be_used_in_a_ts_file: { code: 8012, category: ts.DiagnosticCategory.Error, key: "'parameter modifiers' can only be used in a .ts file." }, - can_only_be_used_in_a_ts_file: { code: 8013, category: ts.DiagnosticCategory.Error, key: "'?' can only be used in a .ts file." }, property_declarations_can_only_be_used_in_a_ts_file: { code: 8014, category: ts.DiagnosticCategory.Error, key: "'property declarations' can only be used in a .ts file." }, enum_declarations_can_only_be_used_in_a_ts_file: { code: 8015, category: ts.DiagnosticCategory.Error, key: "'enum declarations' can only be used in a .ts file." }, type_assertion_expressions_can_only_be_used_in_a_ts_file: { code: 8016, category: ts.DiagnosticCategory.Error, key: "'type assertion expressions' can only be used in a .ts file." }, decorators_can_only_be_used_in_a_ts_file: { code: 8017, category: ts.DiagnosticCategory.Error, key: "'decorators' can only be used in a .ts file." }, - yield_expressions_are_not_currently_supported: { code: 9000, category: ts.DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." }, - Generators_are_not_currently_supported: { code: 9001, category: ts.DiagnosticCategory.Error, key: "Generators are not currently supported." }, Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: ts.DiagnosticCategory.Error, key: "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses." }, - class_expressions_are_not_currently_supported: { code: 9003, category: ts.DiagnosticCategory.Error, key: "'class' expressions are not currently supported." }, - class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration: { code: 9004, category: ts.DiagnosticCategory.Error, key: "'class' declarations are only supported directly inside a module or as a top level declaration." } + class_expressions_are_not_currently_supported: { code: 9003, category: ts.DiagnosticCategory.Error, key: "'class' expressions are not currently supported." } }; })(ts || (ts = {})); /// @@ -3155,17 +3170,17 @@ var ts; ts.getFullWidth = getFullWidth; function containsParseError(node) { aggregateChildData(node); - return (node.parserContextFlags & 64) !== 0; + return (node.parserContextFlags & 128) !== 0; } ts.containsParseError = containsParseError; function aggregateChildData(node) { - if (!(node.parserContextFlags & 128)) { + if (!(node.parserContextFlags & 256)) { var thisNodeOrAnySubNodesHasError = ((node.parserContextFlags & 32) !== 0) || ts.forEachChild(node, containsParseError); if (thisNodeOrAnySubNodesHasError) { - node.parserContextFlags |= 64; + node.parserContextFlags |= 128; } - node.parserContextFlags |= 128; + node.parserContextFlags |= 256; } } function getSourceFileOfNode(node) { @@ -3408,6 +3423,75 @@ var ts; } ts.getJsDocComments = getJsDocComments; ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; + function isTypeNode(node) { + if (142 <= node.kind && node.kind <= 150) { + return true; + } + switch (node.kind) { + case 112: + case 120: + case 122: + case 113: + case 123: + return true; + case 99: + return node.parent.kind !== 167; + case 8: + return node.parent.kind === 130; + case 177: + return true; + case 65: + if (node.parent.kind === 127 && node.parent.right === node) { + node = node.parent; + } + else if (node.parent.kind === 156 && node.parent.name === node) { + node = node.parent; + } + case 127: + case 156: + ts.Debug.assert(node.kind === 65 || node.kind === 127 || node.kind === 156, "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'."); + var parent_1 = node.parent; + if (parent_1.kind === 145) { + return false; + } + if (142 <= parent_1.kind && parent_1.kind <= 150) { + return true; + } + switch (parent_1.kind) { + case 177: + return true; + case 129: + return node === parent_1.constraint; + case 133: + case 132: + case 130: + case 199: + return node === parent_1.type; + case 201: + case 163: + case 164: + case 136: + case 135: + case 134: + case 137: + case 138: + return node === parent_1.type; + case 139: + case 140: + case 141: + return node === parent_1.type; + case 161: + return node === parent_1.type; + case 158: + case 159: + return parent_1.typeArguments && ts.indexOf(parent_1.typeArguments, node) >= 0; + case 160: + return false; + } + } + return false; + } + ts.isTypeNode = isTypeNode; function forEachReturnStatement(body, visitor) { return traverse(body); function traverse(node) { @@ -3434,6 +3518,37 @@ var ts; } } ts.forEachReturnStatement = forEachReturnStatement; + function forEachYieldExpression(body, visitor) { + return traverse(body); + function traverse(node) { + switch (node.kind) { + case 173: + visitor(node); + var operand = node.expression; + if (operand) { + traverse(operand); + } + case 205: + case 203: + case 206: + case 204: + case 202: + return; + default: + if (isFunctionLike(node)) { + var name_3 = node.name; + if (name_3 && name_3.kind === 128) { + traverse(name_3.expression); + return; + } + } + else if (!isTypeNode(node)) { + ts.forEachChild(node, traverse); + } + } + } + } + ts.forEachYieldExpression = forEachYieldExpression; function isVariableLike(node) { if (node) { switch (node.kind) { @@ -3462,6 +3577,12 @@ var ts; return false; } ts.isAccessor = isAccessor; + function isClassLike(node) { + if (node) { + return node.kind === 202 || node.kind === 175; + } + } + ts.isClassLike = isClassLike; function isFunctionLike(node) { if (node) { switch (node.kind) { @@ -3678,6 +3799,7 @@ var ts; case 172: case 10: case 176: + case 173: return true; case 127: while (node.parent.kind === 127) { @@ -3690,8 +3812,8 @@ var ts; } case 7: case 8: - var parent_1 = node.parent; - switch (parent_1.kind) { + var parent_2 = node.parent; + switch (parent_2.kind) { case 199: case 130: case 133: @@ -3699,7 +3821,7 @@ var ts; case 227: case 225: case 153: - return parent_1.initializer === node; + return parent_2.initializer === node; case 183: case 184: case 185: @@ -3710,27 +3832,27 @@ var ts; case 221: case 196: case 194: - return parent_1.expression === node; + return parent_2.expression === node; case 187: - var forStatement = parent_1; + var forStatement = parent_2; return (forStatement.initializer === node && forStatement.initializer.kind !== 200) || forStatement.condition === node || forStatement.incrementor === node; case 188: case 189: - var forInStatement = parent_1; + var forInStatement = parent_2; return (forInStatement.initializer === node && forInStatement.initializer.kind !== 200) || forInStatement.expression === node; case 161: - return node === parent_1.expression; + return node === parent_2.expression; case 178: - return node === parent_1.expression; + return node === parent_2.expression; case 128: - return node === parent_1.expression; + return node === parent_2.expression; case 131: return true; default: - if (isExpression(parent_1)) { + if (isExpression(parent_2)) { return true; } } @@ -3798,6 +3920,72 @@ var ts; return s.parameters.length > 0 && ts.lastOrUndefined(s.parameters).dotDotDotToken !== undefined; } ts.hasRestParameters = hasRestParameters; + function isJSDocConstructSignature(node) { + return node.kind === 241 && + node.parameters.length > 0 && + node.parameters[0].type.kind === 243; + } + ts.isJSDocConstructSignature = isJSDocConstructSignature; + function getJSDocTag(node, kind) { + if (node && node.jsDocComment) { + for (var _i = 0, _a = node.jsDocComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.kind === kind) { + return tag; + } + } + } + } + function getJSDocTypeTag(node) { + return getJSDocTag(node, 249); + } + ts.getJSDocTypeTag = getJSDocTypeTag; + function getJSDocReturnTag(node) { + return getJSDocTag(node, 248); + } + ts.getJSDocReturnTag = getJSDocReturnTag; + function getJSDocTemplateTag(node) { + return getJSDocTag(node, 250); + } + ts.getJSDocTemplateTag = getJSDocTemplateTag; + function getCorrespondingJSDocParameterTag(parameter) { + if (parameter.name && parameter.name.kind === 65) { + var parameterName = parameter.name.text; + var docComment = parameter.parent.jsDocComment; + if (docComment) { + return ts.forEach(docComment.tags, function (t) { + if (t.kind === 247) { + var parameterTag = t; + var name_4 = parameterTag.preParameterName || parameterTag.postParameterName; + if (name_4.text === parameterName) { + return t; + } + } + }); + } + } + } + ts.getCorrespondingJSDocParameterTag = getCorrespondingJSDocParameterTag; + function hasRestParameter(s) { + return isRestParameter(ts.lastOrUndefined(s.parameters)); + } + ts.hasRestParameter = hasRestParameter; + function isRestParameter(node) { + if (node) { + if (node.parserContextFlags & 64) { + if (node.type && node.type.kind === 242) { + return true; + } + var paramTag = getCorrespondingJSDocParameterTag(node); + if (paramTag && paramTag.typeExpression) { + return paramTag.typeExpression.type.kind === 242; + } + } + return node.dotDotDotToken !== undefined; + } + return false; + } + ts.isRestParameter = isRestParameter; function isLiteralKind(kind) { return 7 <= kind && kind <= 10; } @@ -4521,6 +4709,10 @@ var ts; return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & 256) ? symbol.valueDeclaration.localSymbol : undefined; } ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault; + function isJavaScript(fileName) { + return ts.fileExtensionIs(fileName, ".js"); + } + ts.isJavaScript = isJavaScript; function getExpandedCharCodes(input) { var output = []; var length = input.length; @@ -4691,12 +4883,23 @@ var ts; return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), newEndN - oldStartN); } ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions; + function getTypeParameterOwner(d) { + if (d && d.kind === 129) { + for (var current = d; current; current = current.parent) { + if (ts.isFunctionLike(current) || ts.isClassLike(current) || current.kind === 203) { + return current; + } + } + } + } + ts.getTypeParameterOwner = getTypeParameterOwner; })(ts || (ts = {})); /// /// var ts; (function (ts) { - var nodeConstructors = new Array(230); + ts.throwOnJSDocErrors = false; + var nodeConstructors = new Array(252); ts.parseTime = 0; function getNodeConstructor(kind) { return nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind)); @@ -4999,6 +5202,49 @@ var ts; return visitNode(cbNode, node.expression); case 219: return visitNodes(cbNodes, node.decorators); + case 229: + return visitNode(cbNode, node.type); + case 233: + return visitNodes(cbNodes, node.types); + case 234: + return visitNodes(cbNodes, node.types); + case 232: + return visitNode(cbNode, node.elementType); + case 236: + return visitNode(cbNode, node.type); + case 235: + return visitNode(cbNode, node.type); + case 237: + return visitNodes(cbNodes, node.members); + case 239: + return visitNode(cbNode, node.name) || + visitNodes(cbNodes, node.typeArguments); + case 240: + return visitNode(cbNode, node.type); + case 241: + return visitNodes(cbNodes, node.parameters) || + visitNode(cbNode, node.type); + case 242: + return visitNode(cbNode, node.type); + case 243: + return visitNode(cbNode, node.type); + case 244: + return visitNode(cbNode, node.type); + case 238: + return visitNode(cbNode, node.name) || + visitNode(cbNode, node.type); + case 245: + return visitNodes(cbNodes, node.tags); + case 247: + return visitNode(cbNode, node.preParameterName) || + visitNode(cbNode, node.typeExpression) || + visitNode(cbNode, node.postParameterName); + case 248: + return visitNode(cbNode, node.typeExpression); + case 249: + return visitNode(cbNode, node.typeExpression); + case 250: + return visitNodes(cbNodes, node.typeParameters); } } ts.forEachChild = forEachChild; @@ -5014,11 +5260,20 @@ var ts; return IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); } ts.updateSourceFile = updateSourceFile; + function parseIsolatedJSDocComment(content, start, length) { + return Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length); + } + ts.parseIsolatedJSDocComment = parseIsolatedJSDocComment; + function parseJSDocTypeExpressionForTests(content, start, length) { + return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length); + } + ts.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests; var Parser; (function (Parser) { var scanner = ts.createScanner(2, true); var disallowInAndDecoratorContext = 2 | 16; var sourceFile; + var parseDiagnostics; var syntaxCursor; var token; var sourceText; @@ -5026,21 +5281,40 @@ var ts; var identifiers; var identifierCount; var parsingContext; - var contextFlags = 0; + var contextFlags; var parseErrorBeforeNextFinishedNode = false; function parseSourceFile(fileName, _sourceText, languageVersion, _syntaxCursor, setParentNodes) { + initializeState(fileName, _sourceText, languageVersion, _syntaxCursor); + var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes); + clearState(); + return result; + } + Parser.parseSourceFile = parseSourceFile; + function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor) { sourceText = _sourceText; syntaxCursor = _syntaxCursor; + parseDiagnostics = []; parsingContext = 0; identifiers = {}; identifierCount = 0; nodeCount = 0; - contextFlags = 0; + contextFlags = ts.isJavaScript(fileName) ? 64 : 0; parseErrorBeforeNextFinishedNode = false; - createSourceFile(fileName, languageVersion); scanner.setText(sourceText); scanner.setOnError(scanError); scanner.setScriptTarget(languageVersion); + } + function clearState() { + scanner.setText(""); + scanner.setOnError(undefined); + parseDiagnostics = undefined; + sourceFile = undefined; + identifiers = undefined; + syntaxCursor = undefined; + sourceText = undefined; + } + function parseSourceFileWorker(fileName, languageVersion, setParentNodes) { + sourceFile = createSourceFile(fileName, languageVersion); token = nextToken(); processReferenceComments(sourceFile); sourceFile.statements = parseList(0, true, parseSourceElement); @@ -5050,20 +5324,40 @@ var ts; sourceFile.nodeCount = nodeCount; sourceFile.identifierCount = identifierCount; sourceFile.identifiers = identifiers; + sourceFile.parseDiagnostics = parseDiagnostics; if (setParentNodes) { fixupParentReferences(sourceFile); } - syntaxCursor = undefined; - scanner.setText(""); - scanner.setOnError(undefined); - var result = sourceFile; - sourceFile = undefined; - identifiers = undefined; - syntaxCursor = undefined; - sourceText = undefined; - return result; + if (ts.isJavaScript(fileName)) { + addJSDocComments(); + } + return sourceFile; + } + function addJSDocComments() { + forEachChild(sourceFile, visit); + return; + function visit(node) { + switch (node.kind) { + case 181: + case 201: + case 130: + addJSDocComment(node); + } + forEachChild(node, visit); + } + } + function addJSDocComment(node) { + var comments = ts.getLeadingCommentRangesOfNode(node, sourceFile); + if (comments) { + for (var _i = 0; _i < comments.length; _i++) { + var comment = comments[_i]; + var jsDocComment = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); + if (jsDocComment) { + node.jsDocComment = jsDocComment; + } + } + } } - Parser.parseSourceFile = parseSourceFile; function fixupParentReferences(sourceFile) { // normally parent references are set during binding. However, for clients that only need // a syntax tree, and no semantic features, then the binding process is an unnecessary @@ -5082,16 +5376,17 @@ var ts; } } } + Parser.fixupParentReferences = fixupParentReferences; function createSourceFile(fileName, languageVersion) { - sourceFile = createNode(228, 0); + var sourceFile = createNode(228, 0); sourceFile.pos = 0; sourceFile.end = sourceText.length; sourceFile.text = sourceText; - sourceFile.parseDiagnostics = []; sourceFile.bindDiagnostics = []; sourceFile.languageVersion = languageVersion; sourceFile.fileName = ts.normalizePath(fileName); sourceFile.flags = ts.fileExtensionIs(sourceFile.fileName, ".d.ts") ? 2048 : 0; + return sourceFile; } function setContextFlag(val, flag) { if (val) { @@ -5192,9 +5487,9 @@ var ts; parseErrorAtPosition(start, length, message, arg0); } function parseErrorAtPosition(start, length, message, arg0) { - var lastError = ts.lastOrUndefined(sourceFile.parseDiagnostics); + var lastError = ts.lastOrUndefined(parseDiagnostics); if (!lastError || start !== lastError.start) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0)); } parseErrorBeforeNextFinishedNode = true; } @@ -5225,7 +5520,7 @@ var ts; } function speculationHelper(callback, isLookAhead) { var saveToken = token; - var saveParseDiagnosticsLength = sourceFile.parseDiagnostics.length; + var saveParseDiagnosticsLength = parseDiagnostics.length; var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; var saveContextFlags = contextFlags; var result = isLookAhead @@ -5234,7 +5529,7 @@ var ts; ts.Debug.assert(saveContextFlags === contextFlags); if (!result || isLookAhead) { token = saveToken; - sourceFile.parseDiagnostics.length = saveParseDiagnosticsLength; + parseDiagnostics.length = saveParseDiagnosticsLength; parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; } return result; @@ -5316,8 +5611,8 @@ var ts; node.end = pos; return node; } - function finishNode(node) { - node.end = scanner.getStartPos(); + function finishNode(node, end) { + node.end = end === undefined ? scanner.getStartPos() : end; if (contextFlags) { node.parserContextFlags = contextFlags; } @@ -5366,15 +5661,24 @@ var ts; token === 8 || token === 7; } - function parsePropertyName() { + function parsePropertyNameWorker(allowComputedPropertyNames) { if (token === 8 || token === 7) { return parseLiteralNode(true); } - if (token === 18) { + if (allowComputedPropertyNames && token === 18) { return parseComputedPropertyName(); } return parseIdentifierName(); } + function parsePropertyName() { + return parsePropertyNameWorker(true); + } + function parseSimplePropertyName() { + return parsePropertyNameWorker(false); + } + function isSimplePropertyName() { + return token === 8 || token === 7 || isIdentifierOrKeyword(); + } function parseComputedPropertyName() { var node = createNode(128); parseExpected(18); @@ -5430,10 +5734,10 @@ var ts; switch (parsingContext) { case 0: case 1: - return isSourceElement(inErrorRecovery); + return !(token === 22 && inErrorRecovery) && isStartOfModuleElement(); case 2: case 4: - return isStartOfStatement(inErrorRecovery); + return !(token === 22 && inErrorRecovery) && isStartOfStatement(); case 3: return token === 67 || token === 73; case 5: @@ -5474,6 +5778,12 @@ var ts; return isHeritageClause(); case 20: return isIdentifierOrKeyword(); + case 21: + case 22: + case 24: + return JSDocParser.isJSDocType(); + case 23: + return isSimplePropertyName(); } ts.Debug.fail("Non-exhaustive case in 'isListElement'."); } @@ -5535,6 +5845,14 @@ var ts; return token === 25 || token === 16; case 19: return token === 14 || token === 15; + case 21: + return token === 17 || token === 51 || token === 15; + case 22: + return token === 25 || token === 15; + case 24: + return token === 19 || token === 15; + case 23: + return token === 15; } } function isVariableDeclaratorListTerminator() { @@ -5550,7 +5868,7 @@ var ts; return false; } function isInSomeParsingContext() { - for (var kind = 0; kind < 21; kind++) { + for (var kind = 0; kind < 25; kind++) { if (parsingContext & (1 << kind)) { if (isListElement(kind, true) || isListTerminator(kind)) { return true; @@ -5571,7 +5889,7 @@ var ts; result.push(element); if (checkForStrictMode && !inStrictModeContext()) { if (ts.isPrologueDirective(element)) { - if (isUseStrictPrologueDirective(sourceFile, element)) { + if (isUseStrictPrologueDirective(element)) { setStrictModeContext(true); checkForStrictMode = false; } @@ -5591,9 +5909,9 @@ var ts; parsingContext = saveParsingContext; return result; } - function isUseStrictPrologueDirective(sourceFile, node) { + function isUseStrictPrologueDirective(node) { ts.Debug.assert(ts.isPrologueDirective(node)); - var nodeText = ts.getSourceTextOfNodeFromSourceFile(sourceFile, node.expression); + var nodeText = ts.getTextOfNodeFromSourceText(sourceText, node.expression); return nodeText === '"use strict"' || nodeText === "'use strict'"; } function parseListElement(parsingContext, parseElement) { @@ -5794,6 +6112,10 @@ var ts; case 18: return ts.Diagnostics.Type_expected; case 19: return ts.Diagnostics.Unexpected_token_expected; case 20: return ts.Diagnostics.Identifier_expected; + case 21: return ts.Diagnostics.Parameter_declaration_expected; + case 22: return ts.Diagnostics.Type_argument_expected; + case 24: return ts.Diagnostics.Type_expected; + case 23: return ts.Diagnostics.Property_assignment_expected; } } ; @@ -6442,11 +6764,6 @@ var ts; nextToken(); return !scanner.hasPrecedingLineBreak() && isIdentifier(); } - function nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine() { - nextToken(); - return !scanner.hasPrecedingLineBreak() && - (isIdentifier() || token === 14 || token === 18); - } function parseYieldExpression() { var node = createNode(173); nextToken(); @@ -6555,10 +6872,11 @@ var ts; if (token === 14) { return parseFunctionBlock(false, false); } - if (isStartOfStatement(true) && - !isStartOfExpressionStatement() && + if (token !== 22 && token !== 83 && - token !== 69) { + token !== 69 && + isStartOfStatement() && + !isStartOfExpressionStatement()) { return parseFunctionBlock(false, true); } return parseAssignmentExpressionOrHigher(); @@ -7201,21 +7519,68 @@ var ts; return finishNode(expressionStatement); } } - function isStartOfStatement(inErrorRecovery) { - if (ts.isModifier(token)) { - var result = lookAhead(parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers); - if (result) { - return true; + function isIdentifierOrKeyword() { + return token >= 65; + } + function nextTokenIsIdentifierOrKeywordOnSameLine() { + nextToken(); + return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak(); + } + function parseDeclarationFlags() { + while (true) { + switch (token) { + case 98: + case 104: + case 70: + case 83: + case 69: + case 77: + return 1; + case 103: + case 124: + nextToken(); + return isIdentifierOrKeyword() ? 1 : 0; + case 117: + case 118: + nextToken(); + return isIdentifierOrKeyword() || token === 8 ? 2 : 0; + case 85: + nextToken(); + return token === 8 || token === 35 || + token === 14 || isIdentifierOrKeyword() ? + 2 : 0; + case 78: + nextToken(); + if (token === 53 || token === 35 || + token === 14 || token === 73) { + return 2; + } + continue; + case 115: + case 108: + case 106: + case 107: + case 109: + nextToken(); + continue; + default: + return 0; } } + } + function getDeclarationFlags() { + return lookAhead(parseDeclarationFlags); + } + function getStatementFlags() { switch (token) { + case 52: case 22: - return !inErrorRecovery; case 14: case 98: case 104: case 83: case 69: + case 77: case 84: case 75: case 100: @@ -7230,50 +7595,67 @@ var ts; case 72: case 68: case 81: - return true; + return 1; case 70: - var isConstEnum = lookAhead(nextTokenIsEnumKeyword); - return !isConstEnum; + case 78: + case 85: + return getDeclarationFlags(); + case 115: case 103: case 117: case 118: - case 77: case 124: - if (isDeclarationStart()) { - return false; - } + return getDeclarationFlags() || 1; case 108: case 106: case 107: case 109: - if (lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine)) { - return false; - } + return getDeclarationFlags() || + (lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? 0 : 1); default: - return isStartOfExpression(); + return isStartOfExpression() ? 1 : 0; } } - function nextTokenIsEnumKeyword() { - nextToken(); - return token === 77; + function isStartOfStatement() { + return (getStatementFlags() & 1) !== 0; } - function nextTokenIsIdentifierOrKeywordOnSameLine() { + function isStartOfModuleElement() { + return (getStatementFlags() & 3) !== 0; + } + function nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine() { nextToken(); - return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak(); + return !scanner.hasPrecedingLineBreak() && + (isIdentifier() || token === 14 || token === 18); + } + function isLetDeclaration() { + return inStrictModeContext() || lookAhead(nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine); } function parseStatement() { + return parseModuleElementOfKind(1); + } + function parseModuleElement() { + return parseModuleElementOfKind(3); + } + function parseSourceElement() { + return parseModuleElementOfKind(3); + } + function parseModuleElementOfKind(flags) { switch (token) { + case 22: + return parseEmptyStatement(); case 14: return parseBlock(false, false); case 98: - case 70: return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + case 104: + if (isLetDeclaration()) { + return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + } + break; case 83: return parseFunctionDeclaration(scanner.getStartPos(), undefined, undefined); case 69: return parseClassDeclaration(scanner.getStartPos(), undefined, undefined); - case 22: - return parseEmptyStatement(); case 84: return parseIfStatement(); case 75: @@ -7300,44 +7682,66 @@ var ts; return parseTryStatement(); case 72: return parseDebuggerStatement(); - case 104: - if (isLetDeclaration()) { - return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + case 52: + return parseDeclaration(); + case 70: + case 115: + case 77: + case 78: + case 85: + case 103: + case 117: + case 118: + case 106: + case 107: + case 108: + case 109: + case 124: + if (getDeclarationFlags() & flags) { + return parseDeclaration(); } - default: - if (ts.isModifier(token) || token === 52) { - var result = tryParse(parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers); - if (result) { - return result; - } - } - return parseExpressionOrLabeledStatement(); + break; } + return parseExpressionOrLabeledStatement(); } - function parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers() { - var start = scanner.getStartPos(); + function parseDeclaration() { + var fullStart = getNodePos(); var decorators = parseDecorators(); var modifiers = parseModifiers(); switch (token) { - case 70: - var nextTokenIsEnum = lookAhead(nextTokenIsEnumKeyword); - if (nextTokenIsEnum) { - return undefined; - } - return parseVariableStatement(start, decorators, modifiers); - case 104: - if (!isLetDeclaration()) { - return undefined; - } - return parseVariableStatement(start, decorators, modifiers); case 98: - return parseVariableStatement(start, decorators, modifiers); + case 104: + case 70: + return parseVariableStatement(fullStart, decorators, modifiers); case 83: - return parseFunctionDeclaration(start, decorators, modifiers); + return parseFunctionDeclaration(fullStart, decorators, modifiers); case 69: - return parseClassDeclaration(start, decorators, modifiers); + return parseClassDeclaration(fullStart, decorators, modifiers); + case 103: + return parseInterfaceDeclaration(fullStart, decorators, modifiers); + case 124: + return parseTypeAliasDeclaration(fullStart, decorators, modifiers); + case 77: + return parseEnumDeclaration(fullStart, decorators, modifiers); + case 117: + case 118: + return parseModuleDeclaration(fullStart, decorators, modifiers); + case 85: + return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers); + case 78: + nextToken(); + return token === 73 || token === 53 ? + parseExportAssignment(fullStart, decorators, modifiers) : + parseExportDeclaration(fullStart, decorators, modifiers); + default: + if (decorators) { + var node = createMissingNode(219, true, ts.Diagnostics.Declaration_expected); + node.pos = fullStart; + node.decorators = decorators; + setModifiers(node, modifiers); + return finishNode(node); + } } - return undefined; } function parseFunctionBlockOrSemicolon(isGenerator, diagnosticMessage) { if (token !== 14 && canParseSemicolon()) { @@ -7481,7 +7885,9 @@ var ts; property.name = name; property.questionToken = questionToken; property.type = parseTypeAnnotation(); - property.initializer = allowInAnd(parseNonParameterInitializer); + property.initializer = modifiers && modifiers.flags & 128 + ? allowInAnd(parseNonParameterInitializer) + : doOutsideOfContext(4 | 2, parseNonParameterInitializer); parseSemicolon(); return finishNode(property); } @@ -7627,8 +8033,8 @@ var ts; return parsePropertyOrMethodDeclaration(fullStart, decorators, modifiers); } if (decorators) { - var name_3 = createMissingNode(65, true, ts.Diagnostics.Declaration_expected); - return parsePropertyDeclaration(fullStart, decorators, modifiers, name_3, undefined); + var name_5 = createMissingNode(65, true, ts.Diagnostics.Declaration_expected); + return parsePropertyDeclaration(fullStart, decorators, modifiers, name_5, undefined); } ts.Debug.fail("Should not have attempted to parse class member declaration."); } @@ -7935,125 +8341,6 @@ var ts; parseSemicolon(); return finishNode(node); } - function isLetDeclaration() { - return inStrictModeContext() || lookAhead(nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine); - } - function isDeclarationStart(followsModifier) { - switch (token) { - case 98: - case 70: - case 83: - return true; - case 104: - return isLetDeclaration(); - case 69: - case 103: - case 77: - case 124: - return lookAhead(nextTokenIsIdentifierOrKeyword); - case 85: - return lookAhead(nextTokenCanFollowImportKeyword); - case 117: - case 118: - return lookAhead(nextTokenIsIdentifierOrKeywordOrStringLiteral); - case 78: - return lookAhead(nextTokenCanFollowExportKeyword); - case 115: - case 108: - case 106: - case 107: - case 109: - return lookAhead(nextTokenIsDeclarationStart); - case 52: - return !followsModifier; - } - } - function isIdentifierOrKeyword() { - return token >= 65; - } - function nextTokenIsIdentifierOrKeyword() { - nextToken(); - return isIdentifierOrKeyword(); - } - function nextTokenIsIdentifierOrKeywordOrStringLiteral() { - nextToken(); - return isIdentifierOrKeyword() || token === 8; - } - function nextTokenCanFollowImportKeyword() { - nextToken(); - return isIdentifierOrKeyword() || token === 8 || - token === 35 || token === 14; - } - function nextTokenCanFollowExportKeyword() { - nextToken(); - return token === 53 || token === 35 || - token === 14 || token === 73 || isDeclarationStart(true); - } - function nextTokenIsDeclarationStart() { - nextToken(); - return isDeclarationStart(true); - } - function nextTokenIsAsKeyword() { - return nextToken() === 111; - } - function parseDeclaration() { - var fullStart = getNodePos(); - var decorators = parseDecorators(); - var modifiers = parseModifiers(); - if (token === 78) { - nextToken(); - if (token === 73 || token === 53) { - return parseExportAssignment(fullStart, decorators, modifiers); - } - if (token === 35 || token === 14) { - return parseExportDeclaration(fullStart, decorators, modifiers); - } - } - switch (token) { - case 98: - case 104: - case 70: - return parseVariableStatement(fullStart, decorators, modifiers); - case 83: - return parseFunctionDeclaration(fullStart, decorators, modifiers); - case 69: - return parseClassDeclaration(fullStart, decorators, modifiers); - case 103: - return parseInterfaceDeclaration(fullStart, decorators, modifiers); - case 124: - return parseTypeAliasDeclaration(fullStart, decorators, modifiers); - case 77: - return parseEnumDeclaration(fullStart, decorators, modifiers); - case 117: - case 118: - return parseModuleDeclaration(fullStart, decorators, modifiers); - case 85: - return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers); - default: - if (decorators) { - var node = createMissingNode(219, true, ts.Diagnostics.Declaration_expected); - node.pos = fullStart; - node.decorators = decorators; - setModifiers(node, modifiers); - return finishNode(node); - } - ts.Debug.fail("Mismatch between isDeclarationStart and parseDeclaration"); - } - } - function isSourceElement(inErrorRecovery) { - return isDeclarationStart() || isStartOfStatement(inErrorRecovery); - } - function parseSourceElement() { - return parseSourceElementOrModuleElement(); - } - function parseModuleElement() { - return parseSourceElementOrModuleElement(); - } - function parseSourceElementOrModuleElement() { - return isDeclarationStart() - ? parseDeclaration() - : parseStatement(); - } function processReferenceComments(sourceFile) { var triviaScanner = ts.createScanner(sourceFile.languageVersion, false, sourceText); var referencedFiles = []; @@ -8078,7 +8365,7 @@ var ts; referencedFiles.push(fileReference); } if (diagnosticMessage) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); } } else { @@ -8086,7 +8373,7 @@ var ts; var amdModuleNameMatchResult = amdModuleNameRegEx.exec(comment); if (amdModuleNameMatchResult) { if (amdModuleName) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); } amdModuleName = amdModuleNameMatchResult[2]; } @@ -8119,6 +8406,520 @@ var ts; : undefined; }); } + var JSDocParser; + (function (JSDocParser) { + function isJSDocType() { + switch (token) { + case 35: + case 50: + case 16: + case 18: + case 46: + case 14: + case 83: + case 21: + case 88: + case 93: + return true; + } + return isIdentifierOrKeyword(); + } + JSDocParser.isJSDocType = isJSDocType; + function parseJSDocTypeExpressionForTests(content, start, length) { + initializeState("file.js", content, 2, undefined); + var jsDocTypeExpression = parseJSDocTypeExpression(start, length); + var diagnostics = parseDiagnostics; + clearState(); + return jsDocTypeExpression ? { jsDocTypeExpression: jsDocTypeExpression, diagnostics: diagnostics } : undefined; + } + JSDocParser.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests; + function parseJSDocTypeExpression(start, length) { + scanner.setText(sourceText, start, length); + token = nextToken(); + var result = createNode(229); + parseExpected(14); + result.type = parseJSDocTopLevelType(); + parseExpected(15); + fixupParentReferences(result); + return finishNode(result); + } + JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression; + function setError(message) { + parseErrorAtCurrentToken(message); + if (ts.throwOnJSDocErrors) { + throw new Error(message.key); + } + } + function parseJSDocTopLevelType() { + var type = parseJSDocType(); + if (token === 44) { + var unionType = createNode(233, type.pos); + unionType.types = parseJSDocTypeList(type); + type = finishNode(unionType); + } + if (token === 53) { + var optionalType = createNode(240, type.pos); + nextToken(); + optionalType.type = type; + type = finishNode(optionalType); + } + return type; + } + function parseJSDocType() { + var type = parseBasicTypeExpression(); + while (true) { + if (token === 18) { + var arrayType = createNode(232, type.pos); + arrayType.elementType = type; + nextToken(); + parseExpected(19); + type = finishNode(arrayType); + } + else if (token === 50) { + var nullableType = createNode(235, type.pos); + nullableType.type = type; + nextToken(); + type = finishNode(nullableType); + } + else if (token === 46) { + var nonNullableType = createNode(236, type.pos); + nonNullableType.type = type; + nextToken(); + type = finishNode(nonNullableType); + } + else { + break; + } + } + return type; + } + function parseBasicTypeExpression() { + switch (token) { + case 35: + return parseJSDocAllType(); + case 50: + return parseJSDocUnknownOrNullableType(); + case 16: + return parseJSDocUnionType(); + case 18: + return parseJSDocTupleType(); + case 46: + return parseJSDocNonNullableType(); + case 14: + return parseJSDocRecordType(); + case 83: + return parseJSDocFunctionType(); + case 21: + return parseJSDocVariadicType(); + case 88: + return parseJSDocConstructorType(); + case 93: + return parseJSDocThisType(); + case 112: + case 122: + case 120: + case 113: + case 123: + case 99: + return parseTokenNode(); + } + return parseJSDocTypeReference(); + } + function parseJSDocThisType() { + var result = createNode(244); + nextToken(); + parseExpected(51); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocConstructorType() { + var result = createNode(243); + nextToken(); + parseExpected(51); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocVariadicType() { + var result = createNode(242); + nextToken(); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocFunctionType() { + var result = createNode(241); + nextToken(); + parseExpected(16); + result.parameters = parseDelimitedList(21, parseJSDocParameter); + checkForTrailingComma(result.parameters); + parseExpected(17); + if (token === 51) { + nextToken(); + result.type = parseJSDocType(); + } + return finishNode(result); + } + function parseJSDocParameter() { + var parameter = createNode(130); + parameter.type = parseJSDocType(); + return finishNode(parameter); + } + function parseJSDocOptionalType(type) { + var result = createNode(240, type.pos); + nextToken(); + result.type = type; + return finishNode(result); + } + function parseJSDocTypeReference() { + var result = createNode(239); + result.name = parseSimplePropertyName(); + while (parseOptional(20)) { + if (token === 24) { + result.typeArguments = parseTypeArguments(); + break; + } + else { + result.name = parseQualifiedName(result.name); + } + } + return finishNode(result); + } + function parseTypeArguments() { + nextToken(); + var typeArguments = parseDelimitedList(22, parseJSDocType); + checkForTrailingComma(typeArguments); + checkForEmptyTypeArgumentList(typeArguments); + parseExpected(25); + return typeArguments; + } + function checkForEmptyTypeArgumentList(typeArguments) { + if (parseDiagnostics.length === 0 && typeArguments && typeArguments.length === 0) { + var start = typeArguments.pos - "<".length; + var end = ts.skipTrivia(sourceText, typeArguments.end) + ">".length; + return parseErrorAtPosition(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty); + } + } + function parseQualifiedName(left) { + var result = createNode(127, left.pos); + result.left = left; + result.right = parseIdentifierName(); + return finishNode(result); + } + function parseJSDocRecordType() { + var result = createNode(237); + nextToken(); + result.members = parseDelimitedList(23, parseJSDocRecordMember); + checkForTrailingComma(result.members); + parseExpected(15); + return finishNode(result); + } + function parseJSDocRecordMember() { + var result = createNode(238); + result.name = parseSimplePropertyName(); + if (token === 51) { + nextToken(); + result.type = parseJSDocType(); + } + return finishNode(result); + } + function parseJSDocNonNullableType() { + var result = createNode(236); + nextToken(); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocTupleType() { + var result = createNode(234); + nextToken(); + result.types = parseDelimitedList(24, parseJSDocType); + checkForTrailingComma(result.types); + parseExpected(19); + return finishNode(result); + } + function checkForTrailingComma(list) { + if (parseDiagnostics.length === 0 && list.hasTrailingComma) { + var start = list.end - ",".length; + parseErrorAtPosition(start, ",".length, ts.Diagnostics.Trailing_comma_not_allowed); + } + } + function parseJSDocUnionType() { + var result = createNode(233); + nextToken(); + result.types = parseJSDocTypeList(parseJSDocType()); + parseExpected(17); + return finishNode(result); + } + function parseJSDocTypeList(firstType) { + ts.Debug.assert(!!firstType); + var types = []; + types.pos = firstType.pos; + types.push(firstType); + while (parseOptional(44)) { + types.push(parseJSDocType()); + } + types.end = scanner.getStartPos(); + return types; + } + function parseJSDocAllType() { + var result = createNode(230); + nextToken(); + return finishNode(result); + } + function parseJSDocUnknownOrNullableType() { + var pos = scanner.getStartPos(); + nextToken(); + if (token === 23 || + token === 15 || + token === 17 || + token === 25 || + token === 53 || + token === 44) { + var result = createNode(231, pos); + return finishNode(result); + } + else { + var result = createNode(235, pos); + result.type = parseJSDocType(); + return finishNode(result); + } + } + function parseIsolatedJSDocComment(content, start, length) { + initializeState("file.js", content, 2, undefined); + var jsDocComment = parseJSDocComment(undefined, start, length); + var diagnostics = parseDiagnostics; + clearState(); + return jsDocComment ? { jsDocComment: jsDocComment, diagnostics: diagnostics } : undefined; + } + JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment; + function parseJSDocComment(parent, start, length) { + var comment = parseJSDocCommentWorker(start, length); + if (comment) { + fixupParentReferences(comment); + comment.parent = parent; + } + return comment; + } + JSDocParser.parseJSDocComment = parseJSDocComment; + function parseJSDocCommentWorker(start, length) { + var content = sourceText; + start = start || 0; + var end = length === undefined ? content.length : start + length; + length = end - start; + ts.Debug.assert(start >= 0); + ts.Debug.assert(start <= end); + ts.Debug.assert(end <= content.length); + var tags; + var pos; + if (length >= "/** */".length) { + if (content.charCodeAt(start) === 47 && + content.charCodeAt(start + 1) === 42 && + content.charCodeAt(start + 2) === 42 && + content.charCodeAt(start + 3) !== 42) { + var canParseTag = true; + var seenAsterisk = true; + for (pos = start + "/**".length; pos < end;) { + var ch = content.charCodeAt(pos); + pos++; + if (ch === 64 && canParseTag) { + parseTag(); + canParseTag = false; + continue; + } + if (ts.isLineBreak(ch)) { + canParseTag = true; + seenAsterisk = false; + continue; + } + if (ts.isWhiteSpace(ch)) { + continue; + } + if (ch === 42) { + if (seenAsterisk) { + canParseTag = false; + } + seenAsterisk = true; + continue; + } + canParseTag = false; + } + } + } + return createJSDocComment(); + function createJSDocComment() { + if (!tags) { + return undefined; + } + var result = createNode(245, start); + result.tags = tags; + return finishNode(result, end); + } + function skipWhitespace() { + while (pos < end && ts.isWhiteSpace(content.charCodeAt(pos))) { + pos++; + } + } + function parseTag() { + ts.Debug.assert(content.charCodeAt(pos - 1) === 64); + var atToken = createNode(52, pos - 1); + atToken.end = pos; + var startPos = pos; + var tagName = scanIdentifier(); + if (!tagName) { + return; + } + var tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName); + addTag(tag); + } + function handleTag(atToken, tagName) { + if (tagName) { + switch (tagName.text) { + case "param": + return handleParamTag(atToken, tagName); + case "return": + case "returns": + return handleReturnTag(atToken, tagName); + case "template": + return handleTemplateTag(atToken, tagName); + case "type": + return handleTypeTag(atToken, tagName); + } + } + return undefined; + } + function handleUnknownTag(atToken, tagName) { + var result = createNode(246, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + return finishNode(result, pos); + } + function addTag(tag) { + if (tag) { + if (!tags) { + tags = []; + tags.pos = tag.pos; + } + tags.push(tag); + tags.end = tag.end; + } + } + function tryParseTypeExpression() { + skipWhitespace(); + if (content.charCodeAt(pos) !== 123) { + return undefined; + } + var typeExpression = parseJSDocTypeExpression(pos, end - pos); + pos = typeExpression.end; + return typeExpression; + } + function handleParamTag(atToken, tagName) { + var typeExpression = tryParseTypeExpression(); + skipWhitespace(); + var name; + var isBracketed; + if (content.charCodeAt(pos) === 91) { + pos++; + skipWhitespace(); + name = scanIdentifier(); + isBracketed = true; + } + else { + name = scanIdentifier(); + } + if (!name) { + parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); + return undefined; + } + var preName, postName; + if (typeExpression) { + postName = name; + } + else { + preName = name; + } + if (!typeExpression) { + typeExpression = tryParseTypeExpression(); + } + var result = createNode(247, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.preParameterName = preName; + result.typeExpression = typeExpression; + result.postParameterName = postName; + result.isBracketed = isBracketed; + return finishNode(result, pos); + } + function handleReturnTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 248; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var result = createNode(248, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeExpression = tryParseTypeExpression(); + return finishNode(result, pos); + } + function handleTypeTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 249; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var result = createNode(249, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeExpression = tryParseTypeExpression(); + return finishNode(result, pos); + } + function handleTemplateTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 250; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var typeParameters = []; + typeParameters.pos = pos; + while (true) { + skipWhitespace(); + var startPos = pos; + var name_6 = scanIdentifier(); + if (!name_6) { + parseErrorAtPosition(startPos, 0, ts.Diagnostics.Identifier_expected); + return undefined; + } + var typeParameter = createNode(129, name_6.pos); + typeParameter.name = name_6; + finishNode(typeParameter, pos); + typeParameters.push(typeParameter); + skipWhitespace(); + if (content.charCodeAt(pos) !== 44) { + break; + } + pos++; + } + typeParameters.end = pos; + var result = createNode(250, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeParameters = typeParameters; + return finishNode(result, pos); + } + function scanIdentifier() { + var startPos = pos; + for (; pos < end; pos++) { + var ch = content.charCodeAt(pos); + if (pos === startPos && ts.isIdentifierStart(ch, 2)) { + continue; + } + else if (pos > startPos && ts.isIdentifierPart(ch, 2)) { + continue; + } + break; + } + if (startPos === pos) { + return undefined; + } + var result = createNode(65, startPos); + result.text = content.substring(startPos, pos); + return finishNode(result, pos); + } + } + JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker; + })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {})); })(Parser || (Parser = {})); var IncrementalParser; (function (IncrementalParser) { @@ -8159,7 +8960,12 @@ var ts; if (aggressiveChecks && shouldCheckNode(node)) { var text = oldText.substring(node.pos, node.end); } - node._children = undefined; + if (node._children) { + node._children = undefined; + } + if (node.jsDocComment) { + node.jsDocComment = undefined; + } node.pos += delta; node.end += delta; if (aggressiveChecks && shouldCheckNode(node)) { @@ -8820,17 +9626,17 @@ var ts; bindBlockScopedDeclaration(node, 32, 899583); break; case 203: - bindDeclaration(node, 64, 792992, false); + bindBlockScopedDeclaration(node, 64, 792992); break; case 204: - bindDeclaration(node, 524288, 793056, false); + bindBlockScopedDeclaration(node, 524288, 793056); break; case 205: if (ts.isConst(node)) { - bindDeclaration(node, 128, 899967, false); + bindBlockScopedDeclaration(node, 128, 899967); } else { - bindDeclaration(node, 256, 899327, false); + bindBlockScopedDeclaration(node, 256, 899327); } break; case 206: @@ -8991,13 +9797,15 @@ var ts; var undefinedType = createIntrinsicType(32 | 262144, "undefined"); var nullType = createIntrinsicType(64 | 262144, "null"); var unknownType = createIntrinsicType(1, "unknown"); + var circularType = createIntrinsicType(1, "__circular__"); var emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + var emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + emptyGenericType.instantiations = {}; var anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); var noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); var anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, false, false); var unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false); var globals = {}; - var globalArraySymbol; var globalESSymbolConstructorSymbol; var globalObjectType; var globalFunctionType; @@ -9009,6 +9817,8 @@ var ts; var globalTemplateStringsArrayType; var globalESSymbolType; var globalIterableType; + var globalIteratorType; + var globalIterableIteratorType; var anyArrayType; var getGlobalClassDecoratorType; var getGlobalParameterDecoratorType; @@ -9225,7 +10035,13 @@ var ts; loop: while (location) { if (location.locals && !isGlobalSourceFile(location)) { if (result = getSymbol(location.locals, name, meaning)) { - break loop; + if (!(meaning & 793056) || + !(result.flags & (793056 & ~262144)) || + !ts.isFunctionLike(location) || + lastLocation === location.body) { + break loop; + } + result = undefined; } } switch (location.kind) { @@ -9457,15 +10273,15 @@ var ts; var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier); var targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier); if (targetSymbol) { - var name_4 = specifier.propertyName || specifier.name; - if (name_4.text) { - var symbolFromModule = getExportOfModule(targetSymbol, name_4.text); - var symbolFromVariable = getPropertyOfVariable(targetSymbol, name_4.text); + var name_7 = specifier.propertyName || specifier.name; + if (name_7.text) { + var symbolFromModule = getExportOfModule(targetSymbol, name_7.text); + var symbolFromVariable = getPropertyOfVariable(targetSymbol, name_7.text); var symbol = symbolFromModule && symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { - error(name_4, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name_4)); + error(name_7, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name_7)); } return symbol; } @@ -10113,17 +10929,46 @@ var ts; writeType(types[i], union ? 64 : 0); } } + function writeSymbolTypeReference(symbol, typeArguments, pos, end) { + if (!isReservedMemberName(symbol.name)) { + buildSymbolDisplay(symbol, writer, enclosingDeclaration, 793056); + } + if (pos < end) { + writePunctuation(writer, 24); + writeType(typeArguments[pos++], 0); + while (pos < end) { + writePunctuation(writer, 23); + writeSpace(writer); + writeType(typeArguments[pos++], 0); + } + writePunctuation(writer, 25); + } + } function writeTypeReference(type, flags) { + var typeArguments = type.typeArguments; if (type.target === globalArrayType && !(flags & 1)) { - writeType(type.typeArguments[0], 64); + writeType(typeArguments[0], 64); writePunctuation(writer, 18); writePunctuation(writer, 19); } else { - buildSymbolDisplay(type.target.symbol, writer, enclosingDeclaration, 793056); - writePunctuation(writer, 24); - writeTypeList(type.typeArguments, false); - writePunctuation(writer, 25); + var outerTypeParameters = type.target.outerTypeParameters; + var i = 0; + if (outerTypeParameters) { + var length_1 = outerTypeParameters.length; + while (i < length_1) { + var start = i; + var parent_3 = getParentSymbolOfTypeParameter(outerTypeParameters[i]); + do { + i++; + } while (i < length_1 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent_3); + if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) { + writeSymbolTypeReference(parent_3, typeArguments, start, i); + writePunctuation(writer, 20); + } + } + } + writeSymbolTypeReference(type.symbol, typeArguments, i, typeArguments.length); } } function writeTupleType(type) { @@ -10302,7 +11147,7 @@ var ts; function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); if (targetSymbol.flags & 32 || targetSymbol.flags & 64) { - buildDisplayForTypeParametersAndDelimiters(getTypeParametersOfClassOrInterface(symbol), writer, enclosingDeclaraiton, flags); + buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterface(symbol), writer, enclosingDeclaraiton, flags); } } function buildTypeParameterDisplay(tp, writer, enclosingDeclaration, flags, typeStack) { @@ -10465,12 +11310,12 @@ var ts; case 201: case 205: case 209: - var parent_2 = getDeclarationContainer(node); + var parent_4 = getDeclarationContainer(node); if (!(ts.getCombinedNodeFlags(node) & 1) && - !(node.kind !== 209 && parent_2.kind !== 228 && ts.isInAmbientContext(parent_2))) { - return isGlobalSourceFile(parent_2); + !(node.kind !== 209 && parent_4.kind !== 228 && ts.isInAmbientContext(parent_4))) { + return isGlobalSourceFile(parent_4); } - return isDeclarationVisible(parent_2); + return isDeclarationVisible(parent_4); case 133: case 132: case 137: @@ -10591,12 +11436,12 @@ var ts; } var type; if (pattern.kind === 151) { - var name_5 = declaration.propertyName || declaration.name; - type = getTypeOfPropertyOfType(parentType, name_5.text) || - isNumericLiteralName(name_5.text) && getIndexTypeOfType(parentType, 1) || + var name_8 = declaration.propertyName || declaration.name; + type = getTypeOfPropertyOfType(parentType, name_8.text) || + isNumericLiteralName(name_8.text) && getIndexTypeOfType(parentType, 1) || getIndexTypeOfType(parentType, 0); if (!type) { - error(name_5, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_5)); + error(name_8, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_8)); return unknownType; } } @@ -10874,26 +11719,55 @@ var ts; return target === checkBase || ts.forEach(getBaseTypes(target), check); } } - function getTypeParametersOfClassOrInterface(symbol) { - var result; - ts.forEach(symbol.declarations, function (node) { - if (node.kind === 203 || node.kind === 202) { - var declaration = node; - if (declaration.typeParameters && declaration.typeParameters.length) { - ts.forEach(declaration.typeParameters, function (node) { - var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node)); - if (!result) { - result = [tp]; - } - else if (!ts.contains(result, tp)) { - result.push(tp); - } - }); + function appendTypeParameters(typeParameters, declarations) { + for (var _i = 0; _i < declarations.length; _i++) { + var declaration = declarations[_i]; + var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); + if (!typeParameters) { + typeParameters = [tp]; + } + else if (!ts.contains(typeParameters, tp)) { + typeParameters.push(tp); + } + } + return typeParameters; + } + function appendOuterTypeParameters(typeParameters, node) { + while (true) { + node = node.parent; + if (!node) { + return typeParameters; + } + if (node.kind === 202 || node.kind === 201 || + node.kind === 163 || node.kind === 135 || + node.kind === 164) { + var declarations = node.typeParameters; + if (declarations) { + return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations); } } - }); + } + } + function getOuterTypeParametersOfClassOrInterface(symbol) { + var kind = symbol.flags & 32 ? 202 : 203; + return appendOuterTypeParameters(undefined, ts.getDeclarationOfKind(symbol, kind)); + } + function getLocalTypeParametersOfClassOrInterface(symbol) { + var result; + for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { + var node = _a[_i]; + if (node.kind === 203 || node.kind === 202) { + var declaration = node; + if (declaration.typeParameters) { + result = appendTypeParameters(result, declaration.typeParameters); + } + } + } return result; } + function getTypeParametersOfClassOrInterface(symbol) { + return ts.concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterface(symbol)); + } function getBaseTypes(type) { var typeWithBaseTypes = type; if (!typeWithBaseTypes.baseTypes) { @@ -10960,10 +11834,13 @@ var ts; if (!links.declaredType) { var kind = symbol.flags & 32 ? 1024 : 2048; var type = links.declaredType = createObjectType(kind, symbol); - var typeParameters = getTypeParametersOfClassOrInterface(symbol); - if (typeParameters) { + var outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol); + var localTypeParameters = getLocalTypeParametersOfClassOrInterface(symbol); + if (outerTypeParameters || localTypeParameters) { type.flags |= 4096; - type.typeParameters = typeParameters; + type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters); + type.outerTypeParameters = outerTypeParameters; + type.localTypeParameters = localTypeParameters; type.instantiations = {}; type.instantiations[getTypeListId(type.typeParameters)] = type; type.target = type; @@ -11139,12 +12016,12 @@ var ts; return ts.map(baseSignatures, function (baseSignature) { var signature = baseType.flags & 4096 ? getSignatureInstantiation(baseSignature, baseType.typeArguments) : cloneSignature(baseSignature); - signature.typeParameters = classType.typeParameters; + signature.typeParameters = classType.localTypeParameters; signature.resolvedReturnType = classType; return signature; }); } - return [createSignature(undefined, classType.typeParameters, emptyArray, classType, 0, false, false)]; + return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, 0, false, false)]; } function createTupleTypeMemberSymbols(memberTypes) { var members = {}; @@ -11450,7 +12327,7 @@ var ts; var links = getNodeLinks(declaration); if (!links.resolvedSignature) { var classType = declaration.kind === 136 ? getDeclaredTypeOfClassOrInterface(declaration.parent.symbol) : undefined; - var typeParameters = classType ? classType.typeParameters : + var typeParameters = classType ? classType.localTypeParameters : declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) : undefined; var parameters = []; var hasStringLiterals = false; @@ -11628,6 +12505,9 @@ var ts; } return type.constraint === noConstraintType ? undefined : type.constraint; } + function getParentSymbolOfTypeParameter(typeParameter) { + return getSymbolOfNode(ts.getDeclarationOfKind(typeParameter.symbol, 129).parent); + } function getTypeListId(types) { switch (types.length) { case 1: @@ -11714,12 +12594,16 @@ var ts; else { type = getDeclaredTypeOfSymbol(symbol); if (type.flags & (1024 | 2048) && type.flags & 4096) { - var typeParameters = type.typeParameters; - if (node.typeArguments && node.typeArguments.length === typeParameters.length) { - type = createTypeReference(type, ts.map(node.typeArguments, getTypeFromTypeNode)); + var localTypeParameters = type.localTypeParameters; + var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; + var typeArgCount = node.typeArguments ? node.typeArguments.length : 0; + if (typeArgCount === expectedTypeArgCount) { + if (typeArgCount) { + type = createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(node.typeArguments, getTypeFromTypeNode))); + } } else { - error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1), typeParameters.length); + error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1), expectedTypeArgCount); type = undefined; } } @@ -11757,16 +12641,16 @@ var ts; } } if (!symbol) { - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } var type = getDeclaredTypeOfSymbol(symbol); if (!(type.flags & 48128)) { error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, symbol.name); - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } if ((type.typeParameters ? type.typeParameters.length : 0) !== arity) { error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbol.name, arity); - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } return type; } @@ -11786,12 +12670,17 @@ var ts; function getGlobalESSymbolConstructorSymbol() { return globalESSymbolConstructorSymbol || (globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol")); } + function createTypeFromGenericGlobalType(genericGlobalType, elementType) { + return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, [elementType]) : emptyObjectType; + } function createIterableType(elementType) { - return globalIterableType !== emptyObjectType ? createTypeReference(globalIterableType, [elementType]) : emptyObjectType; + return createTypeFromGenericGlobalType(globalIterableType, elementType); + } + function createIterableIteratorType(elementType) { + return createTypeFromGenericGlobalType(globalIterableIteratorType, elementType); } function createArrayType(elementType) { - var arrayType = globalArrayType || getDeclaredTypeOfSymbol(globalArraySymbol); - return arrayType !== emptyObjectType ? createTypeReference(arrayType, [elementType]) : emptyObjectType; + return createTypeFromGenericGlobalType(globalArrayType, elementType); } function getTypeFromArrayTypeNode(node) { var links = getNodeLinks(node); @@ -11846,13 +12735,7 @@ var ts; } return false; } - var removeSubtypesStack = []; function removeSubtypes(types) { - var typeListId = getTypeListId(types); - if (removeSubtypesStack.lastIndexOf(typeListId) >= 0) { - return; - } - removeSubtypesStack.push(typeListId); var i = types.length; while (i > 0) { i--; @@ -11860,7 +12743,6 @@ var ts; types.splice(i, 1); } } - removeSubtypesStack.pop(); } function containsAnyType(types) { for (var _i = 0; _i < types.length; _i++) { @@ -11910,7 +12792,14 @@ var ts; } function getReducedTypeOfUnionType(type) { if (!type.reducedType) { - type.reducedType = getUnionType(type.types, false); + type.reducedType = circularType; + var reducedType = getUnionType(type.types, false); + if (type.reducedType === circularType) { + type.reducedType = reducedType; + } + } + else if (type.reducedType === circularType) { + type.reducedType = type; } return type.reducedType; } @@ -12094,6 +12983,15 @@ var ts; return result; } function instantiateAnonymousType(type, mapper) { + if (mapper.mappings) { + var cached = mapper.mappings[type.id]; + if (cached) { + return cached; + } + } + else { + mapper.mappings = {}; + } var result = createObjectType(32768, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); result.members = createSymbolTable(result.properties); @@ -12105,6 +13003,7 @@ var ts; result.stringIndexType = instantiateType(stringIndexType, mapper); if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper); + mapper.mappings[type.id] = result; return result; } function instantiateType(type, mapper) { @@ -12113,7 +13012,7 @@ var ts; return mapper(type); } if (type.flags & 32768) { - return type.symbol && type.symbol.flags & (16 | 8192 | 2048 | 4096) ? + return type.symbol && type.symbol.flags & (16 | 8192 | 32 | 2048 | 4096) ? instantiateAnonymousType(type, mapper) : type; } if (type.flags & 4096) { @@ -13290,10 +14189,10 @@ var ts; } function resolveLocation(node) { var containerNodes = []; - for (var parent_3 = node.parent; parent_3; parent_3 = parent_3.parent) { - if ((ts.isExpression(parent_3) || ts.isObjectLiteralMethod(node)) && - isContextSensitive(parent_3)) { - containerNodes.unshift(parent_3); + for (var parent_5 = node.parent; parent_5; parent_5 = parent_5.parent) { + if ((ts.isExpression(parent_5) || ts.isObjectLiteralMethod(node)) && + isContextSensitive(parent_5)) { + containerNodes.unshift(parent_5); } } ts.forEach(containerNodes, function (node) { getTypeOfNode(node); }); @@ -13698,18 +14597,36 @@ var ts; return undefined; } function getContextualTypeForReturnExpression(node) { + var func = ts.getContainingFunction(node); + if (func && !func.asteriskToken) { + return getContextualReturnType(func); + } + return undefined; + } + function getContextualTypeForYieldOperand(node) { var func = ts.getContainingFunction(node); if (func) { - if (func.type || func.kind === 136 || func.kind === 137 && getSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(func.symbol, 138))) { - return getReturnTypeOfSignature(getSignatureFromDeclaration(func)); - } - var signature = getContextualSignatureForFunctionLikeDeclaration(func); - if (signature) { - return getReturnTypeOfSignature(signature); + var contextualReturnType = getContextualReturnType(func); + if (contextualReturnType) { + return node.asteriskToken + ? contextualReturnType + : getElementTypeOfIterableIterator(contextualReturnType); } } return undefined; } + function getContextualReturnType(functionDecl) { + if (functionDecl.type || + functionDecl.kind === 136 || + functionDecl.kind === 137 && getSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(functionDecl.symbol, 138))) { + return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl)); + } + var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); + if (signature) { + return getReturnTypeOfSignature(signature); + } + return undefined; + } function getContextualTypeForArgument(callTarget, arg) { var args = getEffectiveCallArguments(callTarget); var argIndex = ts.indexOf(args, arg); @@ -13811,7 +14728,7 @@ var ts; var index = ts.indexOf(arrayLiteral.elements, node); return getTypeOfPropertyOfContextualType(type, "" + index) || getIndexTypeOfContextualType(type, 1) - || (languageVersion >= 2 ? checkIteratedType(type, undefined) : undefined); + || (languageVersion >= 2 ? getElementTypeOfIterable(type, undefined) : undefined); } return undefined; } @@ -13837,6 +14754,8 @@ var ts; case 164: case 192: return getContextualTypeForReturnExpression(node); + case 173: + return getContextualTypeForYieldOperand(parent); case 158: case 159: return getContextualTypeForArgument(parent, node); @@ -13871,7 +14790,9 @@ var ts; return node.kind === 163 || node.kind === 164; } function getContextualSignatureForFunctionLikeDeclaration(node) { - return isFunctionExpressionOrArrowFunction(node) ? getContextualSignature(node) : undefined; + return isFunctionExpressionOrArrowFunction(node) || ts.isObjectLiteralMethod(node) + ? getContextualSignature(node) + : undefined; } function getContextualSignature(node) { ts.Debug.assert(node.kind !== 135 || ts.isObjectLiteralMethod(node)); @@ -13946,7 +14867,7 @@ var ts; if (inDestructuringPattern && e.kind === 174) { var restArrayType = checkExpression(e.expression, contextualMapper); var restElementType = getIndexTypeOfType(restArrayType, 1) || - (languageVersion >= 2 ? checkIteratedType(restArrayType, undefined) : undefined); + (languageVersion >= 2 ? getElementTypeOfIterable(restArrayType, undefined) : undefined); if (restElementType) { elementTypes.push(restElementType); } @@ -14169,15 +15090,15 @@ var ts; return unknownType; } if (node.argumentExpression) { - var name_6 = getPropertyNameForIndexedAccess(node.argumentExpression, indexType); - if (name_6 !== undefined) { - var prop = getPropertyOfType(objectType, name_6); + var name_9 = getPropertyNameForIndexedAccess(node.argumentExpression, indexType); + if (name_9 !== undefined) { + var prop = getPropertyOfType(objectType, name_9); if (prop) { getNodeLinks(node).resolvedSymbol = prop; return getTypeOfSymbol(prop); } else if (isConstEnum) { - error(node.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_const_enum_1, name_6, symbolToString(objectType.symbol)); + error(node.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_const_enum_1, name_9, symbolToString(objectType.symbol)); return unknownType; } } @@ -14267,19 +15188,19 @@ var ts; for (var _i = 0; _i < signatures.length; _i++) { var signature = signatures[_i]; var symbol = signature.declaration && getSymbolOfNode(signature.declaration); - var parent_4 = signature.declaration && signature.declaration.parent; + var parent_6 = signature.declaration && signature.declaration.parent; if (!lastSymbol || symbol === lastSymbol) { - if (lastParent && parent_4 === lastParent) { + if (lastParent && parent_6 === lastParent) { index++; } else { - lastParent = parent_4; + lastParent = parent_6; index = cutoffIndex; } } else { index = cutoffIndex = result.length; - lastParent = parent_4; + lastParent = parent_6; } lastSymbol = symbol; if (signature.hasStringLiterals) { @@ -14618,10 +15539,10 @@ var ts; return resolveCall(node, callSignatures, candidatesOutArray); } function resolveNewExpression(node, candidatesOutArray) { - if (node.arguments && languageVersion < 2) { + if (node.arguments && languageVersion < 1) { var spreadIndex = getSpreadArgumentIndex(node.arguments); if (spreadIndex >= 0) { - error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher); + error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher); } } var expressionType = checkExpression(node.expression); @@ -14747,14 +15668,37 @@ var ts; type = checkExpressionCached(func.body, contextualMapper); } else { - var types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper); - if (types.length === 0) { - return voidType; + var types; + var funcIsGenerator = !!func.asteriskToken; + if (funcIsGenerator) { + types = checkAndAggregateYieldOperandTypes(func.body, contextualMapper); + if (types.length === 0) { + var iterableIteratorAny = createIterableIteratorType(anyType); + if (compilerOptions.noImplicitAny) { + error(func.asteriskToken, ts.Diagnostics.Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type, typeToString(iterableIteratorAny)); + } + return iterableIteratorAny; + } + } + else { + types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper); + if (types.length === 0) { + return voidType; + } } type = contextualSignature ? getUnionType(types) : getCommonSupertype(types); if (!type) { - error(func, ts.Diagnostics.No_best_common_type_exists_among_return_expressions); - return unknownType; + if (funcIsGenerator) { + error(func, ts.Diagnostics.No_best_common_type_exists_among_yield_expressions); + return createIterableIteratorType(unknownType); + } + else { + error(func, ts.Diagnostics.No_best_common_type_exists_among_return_expressions); + return unknownType; + } + } + if (funcIsGenerator) { + type = createIterableIteratorType(type); } } if (!contextualSignature) { @@ -14762,6 +15706,22 @@ var ts; } return getWidenedType(type); } + function checkAndAggregateYieldOperandTypes(body, contextualMapper) { + var aggregatedTypes = []; + ts.forEachYieldExpression(body, function (yieldExpression) { + var expr = yieldExpression.expression; + if (expr) { + var type = checkExpressionCached(expr, contextualMapper); + if (yieldExpression.asteriskToken) { + type = checkElementTypeOfIterable(type, yieldExpression.expression); + } + if (!ts.contains(aggregatedTypes, type)) { + aggregatedTypes.push(type); + } + } + }); + return aggregatedTypes; + } function checkAndAggregateReturnExpressionTypes(body, contextualMapper) { var aggregatedTypes = []; ts.forEachReturnStatement(body, function (returnStatement) { @@ -14897,8 +15857,8 @@ var ts; var index = n.argumentExpression; var symbol = findSymbol(n.expression); if (symbol && index && index.kind === 8) { - var name_7 = index.text; - var prop = getPropertyOfType(getTypeOfSymbol(symbol), name_7); + var name_10 = index.text; + var prop = getPropertyOfType(getTypeOfSymbol(symbol), name_10); return prop && (prop.flags & 3) !== 0 && (getDeclarationFlagsFromSymbol(prop) & 8192) !== 0; } return false; @@ -15029,16 +15989,16 @@ var ts; for (var _i = 0; _i < properties.length; _i++) { var p = properties[_i]; if (p.kind === 225 || p.kind === 226) { - var name_8 = p.name; + var name_11 = p.name; var type = sourceType.flags & 1 ? sourceType : - getTypeOfPropertyOfType(sourceType, name_8.text) || - isNumericLiteralName(name_8.text) && getIndexTypeOfType(sourceType, 1) || + getTypeOfPropertyOfType(sourceType, name_11.text) || + isNumericLiteralName(name_11.text) && getIndexTypeOfType(sourceType, 1) || getIndexTypeOfType(sourceType, 0); if (type) { - checkDestructuringAssignment(p.initializer || name_8, type); + checkDestructuringAssignment(p.initializer || name_11, type); } else { - error(name_8, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), ts.declarationNameToString(name_8)); + error(name_11, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), ts.declarationNameToString(name_11)); } } else { @@ -15253,13 +16213,46 @@ var ts; error(node, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(node.operatorToken.kind), typeToString(leftType), typeToString(rightType)); } } + function isYieldExpressionInClass(node) { + var current = node; + var parent = node.parent; + while (parent) { + if (ts.isFunctionLike(parent) && current === parent.body) { + return false; + } + else if (current.kind === 202 || current.kind === 175) { + return true; + } + current = parent; + parent = parent.parent; + } + return false; + } function checkYieldExpression(node) { - if (!(node.parserContextFlags & 4)) { - grammarErrorOnFirstToken(node, ts.Diagnostics.yield_expression_must_be_contained_within_a_generator_declaration); + if (!(node.parserContextFlags & 4) || isYieldExpressionInClass(node)) { + grammarErrorOnFirstToken(node, ts.Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body); } - else { - grammarErrorOnFirstToken(node, ts.Diagnostics.yield_expressions_are_not_currently_supported); + if (node.expression) { + var func = ts.getContainingFunction(node); + if (func && func.asteriskToken) { + var expressionType = checkExpressionCached(node.expression, undefined); + var expressionElementType; + var nodeIsYieldStar = !!node.asteriskToken; + if (nodeIsYieldStar) { + expressionElementType = checkElementTypeOfIterable(expressionType, node.expression); + } + if (func.type) { + var signatureElementType = getElementTypeOfIterableIterator(getTypeFromTypeNode(func.type)) || anyType; + if (nodeIsYieldStar) { + checkTypeAssignableTo(expressionElementType, signatureElementType, node.expression, undefined); + } + else { + checkTypeAssignableTo(expressionType, signatureElementType, node.expression, undefined); + } + } + } } + return anyType; } function checkConditionalExpression(node, contextualMapper) { checkExpression(node.condition); @@ -15406,8 +16399,7 @@ var ts; case 176: return undefinedType; case 173: - checkYieldExpression(node); - return unknownType; + return checkYieldExpression(node); } return unknownType; } @@ -15445,6 +16437,14 @@ var ts; error(node, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type); } } + function isSyntacticallyValidGenerator(node) { + if (!node.asteriskToken || !node.body) { + return false; + } + return node.kind === 135 || + node.kind === 201 || + node.kind === 163; + } function checkSignatureDeclaration(node) { if (node.kind === 141) { checkGrammarIndexSignature(node); @@ -15471,6 +16471,19 @@ var ts; break; } } + if (node.type) { + if (languageVersion >= 2 && isSyntacticallyValidGenerator(node)) { + var returnType = getTypeFromTypeNode(node.type); + if (returnType === voidType) { + error(node.type, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation); + } + else { + var generatorElementType = getElementTypeOfIterableIterator(returnType) || anyType; + var iterableIteratorInstantiation = createIterableIteratorType(generatorElementType); + checkTypeAssignableTo(iterableIteratorInstantiation, returnType, node.type); + } + } + } } checkSpecializedSignatureDeclaration(node); } @@ -16014,7 +17027,6 @@ var ts; function checkFunctionDeclaration(node) { if (produceDiagnostics) { checkFunctionLikeDeclaration(node) || - checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarFunctionName(node.name) || checkGrammarForGenerator(node); checkCollisionWithCapturedSuperVariable(node, node.name); @@ -16046,8 +17058,13 @@ var ts; if (node.type && !isAccessor(node.kind) && !node.asteriskToken) { checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } - if (compilerOptions.noImplicitAny && ts.nodeIsMissing(node.body) && !node.type && !isPrivateWithinAmbient(node)) { - reportImplicitAnyError(node, anyType); + if (produceDiagnostics && !node.type) { + if (compilerOptions.noImplicitAny && ts.nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) { + reportImplicitAnyError(node, anyType); + } + if (node.asteriskToken && ts.nodeIsPresent(node.body)) { + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } } } function checkBlock(node) { @@ -16168,8 +17185,8 @@ var ts; container.kind === 206 || container.kind === 228); if (!namesShareScope) { - var name_9 = symbolToString(localDeclarationSymbol); - error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name_9, name_9); + var name_12 = symbolToString(localDeclarationSymbol); + error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name_12, name_12); } } } @@ -16262,7 +17279,7 @@ var ts; return checkVariableLikeDeclaration(node); } function checkVariableStatement(node) { - checkGrammarDecorators(node) || checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node); + checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node); ts.forEach(node.declarationList.declarations, checkSourceElement); } function checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) { @@ -16385,7 +17402,7 @@ var ts; return inputType; } if (languageVersion >= 2) { - return checkIteratedType(inputType, errorNode) || anyType; + return checkElementTypeOfIterable(inputType, errorNode); } if (allowStringInput) { return checkElementTypeOfArrayOrString(inputType, errorNode); @@ -16399,84 +17416,85 @@ var ts; error(errorNode, ts.Diagnostics.Type_0_is_not_an_array_type, typeToString(inputType)); return unknownType; } - function checkIteratedType(iterable, errorNode) { - ts.Debug.assert(languageVersion >= 2); - var iteratedType = getIteratedType(iterable, errorNode); - if (errorNode && iteratedType) { - checkTypeAssignableTo(iterable, createIterableType(iteratedType), errorNode); + function checkElementTypeOfIterable(iterable, errorNode) { + var elementType = getElementTypeOfIterable(iterable, errorNode); + if (errorNode && elementType) { + checkTypeAssignableTo(iterable, createIterableType(elementType), errorNode); } - return iteratedType; - function getIteratedType(iterable, errorNode) { - // We want to treat type as an iterable, and get the type it is an iterable of. The iterable - // must have the following structure (annotated with the names of the variables below): - // - // { // iterable - // [Symbol.iterator]: { // iteratorFunction - // (): { // iterator - // next: { // iteratorNextFunction - // (): { // iteratorNextResult - // value: T // iteratorNextValue - // } - // } - // } - // } - // } - // - // T is the type we are after. At every level that involves analyzing return types - // of signatures, we union the return types of all the signatures. - // - // Another thing to note is that at any step of this process, we could run into a dead end, - // meaning either the property is missing, or we run into the anyType. If either of these things - // happens, we return undefined to signal that we could not find the iterated type. If a property - // is missing, and the previous step did not result in 'any', then we also give an error if the - // caller requested it. Then the caller can decide what to do in the case where there is no iterated - // type. This is different from returning anyType, because that would signify that we have matched the - // whole pattern and that T (above) is 'any'. - if (allConstituentTypesHaveKind(iterable, 1)) { - return undefined; - } - if ((iterable.flags & 4096) && iterable.target === globalIterableType) { - return iterable.typeArguments[0]; - } - var iteratorFunction = getTypeOfPropertyOfType(iterable, ts.getPropertyNameForKnownSymbolName("iterator")); - if (iteratorFunction && allConstituentTypesHaveKind(iteratorFunction, 1)) { - return undefined; - } - var iteratorFunctionSignatures = iteratorFunction ? getSignaturesOfType(iteratorFunction, 0) : emptyArray; - if (iteratorFunctionSignatures.length === 0) { - if (errorNode) { - error(errorNode, ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator); - } - return undefined; - } - var iterator = getUnionType(ts.map(iteratorFunctionSignatures, getReturnTypeOfSignature)); - if (allConstituentTypesHaveKind(iterator, 1)) { - return undefined; - } - var iteratorNextFunction = getTypeOfPropertyOfType(iterator, "next"); - if (iteratorNextFunction && allConstituentTypesHaveKind(iteratorNextFunction, 1)) { - return undefined; - } - var iteratorNextFunctionSignatures = iteratorNextFunction ? getSignaturesOfType(iteratorNextFunction, 0) : emptyArray; - if (iteratorNextFunctionSignatures.length === 0) { - if (errorNode) { - error(errorNode, ts.Diagnostics.An_iterator_must_have_a_next_method); - } - return undefined; - } - var iteratorNextResult = getUnionType(ts.map(iteratorNextFunctionSignatures, getReturnTypeOfSignature)); - if (allConstituentTypesHaveKind(iteratorNextResult, 1)) { - return undefined; - } - var iteratorNextValue = getTypeOfPropertyOfType(iteratorNextResult, "value"); - if (!iteratorNextValue) { - if (errorNode) { - error(errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property); - } - return undefined; - } - return iteratorNextValue; + return elementType || anyType; + } + function getElementTypeOfIterable(type, errorNode) { + if (type.flags & 1) { + return undefined; } + var typeAsIterable = type; + if (!typeAsIterable.iterableElementType) { + if ((type.flags & 4096) && type.target === globalIterableType) { + typeAsIterable.iterableElementType = type.typeArguments[0]; + } + else { + var iteratorFunction = getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("iterator")); + if (iteratorFunction && iteratorFunction.flags & 1) { + return undefined; + } + var iteratorFunctionSignatures = iteratorFunction ? getSignaturesOfType(iteratorFunction, 0) : emptyArray; + if (iteratorFunctionSignatures.length === 0) { + if (errorNode) { + error(errorNode, ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator); + } + return undefined; + } + typeAsIterable.iterableElementType = getElementTypeOfIterator(getUnionType(ts.map(iteratorFunctionSignatures, getReturnTypeOfSignature)), errorNode); + } + } + return typeAsIterable.iterableElementType; + } + function getElementTypeOfIterator(type, errorNode) { + if (type.flags & 1) { + return undefined; + } + var typeAsIterator = type; + if (!typeAsIterator.iteratorElementType) { + if ((type.flags & 4096) && type.target === globalIteratorType) { + typeAsIterator.iteratorElementType = type.typeArguments[0]; + } + else { + var iteratorNextFunction = getTypeOfPropertyOfType(type, "next"); + if (iteratorNextFunction && iteratorNextFunction.flags & 1) { + return undefined; + } + var iteratorNextFunctionSignatures = iteratorNextFunction ? getSignaturesOfType(iteratorNextFunction, 0) : emptyArray; + if (iteratorNextFunctionSignatures.length === 0) { + if (errorNode) { + error(errorNode, ts.Diagnostics.An_iterator_must_have_a_next_method); + } + return undefined; + } + var iteratorNextResult = getUnionType(ts.map(iteratorNextFunctionSignatures, getReturnTypeOfSignature)); + if (iteratorNextResult.flags & 1) { + return undefined; + } + var iteratorNextValue = getTypeOfPropertyOfType(iteratorNextResult, "value"); + if (!iteratorNextValue) { + if (errorNode) { + error(errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property); + } + return undefined; + } + typeAsIterator.iteratorElementType = iteratorNextValue; + } + } + return typeAsIterator.iteratorElementType; + } + function getElementTypeOfIterableIterator(type) { + if (type.flags & 1) { + return undefined; + } + if ((type.flags & 4096) && type.target === globalIterableIteratorType) { + return type.typeArguments[0]; + } + return getElementTypeOfIterable(type, undefined) || + getElementTypeOfIterator(type, undefined); } function checkElementTypeOfArrayOrString(arrayOrStringType, errorNode) { ts.Debug.assert(languageVersion < 2); @@ -16528,19 +17546,20 @@ var ts; if (func) { var returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func)); var exprType = checkExpressionCached(node.expression); + if (func.asteriskToken) { + return; + } if (func.kind === 138) { error(node.expression, ts.Diagnostics.Setters_cannot_return_a_value); } - else { - if (func.kind === 136) { - if (!isTypeAssignableTo(exprType, returnType)) { - error(node.expression, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); - } - } - else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) { - checkTypeAssignableTo(exprType, returnType, node.expression, undefined); + else if (func.kind === 136) { + if (!isTypeAssignableTo(exprType, returnType)) { + error(node.expression, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } + else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) { + checkTypeAssignableTo(exprType, returnType, node.expression, undefined); + } } } } @@ -16734,9 +17753,6 @@ var ts; } function checkClassDeclaration(node) { checkGrammarDeclarationNameInStrictMode(node); - if (node.parent.kind !== 207 && node.parent.kind !== 228) { - grammarErrorOnNode(node, ts.Diagnostics.class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration); - } if (!node.name && !(node.flags & 256)) { grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } @@ -17776,74 +18792,6 @@ var ts; } return node.parent && node.parent.kind === 177; } - function isTypeNode(node) { - if (142 <= node.kind && node.kind <= 150) { - return true; - } - switch (node.kind) { - case 112: - case 120: - case 122: - case 113: - case 123: - return true; - case 99: - return node.parent.kind !== 167; - case 8: - return node.parent.kind === 130; - case 177: - return true; - case 65: - if (node.parent.kind === 127 && node.parent.right === node) { - node = node.parent; - } - else if (node.parent.kind === 156 && node.parent.name === node) { - node = node.parent; - } - case 127: - case 156: - ts.Debug.assert(node.kind === 65 || node.kind === 127 || node.kind === 156, "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'."); - var parent_5 = node.parent; - if (parent_5.kind === 145) { - return false; - } - if (142 <= parent_5.kind && parent_5.kind <= 150) { - return true; - } - switch (parent_5.kind) { - case 177: - return true; - case 129: - return node === parent_5.constraint; - case 133: - case 132: - case 130: - case 199: - return node === parent_5.type; - case 201: - case 163: - case 164: - case 136: - case 135: - case 134: - case 137: - case 138: - return node === parent_5.type; - case 139: - case 140: - case 141: - return node === parent_5.type; - case 161: - return node === parent_5.type; - case 158: - case 159: - return parent_5.typeArguments && ts.indexOf(parent_5.typeArguments, node) >= 0; - case 160: - return false; - } - } - return false; - } function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide) { while (nodeOnRightSide.parent.kind === 127) { nodeOnRightSide = nodeOnRightSide.parent; @@ -17968,7 +18916,7 @@ var ts; if (isInsideWithStatementBody(node)) { return unknownType; } - if (isTypeNode(node)) { + if (ts.isTypeNode(node)) { return getTypeFromTypeNode(node); } if (ts.isExpression(node)) { @@ -18018,9 +18966,9 @@ var ts; function getRootSymbols(symbol) { if (symbol.flags & 268435456) { var symbols = []; - var name_10 = symbol.name; + var name_13 = symbol.name; ts.forEach(getSymbolLinks(symbol).unionType.types, function (t) { - symbols.push(getPropertyOfType(t, name_10)); + symbols.push(getPropertyOfType(t, name_13)); }); return symbols; } @@ -18398,8 +19346,7 @@ var ts; getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments"); getSymbolLinks(unknownSymbol).type = unknownType; globals[undefinedSymbol.name] = undefinedSymbol; - globalArraySymbol = getGlobalTypeSymbol("Array"); - globalArrayType = getTypeOfGlobalSymbol(globalArraySymbol, 1); + globalArrayType = getGlobalType("Array", 1); globalObjectType = getGlobalType("Object"); globalFunctionType = getGlobalType("Function"); globalStringType = getGlobalType("String"); @@ -18415,11 +19362,16 @@ var ts; globalESSymbolType = getGlobalType("Symbol"); globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol"); globalIterableType = getGlobalType("Iterable", 1); + globalIteratorType = getGlobalType("Iterator", 1); + globalIterableIteratorType = getGlobalType("IterableIterator", 1); } else { globalTemplateStringsArrayType = unknownType; globalESSymbolType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); globalESSymbolConstructorSymbol = undefined; + globalIterableType = emptyGenericType; + globalIteratorType = emptyGenericType; + globalIterableIteratorType = emptyGenericType; } anyArrayType = createArrayType(anyType); } @@ -18439,20 +19391,20 @@ var ts; if (impotClause.namedBindings) { var nameBindings = impotClause.namedBindings; if (nameBindings.kind === 212) { - var name_11 = nameBindings.name; - if (isReservedWordInStrictMode(name_11)) { - var nameText = ts.declarationNameToString(name_11); - return grammarErrorOnNode(name_11, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); + var name_14 = nameBindings.name; + if (isReservedWordInStrictMode(name_14)) { + var nameText = ts.declarationNameToString(name_14); + return grammarErrorOnNode(name_14, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); } } else if (nameBindings.kind === 213) { var reportError = false; for (var _i = 0, _a = nameBindings.elements; _i < _a.length; _i++) { var element = _a[_i]; - var name_12 = element.name; - if (isReservedWordInStrictMode(name_12)) { - var nameText = ts.declarationNameToString(name_12); - reportError = reportError || grammarErrorOnNode(name_12, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); + var name_15 = element.name; + if (isReservedWordInStrictMode(name_15)) { + var nameText = ts.declarationNameToString(name_15); + reportError = reportError || grammarErrorOnNode(name_15, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); } } return reportError; @@ -18550,19 +19502,28 @@ var ts; case 135: case 134: case 141: - case 202: - case 203: case 206: - case 205: - case 181: - case 201: - case 204: case 210: case 209: case 216: case 215: case 130: break; + case 202: + case 203: + case 181: + case 201: + case 204: + if (node.modifiers && node.parent.kind !== 207 && node.parent.kind !== 228) { + return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here); + } + break; + case 205: + if (node.modifiers && (node.modifiers.length > 1 || node.modifiers[0].kind !== 70) && + node.parent.kind !== 207 && node.parent.kind !== 228) { + return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here); + } + break; default: return false; } @@ -18660,9 +19621,6 @@ var ts; else if ((node.kind === 210 || node.kind === 209) && flags & 2) { return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_declare_modifier_cannot_be_used_with_an_import_declaration, "declare"); } - else if (node.kind === 203 && flags & 2) { - return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_declare_modifier_cannot_be_used_with_an_interface_declaration, "declare"); - } else if (node.kind === 130 && (flags & 112) && ts.isBindingPattern(node.name)) { return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_may_not_be_a_binding_pattern); } @@ -18874,7 +19832,18 @@ var ts; } function checkGrammarForGenerator(node) { if (node.asteriskToken) { - return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_currently_supported); + ts.Debug.assert(node.kind === 201 || + node.kind === 163 || + node.kind === 135); + if (ts.isInAmbientContext(node)) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_allowed_in_an_ambient_context); + } + if (!node.body) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator); + } + if (languageVersion < 2) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_only_available_when_targeting_ECMAScript_6_or_higher); + } } } function checkGrammarFunctionName(name) { @@ -18894,17 +19863,17 @@ var ts; var inStrictMode = (node.parserContextFlags & 1) !== 0; for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var prop = _a[_i]; - var name_13 = prop.name; + var name_16 = prop.name; if (prop.kind === 176 || - name_13.kind === 128) { - checkGrammarComputedPropertyName(name_13); + name_16.kind === 128) { + checkGrammarComputedPropertyName(name_16); continue; } var currentKind = void 0; if (prop.kind === 225 || prop.kind === 226) { checkGrammarForInvalidQuestionMark(prop, prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional); - if (name_13.kind === 7) { - checkGrammarNumericLiteral(name_13); + if (name_16.kind === 7) { + checkGrammarNumericLiteral(name_16); } currentKind = Property; } @@ -18920,26 +19889,26 @@ var ts; else { ts.Debug.fail("Unexpected syntax kind:" + prop.kind); } - if (!ts.hasProperty(seen, name_13.text)) { - seen[name_13.text] = currentKind; + if (!ts.hasProperty(seen, name_16.text)) { + seen[name_16.text] = currentKind; } else { - var existingKind = seen[name_13.text]; + var existingKind = seen[name_16.text]; if (currentKind === Property && existingKind === Property) { if (inStrictMode) { - grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode); + grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode); } } else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { - seen[name_13.text] = currentKind | existingKind; + seen[name_16.text] = currentKind | existingKind; } else { - return grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); + return grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); } } else { - return grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name); + return grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name); } } } @@ -19718,9 +20687,9 @@ var ts; } var count = 0; while (true) { - var name_14 = baseName + "_" + (++count); - if (!ts.hasProperty(currentSourceFile.identifiers, name_14)) { - return name_14; + var name_17 = baseName + "_" + (++count); + if (!ts.hasProperty(currentSourceFile.identifiers, name_17)) { + return name_17; } } } @@ -20804,9 +21773,9 @@ var ts; var count = tempFlags & 268435455; tempFlags++; if (count !== 8 && count !== 13) { - var name_15 = count < 26 ? "_" + String.fromCharCode(97 + count) : "_" + (count - 26); - if (isUniqueName(name_15)) { - return name_15; + var name_18 = count < 26 ? "_" + String.fromCharCode(97 + count) : "_" + (count - 26); + if (isUniqueName(name_18)) { + return name_18; } } } @@ -20834,8 +21803,8 @@ var ts; } function generateNameForModuleOrEnum(node) { if (node.name.kind === 65) { - var name_16 = node.name.text; - assignGeneratedName(node, isUniqueLocalName(name_16, node) ? name_16 : makeUniqueName(name_16)); + var name_19 = node.name.text; + assignGeneratedName(node, isUniqueLocalName(name_19, node) ? name_19 : makeUniqueName(name_19)); } } function generateNameForImportOrExportDeclaration(node) { @@ -21021,8 +21990,8 @@ var ts; if (scopeName) { var parentIndex = getSourceMapNameIndex(); if (parentIndex !== -1) { - var name_17 = node.name; - if (!name_17 || name_17.kind !== 128) { + var name_20 = node.name; + if (!name_20 || name_20.kind !== 128) { scopeName = "." + scopeName; } scopeName = sourceMapData.sourceMapNames[parentIndex] + scopeName; @@ -21049,9 +22018,9 @@ var ts; node.kind === 202 || node.kind === 205) { if (node.name) { - var name_18 = node.name; - scopeName = name_18.kind === 128 - ? ts.getTextOfNode(name_18) + var name_21 = node.name; + scopeName = name_21.kind === 128 + ? ts.getTextOfNode(name_21) : node.name.text; } recordScopeNameStart(scopeName); @@ -21672,15 +22641,15 @@ var ts; } return true; } - function emitListWithSpread(elements, alwaysCopy, multiLine, trailingComma) { + function emitListWithSpread(elements, needsUniqueCopy, multiLine, trailingComma, useConcat) { var pos = 0; var group = 0; var length = elements.length; while (pos < length) { - if (group === 1) { + if (group === 1 && useConcat) { write(".concat("); } - else if (group > 1) { + else if (group > 0) { write(", "); } var e = elements[pos]; @@ -21688,7 +22657,7 @@ var ts; e = e.expression; emitParenthesizedIf(e, group === 0 && needsParenthesisForPropertyAccessOrInvocation(e)); pos++; - if (pos === length && group === 0 && alwaysCopy && e.kind !== 154) { + if (pos === length && group === 0 && needsUniqueCopy && e.kind !== 154) { write(".slice()"); } } @@ -21711,7 +22680,9 @@ var ts; group++; } if (group > 1) { - write(")"); + if (useConcat) { + write(")"); + } } } function isSpreadElementExpression(node) { @@ -21728,7 +22699,7 @@ var ts; write("]"); } else { - emitListWithSpread(elements, true, (node.flags & 512) !== 0, elements.hasTrailingComma); + emitListWithSpread(elements, true, (node.flags & 512) !== 0, elements.hasTrailingComma, true); } } function emitObjectLiteralBody(node, numElements) { @@ -22054,7 +23025,7 @@ var ts; write("void 0"); } write(", "); - emitListWithSpread(node.arguments, false, false, false); + emitListWithSpread(node.arguments, false, false, false, true); write(")"); } function emitCallExpression(node) { @@ -22088,11 +23059,25 @@ var ts; } function emitNewExpression(node) { write("new "); - emit(node.expression); - if (node.arguments) { + if (languageVersion === 1 && + node.arguments && + hasSpreadElement(node.arguments)) { write("("); - emitCommaList(node.arguments); - write(")"); + var target = emitCallTarget(node.expression); + write(".bind.apply("); + emit(target); + write(", [void 0].concat("); + emitListWithSpread(node.arguments, false, false, false, false); + write(")))"); + write("()"); + } + else { + emit(node.expression); + if (node.arguments) { + write("("); + emitCommaList(node.arguments); + write(")"); + } } } function emitTaggedTemplateExpression(node) { @@ -23044,15 +24029,30 @@ var ts; ts.forEach(node.declarationList.declarations, emitExportVariableAssignments); } } + function shouldEmitLeadingAndTrailingCommentsForVariableStatement(node) { + if (!(node.flags & 1)) { + return true; + } + if (isES6ExportedDeclaration(node)) { + return true; + } + for (var _a = 0, _b = node.declarationList.declarations; _a < _b.length; _a++) { + var declaration = _b[_a]; + if (declaration.initializer) { + return true; + } + } + return false; + } function emitParameter(node) { if (languageVersion < 2) { if (ts.isBindingPattern(node.name)) { - var name_19 = createTempVariable(0); + var name_22 = createTempVariable(0); if (!tempParameters) { tempParameters = []; } - tempParameters.push(name_19); - emit(name_19); + tempParameters.push(name_22); + emit(name_22); } else { emit(node.name); @@ -24512,8 +25512,8 @@ var ts; else { for (var _c = 0, _d = node.exportClause.elements; _c < _d.length; _c++) { var specifier = _d[_c]; - var name_20 = (specifier.propertyName || specifier.name).text; - (exportSpecifiers[name_20] || (exportSpecifiers[name_20] = [])).push(specifier); + var name_23 = (specifier.propertyName || specifier.name).text; + (exportSpecifiers[name_23] || (exportSpecifiers[name_23] = [])).push(specifier); } } break; @@ -24686,11 +25686,11 @@ var ts; var seen = {}; for (var i = 0; i < hoistedVars.length; ++i) { var local = hoistedVars[i]; - var name_21 = local.kind === 65 + var name_24 = local.kind === 65 ? local : local.name; - if (name_21) { - var text = ts.unescapeIdentifier(name_21.text); + if (name_24) { + var text = ts.unescapeIdentifier(name_24.text); if (ts.hasProperty(seen, text)) { continue; } @@ -24769,15 +25769,15 @@ var ts; } if (node.kind === 199 || node.kind === 153) { if (shouldHoistVariable(node, false)) { - var name_22 = node.name; - if (name_22.kind === 65) { + var name_25 = node.name; + if (name_25.kind === 65) { if (!hoistedVars) { hoistedVars = []; } - hoistedVars.push(name_22); + hoistedVars.push(name_25); } else { - ts.forEachChild(name_22, visit); + ts.forEachChild(name_25, visit); } } return; @@ -25144,6 +26144,8 @@ var ts; case 204: case 215: return false; + case 181: + return shouldEmitLeadingAndTrailingCommentsForVariableStatement(node); case 206: return shouldEmitModuleDeclaration(node); case 205: @@ -26403,24 +27405,24 @@ var ts; switch (n.kind) { case 180: if (!ts.isFunctionBlock(n)) { - var parent_6 = n.parent; + var parent_7 = n.parent; var openBrace = ts.findChildOfKind(n, 14, sourceFile); var closeBrace = ts.findChildOfKind(n, 15, sourceFile); - if (parent_6.kind === 185 || - parent_6.kind === 188 || - parent_6.kind === 189 || - parent_6.kind === 187 || - parent_6.kind === 184 || - parent_6.kind === 186 || - parent_6.kind === 193 || - parent_6.kind === 224) { - addOutliningSpan(parent_6, openBrace, closeBrace, autoCollapse(n)); + if (parent_7.kind === 185 || + parent_7.kind === 188 || + parent_7.kind === 189 || + parent_7.kind === 187 || + parent_7.kind === 184 || + parent_7.kind === 186 || + parent_7.kind === 193 || + parent_7.kind === 224) { + addOutliningSpan(parent_7, openBrace, closeBrace, autoCollapse(n)); break; } - if (parent_6.kind === 197) { - var tryStatement = parent_6; + if (parent_7.kind === 197) { + var tryStatement = parent_7; if (tryStatement.tryBlock === n) { - addOutliningSpan(parent_6, openBrace, closeBrace, autoCollapse(n)); + addOutliningSpan(parent_7, openBrace, closeBrace, autoCollapse(n)); break; } else if (tryStatement.finallyBlock === n) { @@ -26482,10 +27484,10 @@ var ts; ts.forEach(program.getSourceFiles(), function (sourceFile) { cancellationToken.throwIfCancellationRequested(); var nameToDeclarations = sourceFile.getNamedDeclarations(); - for (var name_23 in nameToDeclarations) { - var declarations = ts.getProperty(nameToDeclarations, name_23); + for (var name_26 in nameToDeclarations) { + var declarations = ts.getProperty(nameToDeclarations, name_26); if (declarations) { - var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_23); + var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_26); if (!matches) { continue; } @@ -26496,14 +27498,14 @@ var ts; if (!containers) { return undefined; } - matches = patternMatcher.getMatches(containers, name_23); + matches = patternMatcher.getMatches(containers, name_26); if (!matches) { continue; } } var fileName = sourceFile.fileName; var matchKind = bestMatchKind(matches); - rawItems.push({ name: name_23, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); + rawItems.push({ name: name_26, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); } } } @@ -26833,9 +27835,9 @@ var ts; case 199: case 153: var variableDeclarationNode; - var name_24; + var name_27; if (node.kind === 153) { - name_24 = node.name; + name_27 = node.name; variableDeclarationNode = node; while (variableDeclarationNode && variableDeclarationNode.kind !== 199) { variableDeclarationNode = variableDeclarationNode.parent; @@ -26845,16 +27847,16 @@ var ts; else { ts.Debug.assert(!ts.isBindingPattern(node.name)); variableDeclarationNode = node; - name_24 = node.name; + name_27 = node.name; } if (ts.isConst(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.constElement); + return createItem(node, getTextOfNode(name_27), ts.ScriptElementKind.constElement); } else if (ts.isLet(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.letElement); + return createItem(node, getTextOfNode(name_27), ts.ScriptElementKind.letElement); } else { - return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.variableElement); + return createItem(node, getTextOfNode(name_27), ts.ScriptElementKind.variableElement); } case 136: return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); @@ -27943,7 +28945,7 @@ var ts; ts.findChildOfKind = findChildOfKind; function findContainingList(node) { var syntaxList = ts.forEach(node.parent.getChildren(), function (c) { - if (c.kind === 229 && c.pos <= node.pos && c.end >= node.end) { + if (c.kind === 251 && c.pos <= node.pos && c.end >= node.end) { return c; } }); @@ -28313,10 +29315,6 @@ var ts; }); } ts.signatureToDisplayParts = signatureToDisplayParts; - function isJavaScript(fileName) { - return ts.fileExtensionIs(fileName, ".js"); - } - ts.isJavaScript = isJavaScript; })(ts || (ts = {})); /// /// @@ -28720,7 +29718,7 @@ var ts; this.NoSpaceBeforeOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8)); this.NoSpaceAfterOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create3(18, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8)); this.NoSpaceBeforeCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 19), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8)); - this.NoSpaceAfterCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create3(19, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8)); + this.NoSpaceAfterCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create3(19, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBeforeBlockInFunctionDeclarationContext), 8)); this.FunctionOpenBraceLeftTokenRange = formatting.Shared.TokenRange.AnyIncludingMultilineComments; this.SpaceBeforeOpenBraceInFunction = new formatting.Rule(formatting.RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, 14), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext, Rules.IsBeforeBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), 2), 1); this.TypeScriptOpenBraceLeftTokenRange = formatting.Shared.TokenRange.FromTokens([65, 3]); @@ -28773,6 +29771,10 @@ var ts; this.SpaceBeforeAt = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 52), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2)); this.NoSpaceAfterAt = new formatting.Rule(formatting.RuleDescriptor.create3(52, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8)); this.SpaceAfterDecorator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([65, 78, 73, 69, 109, 108, 106, 107, 116, 121, 18, 35])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsEndOfDecoratorContextOnSameLine), 2)); + this.NoSpaceBetweenFunctionKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(83, 35), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 8)); + this.SpaceAfterStarInGeneratorDeclaration = new formatting.Rule(formatting.RuleDescriptor.create3(35, formatting.Shared.TokenRange.FromTokens([65, 16])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 2)); + this.NoSpaceBetweenYieldKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(110, 35), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 8)); + this.SpaceBetweenYieldOrYieldStarAndOperand = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([110, 35]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 2)); this.HighPriorityCommonRules = [ this.IgnoreBeforeComment, this.IgnoreAfterLineComment, @@ -28789,7 +29791,9 @@ var ts; this.NoSpaceAfterCloseBrace, this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NewLineBeforeCloseBraceInBlockContext, this.SpaceAfterCloseBrace, this.SpaceBetweenCloseBraceAndElse, this.SpaceBetweenCloseBraceAndWhile, this.NoSpaceBetweenEmptyBraceBrackets, + this.NoSpaceBetweenFunctionKeywordAndStar, this.SpaceAfterStarInGeneratorDeclaration, this.SpaceAfterFunctionInFuncDecl, this.NewLineAfterOpenBraceInBlockContext, this.SpaceAfterGetSetInMember, + this.NoSpaceBetweenYieldKeywordAndStar, this.SpaceBetweenYieldOrYieldStarAndOperand, this.NoSpaceBetweenReturnAndSemicolon, this.SpaceAfterCertainKeywords, this.SpaceAfterLetConstInVariableDeclaration, @@ -28846,9 +29850,9 @@ var ts; } Rules.prototype.getRuleName = function (rule) { var o = this; - for (var name_25 in o) { - if (o[name_25] === rule) { - return name_25; + for (var name_28 in o) { + if (o[name_28] === rule) { + return name_28; } } throw new Error("Unknown rule"); @@ -28949,6 +29953,9 @@ var ts; } return false; }; + Rules.IsFunctionDeclarationOrFunctionExpressionContext = function (context) { + return context.contextNode.kind === 201 || context.contextNode.kind === 163; + }; Rules.IsTypeScriptDeclWithBlockContext = function (context) { return Rules.NodeIsTypeScriptDeclWithBlockContext(context.contextNode); }; @@ -29011,6 +30018,9 @@ var ts; Rules.IsSameLineTokenContext = function (context) { return context.TokensAreOnSameLine(); }; + Rules.IsNotBeforeBlockInFunctionDeclarationContext = function (context) { + return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context); + }; Rules.IsEndOfDecoratorContextOnSameLine = function (context) { return context.TokensAreOnSameLine() && context.contextNode.decorators && @@ -29065,6 +30075,9 @@ var ts; Rules.IsVoidOpContext = function (context) { return context.currentTokenSpan.kind === 99 && context.currentTokenParent.kind === 167; }; + Rules.IsYieldOrYieldStarWithOperand = function (context) { + return context.contextNode.kind === 173 && context.contextNode.expression !== undefined; + }; return Rules; })(); formatting.Rules = Rules; @@ -30564,7 +31577,7 @@ var ts; return pos; }; NodeObject.prototype.createSyntaxList = function (nodes) { - var list = createNode(229, nodes.pos, nodes.end, 1024, this); + var list = createNode(251, nodes.pos, nodes.end, 1024, this); list._children = []; var pos = nodes.pos; for (var _i = 0; _i < nodes.length; _i++) { @@ -31244,8 +32257,8 @@ var ts; if (declaration.kind !== 199 && declaration.kind !== 201) { return false; } - for (var parent_7 = declaration.parent; !ts.isFunctionBlock(parent_7); parent_7 = parent_7.parent) { - if (parent_7.kind === 228 || parent_7.kind === 207) { + for (var parent_8 = declaration.parent; !ts.isFunctionBlock(parent_8); parent_8 = parent_8.parent) { + if (parent_8.kind === 228 || parent_8.kind === 207) { return false; } } @@ -32064,7 +33077,7 @@ var ts; return true; } if (parameter.questionToken) { - diagnostics.push(ts.createDiagnosticForNode(parameter.questionToken, ts.Diagnostics.can_only_be_used_in_a_ts_file)); + diagnostics.push(ts.createDiagnosticForNode(parameter.questionToken, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, '?')); return true; } if (parameter.type) { @@ -32381,12 +33394,12 @@ var ts; function getContainingObjectLiteralApplicableForCompletion(previousToken) { // The locations in an object literal expression that are applicable for completion are property name definition locations. if (previousToken) { - var parent_8 = previousToken.parent; + var parent_9 = previousToken.parent; switch (previousToken.kind) { case 14: case 23: - if (parent_8 && parent_8.kind === 155) { - return parent_8; + if (parent_9 && parent_9.kind === 155) { + return parent_9; } break; } @@ -32564,10 +33577,10 @@ var ts; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; var nameTable = getNameTable(sourceFile); - for (var name_26 in nameTable) { - if (!allNames[name_26]) { - allNames[name_26] = name_26; - var displayName = getCompletionEntryDisplayName(name_26, target, true); + for (var name_29 in nameTable) { + if (!allNames[name_29]) { + allNames[name_29] = name_29; + var displayName = getCompletionEntryDisplayName(name_29, target, true); if (displayName) { var entry = { name: displayName, @@ -33403,17 +34416,17 @@ var ts; function getThrowStatementOwner(throwStatement) { var child = throwStatement; while (child.parent) { - var parent_9 = child.parent; - if (ts.isFunctionBlock(parent_9) || parent_9.kind === 228) { - return parent_9; + var parent_10 = child.parent; + if (ts.isFunctionBlock(parent_10) || parent_10.kind === 228) { + return parent_10; } - if (parent_9.kind === 197) { - var tryStatement = parent_9; + if (parent_10.kind === 197) { + var tryStatement = parent_10; if (tryStatement.tryBlock === child && tryStatement.catchClause) { return child; } } - child = parent_9; + child = parent_10; } return undefined; } @@ -34246,17 +35259,17 @@ var ts; if (isNameOfPropertyAssignment(node)) { var objectLiteral = node.parent.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name_27 = node.text; + var name_30 = node.text; if (contextualType) { if (contextualType.flags & 16384) { - var unionProperty = contextualType.getProperty(name_27); + var unionProperty = contextualType.getProperty(name_30); if (unionProperty) { return [unionProperty]; } else { var result_4 = []; ts.forEach(contextualType.types, function (t) { - var symbol = t.getProperty(name_27); + var symbol = t.getProperty(name_30); if (symbol) { result_4.push(symbol); } @@ -34265,7 +35278,7 @@ var ts; } } else { - var symbol_1 = contextualType.getProperty(name_27); + var symbol_1 = contextualType.getProperty(name_30); if (symbol_1) { return [symbol_1]; } @@ -35076,7 +36089,7 @@ var ts; var lastEnd = 0; for (var i = 0, n = dense.length; i < n; i += 3) { var start = dense[i]; - var length_1 = dense[i + 1]; + var length_2 = dense[i + 1]; var type = dense[i + 2]; if (lastEnd >= 0) { var whitespaceLength_1 = start - lastEnd; @@ -35084,8 +36097,8 @@ var ts; entries.push({ length: whitespaceLength_1, classification: TokenClass.Whitespace }); } } - entries.push({ length: length_1, classification: convertClassification(type) }); - lastEnd = start + length_1; + entries.push({ length: length_2, classification: convertClassification(type) }); + lastEnd = start + length_2; } var whitespaceLength = text.length - lastEnd; if (whitespaceLength > 0) { diff --git a/bin/typescript.d.ts b/bin/typescript.d.ts index 50f5c1ade22..ede16aa7ed2 100644 --- a/bin/typescript.d.ts +++ b/bin/typescript.d.ts @@ -251,8 +251,30 @@ declare module "typescript" { ShorthandPropertyAssignment = 226, EnumMember = 227, SourceFile = 228, - SyntaxList = 229, - Count = 230, + JSDocTypeExpression = 229, + JSDocAllType = 230, + JSDocUnknownType = 231, + JSDocArrayType = 232, + JSDocUnionType = 233, + JSDocTupleType = 234, + JSDocNullableType = 235, + JSDocNonNullableType = 236, + JSDocRecordType = 237, + JSDocRecordMember = 238, + JSDocTypeReference = 239, + JSDocOptionalType = 240, + JSDocFunctionType = 241, + JSDocVariadicType = 242, + JSDocConstructorType = 243, + JSDocThisType = 244, + JSDocComment = 245, + JSDocTag = 246, + JSDocParameterTag = 247, + JSDocReturnTag = 248, + JSDocTypeTag = 249, + JSDocTemplateTag = 250, + SyntaxList = 251, + Count = 252, FirstAssignment = 53, LastAssignment = 64, FirstReservedWord = 66, @@ -495,7 +517,7 @@ declare module "typescript" { } interface YieldExpression extends Expression { asteriskToken?: Node; - expression: Expression; + expression?: Expression; } interface BinaryExpression extends Expression { left: Expression; @@ -666,7 +688,7 @@ declare module "typescript" { interface ClassElement extends Declaration { _classElementBrand: any; } - interface InterfaceDeclaration extends Declaration, ModuleElement { + interface InterfaceDeclaration extends Declaration, Statement { name: Identifier; typeParameters?: NodeArray; heritageClauses?: NodeArray; @@ -676,7 +698,7 @@ declare module "typescript" { token: SyntaxKind; types?: NodeArray; } - interface TypeAliasDeclaration extends Declaration, ModuleElement { + interface TypeAliasDeclaration extends Declaration, Statement { name: Identifier; type: TypeNode; } @@ -684,7 +706,7 @@ declare module "typescript" { name: DeclarationName; initializer?: Expression; } - interface EnumDeclaration extends Declaration, ModuleElement { + interface EnumDeclaration extends Declaration, Statement { name: Identifier; members: NodeArray; } @@ -739,6 +761,82 @@ declare module "typescript" { hasTrailingNewLine?: boolean; kind: SyntaxKind; } + interface JSDocTypeExpression extends Node { + type: JSDocType; + } + interface JSDocType extends TypeNode { + _jsDocTypeBrand: any; + } + interface JSDocAllType extends JSDocType { + _JSDocAllTypeBrand: any; + } + interface JSDocUnknownType extends JSDocType { + _JSDocUnknownTypeBrand: any; + } + interface JSDocArrayType extends JSDocType { + elementType: JSDocType; + } + interface JSDocUnionType extends JSDocType { + types: NodeArray; + } + interface JSDocTupleType extends JSDocType { + types: NodeArray; + } + interface JSDocNonNullableType extends JSDocType { + type: JSDocType; + } + interface JSDocNullableType extends JSDocType { + type: JSDocType; + } + interface JSDocRecordType extends JSDocType, TypeLiteralNode { + members: NodeArray; + } + interface JSDocTypeReference extends JSDocType { + name: EntityName; + typeArguments: NodeArray; + } + interface JSDocOptionalType extends JSDocType { + type: JSDocType; + } + interface JSDocFunctionType extends JSDocType, SignatureDeclaration { + parameters: NodeArray; + type: JSDocType; + } + interface JSDocVariadicType extends JSDocType { + type: JSDocType; + } + interface JSDocConstructorType extends JSDocType { + type: JSDocType; + } + interface JSDocThisType extends JSDocType { + type: JSDocType; + } + interface JSDocRecordMember extends PropertyDeclaration { + name: Identifier | LiteralExpression; + type?: JSDocType; + } + interface JSDocComment extends Node { + tags: NodeArray; + } + interface JSDocTag extends Node { + atToken: Node; + tagName: Identifier; + } + interface JSDocTemplateTag extends JSDocTag { + typeParameters: NodeArray; + } + interface JSDocReturnTag extends JSDocTag { + typeExpression: JSDocTypeExpression; + } + interface JSDocTypeTag extends JSDocTag { + typeExpression: JSDocTypeExpression; + } + interface JSDocParameterTag extends JSDocTag { + preParameterName?: Identifier; + typeExpression?: JSDocTypeExpression; + postParameterName?: Identifier; + isBracketed: boolean; + } interface SourceFile extends Declaration { statements: NodeArray; endOfFileToken: Node; @@ -1011,6 +1109,8 @@ declare module "typescript" { } interface InterfaceType extends ObjectType { typeParameters: TypeParameter[]; + outerTypeParameters: TypeParameter[]; + localTypeParameters: TypeParameter[]; } interface InterfaceTypeWithBaseTypes extends InterfaceType { baseTypes: ObjectType[]; @@ -1227,8 +1327,6 @@ declare module "typescript" { function getTrailingCommentRanges(text: string, pos: number): CommentRange[]; function isIdentifierStart(ch: number, languageVersion: ScriptTarget): boolean; function isIdentifierPart(ch: number, languageVersion: ScriptTarget): boolean; - /** Creates a scanner over a (possibly unspecified) range of a piece of text. */ - function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, text?: string, onError?: ErrorCallback, start?: number, length?: number): Scanner; } declare module "typescript" { function getDefaultLibFileName(options: CompilerOptions): string; @@ -1257,8 +1355,10 @@ declare module "typescript" { * Vn. */ function collapseTextChangeRangesAcrossMultipleVersions(changes: TextChangeRange[]): TextChangeRange; + function getTypeParameterOwner(d: Declaration): Declaration; } declare module "typescript" { + var throwOnJSDocErrors: boolean; function getNodeConstructor(kind: SyntaxKind): new () => Node; function createNode(kind: SyntaxKind): Node; function forEachChild(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T; diff --git a/bin/typescript.js b/bin/typescript.js index f91570ad95f..1b5c7949463 100644 --- a/bin/typescript.js +++ b/bin/typescript.js @@ -270,10 +270,35 @@ var ts; SyntaxKind[SyntaxKind["EnumMember"] = 227] = "EnumMember"; // Top-level nodes SyntaxKind[SyntaxKind["SourceFile"] = 228] = "SourceFile"; + // JSDoc nodes. + SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 229] = "JSDocTypeExpression"; + // The * type. + SyntaxKind[SyntaxKind["JSDocAllType"] = 230] = "JSDocAllType"; + // The ? type. + SyntaxKind[SyntaxKind["JSDocUnknownType"] = 231] = "JSDocUnknownType"; + SyntaxKind[SyntaxKind["JSDocArrayType"] = 232] = "JSDocArrayType"; + SyntaxKind[SyntaxKind["JSDocUnionType"] = 233] = "JSDocUnionType"; + SyntaxKind[SyntaxKind["JSDocTupleType"] = 234] = "JSDocTupleType"; + SyntaxKind[SyntaxKind["JSDocNullableType"] = 235] = "JSDocNullableType"; + SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 236] = "JSDocNonNullableType"; + SyntaxKind[SyntaxKind["JSDocRecordType"] = 237] = "JSDocRecordType"; + SyntaxKind[SyntaxKind["JSDocRecordMember"] = 238] = "JSDocRecordMember"; + SyntaxKind[SyntaxKind["JSDocTypeReference"] = 239] = "JSDocTypeReference"; + SyntaxKind[SyntaxKind["JSDocOptionalType"] = 240] = "JSDocOptionalType"; + SyntaxKind[SyntaxKind["JSDocFunctionType"] = 241] = "JSDocFunctionType"; + SyntaxKind[SyntaxKind["JSDocVariadicType"] = 242] = "JSDocVariadicType"; + SyntaxKind[SyntaxKind["JSDocConstructorType"] = 243] = "JSDocConstructorType"; + SyntaxKind[SyntaxKind["JSDocThisType"] = 244] = "JSDocThisType"; + SyntaxKind[SyntaxKind["JSDocComment"] = 245] = "JSDocComment"; + SyntaxKind[SyntaxKind["JSDocTag"] = 246] = "JSDocTag"; + SyntaxKind[SyntaxKind["JSDocParameterTag"] = 247] = "JSDocParameterTag"; + SyntaxKind[SyntaxKind["JSDocReturnTag"] = 248] = "JSDocReturnTag"; + SyntaxKind[SyntaxKind["JSDocTypeTag"] = 249] = "JSDocTypeTag"; + SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 250] = "JSDocTemplateTag"; // Synthesized list - SyntaxKind[SyntaxKind["SyntaxList"] = 229] = "SyntaxList"; + SyntaxKind[SyntaxKind["SyntaxList"] = 251] = "SyntaxList"; // Enum value count - SyntaxKind[SyntaxKind["Count"] = 230] = "Count"; + SyntaxKind[SyntaxKind["Count"] = 252] = "Count"; // Markers SyntaxKind[SyntaxKind["FirstAssignment"] = 53] = "FirstAssignment"; SyntaxKind[SyntaxKind["LastAssignment"] = 64] = "LastAssignment"; @@ -323,6 +348,7 @@ var ts; var NodeFlags = ts.NodeFlags; /* @internal */ (function (ParserContextFlags) { + ParserContextFlags[ParserContextFlags["None"] = 0] = "None"; // Set if this node was parsed in strict mode. Used for grammar error checks, as well as // checking if the node can be reused in incremental settings. ParserContextFlags[ParserContextFlags["StrictMode"] = 1] = "StrictMode"; @@ -338,14 +364,17 @@ var ts; // the parser only sets this directly on the node it creates right after encountering the // error. ParserContextFlags[ParserContextFlags["ThisNodeHasError"] = 32] = "ThisNodeHasError"; + // This node was parsed in a JavaScript file and can be processed differently. For example + // its type can be specified usign a JSDoc comment. + ParserContextFlags[ParserContextFlags["JavaScriptFile"] = 64] = "JavaScriptFile"; // Context flags set directly by the parser. ParserContextFlags[ParserContextFlags["ParserGeneratedFlags"] = 63] = "ParserGeneratedFlags"; // Context flags computed by aggregating child flags upwards. // Used during incremental parsing to determine if this node or any of its children had an // error. Computed only once and then cached. - ParserContextFlags[ParserContextFlags["ThisNodeOrAnySubNodesHasError"] = 64] = "ThisNodeOrAnySubNodesHasError"; + ParserContextFlags[ParserContextFlags["ThisNodeOrAnySubNodesHasError"] = 128] = "ThisNodeOrAnySubNodesHasError"; // Used to know if we've computed data from children and cached it in this node. - ParserContextFlags[ParserContextFlags["HasAggregatedChildData"] = 128] = "HasAggregatedChildData"; + ParserContextFlags[ParserContextFlags["HasAggregatedChildData"] = 256] = "HasAggregatedChildData"; })(ts.ParserContextFlags || (ts.ParserContextFlags = {})); var ParserContextFlags = ts.ParserContextFlags; /* @internal */ @@ -826,6 +855,16 @@ var ts; } } ts.addRange = addRange; + function rangeEquals(array1, array2, pos, end) { + while (pos < end) { + if (array1[pos] !== array2[pos]) { + return false; + } + pos++; + } + return true; + } + ts.rangeEquals = rangeEquals; /** * Returns the last element of an array if non-empty, undefined otherwise. */ @@ -995,8 +1034,10 @@ var ts; var end = start + length; Debug.assert(start >= 0, "start must be non-negative, is " + start); Debug.assert(length >= 0, "length must be non-negative, is " + length); - Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); - Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + if (file) { + Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); + Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + } var text = getLocaleSpecificMessage(message.key); if (arguments.length > 4) { text = formatStringFromArgs(text, arguments, 4); @@ -1584,7 +1625,7 @@ var ts; for (var _i = 0; _i < files.length; _i++) { var current = files[_i]; var name = ts.combinePaths(path, current); - var stat = _fs.lstatSync(name); + var stat = _fs.statSync(name); if (stat.isFile()) { if (!extension || ts.fileExtensionIs(name, extension)) { result.push(name); @@ -1790,7 +1831,7 @@ var ts; Unterminated_template_literal: { code: 1160, category: ts.DiagnosticCategory.Error, key: "Unterminated template literal." }, Unterminated_regular_expression_literal: { code: 1161, category: ts.DiagnosticCategory.Error, key: "Unterminated regular expression literal." }, An_object_member_cannot_be_declared_optional: { code: 1162, category: ts.DiagnosticCategory.Error, key: "An object member cannot be declared optional." }, - yield_expression_must_be_contained_within_a_generator_declaration: { code: 1163, category: ts.DiagnosticCategory.Error, key: "'yield' expression must be contained_within a generator declaration." }, + A_yield_expression_is_only_allowed_in_a_generator_body: { code: 1163, category: ts.DiagnosticCategory.Error, key: "A 'yield' expression is only allowed in a generator body." }, Computed_property_names_are_not_allowed_in_enums: { code: 1164, category: ts.DiagnosticCategory.Error, key: "Computed property names are not allowed in enums." }, A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol: { code: 1165, category: ts.DiagnosticCategory.Error, key: "A computed property name in an ambient context must directly refer to a built-in symbol." }, A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol: { code: 1166, category: ts.DiagnosticCategory.Error, key: "A computed property name in a class property declaration must directly refer to a built-in symbol." }, @@ -1845,6 +1886,10 @@ var ts; Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." }, Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: ts.DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." }, Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: ts.DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." }, + Generators_are_only_available_when_targeting_ECMAScript_6_or_higher: { code: 1220, category: ts.DiagnosticCategory.Error, key: "Generators are only available when targeting ECMAScript 6 or higher." }, + Generators_are_not_allowed_in_an_ambient_context: { code: 1221, category: ts.DiagnosticCategory.Error, key: "Generators are not allowed in an ambient context." }, + An_overload_signature_cannot_be_declared_as_a_generator: { code: 1222, category: ts.DiagnosticCategory.Error, key: "An overload signature cannot be declared as a generator." }, + _0_tag_already_specified: { code: 1223, category: ts.DiagnosticCategory.Error, key: "'{0}' tag already specified." }, Duplicate_identifier_0: { code: 2300, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: ts.DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: ts.DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, @@ -2005,7 +2050,7 @@ var ts; The_0_operator_cannot_be_applied_to_type_symbol: { code: 2469, category: ts.DiagnosticCategory.Error, key: "The '{0}' operator cannot be applied to type 'symbol'." }, Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: { code: 2470, category: ts.DiagnosticCategory.Error, key: "'Symbol' reference does not refer to the global Symbol constructor object." }, A_computed_property_name_of_the_form_0_must_be_of_type_symbol: { code: 2471, category: ts.DiagnosticCategory.Error, key: "A computed property name of the form '{0}' must be of type 'symbol'." }, - Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher: { code: 2472, category: ts.DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher." }, + Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: { code: 2472, category: ts.DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher." }, Enum_declarations_must_all_be_const_or_non_const: { code: 2473, category: ts.DiagnosticCategory.Error, key: "Enum declarations must all be const or non-const." }, In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 2474, category: ts.DiagnosticCategory.Error, key: "In 'const' enum declarations member initializer must be constant expression." }, const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: { code: 2475, category: ts.DiagnosticCategory.Error, key: "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment." }, @@ -2036,6 +2081,8 @@ var ts; A_rest_element_cannot_contain_a_binding_pattern: { code: 2501, category: ts.DiagnosticCategory.Error, key: "A rest element cannot contain a binding pattern." }, _0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: { code: 2502, category: ts.DiagnosticCategory.Error, key: "'{0}' is referenced directly or indirectly in its own type annotation." }, Cannot_find_namespace_0: { code: 2503, category: ts.DiagnosticCategory.Error, key: "Cannot find namespace '{0}'." }, + No_best_common_type_exists_among_yield_expressions: { code: 2504, category: ts.DiagnosticCategory.Error, key: "No best common type exists among yield expressions." }, + A_generator_cannot_have_a_void_type_annotation: { code: 2505, category: ts.DiagnosticCategory.Error, key: "A generator cannot have a 'void' type annotation." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, @@ -2196,6 +2243,7 @@ var ts; _0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: ts.DiagnosticCategory.Error, key: "'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer." }, _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7023, category: ts.DiagnosticCategory.Error, key: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: ts.DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, + Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: ts.DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." }, You_cannot_rename_this_element: { code: 8000, category: ts.DiagnosticCategory.Error, key: "You cannot rename this element." }, You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: ts.DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." }, import_can_only_be_used_in_a_ts_file: { code: 8002, category: ts.DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." }, @@ -2209,16 +2257,12 @@ var ts; types_can_only_be_used_in_a_ts_file: { code: 8010, category: ts.DiagnosticCategory.Error, key: "'types' can only be used in a .ts file." }, type_arguments_can_only_be_used_in_a_ts_file: { code: 8011, category: ts.DiagnosticCategory.Error, key: "'type arguments' can only be used in a .ts file." }, parameter_modifiers_can_only_be_used_in_a_ts_file: { code: 8012, category: ts.DiagnosticCategory.Error, key: "'parameter modifiers' can only be used in a .ts file." }, - can_only_be_used_in_a_ts_file: { code: 8013, category: ts.DiagnosticCategory.Error, key: "'?' can only be used in a .ts file." }, property_declarations_can_only_be_used_in_a_ts_file: { code: 8014, category: ts.DiagnosticCategory.Error, key: "'property declarations' can only be used in a .ts file." }, enum_declarations_can_only_be_used_in_a_ts_file: { code: 8015, category: ts.DiagnosticCategory.Error, key: "'enum declarations' can only be used in a .ts file." }, type_assertion_expressions_can_only_be_used_in_a_ts_file: { code: 8016, category: ts.DiagnosticCategory.Error, key: "'type assertion expressions' can only be used in a .ts file." }, decorators_can_only_be_used_in_a_ts_file: { code: 8017, category: ts.DiagnosticCategory.Error, key: "'decorators' can only be used in a .ts file." }, - yield_expressions_are_not_currently_supported: { code: 9000, category: ts.DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." }, - Generators_are_not_currently_supported: { code: 9001, category: ts.DiagnosticCategory.Error, key: "Generators are not currently supported." }, Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: ts.DiagnosticCategory.Error, key: "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses." }, - class_expressions_are_not_currently_supported: { code: 9003, category: ts.DiagnosticCategory.Error, key: "'class' expressions are not currently supported." }, - class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration: { code: 9004, category: ts.DiagnosticCategory.Error, key: "'class' declarations are only supported directly inside a module or as a top level declaration." } + class_expressions_are_not_currently_supported: { code: 9003, category: ts.DiagnosticCategory.Error, key: "'class' expressions are not currently supported." } }; })(ts || (ts = {})); /// @@ -2754,12 +2798,17 @@ var ts; ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierPart(ch, languageVersion); } ts.isIdentifierPart = isIdentifierPart; - /** Creates a scanner over a (possibly unspecified) range of a piece of text. */ + /* @internal */ + // Creates a scanner over a (possibly unspecified) range of a piece of text. function createScanner(languageVersion, skipTrivia, text, onError, start, length) { - var pos; // Current position (end position of text of current token) - var end; // end of text - var startPos; // Start position of whitespace before current token - var tokenPos; // Start position of text of current token + // Current position (end position of text of current token) + var pos; + // end of text + var end; + // Start position of whitespace before current token + var startPos; + // Start position of text of current token + var tokenPos; var token; var tokenValue; var precedingLineBreak; @@ -4071,17 +4120,17 @@ var ts; bindBlockScopedDeclaration(node, 32 /* Class */, 899583 /* ClassExcludes */); break; case 203 /* InterfaceDeclaration */: - bindDeclaration(node, 64 /* Interface */, 792992 /* InterfaceExcludes */, false); + bindBlockScopedDeclaration(node, 64 /* Interface */, 792992 /* InterfaceExcludes */); break; case 204 /* TypeAliasDeclaration */: - bindDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */, false); + bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */); break; case 205 /* EnumDeclaration */: if (ts.isConst(node)) { - bindDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */, false); + bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */); } else { - bindDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */, false); + bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */); } break; case 206 /* ModuleDeclaration */: @@ -4230,11 +4279,11 @@ var ts; // Returns true if this node contains a parse error anywhere underneath it. function containsParseError(node) { aggregateChildData(node); - return (node.parserContextFlags & 64 /* ThisNodeOrAnySubNodesHasError */) !== 0; + return (node.parserContextFlags & 128 /* ThisNodeOrAnySubNodesHasError */) !== 0; } ts.containsParseError = containsParseError; function aggregateChildData(node) { - if (!(node.parserContextFlags & 128 /* HasAggregatedChildData */)) { + if (!(node.parserContextFlags & 256 /* HasAggregatedChildData */)) { // A node is considered to contain a parse error if: // a) the parser explicitly marked that it had an error // b) any of it's children reported that it had an error. @@ -4242,12 +4291,12 @@ var ts; ts.forEachChild(node, containsParseError); // If so, mark ourselves accordingly. if (thisNodeOrAnySubNodesHasError) { - node.parserContextFlags |= 64 /* ThisNodeOrAnySubNodesHasError */; + node.parserContextFlags |= 128 /* ThisNodeOrAnySubNodesHasError */; } // Also mark that we've propogated the child information to this node. This way we can // always consult the bit directly on this node without needing to check its children // again. - node.parserContextFlags |= 128 /* HasAggregatedChildData */; + node.parserContextFlags |= 256 /* HasAggregatedChildData */; } } function getSourceFileOfNode(node) { @@ -4534,6 +4583,88 @@ var ts; } ts.getJsDocComments = getJsDocComments; ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; + function isTypeNode(node) { + if (142 /* FirstTypeNode */ <= node.kind && node.kind <= 150 /* LastTypeNode */) { + return true; + } + switch (node.kind) { + case 112 /* AnyKeyword */: + case 120 /* NumberKeyword */: + case 122 /* StringKeyword */: + case 113 /* BooleanKeyword */: + case 123 /* SymbolKeyword */: + return true; + case 99 /* VoidKeyword */: + return node.parent.kind !== 167 /* VoidExpression */; + case 8 /* StringLiteral */: + // Specialized signatures can have string literals as their parameters' type names + return node.parent.kind === 130 /* Parameter */; + case 177 /* ExpressionWithTypeArguments */: + return true; + // Identifiers and qualified names may be type nodes, depending on their context. Climb + // above them to find the lowest container + case 65 /* Identifier */: + // If the identifier is the RHS of a qualified name, then it's a type iff its parent is. + if (node.parent.kind === 127 /* QualifiedName */ && node.parent.right === node) { + node = node.parent; + } + else if (node.parent.kind === 156 /* PropertyAccessExpression */ && node.parent.name === node) { + node = node.parent; + } + // fall through + case 127 /* QualifiedName */: + case 156 /* PropertyAccessExpression */: + // At this point, node is either a qualified name or an identifier + ts.Debug.assert(node.kind === 65 /* Identifier */ || node.kind === 127 /* QualifiedName */ || node.kind === 156 /* PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'."); + var parent_1 = node.parent; + if (parent_1.kind === 145 /* TypeQuery */) { + return false; + } + // Do not recursively call isTypeNode on the parent. In the example: + // + // let a: A.B.C; + // + // Calling isTypeNode would consider the qualified name A.B a type node. Only C or + // A.B.C is a type node. + if (142 /* FirstTypeNode */ <= parent_1.kind && parent_1.kind <= 150 /* LastTypeNode */) { + return true; + } + switch (parent_1.kind) { + case 177 /* ExpressionWithTypeArguments */: + return true; + case 129 /* TypeParameter */: + return node === parent_1.constraint; + case 133 /* PropertyDeclaration */: + case 132 /* PropertySignature */: + case 130 /* Parameter */: + case 199 /* VariableDeclaration */: + return node === parent_1.type; + case 201 /* FunctionDeclaration */: + case 163 /* FunctionExpression */: + case 164 /* ArrowFunction */: + case 136 /* Constructor */: + case 135 /* MethodDeclaration */: + case 134 /* MethodSignature */: + case 137 /* GetAccessor */: + case 138 /* SetAccessor */: + return node === parent_1.type; + case 139 /* CallSignature */: + case 140 /* ConstructSignature */: + case 141 /* IndexSignature */: + return node === parent_1.type; + case 161 /* TypeAssertionExpression */: + return node === parent_1.type; + case 158 /* CallExpression */: + case 159 /* NewExpression */: + return parent_1.typeArguments && ts.indexOf(parent_1.typeArguments, node) >= 0; + case 160 /* TaggedTemplateExpression */: + // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments. + return false; + } + } + return false; + } + ts.isTypeNode = isTypeNode; // Warning: This has the same semantics as the forEach family of functions, // in that traversal terminates in the event that 'visitor' supplies a truthy value. function forEachReturnStatement(body, visitor) { @@ -4562,6 +4693,44 @@ var ts; } } ts.forEachReturnStatement = forEachReturnStatement; + function forEachYieldExpression(body, visitor) { + return traverse(body); + function traverse(node) { + switch (node.kind) { + case 173 /* YieldExpression */: + visitor(node); + var operand = node.expression; + if (operand) { + traverse(operand); + } + case 205 /* EnumDeclaration */: + case 203 /* InterfaceDeclaration */: + case 206 /* ModuleDeclaration */: + case 204 /* TypeAliasDeclaration */: + case 202 /* ClassDeclaration */: + // These are not allowed inside a generator now, but eventually they may be allowed + // as local types. Regardless, any yield statements contained within them should be + // skipped in this traversal. + return; + default: + if (isFunctionLike(node)) { + var name_3 = node.name; + if (name_3 && name_3.kind === 128 /* ComputedPropertyName */) { + // Note that we will not include methods/accessors of a class because they would require + // first descending into the class. This is by design. + traverse(name_3.expression); + return; + } + } + else if (!isTypeNode(node)) { + // This is the general case, which should include mostly expressions and statements. + // Also includes NodeArrays. + ts.forEachChild(node, traverse); + } + } + } + } + ts.forEachYieldExpression = forEachYieldExpression; function isVariableLike(node) { if (node) { switch (node.kind) { @@ -4590,6 +4759,12 @@ var ts; return false; } ts.isAccessor = isAccessor; + function isClassLike(node) { + if (node) { + return node.kind === 202 /* ClassDeclaration */ || node.kind === 175 /* ClassExpression */; + } + } + ts.isClassLike = isClassLike; function isFunctionLike(node) { if (node) { switch (node.kind) { @@ -4840,6 +5015,7 @@ var ts; case 172 /* TemplateExpression */: case 10 /* NoSubstitutionTemplateLiteral */: case 176 /* OmittedExpression */: + case 173 /* YieldExpression */: return true; case 127 /* QualifiedName */: while (node.parent.kind === 127 /* QualifiedName */) { @@ -4853,8 +5029,8 @@ var ts; // fall through case 7 /* NumericLiteral */: case 8 /* StringLiteral */: - var parent_1 = node.parent; - switch (parent_1.kind) { + var parent_2 = node.parent; + switch (parent_2.kind) { case 199 /* VariableDeclaration */: case 130 /* Parameter */: case 133 /* PropertyDeclaration */: @@ -4862,7 +5038,7 @@ var ts; case 227 /* EnumMember */: case 225 /* PropertyAssignment */: case 153 /* BindingElement */: - return parent_1.initializer === node; + return parent_2.initializer === node; case 183 /* ExpressionStatement */: case 184 /* IfStatement */: case 185 /* DoStatement */: @@ -4873,27 +5049,27 @@ var ts; case 221 /* CaseClause */: case 196 /* ThrowStatement */: case 194 /* SwitchStatement */: - return parent_1.expression === node; + return parent_2.expression === node; case 187 /* ForStatement */: - var forStatement = parent_1; + var forStatement = parent_2; return (forStatement.initializer === node && forStatement.initializer.kind !== 200 /* VariableDeclarationList */) || forStatement.condition === node || forStatement.incrementor === node; case 188 /* ForInStatement */: case 189 /* ForOfStatement */: - var forInStatement = parent_1; + var forInStatement = parent_2; return (forInStatement.initializer === node && forInStatement.initializer.kind !== 200 /* VariableDeclarationList */) || forInStatement.expression === node; case 161 /* TypeAssertionExpression */: - return node === parent_1.expression; + return node === parent_2.expression; case 178 /* TemplateSpan */: - return node === parent_1.expression; + return node === parent_2.expression; case 128 /* ComputedPropertyName */: - return node === parent_1.expression; + return node === parent_2.expression; case 131 /* Decorator */: return true; default: - if (isExpression(parent_1)) { + if (isExpression(parent_2)) { return true; } } @@ -4961,6 +5137,74 @@ var ts; return s.parameters.length > 0 && ts.lastOrUndefined(s.parameters).dotDotDotToken !== undefined; } ts.hasRestParameters = hasRestParameters; + function isJSDocConstructSignature(node) { + return node.kind === 241 /* JSDocFunctionType */ && + node.parameters.length > 0 && + node.parameters[0].type.kind === 243 /* JSDocConstructorType */; + } + ts.isJSDocConstructSignature = isJSDocConstructSignature; + function getJSDocTag(node, kind) { + if (node && node.jsDocComment) { + for (var _i = 0, _a = node.jsDocComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.kind === kind) { + return tag; + } + } + } + } + function getJSDocTypeTag(node) { + return getJSDocTag(node, 249 /* JSDocTypeTag */); + } + ts.getJSDocTypeTag = getJSDocTypeTag; + function getJSDocReturnTag(node) { + return getJSDocTag(node, 248 /* JSDocReturnTag */); + } + ts.getJSDocReturnTag = getJSDocReturnTag; + function getJSDocTemplateTag(node) { + return getJSDocTag(node, 250 /* JSDocTemplateTag */); + } + ts.getJSDocTemplateTag = getJSDocTemplateTag; + function getCorrespondingJSDocParameterTag(parameter) { + if (parameter.name && parameter.name.kind === 65 /* Identifier */) { + // If it's a parameter, see if the parent has a jsdoc comment with an @param + // annotation. + var parameterName = parameter.name.text; + var docComment = parameter.parent.jsDocComment; + if (docComment) { + return ts.forEach(docComment.tags, function (t) { + if (t.kind === 247 /* JSDocParameterTag */) { + var parameterTag = t; + var name_4 = parameterTag.preParameterName || parameterTag.postParameterName; + if (name_4.text === parameterName) { + return t; + } + } + }); + } + } + } + ts.getCorrespondingJSDocParameterTag = getCorrespondingJSDocParameterTag; + function hasRestParameter(s) { + return isRestParameter(ts.lastOrUndefined(s.parameters)); + } + ts.hasRestParameter = hasRestParameter; + function isRestParameter(node) { + if (node) { + if (node.parserContextFlags & 64 /* JavaScriptFile */) { + if (node.type && node.type.kind === 242 /* JSDocVariadicType */) { + return true; + } + var paramTag = getCorrespondingJSDocParameterTag(node); + if (paramTag && paramTag.typeExpression) { + return paramTag.typeExpression.type.kind === 242 /* JSDocVariadicType */; + } + } + return node.dotDotDotToken !== undefined; + } + return false; + } + ts.isRestParameter = isRestParameter; function isLiteralKind(kind) { return 7 /* FirstLiteralToken */ <= kind && kind <= 10 /* LastLiteralToken */; } @@ -5751,6 +5995,10 @@ var ts; return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & 256 /* Default */) ? symbol.valueDeclaration.localSymbol : undefined; } ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault; + function isJavaScript(fileName) { + return ts.fileExtensionIs(fileName, ".js"); + } + ts.isJavaScript = isJavaScript; /** * Replace each instance of non-ascii characters by one, two, three, or four escape sequences * representing the UTF-8 encoding of the character, and return the expanded char code list. @@ -6024,12 +6272,23 @@ var ts; return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), newEndN - oldStartN); } ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions; + function getTypeParameterOwner(d) { + if (d && d.kind === 129 /* TypeParameter */) { + for (var current = d; current; current = current.parent) { + if (ts.isFunctionLike(current) || ts.isClassLike(current) || current.kind === 203 /* InterfaceDeclaration */) { + return current; + } + } + } + } + ts.getTypeParameterOwner = getTypeParameterOwner; })(ts || (ts = {})); /// /// var ts; (function (ts) { - var nodeConstructors = new Array(230 /* Count */); + ts.throwOnJSDocErrors = false; + var nodeConstructors = new Array(252 /* Count */); /* @internal */ ts.parseTime = 0; function getNodeConstructor(kind) { return nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind)); @@ -6339,6 +6598,49 @@ var ts; return visitNode(cbNode, node.expression); case 219 /* MissingDeclaration */: return visitNodes(cbNodes, node.decorators); + case 229 /* JSDocTypeExpression */: + return visitNode(cbNode, node.type); + case 233 /* JSDocUnionType */: + return visitNodes(cbNodes, node.types); + case 234 /* JSDocTupleType */: + return visitNodes(cbNodes, node.types); + case 232 /* JSDocArrayType */: + return visitNode(cbNode, node.elementType); + case 236 /* JSDocNonNullableType */: + return visitNode(cbNode, node.type); + case 235 /* JSDocNullableType */: + return visitNode(cbNode, node.type); + case 237 /* JSDocRecordType */: + return visitNodes(cbNodes, node.members); + case 239 /* JSDocTypeReference */: + return visitNode(cbNode, node.name) || + visitNodes(cbNodes, node.typeArguments); + case 240 /* JSDocOptionalType */: + return visitNode(cbNode, node.type); + case 241 /* JSDocFunctionType */: + return visitNodes(cbNodes, node.parameters) || + visitNode(cbNode, node.type); + case 242 /* JSDocVariadicType */: + return visitNode(cbNode, node.type); + case 243 /* JSDocConstructorType */: + return visitNode(cbNode, node.type); + case 244 /* JSDocThisType */: + return visitNode(cbNode, node.type); + case 238 /* JSDocRecordMember */: + return visitNode(cbNode, node.name) || + visitNode(cbNode, node.type); + case 245 /* JSDocComment */: + return visitNodes(cbNodes, node.tags); + case 247 /* JSDocParameterTag */: + return visitNode(cbNode, node.preParameterName) || + visitNode(cbNode, node.typeExpression) || + visitNode(cbNode, node.postParameterName); + case 248 /* JSDocReturnTag */: + return visitNode(cbNode, node.typeExpression); + case 249 /* JSDocTypeTag */: + return visitNode(cbNode, node.typeExpression); + case 250 /* JSDocTemplateTag */: + return visitNodes(cbNodes, node.typeParameters); } } ts.forEachChild = forEachChild; @@ -6363,6 +6665,17 @@ var ts; return IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); } ts.updateSourceFile = updateSourceFile; + /* @internal */ + function parseIsolatedJSDocComment(content, start, length) { + return Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length); + } + ts.parseIsolatedJSDocComment = parseIsolatedJSDocComment; + /* @internal */ + // Exposed only for testing. + function parseJSDocTypeExpressionForTests(content, start, length) { + return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length); + } + ts.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests; // Implement the parser as a singleton module. We do this for perf reasons because creating // parser instances can actually be expensive enough to impact us on projects with many source // files. @@ -6373,6 +6686,7 @@ var ts; var scanner = ts.createScanner(2 /* Latest */, true); var disallowInAndDecoratorContext = 2 /* DisallowIn */ | 16 /* Decorator */; var sourceFile; + var parseDiagnostics; var syntaxCursor; var token; var sourceText; @@ -6426,7 +6740,7 @@ var ts; // Note: it should not be necessary to save/restore these flags during speculative/lookahead // parsing. These context flags are naturally stored and restored through normal recursive // descent parsing and unwinding. - var contextFlags = 0; + var contextFlags; // Whether or not we've had a parse error since creating the last AST node. If we have // encountered an error, it will be stored on the next AST node we create. Parse errors // can be broken down into three categories: @@ -6455,20 +6769,49 @@ var ts; // Note: any errors at the end of the file that do not precede a regular node, should get // attached to the EOF token. var parseErrorBeforeNextFinishedNode = false; + (function (StatementFlags) { + StatementFlags[StatementFlags["None"] = 0] = "None"; + StatementFlags[StatementFlags["Statement"] = 1] = "Statement"; + StatementFlags[StatementFlags["ModuleElement"] = 2] = "ModuleElement"; + StatementFlags[StatementFlags["StatementOrModuleElement"] = 3] = "StatementOrModuleElement"; + })(Parser.StatementFlags || (Parser.StatementFlags = {})); + var StatementFlags = Parser.StatementFlags; function parseSourceFile(fileName, _sourceText, languageVersion, _syntaxCursor, setParentNodes) { + initializeState(fileName, _sourceText, languageVersion, _syntaxCursor); + var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes); + clearState(); + return result; + } + Parser.parseSourceFile = parseSourceFile; + function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor) { sourceText = _sourceText; syntaxCursor = _syntaxCursor; + parseDiagnostics = []; parsingContext = 0; identifiers = {}; identifierCount = 0; nodeCount = 0; - contextFlags = 0; + contextFlags = ts.isJavaScript(fileName) ? 64 /* JavaScriptFile */ : 0 /* None */; parseErrorBeforeNextFinishedNode = false; - createSourceFile(fileName, languageVersion); // Initialize and prime the scanner before parsing the source elements. scanner.setText(sourceText); scanner.setOnError(scanError); scanner.setScriptTarget(languageVersion); + } + function clearState() { + // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily. + scanner.setText(""); + scanner.setOnError(undefined); + // Clear any data. We don't want to accidently hold onto it for too long. + parseDiagnostics = undefined; + sourceFile = undefined; + identifiers = undefined; + syntaxCursor = undefined; + sourceText = undefined; + } + function parseSourceFileWorker(fileName, languageVersion, setParentNodes) { + sourceFile = createSourceFile(fileName, languageVersion); + // Prime the scanner. token = nextToken(); processReferenceComments(sourceFile); sourceFile.statements = parseList(0 /* SourceElements */, true, parseSourceElement); @@ -6478,22 +6821,45 @@ var ts; sourceFile.nodeCount = nodeCount; sourceFile.identifierCount = identifierCount; sourceFile.identifiers = identifiers; + sourceFile.parseDiagnostics = parseDiagnostics; if (setParentNodes) { fixupParentReferences(sourceFile); } - syntaxCursor = undefined; - // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily. - scanner.setText(""); - scanner.setOnError(undefined); - var result = sourceFile; - // Clear any data. We don't want to accidently hold onto it for too long. - sourceFile = undefined; - identifiers = undefined; - syntaxCursor = undefined; - sourceText = undefined; - return result; + // If this is a javascript file, proactively see if we can get JSDoc comments for + // relevant nodes in the file. We'll use these to provide typing informaion if they're + // available. + if (ts.isJavaScript(fileName)) { + addJSDocComments(); + } + return sourceFile; + } + function addJSDocComments() { + forEachChild(sourceFile, visit); + return; + function visit(node) { + // Add additional cases as necessary depending on how we see JSDoc comments used + // in the wild. + switch (node.kind) { + case 181 /* VariableStatement */: + case 201 /* FunctionDeclaration */: + case 130 /* Parameter */: + addJSDocComment(node); + } + forEachChild(node, visit); + } + } + function addJSDocComment(node) { + var comments = ts.getLeadingCommentRangesOfNode(node, sourceFile); + if (comments) { + for (var _i = 0; _i < comments.length; _i++) { + var comment = comments[_i]; + var jsDocComment = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); + if (jsDocComment) { + node.jsDocComment = jsDocComment; + } + } + } } - Parser.parseSourceFile = parseSourceFile; function fixupParentReferences(sourceFile) { // normally parent references are set during binding. However, for clients that only need // a syntax tree, and no semantic features, then the binding process is an unnecessary @@ -6515,16 +6881,17 @@ var ts; } } } + Parser.fixupParentReferences = fixupParentReferences; function createSourceFile(fileName, languageVersion) { - sourceFile = createNode(228 /* SourceFile */, 0); + var sourceFile = createNode(228 /* SourceFile */, 0); sourceFile.pos = 0; sourceFile.end = sourceText.length; sourceFile.text = sourceText; - sourceFile.parseDiagnostics = []; sourceFile.bindDiagnostics = []; sourceFile.languageVersion = languageVersion; sourceFile.fileName = ts.normalizePath(fileName); sourceFile.flags = ts.fileExtensionIs(sourceFile.fileName, ".d.ts") ? 2048 /* DeclarationFile */ : 0; + return sourceFile; } function setContextFlag(val, flag) { if (val) { @@ -6632,9 +6999,9 @@ var ts; } function parseErrorAtPosition(start, length, message, arg0) { // Don't report another error if it would just be at the same position as the last error. - var lastError = ts.lastOrUndefined(sourceFile.parseDiagnostics); + var lastError = ts.lastOrUndefined(parseDiagnostics); if (!lastError || start !== lastError.start) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0)); } // Mark that we've encountered an error. We'll set an appropriate bit on the next // node we finish so that it can't be reused incrementally. @@ -6669,7 +7036,7 @@ var ts; // Keep track of the state we'll need to rollback to if lookahead fails (or if the // caller asked us to always reset our state). var saveToken = token; - var saveParseDiagnosticsLength = sourceFile.parseDiagnostics.length; + var saveParseDiagnosticsLength = parseDiagnostics.length; var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; // Note: it is not actually necessary to save/restore the context flags here. That's // because the saving/restorating of these flags happens naturally through the recursive @@ -6687,7 +7054,7 @@ var ts; // then unconditionally restore us to where we were. if (!result || isLookAhead) { token = saveToken; - sourceFile.parseDiagnostics.length = saveParseDiagnosticsLength; + parseDiagnostics.length = saveParseDiagnosticsLength; parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; } return result; @@ -6783,8 +7150,8 @@ var ts; node.end = pos; return node; } - function finishNode(node) { - node.end = scanner.getStartPos(); + function finishNode(node, end) { + node.end = end === undefined ? scanner.getStartPos() : end; if (contextFlags) { node.parserContextFlags = contextFlags; } @@ -6840,15 +7207,24 @@ var ts; token === 8 /* StringLiteral */ || token === 7 /* NumericLiteral */; } - function parsePropertyName() { + function parsePropertyNameWorker(allowComputedPropertyNames) { if (token === 8 /* StringLiteral */ || token === 7 /* NumericLiteral */) { return parseLiteralNode(true); } - if (token === 18 /* OpenBracketToken */) { + if (allowComputedPropertyNames && token === 18 /* OpenBracketToken */) { return parseComputedPropertyName(); } return parseIdentifierName(); } + function parsePropertyName() { + return parsePropertyNameWorker(true); + } + function parseSimplePropertyName() { + return parsePropertyNameWorker(false); + } + function isSimplePropertyName() { + return token === 8 /* StringLiteral */ || token === 7 /* NumericLiteral */ || isIdentifierOrKeyword(); + } function parseComputedPropertyName() { // PropertyName[Yield,GeneratorParameter] : // LiteralPropertyName @@ -6917,10 +7293,17 @@ var ts; switch (parsingContext) { case 0 /* SourceElements */: case 1 /* ModuleElements */: - return isSourceElement(inErrorRecovery); + // If we're in error recovery, then we don't want to treat ';' as an empty statement. + // The problem is that ';' can show up in far too many contexts, and if we see one + // and assume it's a statement, then we may bail out inappropriately from whatever + // we're parsing. For example, if we have a semicolon in the middle of a class, then + // we really don't want to assume the class is over and we're on a statement in the + // outer module. We just want to consume and move on. + return !(token === 22 /* SemicolonToken */ && inErrorRecovery) && isStartOfModuleElement(); case 2 /* BlockStatements */: case 4 /* SwitchClauseStatements */: - return isStartOfStatement(inErrorRecovery); + // During error recovery we don't treat empty statements as statements + return !(token === 22 /* SemicolonToken */ && inErrorRecovery) && isStartOfStatement(); case 3 /* SwitchClauses */: return token === 67 /* CaseKeyword */ || token === 73 /* DefaultKeyword */; case 5 /* TypeMembers */: @@ -6972,6 +7355,12 @@ var ts; return isHeritageClause(); case 20 /* ImportOrExportSpecifiers */: return isIdentifierOrKeyword(); + case 21 /* JSDocFunctionParameters */: + case 22 /* JSDocTypeArguments */: + case 24 /* JSDocTupleTypes */: + return JSDocParser.isJSDocType(); + case 23 /* JSDocRecordMembers */: + return isSimplePropertyName(); } ts.Debug.fail("Non-exhaustive case in 'isListElement'."); } @@ -7046,6 +7435,14 @@ var ts; return token === 25 /* GreaterThanToken */ || token === 16 /* OpenParenToken */; case 19 /* HeritageClauses */: return token === 14 /* OpenBraceToken */ || token === 15 /* CloseBraceToken */; + case 21 /* JSDocFunctionParameters */: + return token === 17 /* CloseParenToken */ || token === 51 /* ColonToken */ || token === 15 /* CloseBraceToken */; + case 22 /* JSDocTypeArguments */: + return token === 25 /* GreaterThanToken */ || token === 15 /* CloseBraceToken */; + case 24 /* JSDocTupleTypes */: + return token === 19 /* CloseBracketToken */ || token === 15 /* CloseBraceToken */; + case 23 /* JSDocRecordMembers */: + return token === 15 /* CloseBraceToken */; } } function isVariableDeclaratorListTerminator() { @@ -7071,7 +7468,7 @@ var ts; } // True if positioned at element or terminator of the current list or any enclosing list function isInSomeParsingContext() { - for (var kind = 0; kind < 21 /* Count */; kind++) { + for (var kind = 0; kind < 25 /* Count */; kind++) { if (parsingContext & (1 << kind)) { if (isListElement(kind, true) || isListTerminator(kind)) { return true; @@ -7094,7 +7491,7 @@ var ts; // test elements only if we are not already in strict mode if (checkForStrictMode && !inStrictModeContext()) { if (ts.isPrologueDirective(element)) { - if (isUseStrictPrologueDirective(sourceFile, element)) { + if (isUseStrictPrologueDirective(element)) { setStrictModeContext(true); checkForStrictMode = false; } @@ -7115,9 +7512,9 @@ var ts; return result; } /// Should be called only on prologue directives (isPrologueDirective(node) should be true) - function isUseStrictPrologueDirective(sourceFile, node) { + function isUseStrictPrologueDirective(node) { ts.Debug.assert(ts.isPrologueDirective(node)); - var nodeText = ts.getSourceTextOfNodeFromSourceFile(sourceFile, node.expression); + var nodeText = ts.getTextOfNodeFromSourceText(sourceText, node.expression); // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the // string to contain unicode escapes (as per ES5). return nodeText === '"use strict"' || nodeText === "'use strict'"; @@ -7390,6 +7787,10 @@ var ts; case 18 /* TupleElementTypes */: return ts.Diagnostics.Type_expected; case 19 /* HeritageClauses */: return ts.Diagnostics.Unexpected_token_expected; case 20 /* ImportOrExportSpecifiers */: return ts.Diagnostics.Identifier_expected; + case 21 /* JSDocFunctionParameters */: return ts.Diagnostics.Parameter_declaration_expected; + case 22 /* JSDocTypeArguments */: return ts.Diagnostics.Type_argument_expected; + case 24 /* JSDocTupleTypes */: return ts.Diagnostics.Type_expected; + case 23 /* JSDocRecordMembers */: return ts.Diagnostics.Property_assignment_expected; } } ; @@ -8249,11 +8650,6 @@ var ts; nextToken(); return !scanner.hasPrecedingLineBreak() && isIdentifier(); } - function nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine() { - nextToken(); - return !scanner.hasPrecedingLineBreak() && - (isIdentifier() || token === 14 /* OpenBraceToken */ || token === 18 /* OpenBracketToken */); - } function parseYieldExpression() { var node = createNode(173 /* YieldExpression */); // YieldExpression[In] : @@ -8425,10 +8821,11 @@ var ts; if (token === 14 /* OpenBraceToken */) { return parseFunctionBlock(false, false); } - if (isStartOfStatement(true) && - !isStartOfExpressionStatement() && + if (token !== 22 /* SemicolonToken */ && token !== 83 /* FunctionKeyword */ && - token !== 69 /* ClassKeyword */) { + token !== 69 /* ClassKeyword */ && + isStartOfStatement() && + !isStartOfExpressionStatement()) { // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations) // // Here we try to recover from a potential error situation in the case where the @@ -9217,33 +9614,68 @@ var ts; return finishNode(expressionStatement); } } - function isStartOfStatement(inErrorRecovery) { - // Functions, variable statements and classes are allowed as a statement. But as per - // the grammar, they also allow modifiers. So we have to check for those statements - // that might be following modifiers.This ensures that things work properly when - // incrementally parsing as the parser will produce the same FunctionDeclaraiton, - // VariableStatement or ClassDeclaration, if it has the same text regardless of whether - // it is inside a block or not. - if (ts.isModifier(token)) { - var result = lookAhead(parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers); - if (result) { - return true; + function isIdentifierOrKeyword() { + return token >= 65 /* Identifier */; + } + function nextTokenIsIdentifierOrKeywordOnSameLine() { + nextToken(); + return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak(); + } + function parseDeclarationFlags() { + while (true) { + switch (token) { + case 98 /* VarKeyword */: + case 104 /* LetKeyword */: + case 70 /* ConstKeyword */: + case 83 /* FunctionKeyword */: + case 69 /* ClassKeyword */: + case 77 /* EnumKeyword */: + return 1 /* Statement */; + case 103 /* InterfaceKeyword */: + case 124 /* TypeKeyword */: + nextToken(); + return isIdentifierOrKeyword() ? 1 /* Statement */ : 0 /* None */; + case 117 /* ModuleKeyword */: + case 118 /* NamespaceKeyword */: + nextToken(); + return isIdentifierOrKeyword() || token === 8 /* StringLiteral */ ? 2 /* ModuleElement */ : 0 /* None */; + case 85 /* ImportKeyword */: + nextToken(); + return token === 8 /* StringLiteral */ || token === 35 /* AsteriskToken */ || + token === 14 /* OpenBraceToken */ || isIdentifierOrKeyword() ? + 2 /* ModuleElement */ : 0 /* None */; + case 78 /* ExportKeyword */: + nextToken(); + if (token === 53 /* EqualsToken */ || token === 35 /* AsteriskToken */ || + token === 14 /* OpenBraceToken */ || token === 73 /* DefaultKeyword */) { + return 2 /* ModuleElement */; + } + continue; + case 115 /* DeclareKeyword */: + case 108 /* PublicKeyword */: + case 106 /* PrivateKeyword */: + case 107 /* ProtectedKeyword */: + case 109 /* StaticKeyword */: + nextToken(); + continue; + default: + return 0 /* None */; } } + } + function getDeclarationFlags() { + return lookAhead(parseDeclarationFlags); + } + function getStatementFlags() { switch (token) { + case 52 /* AtToken */: case 22 /* SemicolonToken */: - // If we're in error recovery, then we don't want to treat ';' as an empty statement. - // The problem is that ';' can show up in far too many contexts, and if we see one - // and assume it's a statement, then we may bail out inappropriately from whatever - // we're parsing. For example, if we have a semicolon in the middle of a class, then - // we really don't want to assume the class is over and we're on a statement in the - // outer module. We just want to consume and move on. - return !inErrorRecovery; case 14 /* OpenBraceToken */: case 98 /* VarKeyword */: case 104 /* LetKeyword */: case 83 /* FunctionKeyword */: case 69 /* ClassKeyword */: + case 77 /* EnumKeyword */: case 84 /* IfKeyword */: case 75 /* DoKeyword */: case 100 /* WhileKeyword */: @@ -9260,58 +9692,72 @@ var ts; // however, we say they are here so that we may gracefully parse them and error later. case 68 /* CatchKeyword */: case 81 /* FinallyKeyword */: - return true; + return 1 /* Statement */; case 70 /* ConstKeyword */: - // const keyword can precede enum keyword when defining constant enums - // 'const enum' do not start statement. - // In ES 6 'enum' is a future reserved keyword, so it should not be used as identifier - var isConstEnum = lookAhead(nextTokenIsEnumKeyword); - return !isConstEnum; + case 78 /* ExportKeyword */: + case 85 /* ImportKeyword */: + return getDeclarationFlags(); + case 115 /* DeclareKeyword */: case 103 /* InterfaceKeyword */: case 117 /* ModuleKeyword */: case 118 /* NamespaceKeyword */: - case 77 /* EnumKeyword */: case 124 /* TypeKeyword */: - // When followed by an identifier, these do not start a statement but might - // instead be following declarations - if (isDeclarationStart()) { - return false; - } + // When these don't start a declaration, they're an identifier in an expression statement + return getDeclarationFlags() || 1 /* Statement */; case 108 /* PublicKeyword */: case 106 /* PrivateKeyword */: case 107 /* ProtectedKeyword */: case 109 /* StaticKeyword */: - // When followed by an identifier or keyword, these do not start a statement but - // might instead be following type members - if (lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine)) { - return false; - } + // When these don't start a declaration, they may be the start of a class member if an identifier + // immediately follows. Otherwise they're an identifier in an expression statement. + return getDeclarationFlags() || + (lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? 0 /* None */ : 1 /* Statement */); default: - return isStartOfExpression(); + return isStartOfExpression() ? 1 /* Statement */ : 0 /* None */; } } - function nextTokenIsEnumKeyword() { - nextToken(); - return token === 77 /* EnumKeyword */; + function isStartOfStatement() { + return (getStatementFlags() & 1 /* Statement */) !== 0; } - function nextTokenIsIdentifierOrKeywordOnSameLine() { + function isStartOfModuleElement() { + return (getStatementFlags() & 3 /* StatementOrModuleElement */) !== 0; + } + function nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine() { nextToken(); - return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak(); + return !scanner.hasPrecedingLineBreak() && + (isIdentifier() || token === 14 /* OpenBraceToken */ || token === 18 /* OpenBracketToken */); + } + function isLetDeclaration() { + // It is let declaration if in strict mode or next token is identifier\open bracket\open curly on same line. + // otherwise it needs to be treated like identifier + return inStrictModeContext() || lookAhead(nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine); } function parseStatement() { + return parseModuleElementOfKind(1 /* Statement */); + } + function parseModuleElement() { + return parseModuleElementOfKind(3 /* StatementOrModuleElement */); + } + function parseSourceElement() { + return parseModuleElementOfKind(3 /* StatementOrModuleElement */); + } + function parseModuleElementOfKind(flags) { switch (token) { + case 22 /* SemicolonToken */: + return parseEmptyStatement(); case 14 /* OpenBraceToken */: return parseBlock(false, false); case 98 /* VarKeyword */: - case 70 /* ConstKeyword */: - // const here should always be parsed as const declaration because of check in 'isStatement' return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + case 104 /* LetKeyword */: + if (isLetDeclaration()) { + return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + } + break; case 83 /* FunctionKeyword */: return parseFunctionDeclaration(scanner.getStartPos(), undefined, undefined); case 69 /* ClassKeyword */: return parseClassDeclaration(scanner.getStartPos(), undefined, undefined); - case 22 /* SemicolonToken */: - return parseEmptyStatement(); case 84 /* IfKeyword */: return parseIfStatement(); case 75 /* DoKeyword */: @@ -9339,54 +9785,68 @@ var ts; return parseTryStatement(); case 72 /* DebuggerKeyword */: return parseDebuggerStatement(); - case 104 /* LetKeyword */: - // If let follows identifier on the same line, it is declaration parse it as variable statement - if (isLetDeclaration()) { - return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + case 52 /* AtToken */: + return parseDeclaration(); + case 70 /* ConstKeyword */: + case 115 /* DeclareKeyword */: + case 77 /* EnumKeyword */: + case 78 /* ExportKeyword */: + case 85 /* ImportKeyword */: + case 103 /* InterfaceKeyword */: + case 117 /* ModuleKeyword */: + case 118 /* NamespaceKeyword */: + case 106 /* PrivateKeyword */: + case 107 /* ProtectedKeyword */: + case 108 /* PublicKeyword */: + case 109 /* StaticKeyword */: + case 124 /* TypeKeyword */: + if (getDeclarationFlags() & flags) { + return parseDeclaration(); } - // Else parse it like identifier - fall through - default: - // Functions and variable statements are allowed as a statement. But as per - // the grammar, they also allow modifiers. So we have to check for those - // statements that might be following modifiers. This ensures that things - // work properly when incrementally parsing as the parser will produce the - // same FunctionDeclaraiton or VariableStatement if it has the same text - // regardless of whether it is inside a block or not. - // Even though variable statements and function declarations cannot have decorators, - // we parse them here to provide better error recovery. - if (ts.isModifier(token) || token === 52 /* AtToken */) { - var result = tryParse(parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers); - if (result) { - return result; - } - } - return parseExpressionOrLabeledStatement(); + break; } + return parseExpressionOrLabeledStatement(); } - function parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers() { - var start = scanner.getStartPos(); + function parseDeclaration() { + var fullStart = getNodePos(); var decorators = parseDecorators(); var modifiers = parseModifiers(); switch (token) { - case 70 /* ConstKeyword */: - var nextTokenIsEnum = lookAhead(nextTokenIsEnumKeyword); - if (nextTokenIsEnum) { - return undefined; - } - return parseVariableStatement(start, decorators, modifiers); - case 104 /* LetKeyword */: - if (!isLetDeclaration()) { - return undefined; - } - return parseVariableStatement(start, decorators, modifiers); case 98 /* VarKeyword */: - return parseVariableStatement(start, decorators, modifiers); + case 104 /* LetKeyword */: + case 70 /* ConstKeyword */: + return parseVariableStatement(fullStart, decorators, modifiers); case 83 /* FunctionKeyword */: - return parseFunctionDeclaration(start, decorators, modifiers); + return parseFunctionDeclaration(fullStart, decorators, modifiers); case 69 /* ClassKeyword */: - return parseClassDeclaration(start, decorators, modifiers); + return parseClassDeclaration(fullStart, decorators, modifiers); + case 103 /* InterfaceKeyword */: + return parseInterfaceDeclaration(fullStart, decorators, modifiers); + case 124 /* TypeKeyword */: + return parseTypeAliasDeclaration(fullStart, decorators, modifiers); + case 77 /* EnumKeyword */: + return parseEnumDeclaration(fullStart, decorators, modifiers); + case 117 /* ModuleKeyword */: + case 118 /* NamespaceKeyword */: + return parseModuleDeclaration(fullStart, decorators, modifiers); + case 85 /* ImportKeyword */: + return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers); + case 78 /* ExportKeyword */: + nextToken(); + return token === 73 /* DefaultKeyword */ || token === 53 /* EqualsToken */ ? + parseExportAssignment(fullStart, decorators, modifiers) : + parseExportDeclaration(fullStart, decorators, modifiers); + default: + if (decorators) { + // We reached this point because we encountered decorators and/or modifiers and assumed a declaration + // would follow. For recovery and error reporting purposes, return an incomplete declaration. + var node = createMissingNode(219 /* MissingDeclaration */, true, ts.Diagnostics.Declaration_expected); + node.pos = fullStart; + node.decorators = decorators; + setModifiers(node, modifiers); + return finishNode(node); + } } - return undefined; } function parseFunctionBlockOrSemicolon(isGenerator, diagnosticMessage) { if (token !== 14 /* OpenBraceToken */ && canParseSemicolon()) { @@ -9541,7 +10001,18 @@ var ts; property.name = name; property.questionToken = questionToken; property.type = parseTypeAnnotation(); - property.initializer = allowInAnd(parseNonParameterInitializer); + // For instance properties specifically, since they are evaluated inside the constructor, + // we do *not * want to parse yield expressions, so we specifically turn the yield context + // off. The grammar would look something like this: + // + // MemberVariableDeclaration[Yield]: + // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initialiser_opt[In]; + // AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initialiser_opt[In, ?Yield]; + // + // The checker may still error in the static case to explicitly disallow the yield expression. + property.initializer = modifiers && modifiers.flags & 128 /* Static */ + ? allowInAnd(parseNonParameterInitializer) + : doOutsideOfContext(4 /* Yield */ | 2 /* DisallowIn */, parseNonParameterInitializer); parseSemicolon(); return finishNode(property); } @@ -9711,17 +10182,17 @@ var ts; } if (decorators) { // treat this as a property declaration with a missing name. - var name_3 = createMissingNode(65 /* Identifier */, true, ts.Diagnostics.Declaration_expected); - return parsePropertyDeclaration(fullStart, decorators, modifiers, name_3, undefined); + var name_5 = createMissingNode(65 /* Identifier */, true, ts.Diagnostics.Declaration_expected); + return parsePropertyDeclaration(fullStart, decorators, modifiers, name_5, undefined); } // 'isClassMemberStart' should have hinted not to attempt parsing. ts.Debug.fail("Should not have attempted to parse class member declaration."); } function parseClassExpression() { return parseClassDeclarationOrExpression( - /*fullStart:*/ scanner.getStartPos(), - /*decorators:*/ undefined, - /*modifiers:*/ undefined, 175 /* ClassExpression */); + /*fullStart*/ scanner.getStartPos(), + /*decorators*/ undefined, + /*modifiers*/ undefined, 175 /* ClassExpression */); } function parseClassDeclaration(fullStart, decorators, modifiers) { return parseClassDeclarationOrExpression(fullStart, decorators, modifiers, 202 /* ClassDeclaration */); @@ -10063,136 +10534,6 @@ var ts; parseSemicolon(); return finishNode(node); } - function isLetDeclaration() { - // It is let declaration if in strict mode or next token is identifier\open bracket\open curly on same line. - // otherwise it needs to be treated like identifier - return inStrictModeContext() || lookAhead(nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine); - } - function isDeclarationStart(followsModifier) { - switch (token) { - case 98 /* VarKeyword */: - case 70 /* ConstKeyword */: - case 83 /* FunctionKeyword */: - return true; - case 104 /* LetKeyword */: - return isLetDeclaration(); - case 69 /* ClassKeyword */: - case 103 /* InterfaceKeyword */: - case 77 /* EnumKeyword */: - case 124 /* TypeKeyword */: - // Not true keywords so ensure an identifier follows - return lookAhead(nextTokenIsIdentifierOrKeyword); - case 85 /* ImportKeyword */: - // Not true keywords so ensure an identifier follows or is string literal or asterisk or open brace - return lookAhead(nextTokenCanFollowImportKeyword); - case 117 /* ModuleKeyword */: - case 118 /* NamespaceKeyword */: - // Not a true keyword so ensure an identifier or string literal follows - return lookAhead(nextTokenIsIdentifierOrKeywordOrStringLiteral); - case 78 /* ExportKeyword */: - // Check for export assignment or modifier on source element - return lookAhead(nextTokenCanFollowExportKeyword); - case 115 /* DeclareKeyword */: - case 108 /* PublicKeyword */: - case 106 /* PrivateKeyword */: - case 107 /* ProtectedKeyword */: - case 109 /* StaticKeyword */: - // Check for modifier on source element - return lookAhead(nextTokenIsDeclarationStart); - case 52 /* AtToken */: - // a lookahead here is too costly, and decorators are only valid on a declaration. - // We will assume we are parsing a declaration here and report an error later - return !followsModifier; - } - } - function isIdentifierOrKeyword() { - return token >= 65 /* Identifier */; - } - function nextTokenIsIdentifierOrKeyword() { - nextToken(); - return isIdentifierOrKeyword(); - } - function nextTokenIsIdentifierOrKeywordOrStringLiteral() { - nextToken(); - return isIdentifierOrKeyword() || token === 8 /* StringLiteral */; - } - function nextTokenCanFollowImportKeyword() { - nextToken(); - return isIdentifierOrKeyword() || token === 8 /* StringLiteral */ || - token === 35 /* AsteriskToken */ || token === 14 /* OpenBraceToken */; - } - function nextTokenCanFollowExportKeyword() { - nextToken(); - return token === 53 /* EqualsToken */ || token === 35 /* AsteriskToken */ || - token === 14 /* OpenBraceToken */ || token === 73 /* DefaultKeyword */ || isDeclarationStart(true); - } - function nextTokenIsDeclarationStart() { - nextToken(); - return isDeclarationStart(true); - } - function nextTokenIsAsKeyword() { - return nextToken() === 111 /* AsKeyword */; - } - function parseDeclaration() { - var fullStart = getNodePos(); - var decorators = parseDecorators(); - var modifiers = parseModifiers(); - if (token === 78 /* ExportKeyword */) { - nextToken(); - if (token === 73 /* DefaultKeyword */ || token === 53 /* EqualsToken */) { - return parseExportAssignment(fullStart, decorators, modifiers); - } - if (token === 35 /* AsteriskToken */ || token === 14 /* OpenBraceToken */) { - return parseExportDeclaration(fullStart, decorators, modifiers); - } - } - switch (token) { - case 98 /* VarKeyword */: - case 104 /* LetKeyword */: - case 70 /* ConstKeyword */: - return parseVariableStatement(fullStart, decorators, modifiers); - case 83 /* FunctionKeyword */: - return parseFunctionDeclaration(fullStart, decorators, modifiers); - case 69 /* ClassKeyword */: - return parseClassDeclaration(fullStart, decorators, modifiers); - case 103 /* InterfaceKeyword */: - return parseInterfaceDeclaration(fullStart, decorators, modifiers); - case 124 /* TypeKeyword */: - return parseTypeAliasDeclaration(fullStart, decorators, modifiers); - case 77 /* EnumKeyword */: - return parseEnumDeclaration(fullStart, decorators, modifiers); - case 117 /* ModuleKeyword */: - case 118 /* NamespaceKeyword */: - return parseModuleDeclaration(fullStart, decorators, modifiers); - case 85 /* ImportKeyword */: - return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers); - default: - if (decorators) { - // We reached this point because we encountered an AtToken and assumed a declaration would - // follow. For recovery and error reporting purposes, return an incomplete declaration. - var node = createMissingNode(219 /* MissingDeclaration */, true, ts.Diagnostics.Declaration_expected); - node.pos = fullStart; - node.decorators = decorators; - setModifiers(node, modifiers); - return finishNode(node); - } - ts.Debug.fail("Mismatch between isDeclarationStart and parseDeclaration"); - } - } - function isSourceElement(inErrorRecovery) { - return isDeclarationStart() || isStartOfStatement(inErrorRecovery); - } - function parseSourceElement() { - return parseSourceElementOrModuleElement(); - } - function parseModuleElement() { - return parseSourceElementOrModuleElement(); - } - function parseSourceElementOrModuleElement() { - return isDeclarationStart() - ? parseDeclaration() - : parseStatement(); - } function processReferenceComments(sourceFile) { var triviaScanner = ts.createScanner(sourceFile.languageVersion, false, sourceText); var referencedFiles = []; @@ -10220,7 +10561,7 @@ var ts; referencedFiles.push(fileReference); } if (diagnosticMessage) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); } } else { @@ -10228,7 +10569,7 @@ var ts; var amdModuleNameMatchResult = amdModuleNameRegEx.exec(comment); if (amdModuleNameMatchResult) { if (amdModuleName) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); } amdModuleName = amdModuleNameMatchResult[2]; } @@ -10284,7 +10625,11 @@ var ts; ParsingContext[ParsingContext["TupleElementTypes"] = 18] = "TupleElementTypes"; ParsingContext[ParsingContext["HeritageClauses"] = 19] = "HeritageClauses"; ParsingContext[ParsingContext["ImportOrExportSpecifiers"] = 20] = "ImportOrExportSpecifiers"; - ParsingContext[ParsingContext["Count"] = 21] = "Count"; // Number of parsing contexts + ParsingContext[ParsingContext["JSDocFunctionParameters"] = 21] = "JSDocFunctionParameters"; + ParsingContext[ParsingContext["JSDocTypeArguments"] = 22] = "JSDocTypeArguments"; + ParsingContext[ParsingContext["JSDocRecordMembers"] = 23] = "JSDocRecordMembers"; + ParsingContext[ParsingContext["JSDocTupleTypes"] = 24] = "JSDocTupleTypes"; + ParsingContext[ParsingContext["Count"] = 25] = "Count"; // Number of parsing contexts })(ParsingContext || (ParsingContext = {})); var Tristate; (function (Tristate) { @@ -10292,6 +10637,552 @@ var ts; Tristate[Tristate["True"] = 1] = "True"; Tristate[Tristate["Unknown"] = 2] = "Unknown"; })(Tristate || (Tristate = {})); + var JSDocParser; + (function (JSDocParser) { + function isJSDocType() { + switch (token) { + case 35 /* AsteriskToken */: + case 50 /* QuestionToken */: + case 16 /* OpenParenToken */: + case 18 /* OpenBracketToken */: + case 46 /* ExclamationToken */: + case 14 /* OpenBraceToken */: + case 83 /* FunctionKeyword */: + case 21 /* DotDotDotToken */: + case 88 /* NewKeyword */: + case 93 /* ThisKeyword */: + return true; + } + return isIdentifierOrKeyword(); + } + JSDocParser.isJSDocType = isJSDocType; + function parseJSDocTypeExpressionForTests(content, start, length) { + initializeState("file.js", content, 2 /* Latest */, undefined); + var jsDocTypeExpression = parseJSDocTypeExpression(start, length); + var diagnostics = parseDiagnostics; + clearState(); + return jsDocTypeExpression ? { jsDocTypeExpression: jsDocTypeExpression, diagnostics: diagnostics } : undefined; + } + JSDocParser.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests; + // Parses out a JSDoc type expression. The starting position should be right at the open + // curly in the type expression. Returns 'undefined' if it encounters any errors while parsing. + /* @internal */ + function parseJSDocTypeExpression(start, length) { + scanner.setText(sourceText, start, length); + // Prime the first token for us to start processing. + token = nextToken(); + var result = createNode(229 /* JSDocTypeExpression */); + parseExpected(14 /* OpenBraceToken */); + result.type = parseJSDocTopLevelType(); + parseExpected(15 /* CloseBraceToken */); + fixupParentReferences(result); + return finishNode(result); + } + JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression; + function setError(message) { + parseErrorAtCurrentToken(message); + if (ts.throwOnJSDocErrors) { + throw new Error(message.key); + } + } + function parseJSDocTopLevelType() { + var type = parseJSDocType(); + if (token === 44 /* BarToken */) { + var unionType = createNode(233 /* JSDocUnionType */, type.pos); + unionType.types = parseJSDocTypeList(type); + type = finishNode(unionType); + } + if (token === 53 /* EqualsToken */) { + var optionalType = createNode(240 /* JSDocOptionalType */, type.pos); + nextToken(); + optionalType.type = type; + type = finishNode(optionalType); + } + return type; + } + function parseJSDocType() { + var type = parseBasicTypeExpression(); + while (true) { + if (token === 18 /* OpenBracketToken */) { + var arrayType = createNode(232 /* JSDocArrayType */, type.pos); + arrayType.elementType = type; + nextToken(); + parseExpected(19 /* CloseBracketToken */); + type = finishNode(arrayType); + } + else if (token === 50 /* QuestionToken */) { + var nullableType = createNode(235 /* JSDocNullableType */, type.pos); + nullableType.type = type; + nextToken(); + type = finishNode(nullableType); + } + else if (token === 46 /* ExclamationToken */) { + var nonNullableType = createNode(236 /* JSDocNonNullableType */, type.pos); + nonNullableType.type = type; + nextToken(); + type = finishNode(nonNullableType); + } + else { + break; + } + } + return type; + } + function parseBasicTypeExpression() { + switch (token) { + case 35 /* AsteriskToken */: + return parseJSDocAllType(); + case 50 /* QuestionToken */: + return parseJSDocUnknownOrNullableType(); + case 16 /* OpenParenToken */: + return parseJSDocUnionType(); + case 18 /* OpenBracketToken */: + return parseJSDocTupleType(); + case 46 /* ExclamationToken */: + return parseJSDocNonNullableType(); + case 14 /* OpenBraceToken */: + return parseJSDocRecordType(); + case 83 /* FunctionKeyword */: + return parseJSDocFunctionType(); + case 21 /* DotDotDotToken */: + return parseJSDocVariadicType(); + case 88 /* NewKeyword */: + return parseJSDocConstructorType(); + case 93 /* ThisKeyword */: + return parseJSDocThisType(); + case 112 /* AnyKeyword */: + case 122 /* StringKeyword */: + case 120 /* NumberKeyword */: + case 113 /* BooleanKeyword */: + case 123 /* SymbolKeyword */: + case 99 /* VoidKeyword */: + return parseTokenNode(); + } + return parseJSDocTypeReference(); + } + function parseJSDocThisType() { + var result = createNode(244 /* JSDocThisType */); + nextToken(); + parseExpected(51 /* ColonToken */); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocConstructorType() { + var result = createNode(243 /* JSDocConstructorType */); + nextToken(); + parseExpected(51 /* ColonToken */); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocVariadicType() { + var result = createNode(242 /* JSDocVariadicType */); + nextToken(); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocFunctionType() { + var result = createNode(241 /* JSDocFunctionType */); + nextToken(); + parseExpected(16 /* OpenParenToken */); + result.parameters = parseDelimitedList(21 /* JSDocFunctionParameters */, parseJSDocParameter); + checkForTrailingComma(result.parameters); + parseExpected(17 /* CloseParenToken */); + if (token === 51 /* ColonToken */) { + nextToken(); + result.type = parseJSDocType(); + } + return finishNode(result); + } + function parseJSDocParameter() { + var parameter = createNode(130 /* Parameter */); + parameter.type = parseJSDocType(); + return finishNode(parameter); + } + function parseJSDocOptionalType(type) { + var result = createNode(240 /* JSDocOptionalType */, type.pos); + nextToken(); + result.type = type; + return finishNode(result); + } + function parseJSDocTypeReference() { + var result = createNode(239 /* JSDocTypeReference */); + result.name = parseSimplePropertyName(); + while (parseOptional(20 /* DotToken */)) { + if (token === 24 /* LessThanToken */) { + result.typeArguments = parseTypeArguments(); + break; + } + else { + result.name = parseQualifiedName(result.name); + } + } + return finishNode(result); + } + function parseTypeArguments() { + // Move past the < + nextToken(); + var typeArguments = parseDelimitedList(22 /* JSDocTypeArguments */, parseJSDocType); + checkForTrailingComma(typeArguments); + checkForEmptyTypeArgumentList(typeArguments); + parseExpected(25 /* GreaterThanToken */); + return typeArguments; + } + function checkForEmptyTypeArgumentList(typeArguments) { + if (parseDiagnostics.length === 0 && typeArguments && typeArguments.length === 0) { + var start = typeArguments.pos - "<".length; + var end = ts.skipTrivia(sourceText, typeArguments.end) + ">".length; + return parseErrorAtPosition(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty); + } + } + function parseQualifiedName(left) { + var result = createNode(127 /* QualifiedName */, left.pos); + result.left = left; + result.right = parseIdentifierName(); + return finishNode(result); + } + function parseJSDocRecordType() { + var result = createNode(237 /* JSDocRecordType */); + nextToken(); + result.members = parseDelimitedList(23 /* JSDocRecordMembers */, parseJSDocRecordMember); + checkForTrailingComma(result.members); + parseExpected(15 /* CloseBraceToken */); + return finishNode(result); + } + function parseJSDocRecordMember() { + var result = createNode(238 /* JSDocRecordMember */); + result.name = parseSimplePropertyName(); + if (token === 51 /* ColonToken */) { + nextToken(); + result.type = parseJSDocType(); + } + return finishNode(result); + } + function parseJSDocNonNullableType() { + var result = createNode(236 /* JSDocNonNullableType */); + nextToken(); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocTupleType() { + var result = createNode(234 /* JSDocTupleType */); + nextToken(); + result.types = parseDelimitedList(24 /* JSDocTupleTypes */, parseJSDocType); + checkForTrailingComma(result.types); + parseExpected(19 /* CloseBracketToken */); + return finishNode(result); + } + function checkForTrailingComma(list) { + if (parseDiagnostics.length === 0 && list.hasTrailingComma) { + var start = list.end - ",".length; + parseErrorAtPosition(start, ",".length, ts.Diagnostics.Trailing_comma_not_allowed); + } + } + function parseJSDocUnionType() { + var result = createNode(233 /* JSDocUnionType */); + nextToken(); + result.types = parseJSDocTypeList(parseJSDocType()); + parseExpected(17 /* CloseParenToken */); + return finishNode(result); + } + function parseJSDocTypeList(firstType) { + ts.Debug.assert(!!firstType); + var types = []; + types.pos = firstType.pos; + types.push(firstType); + while (parseOptional(44 /* BarToken */)) { + types.push(parseJSDocType()); + } + types.end = scanner.getStartPos(); + return types; + } + function parseJSDocAllType() { + var result = createNode(230 /* JSDocAllType */); + nextToken(); + return finishNode(result); + } + function parseJSDocUnknownOrNullableType() { + var pos = scanner.getStartPos(); + // skip the ? + nextToken(); + // Need to lookahead to decide if this is a nullable or unknown type. + // Here are cases where we'll pick the unknown type: + // + // Foo(?, + // { a: ? } + // Foo(?) + // Foo + // Foo(?= + // (?| + if (token === 23 /* CommaToken */ || + token === 15 /* CloseBraceToken */ || + token === 17 /* CloseParenToken */ || + token === 25 /* GreaterThanToken */ || + token === 53 /* EqualsToken */ || + token === 44 /* BarToken */) { + var result = createNode(231 /* JSDocUnknownType */, pos); + return finishNode(result); + } + else { + var result = createNode(235 /* JSDocNullableType */, pos); + result.type = parseJSDocType(); + return finishNode(result); + } + } + function parseIsolatedJSDocComment(content, start, length) { + initializeState("file.js", content, 2 /* Latest */, undefined); + var jsDocComment = parseJSDocComment(undefined, start, length); + var diagnostics = parseDiagnostics; + clearState(); + return jsDocComment ? { jsDocComment: jsDocComment, diagnostics: diagnostics } : undefined; + } + JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment; + function parseJSDocComment(parent, start, length) { + var comment = parseJSDocCommentWorker(start, length); + if (comment) { + fixupParentReferences(comment); + comment.parent = parent; + } + return comment; + } + JSDocParser.parseJSDocComment = parseJSDocComment; + function parseJSDocCommentWorker(start, length) { + var content = sourceText; + start = start || 0; + var end = length === undefined ? content.length : start + length; + length = end - start; + ts.Debug.assert(start >= 0); + ts.Debug.assert(start <= end); + ts.Debug.assert(end <= content.length); + var tags; + var pos; + // NOTE(cyrusn): This is essentially a handwritten scanner for JSDocComments. I + // considered using an actual Scanner, but this would complicate things. The + // scanner would need to know it was in a Doc Comment. Otherwise, it would then + // produce comments *inside* the doc comment. In the end it was just easier to + // write a simple scanner rather than go that route. + if (length >= "/** */".length) { + if (content.charCodeAt(start) === 47 /* slash */ && + content.charCodeAt(start + 1) === 42 /* asterisk */ && + content.charCodeAt(start + 2) === 42 /* asterisk */ && + content.charCodeAt(start + 3) !== 42 /* asterisk */) { + // Initially we can parse out a tag. We also have seen a starting asterisk. + // This is so that /** * @type */ doesn't parse. + var canParseTag = true; + var seenAsterisk = true; + for (pos = start + "/**".length; pos < end;) { + var ch = content.charCodeAt(pos); + pos++; + if (ch === 64 /* at */ && canParseTag) { + parseTag(); + // Once we parse out a tag, we cannot keep parsing out tags on this line. + canParseTag = false; + continue; + } + if (ts.isLineBreak(ch)) { + // After a line break, we can parse a tag, and we haven't seen as asterisk + // on the next line yet. + canParseTag = true; + seenAsterisk = false; + continue; + } + if (ts.isWhiteSpace(ch)) { + // Whitespace doesn't affect any of our parsing. + continue; + } + // Ignore the first asterisk on a line. + if (ch === 42 /* asterisk */) { + if (seenAsterisk) { + // If we've already seen an asterisk, then we can no longer parse a tag + // on this line. + canParseTag = false; + } + seenAsterisk = true; + continue; + } + // Anything else is doc comment text. We can't do anything with it. Because it + // wasn't a tag, we can no longer parse a tag on this line until we hit the next + // line break. + canParseTag = false; + } + } + } + return createJSDocComment(); + function createJSDocComment() { + if (!tags) { + return undefined; + } + var result = createNode(245 /* JSDocComment */, start); + result.tags = tags; + return finishNode(result, end); + } + function skipWhitespace() { + while (pos < end && ts.isWhiteSpace(content.charCodeAt(pos))) { + pos++; + } + } + function parseTag() { + ts.Debug.assert(content.charCodeAt(pos - 1) === 64 /* at */); + var atToken = createNode(52 /* AtToken */, pos - 1); + atToken.end = pos; + var startPos = pos; + var tagName = scanIdentifier(); + if (!tagName) { + return; + } + var tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName); + addTag(tag); + } + function handleTag(atToken, tagName) { + if (tagName) { + switch (tagName.text) { + case "param": + return handleParamTag(atToken, tagName); + case "return": + case "returns": + return handleReturnTag(atToken, tagName); + case "template": + return handleTemplateTag(atToken, tagName); + case "type": + return handleTypeTag(atToken, tagName); + } + } + return undefined; + } + function handleUnknownTag(atToken, tagName) { + var result = createNode(246 /* JSDocTag */, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + return finishNode(result, pos); + } + function addTag(tag) { + if (tag) { + if (!tags) { + tags = []; + tags.pos = tag.pos; + } + tags.push(tag); + tags.end = tag.end; + } + } + function tryParseTypeExpression() { + skipWhitespace(); + if (content.charCodeAt(pos) !== 123 /* openBrace */) { + return undefined; + } + var typeExpression = parseJSDocTypeExpression(pos, end - pos); + pos = typeExpression.end; + return typeExpression; + } + function handleParamTag(atToken, tagName) { + var typeExpression = tryParseTypeExpression(); + skipWhitespace(); + var name; + var isBracketed; + if (content.charCodeAt(pos) === 91 /* openBracket */) { + pos++; + skipWhitespace(); + name = scanIdentifier(); + isBracketed = true; + } + else { + name = scanIdentifier(); + } + if (!name) { + parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); + return undefined; + } + var preName, postName; + if (typeExpression) { + postName = name; + } + else { + preName = name; + } + if (!typeExpression) { + typeExpression = tryParseTypeExpression(); + } + var result = createNode(247 /* JSDocParameterTag */, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.preParameterName = preName; + result.typeExpression = typeExpression; + result.postParameterName = postName; + result.isBracketed = isBracketed; + return finishNode(result, pos); + } + function handleReturnTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 248 /* JSDocReturnTag */; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var result = createNode(248 /* JSDocReturnTag */, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeExpression = tryParseTypeExpression(); + return finishNode(result, pos); + } + function handleTypeTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 249 /* JSDocTypeTag */; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var result = createNode(249 /* JSDocTypeTag */, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeExpression = tryParseTypeExpression(); + return finishNode(result, pos); + } + function handleTemplateTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 250 /* JSDocTemplateTag */; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var typeParameters = []; + typeParameters.pos = pos; + while (true) { + skipWhitespace(); + var startPos = pos; + var name_6 = scanIdentifier(); + if (!name_6) { + parseErrorAtPosition(startPos, 0, ts.Diagnostics.Identifier_expected); + return undefined; + } + var typeParameter = createNode(129 /* TypeParameter */, name_6.pos); + typeParameter.name = name_6; + finishNode(typeParameter, pos); + typeParameters.push(typeParameter); + skipWhitespace(); + if (content.charCodeAt(pos) !== 44 /* comma */) { + break; + } + pos++; + } + typeParameters.end = pos; + var result = createNode(250 /* JSDocTemplateTag */, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeParameters = typeParameters; + return finishNode(result, pos); + } + function scanIdentifier() { + var startPos = pos; + for (; pos < end; pos++) { + var ch = content.charCodeAt(pos); + if (pos === startPos && ts.isIdentifierStart(ch, 2 /* Latest */)) { + continue; + } + else if (pos > startPos && ts.isIdentifierPart(ch, 2 /* Latest */)) { + continue; + } + break; + } + if (startPos === pos) { + return undefined; + } + var result = createNode(65 /* Identifier */, startPos); + result.text = content.substring(startPos, pos); + return finishNode(result, pos); + } + } + JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker; + })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {})); })(Parser || (Parser = {})); var IncrementalParser; (function (IncrementalParser) { @@ -10379,7 +11270,12 @@ var ts; } // Ditch any existing LS children we may have created. This way we can avoid // moving them forward. - node._children = undefined; + if (node._children) { + node._children = undefined; + } + if (node.jsDocComment) { + node.jsDocComment = undefined; + } node.pos += delta; node.end += delta; if (aggressiveChecks && shouldCheckNode(node)) { @@ -10839,13 +11735,15 @@ var ts; var undefinedType = createIntrinsicType(32 /* Undefined */ | 262144 /* ContainsUndefinedOrNull */, "undefined"); var nullType = createIntrinsicType(64 /* Null */ | 262144 /* ContainsUndefinedOrNull */, "null"); var unknownType = createIntrinsicType(1 /* Any */, "unknown"); + var circularType = createIntrinsicType(1 /* Any */, "__circular__"); var emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + var emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + emptyGenericType.instantiations = {}; var anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); var noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); var anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, false, false); var unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false); var globals = {}; - var globalArraySymbol; var globalESSymbolConstructorSymbol; var globalObjectType; var globalFunctionType; @@ -10857,6 +11755,8 @@ var ts; var globalTemplateStringsArrayType; var globalESSymbolType; var globalIterableType; + var globalIteratorType; + var globalIterableIteratorType; var anyArrayType; var getGlobalClassDecoratorType; var getGlobalParameterDecoratorType; @@ -11083,7 +11983,15 @@ var ts; // Locals of a source file are not in scope (because they get merged into the global symbol table) if (location.locals && !isGlobalSourceFile(location)) { if (result = getSymbol(location.locals, name, meaning)) { - break loop; + // Type parameters of a function are in scope in the entire function declaration, including the parameter + // list and return type. However, local types are only in scope in the function body. + if (!(meaning & 793056 /* Type */) || + !(result.flags & (793056 /* Type */ & ~262144 /* TypeParameter */)) || + !ts.isFunctionLike(location) || + lastLocation === location.body) { + break loop; + } + result = undefined; } } switch (location.kind) { @@ -11385,15 +12293,15 @@ var ts; var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier); var targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier); if (targetSymbol) { - var name_4 = specifier.propertyName || specifier.name; - if (name_4.text) { - var symbolFromModule = getExportOfModule(targetSymbol, name_4.text); - var symbolFromVariable = getPropertyOfVariable(targetSymbol, name_4.text); + var name_7 = specifier.propertyName || specifier.name; + if (name_7.text) { + var symbolFromModule = getExportOfModule(targetSymbol, name_7.text); + var symbolFromVariable = getPropertyOfVariable(targetSymbol, name_7.text); var symbol = symbolFromModule && symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { - error(name_4, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name_4)); + error(name_7, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name_7)); } return symbol; } @@ -12150,17 +13058,54 @@ var ts; writeType(types[i], union ? 64 /* InElementType */ : 0 /* None */); } } + function writeSymbolTypeReference(symbol, typeArguments, pos, end) { + // Unnamed function expressions, arrow functions, and unnamed class expressions have reserved names that + // we don't want to display + if (!isReservedMemberName(symbol.name)) { + buildSymbolDisplay(symbol, writer, enclosingDeclaration, 793056 /* Type */); + } + if (pos < end) { + writePunctuation(writer, 24 /* LessThanToken */); + writeType(typeArguments[pos++], 0 /* None */); + while (pos < end) { + writePunctuation(writer, 23 /* CommaToken */); + writeSpace(writer); + writeType(typeArguments[pos++], 0 /* None */); + } + writePunctuation(writer, 25 /* GreaterThanToken */); + } + } function writeTypeReference(type, flags) { + var typeArguments = type.typeArguments; if (type.target === globalArrayType && !(flags & 1 /* WriteArrayAsGenericType */)) { - writeType(type.typeArguments[0], 64 /* InElementType */); + writeType(typeArguments[0], 64 /* InElementType */); writePunctuation(writer, 18 /* OpenBracketToken */); writePunctuation(writer, 19 /* CloseBracketToken */); } else { - buildSymbolDisplay(type.target.symbol, writer, enclosingDeclaration, 793056 /* Type */); - writePunctuation(writer, 24 /* LessThanToken */); - writeTypeList(type.typeArguments, false); - writePunctuation(writer, 25 /* GreaterThanToken */); + // Write the type reference in the format f.g.C where A and B are type arguments + // for outer type parameters, and f and g are the respective declaring containers of those + // type parameters. + var outerTypeParameters = type.target.outerTypeParameters; + var i = 0; + if (outerTypeParameters) { + var length_1 = outerTypeParameters.length; + while (i < length_1) { + // Find group of type arguments for type parameters with the same declaring container. + var start = i; + var parent_3 = getParentSymbolOfTypeParameter(outerTypeParameters[i]); + do { + i++; + } while (i < length_1 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent_3); + // When type parameters are their own type arguments for the whole group (i.e. we have + // the default outer type arguments), we don't show the group. + if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) { + writeSymbolTypeReference(parent_3, typeArguments, start, i); + writePunctuation(writer, 20 /* DotToken */); + } + } + } + writeSymbolTypeReference(type.symbol, typeArguments, i, typeArguments.length); } } function writeTupleType(type) { @@ -12348,7 +13293,7 @@ var ts; function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */) { - buildDisplayForTypeParametersAndDelimiters(getTypeParametersOfClassOrInterface(symbol), writer, enclosingDeclaraiton, flags); + buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterface(symbol), writer, enclosingDeclaraiton, flags); } } function buildTypeParameterDisplay(tp, writer, enclosingDeclaration, flags, typeStack) { @@ -12521,14 +13466,14 @@ var ts; case 201 /* FunctionDeclaration */: case 205 /* EnumDeclaration */: case 209 /* ImportEqualsDeclaration */: - var parent_2 = getDeclarationContainer(node); + var parent_4 = getDeclarationContainer(node); // If the node is not exported or it is not ambient module element (except import declaration) if (!(ts.getCombinedNodeFlags(node) & 1 /* Export */) && - !(node.kind !== 209 /* ImportEqualsDeclaration */ && parent_2.kind !== 228 /* SourceFile */ && ts.isInAmbientContext(parent_2))) { - return isGlobalSourceFile(parent_2); + !(node.kind !== 209 /* ImportEqualsDeclaration */ && parent_4.kind !== 228 /* SourceFile */ && ts.isInAmbientContext(parent_4))) { + return isGlobalSourceFile(parent_4); } // Exported members/ambient module elements (exception import declaration) are visible if parent is visible - return isDeclarationVisible(parent_2); + return isDeclarationVisible(parent_4); case 133 /* PropertyDeclaration */: case 132 /* PropertySignature */: case 137 /* GetAccessor */: @@ -12679,14 +13624,14 @@ var ts; var type; if (pattern.kind === 151 /* ObjectBindingPattern */) { // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form) - var name_5 = declaration.propertyName || declaration.name; + var name_8 = declaration.propertyName || declaration.name; // Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature, // or otherwise the type of the string index signature. - type = getTypeOfPropertyOfType(parentType, name_5.text) || - isNumericLiteralName(name_5.text) && getIndexTypeOfType(parentType, 1 /* Number */) || + type = getTypeOfPropertyOfType(parentType, name_8.text) || + isNumericLiteralName(name_8.text) && getIndexTypeOfType(parentType, 1 /* Number */) || getIndexTypeOfType(parentType, 0 /* String */); if (!type) { - error(name_5, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_5)); + error(name_8, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_8)); return unknownType; } } @@ -12731,7 +13676,7 @@ var ts; // checkRightHandSideOfForOf will return undefined if the for-of expression type was // missing properties/signatures required to get its iteratedType (like // [Symbol.iterator] or next). This may be because we accessed properties from anyType, - // or it may have led to an error inside getIteratedType. + // or it may have led to an error inside getElementTypeOfIterable. return checkRightHandSideOfForOf(declaration.parent.parent.expression) || anyType; } if (ts.isBindingPattern(declaration.parent)) { @@ -13024,29 +13969,65 @@ var ts; return target === checkBase || ts.forEach(getBaseTypes(target), check); } } - // Return combined list of type parameters from all declarations of a class or interface. Elsewhere we check they're all - // the same, but even if they're not we still need the complete list to ensure instantiations supply type arguments - // for all type parameters. - function getTypeParametersOfClassOrInterface(symbol) { - var result; - ts.forEach(symbol.declarations, function (node) { - if (node.kind === 203 /* InterfaceDeclaration */ || node.kind === 202 /* ClassDeclaration */) { - var declaration = node; - if (declaration.typeParameters && declaration.typeParameters.length) { - ts.forEach(declaration.typeParameters, function (node) { - var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node)); - if (!result) { - result = [tp]; - } - else if (!ts.contains(result, tp)) { - result.push(tp); - } - }); + // Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set. + // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set + // in-place and returns the same array. + function appendTypeParameters(typeParameters, declarations) { + for (var _i = 0; _i < declarations.length; _i++) { + var declaration = declarations[_i]; + var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); + if (!typeParameters) { + typeParameters = [tp]; + } + else if (!ts.contains(typeParameters, tp)) { + typeParameters.push(tp); + } + } + return typeParameters; + } + // Appends the outer type parameters of a node to a set of type parameters and returns the resulting set. The function + // allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set in-place and + // returns the same array. + function appendOuterTypeParameters(typeParameters, node) { + while (true) { + node = node.parent; + if (!node) { + return typeParameters; + } + if (node.kind === 202 /* ClassDeclaration */ || node.kind === 201 /* FunctionDeclaration */ || + node.kind === 163 /* FunctionExpression */ || node.kind === 135 /* MethodDeclaration */ || + node.kind === 164 /* ArrowFunction */) { + var declarations = node.typeParameters; + if (declarations) { + return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations); } } - }); + } + } + // The outer type parameters are those defined by enclosing generic classes, methods, or functions. + function getOuterTypeParametersOfClassOrInterface(symbol) { + var kind = symbol.flags & 32 /* Class */ ? 202 /* ClassDeclaration */ : 203 /* InterfaceDeclaration */; + return appendOuterTypeParameters(undefined, ts.getDeclarationOfKind(symbol, kind)); + } + // The local type parameters are the combined set of type parameters from all declarations of the class or interface. + function getLocalTypeParametersOfClassOrInterface(symbol) { + var result; + for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { + var node = _a[_i]; + if (node.kind === 203 /* InterfaceDeclaration */ || node.kind === 202 /* ClassDeclaration */) { + var declaration = node; + if (declaration.typeParameters) { + result = appendTypeParameters(result, declaration.typeParameters); + } + } + } return result; } + // The full set of type parameters for a generic class or interface type consists of its outer type parameters plus + // its locally declared type parameters. + function getTypeParametersOfClassOrInterface(symbol) { + return ts.concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterface(symbol)); + } function getBaseTypes(type) { var typeWithBaseTypes = type; if (!typeWithBaseTypes.baseTypes) { @@ -13113,10 +14094,13 @@ var ts; if (!links.declaredType) { var kind = symbol.flags & 32 /* Class */ ? 1024 /* Class */ : 2048 /* Interface */; var type = links.declaredType = createObjectType(kind, symbol); - var typeParameters = getTypeParametersOfClassOrInterface(symbol); - if (typeParameters) { + var outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol); + var localTypeParameters = getLocalTypeParametersOfClassOrInterface(symbol); + if (outerTypeParameters || localTypeParameters) { type.flags |= 4096 /* Reference */; - type.typeParameters = typeParameters; + type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters); + type.outerTypeParameters = outerTypeParameters; + type.localTypeParameters = localTypeParameters; type.instantiations = {}; type.instantiations[getTypeListId(type.typeParameters)] = type; type.target = type; @@ -13294,12 +14278,12 @@ var ts; return ts.map(baseSignatures, function (baseSignature) { var signature = baseType.flags & 4096 /* Reference */ ? getSignatureInstantiation(baseSignature, baseType.typeArguments) : cloneSignature(baseSignature); - signature.typeParameters = classType.typeParameters; + signature.typeParameters = classType.localTypeParameters; signature.resolvedReturnType = classType; return signature; }); } - return [createSignature(undefined, classType.typeParameters, emptyArray, classType, 0, false, false)]; + return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, 0, false, false)]; } function createTupleTypeMemberSymbols(memberTypes) { var members = {}; @@ -13627,7 +14611,7 @@ var ts; var links = getNodeLinks(declaration); if (!links.resolvedSignature) { var classType = declaration.kind === 136 /* Constructor */ ? getDeclaredTypeOfClassOrInterface(declaration.parent.symbol) : undefined; - var typeParameters = classType ? classType.typeParameters : + var typeParameters = classType ? classType.localTypeParameters : declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) : undefined; var parameters = []; var hasStringLiterals = false; @@ -13814,6 +14798,9 @@ var ts; } return type.constraint === noConstraintType ? undefined : type.constraint; } + function getParentSymbolOfTypeParameter(typeParameter) { + return getSymbolOfNode(ts.getDeclarationOfKind(typeParameter.symbol, 129 /* TypeParameter */).parent); + } function getTypeListId(types) { switch (types.length) { case 1: @@ -13919,12 +14906,21 @@ var ts; else { type = getDeclaredTypeOfSymbol(symbol); if (type.flags & (1024 /* Class */ | 2048 /* Interface */) && type.flags & 4096 /* Reference */) { - var typeParameters = type.typeParameters; - if (node.typeArguments && node.typeArguments.length === typeParameters.length) { - type = createTypeReference(type, ts.map(node.typeArguments, getTypeFromTypeNode)); + // In a type reference, the outer type parameters of the referenced class or interface are automatically + // supplied as type arguments and the type reference only specifies arguments for the local type parameters + // of the class or interface. + var localTypeParameters = type.localTypeParameters; + var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; + var typeArgCount = node.typeArguments ? node.typeArguments.length : 0; + if (typeArgCount === expectedTypeArgCount) { + // When no type arguments are expected we already have the right type because all outer type parameters + // have themselves as default type arguments. + if (typeArgCount) { + type = createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(node.typeArguments, getTypeFromTypeNode))); + } } else { - error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1 /* WriteArrayAsGenericType */), typeParameters.length); + error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1 /* WriteArrayAsGenericType */), expectedTypeArgCount); type = undefined; } } @@ -13966,16 +14962,16 @@ var ts; } } if (!symbol) { - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } var type = getDeclaredTypeOfSymbol(symbol); if (!(type.flags & 48128 /* ObjectType */)) { error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, symbol.name); - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } if ((type.typeParameters ? type.typeParameters.length : 0) !== arity) { error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbol.name, arity); - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } return type; } @@ -13995,15 +14991,20 @@ var ts; function getGlobalESSymbolConstructorSymbol() { return globalESSymbolConstructorSymbol || (globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol")); } + /** + * Instantiates a global type that is generic with some element type, and returns that instantiation. + */ + function createTypeFromGenericGlobalType(genericGlobalType, elementType) { + return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, [elementType]) : emptyObjectType; + } function createIterableType(elementType) { - return globalIterableType !== emptyObjectType ? createTypeReference(globalIterableType, [elementType]) : emptyObjectType; + return createTypeFromGenericGlobalType(globalIterableType, elementType); + } + function createIterableIteratorType(elementType) { + return createTypeFromGenericGlobalType(globalIterableIteratorType, elementType); } function createArrayType(elementType) { - // globalArrayType will be undefined if we get here during creation of the Array type. This for example happens if - // user code augments the Array type with call or construct signatures that have an array type as the return type. - // We instead use globalArraySymbol to obtain the (not yet fully constructed) Array type. - var arrayType = globalArrayType || getDeclaredTypeOfSymbol(globalArraySymbol); - return arrayType !== emptyObjectType ? createTypeReference(arrayType, [elementType]) : emptyObjectType; + return createTypeFromGenericGlobalType(globalArrayType, elementType); } function getTypeFromArrayTypeNode(node) { var links = getNodeLinks(node); @@ -14058,17 +15059,7 @@ var ts; } return false; } - // Since removeSubtypes checks the subtype relation, and the subtype relation on a union - // may attempt to reduce a union, it is possible that removeSubtypes could be called - // recursively on the same set of types. The removeSubtypesStack is used to track which - // sets of types are currently undergoing subtype reduction. - var removeSubtypesStack = []; function removeSubtypes(types) { - var typeListId = getTypeListId(types); - if (removeSubtypesStack.lastIndexOf(typeListId) >= 0) { - return; - } - removeSubtypesStack.push(typeListId); var i = types.length; while (i > 0) { i--; @@ -14076,7 +15067,6 @@ var ts; types.splice(i, 1); } } - removeSubtypesStack.pop(); } function containsAnyType(types) { for (var _i = 0; _i < types.length; _i++) { @@ -14128,10 +15118,20 @@ var ts; } return type; } + // Subtype reduction is basically an optimization we do to avoid excessively large union types, which take longer + // to process and look strange in quick info and error messages. Semantically there is no difference between the + // reduced type and the type itself. So, when we detect a circularity we simply say that the reduced type is the + // type itself. function getReducedTypeOfUnionType(type) { - // If union type was created without subtype reduction, perform the deferred reduction now if (!type.reducedType) { - type.reducedType = getUnionType(type.types, false); + type.reducedType = circularType; + var reducedType = getUnionType(type.types, false); + if (type.reducedType === circularType) { + type.reducedType = reducedType; + } + } + else if (type.reducedType === circularType) { + type.reducedType = type; } return type.reducedType; } @@ -14323,6 +15323,18 @@ var ts; return result; } function instantiateAnonymousType(type, mapper) { + // If this type has already been instantiated using this mapper, returned the cached result. This guards against + // infinite instantiations of cyclic types, e.g. "var x: { a: T, b: typeof x };" + if (mapper.mappings) { + var cached = mapper.mappings[type.id]; + if (cached) { + return cached; + } + } + else { + mapper.mappings = {}; + } + // Instantiate the given type using the given mapper and cache the result var result = createObjectType(32768 /* Anonymous */, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); result.members = createSymbolTable(result.properties); @@ -14334,6 +15346,7 @@ var ts; result.stringIndexType = instantiateType(stringIndexType, mapper); if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper); + mapper.mappings[type.id] = result; return result; } function instantiateType(type, mapper) { @@ -14342,7 +15355,7 @@ var ts; return mapper(type); } if (type.flags & 32768 /* Anonymous */) { - return type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) ? + return type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) ? instantiateAnonymousType(type, mapper) : type; } if (type.flags & 4096 /* Reference */) { @@ -15617,10 +16630,10 @@ var ts; // Resolve location from top down towards node if it is a context sensitive expression // That helps in making sure not assigning types as any when resolved out of order var containerNodes = []; - for (var parent_3 = node.parent; parent_3; parent_3 = parent_3.parent) { - if ((ts.isExpression(parent_3) || ts.isObjectLiteralMethod(node)) && - isContextSensitive(parent_3)) { - containerNodes.unshift(parent_3); + for (var parent_5 = node.parent; parent_5; parent_5 = parent_5.parent) { + if ((ts.isExpression(parent_5) || ts.isObjectLiteralMethod(node)) && + isContextSensitive(parent_5)) { + containerNodes.unshift(parent_5); } } ts.forEach(containerNodes, function (node) { getTypeOfNode(node); }); @@ -16105,22 +17118,40 @@ var ts; return undefined; } function getContextualTypeForReturnExpression(node) { + var func = ts.getContainingFunction(node); + if (func && !func.asteriskToken) { + return getContextualReturnType(func); + } + return undefined; + } + function getContextualTypeForYieldOperand(node) { var func = ts.getContainingFunction(node); if (func) { - // If the containing function has a return type annotation, is a constructor, or is a get accessor whose - // corresponding set accessor has a type annotation, return statements in the function are contextually typed - if (func.type || func.kind === 136 /* Constructor */ || func.kind === 137 /* GetAccessor */ && getSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(func.symbol, 138 /* SetAccessor */))) { - return getReturnTypeOfSignature(getSignatureFromDeclaration(func)); - } - // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature - // and that call signature is non-generic, return statements are contextually typed by the return type of the signature - var signature = getContextualSignatureForFunctionLikeDeclaration(func); - if (signature) { - return getReturnTypeOfSignature(signature); + var contextualReturnType = getContextualReturnType(func); + if (contextualReturnType) { + return node.asteriskToken + ? contextualReturnType + : getElementTypeOfIterableIterator(contextualReturnType); } } return undefined; } + function getContextualReturnType(functionDecl) { + // If the containing function has a return type annotation, is a constructor, or is a get accessor whose + // corresponding set accessor has a type annotation, return statements in the function are contextually typed + if (functionDecl.type || + functionDecl.kind === 136 /* Constructor */ || + functionDecl.kind === 137 /* GetAccessor */ && getSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(functionDecl.symbol, 138 /* SetAccessor */))) { + return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl)); + } + // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature + // and that call signature is non-generic, return statements are contextually typed by the return type of the signature + var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); + if (signature) { + return getReturnTypeOfSignature(signature); + } + return undefined; + } // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter. function getContextualTypeForArgument(callTarget, arg) { var args = getEffectiveCallArguments(callTarget); @@ -16242,7 +17273,7 @@ var ts; var index = ts.indexOf(arrayLiteral.elements, node); return getTypeOfPropertyOfContextualType(type, "" + index) || getIndexTypeOfContextualType(type, 1 /* Number */) - || (languageVersion >= 2 /* ES6 */ ? checkIteratedType(type, undefined) : undefined); + || (languageVersion >= 2 /* ES6 */ ? getElementTypeOfIterable(type, undefined) : undefined); } return undefined; } @@ -16272,6 +17303,8 @@ var ts; case 164 /* ArrowFunction */: case 192 /* ReturnStatement */: return getContextualTypeForReturnExpression(node); + case 173 /* YieldExpression */: + return getContextualTypeForYieldOperand(parent); case 158 /* CallExpression */: case 159 /* NewExpression */: return getContextualTypeForArgument(parent, node); @@ -16308,8 +17341,10 @@ var ts; return node.kind === 163 /* FunctionExpression */ || node.kind === 164 /* ArrowFunction */; } function getContextualSignatureForFunctionLikeDeclaration(node) { - // Only function expressions and arrow functions are contextually typed. - return isFunctionExpressionOrArrowFunction(node) ? getContextualSignature(node) : undefined; + // Only function expressions, arrow functions, and object literal methods are contextually typed. + return isFunctionExpressionOrArrowFunction(node) || ts.isObjectLiteralMethod(node) + ? getContextualSignature(node) + : undefined; } // Return the contextual signature for a given expression node. A contextual type provides a // contextual signature if it has a single call signature and if that call signature is non-generic. @@ -16419,7 +17454,7 @@ var ts; // if there is no index type / iterated type. var restArrayType = checkExpression(e.expression, contextualMapper); var restElementType = getIndexTypeOfType(restArrayType, 1 /* Number */) || - (languageVersion >= 2 /* ES6 */ ? checkIteratedType(restArrayType, undefined) : undefined); + (languageVersion >= 2 /* ES6 */ ? getElementTypeOfIterable(restArrayType, undefined) : undefined); if (restElementType) { elementTypes.push(restElementType); } @@ -16707,15 +17742,15 @@ var ts; // - Otherwise, if IndexExpr is of type Any, the String or Number primitive type, or an enum type, the property access is of type Any. // See if we can index as a property. if (node.argumentExpression) { - var name_6 = getPropertyNameForIndexedAccess(node.argumentExpression, indexType); - if (name_6 !== undefined) { - var prop = getPropertyOfType(objectType, name_6); + var name_9 = getPropertyNameForIndexedAccess(node.argumentExpression, indexType); + if (name_9 !== undefined) { + var prop = getPropertyOfType(objectType, name_9); if (prop) { getNodeLinks(node).resolvedSymbol = prop; return getTypeOfSymbol(prop); } else if (isConstEnum) { - error(node.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_const_enum_1, name_6, symbolToString(objectType.symbol)); + error(node.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_const_enum_1, name_9, symbolToString(objectType.symbol)); return unknownType; } } @@ -16836,13 +17871,13 @@ var ts; for (var _i = 0; _i < signatures.length; _i++) { var signature = signatures[_i]; var symbol = signature.declaration && getSymbolOfNode(signature.declaration); - var parent_4 = signature.declaration && signature.declaration.parent; + var parent_6 = signature.declaration && signature.declaration.parent; if (!lastSymbol || symbol === lastSymbol) { - if (lastParent && parent_4 === lastParent) { + if (lastParent && parent_6 === lastParent) { index++; } else { - lastParent = parent_4; + lastParent = parent_6; index = cutoffIndex; } } @@ -16850,7 +17885,7 @@ var ts; // current declaration belongs to a different symbol // set cutoffIndex so re-orderings in the future won't change result set from 0 to cutoffIndex index = cutoffIndex = result.length; - lastParent = parent_4; + lastParent = parent_6; } lastSymbol = symbol; // specialized signatures always need to be placed before non-specialized signatures regardless @@ -17335,10 +18370,10 @@ var ts; return resolveCall(node, callSignatures, candidatesOutArray); } function resolveNewExpression(node, candidatesOutArray) { - if (node.arguments && languageVersion < 2 /* ES6 */) { + if (node.arguments && languageVersion < 1 /* ES5 */) { var spreadIndex = getSpreadArgumentIndex(node.arguments); if (spreadIndex >= 0) { - error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher); + error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher); } } var expressionType = checkExpression(node.expression); @@ -17354,7 +18389,7 @@ var ts; // If ConstructExpr's apparent type(section 3.8.1) is an object type with one or // more construct signatures, the expression is processed in the same manner as a // function call, but using the construct signatures as the initial set of candidate - // signatures for overload resolution.The result type of the function call becomes + // signatures for overload resolution. The result type of the function call becomes // the result type of the operation. expressionType = getApparentType(expressionType); if (expressionType === unknownType) { @@ -17490,17 +18525,39 @@ var ts; type = checkExpressionCached(func.body, contextualMapper); } else { - // Aggregate the types of expressions within all the return statements. - var types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper); - if (types.length === 0) { - return voidType; + var types; + var funcIsGenerator = !!func.asteriskToken; + if (funcIsGenerator) { + types = checkAndAggregateYieldOperandTypes(func.body, contextualMapper); + if (types.length === 0) { + var iterableIteratorAny = createIterableIteratorType(anyType); + if (compilerOptions.noImplicitAny) { + error(func.asteriskToken, ts.Diagnostics.Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type, typeToString(iterableIteratorAny)); + } + return iterableIteratorAny; + } } - // When return statements are contextually typed we allow the return type to be a union type. Otherwise we require the - // return expressions to have a best common supertype. + else { + types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper); + if (types.length === 0) { + return voidType; + } + } + // When yield/return statements are contextually typed we allow the return type to be a union type. + // Otherwise we require the yield/return expressions to have a best common supertype. type = contextualSignature ? getUnionType(types) : getCommonSupertype(types); if (!type) { - error(func, ts.Diagnostics.No_best_common_type_exists_among_return_expressions); - return unknownType; + if (funcIsGenerator) { + error(func, ts.Diagnostics.No_best_common_type_exists_among_yield_expressions); + return createIterableIteratorType(unknownType); + } + else { + error(func, ts.Diagnostics.No_best_common_type_exists_among_return_expressions); + return unknownType; + } + } + if (funcIsGenerator) { + type = createIterableIteratorType(type); } } if (!contextualSignature) { @@ -17508,7 +18565,23 @@ var ts; } return getWidenedType(type); } - /// Returns a set of types relating to every return expression relating to a function block. + function checkAndAggregateYieldOperandTypes(body, contextualMapper) { + var aggregatedTypes = []; + ts.forEachYieldExpression(body, function (yieldExpression) { + var expr = yieldExpression.expression; + if (expr) { + var type = checkExpressionCached(expr, contextualMapper); + if (yieldExpression.asteriskToken) { + // A yield* expression effectively yields everything that its operand yields + type = checkElementTypeOfIterable(type, yieldExpression.expression); + } + if (!ts.contains(aggregatedTypes, type)) { + aggregatedTypes.push(type); + } + } + }); + return aggregatedTypes; + } function checkAndAggregateReturnExpressionTypes(body, contextualMapper) { var aggregatedTypes = []; ts.forEachReturnStatement(body, function (returnStatement) { @@ -17677,8 +18750,8 @@ var ts; var index = n.argumentExpression; var symbol = findSymbol(n.expression); if (symbol && index && index.kind === 8 /* StringLiteral */) { - var name_7 = index.text; - var prop = getPropertyOfType(getTypeOfSymbol(symbol), name_7); + var name_10 = index.text; + var prop = getPropertyOfType(getTypeOfSymbol(symbol), name_10); return prop && (prop.flags & 3 /* Variable */) !== 0 && (getDeclarationFlagsFromSymbol(prop) & 8192 /* Const */) !== 0; } return false; @@ -17836,16 +18909,16 @@ var ts; var p = properties[_i]; if (p.kind === 225 /* PropertyAssignment */ || p.kind === 226 /* ShorthandPropertyAssignment */) { // TODO(andersh): Computed property support - var name_8 = p.name; + var name_11 = p.name; var type = sourceType.flags & 1 /* Any */ ? sourceType : - getTypeOfPropertyOfType(sourceType, name_8.text) || - isNumericLiteralName(name_8.text) && getIndexTypeOfType(sourceType, 1 /* Number */) || + getTypeOfPropertyOfType(sourceType, name_11.text) || + isNumericLiteralName(name_11.text) && getIndexTypeOfType(sourceType, 1 /* Number */) || getIndexTypeOfType(sourceType, 0 /* String */); if (type) { - checkDestructuringAssignment(p.initializer || name_8, type); + checkDestructuringAssignment(p.initializer || name_11, type); } else { - error(name_8, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), ts.declarationNameToString(name_8)); + error(name_11, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), ts.declarationNameToString(name_11)); } } else { @@ -18095,14 +19168,53 @@ var ts; error(node, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(node.operatorToken.kind), typeToString(leftType), typeToString(rightType)); } } + function isYieldExpressionInClass(node) { + var current = node; + var parent = node.parent; + while (parent) { + if (ts.isFunctionLike(parent) && current === parent.body) { + return false; + } + else if (current.kind === 202 /* ClassDeclaration */ || current.kind === 175 /* ClassExpression */) { + return true; + } + current = parent; + parent = parent.parent; + } + return false; + } function checkYieldExpression(node) { // Grammar checking - if (!(node.parserContextFlags & 4 /* Yield */)) { - grammarErrorOnFirstToken(node, ts.Diagnostics.yield_expression_must_be_contained_within_a_generator_declaration); + if (!(node.parserContextFlags & 4 /* Yield */) || isYieldExpressionInClass(node)) { + grammarErrorOnFirstToken(node, ts.Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body); } - else { - grammarErrorOnFirstToken(node, ts.Diagnostics.yield_expressions_are_not_currently_supported); + if (node.expression) { + var func = ts.getContainingFunction(node); + // If the user's code is syntactically correct, the func should always have a star. After all, + // we are in a yield context. + if (func && func.asteriskToken) { + var expressionType = checkExpressionCached(node.expression, undefined); + var expressionElementType; + var nodeIsYieldStar = !!node.asteriskToken; + if (nodeIsYieldStar) { + expressionElementType = checkElementTypeOfIterable(expressionType, node.expression); + } + // There is no point in doing an assignability check if the function + // has no explicit return type because the return type is directly computed + // from the yield expressions. + if (func.type) { + var signatureElementType = getElementTypeOfIterableIterator(getTypeFromTypeNode(func.type)) || anyType; + if (nodeIsYieldStar) { + checkTypeAssignableTo(expressionElementType, signatureElementType, node.expression, undefined); + } + else { + checkTypeAssignableTo(expressionType, signatureElementType, node.expression, undefined); + } + } + } } + // Both yield and yield* expressions have type 'any' + return anyType; } function checkConditionalExpression(node, contextualMapper) { checkExpression(node.condition); @@ -18273,8 +19385,7 @@ var ts; case 176 /* OmittedExpression */: return undefinedType; case 173 /* YieldExpression */: - checkYieldExpression(node); - return unknownType; + return checkYieldExpression(node); } return unknownType; } @@ -18318,6 +19429,14 @@ var ts; error(node, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type); } } + function isSyntacticallyValidGenerator(node) { + if (!node.asteriskToken || !node.body) { + return false; + } + return node.kind === 135 /* MethodDeclaration */ || + node.kind === 201 /* FunctionDeclaration */ || + node.kind === 163 /* FunctionExpression */; + } function checkSignatureDeclaration(node) { // Grammar checking if (node.kind === 141 /* IndexSignature */) { @@ -18345,6 +19464,25 @@ var ts; break; } } + if (node.type) { + if (languageVersion >= 2 /* ES6 */ && isSyntacticallyValidGenerator(node)) { + var returnType = getTypeFromTypeNode(node.type); + if (returnType === voidType) { + error(node.type, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation); + } + else { + var generatorElementType = getElementTypeOfIterableIterator(returnType) || anyType; + var iterableIteratorInstantiation = createIterableIteratorType(generatorElementType); + // Naively, one could check that IterableIterator is assignable to the return type annotation. + // However, that would not catch the error in the following case. + // + // interface BadGenerator extends Iterable, Iterator { } + // function* g(): BadGenerator { } // Iterable and Iterator have different types! + // + checkTypeAssignableTo(iterableIteratorInstantiation, returnType, node.type); + } + } + } } checkSpecializedSignatureDeclaration(node); } @@ -18984,7 +20122,6 @@ var ts; function checkFunctionDeclaration(node) { if (produceDiagnostics) { checkFunctionLikeDeclaration(node) || - checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarFunctionName(node.name) || checkGrammarForGenerator(node); checkCollisionWithCapturedSuperVariable(node, node.name); @@ -19027,10 +20164,18 @@ var ts; if (node.type && !isAccessor(node.kind) && !node.asteriskToken) { checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } - // Report an implicit any error if there is no body, no explicit return type, and node is not a private method - // in an ambient context - if (compilerOptions.noImplicitAny && ts.nodeIsMissing(node.body) && !node.type && !isPrivateWithinAmbient(node)) { - reportImplicitAnyError(node, anyType); + if (produceDiagnostics && !node.type) { + // Report an implicit any error if there is no body, no explicit return type, and node is not a private method + // in an ambient context + if (compilerOptions.noImplicitAny && ts.nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) { + reportImplicitAnyError(node, anyType); + } + if (node.asteriskToken && ts.nodeIsPresent(node.body)) { + // A generator with a body and no type annotation can still cause errors. It can error if the + // yielded values have no common supertype, or it can give an implicit any error if it has no + // yielded values. The only way to trigger these errors is to try checking its return type. + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } } } function checkBlock(node) { @@ -19191,8 +20336,8 @@ var ts; // otherwise if variable has an initializer - show error that initialization will fail // since LHS will be block scoped name instead of function scoped if (!namesShareScope) { - var name_9 = symbolToString(localDeclarationSymbol); - error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name_9, name_9); + var name_12 = symbolToString(localDeclarationSymbol); + error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name_12, name_12); } } } @@ -19302,7 +20447,7 @@ var ts; } function checkVariableStatement(node) { // Grammar checking - checkGrammarDecorators(node) || checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node); + checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node); ts.forEach(node.declarationList.declarations, checkSourceElement); } function checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) { @@ -19392,7 +20537,7 @@ var ts; // iteratedType will be undefined if the rightType was missing properties/signatures // required to get its iteratedType (like [Symbol.iterator] or next). This may be // because we accessed properties from anyType, or it may have led to an error inside - // getIteratedType. + // getElementTypeOfIterable. if (iteratedType) { checkTypeAssignableTo(iteratedType, leftType, varExpr, undefined); } @@ -19458,7 +20603,7 @@ var ts; return inputType; } if (languageVersion >= 2 /* ES6 */) { - return checkIteratedType(inputType, errorNode) || anyType; + return checkElementTypeOfIterable(inputType, errorNode); } if (allowStringInput) { return checkElementTypeOfArrayOrString(inputType, errorNode); @@ -19475,88 +20620,127 @@ var ts; /** * When errorNode is undefined, it means we should not report any errors. */ - function checkIteratedType(iterable, errorNode) { - ts.Debug.assert(languageVersion >= 2 /* ES6 */); - var iteratedType = getIteratedType(iterable, errorNode); + function checkElementTypeOfIterable(iterable, errorNode) { + var elementType = getElementTypeOfIterable(iterable, errorNode); // Now even though we have extracted the iteratedType, we will have to validate that the type // passed in is actually an Iterable. - if (errorNode && iteratedType) { - checkTypeAssignableTo(iterable, createIterableType(iteratedType), errorNode); + if (errorNode && elementType) { + checkTypeAssignableTo(iterable, createIterableType(elementType), errorNode); } - return iteratedType; - function getIteratedType(iterable, errorNode) { - // We want to treat type as an iterable, and get the type it is an iterable of. The iterable - // must have the following structure (annotated with the names of the variables below): - // - // { // iterable - // [Symbol.iterator]: { // iteratorFunction - // (): { // iterator - // next: { // iteratorNextFunction - // (): { // iteratorNextResult - // value: T // iteratorNextValue - // } - // } - // } - // } - // } - // - // T is the type we are after. At every level that involves analyzing return types - // of signatures, we union the return types of all the signatures. - // - // Another thing to note is that at any step of this process, we could run into a dead end, - // meaning either the property is missing, or we run into the anyType. If either of these things - // happens, we return undefined to signal that we could not find the iterated type. If a property - // is missing, and the previous step did not result in 'any', then we also give an error if the - // caller requested it. Then the caller can decide what to do in the case where there is no iterated - // type. This is different from returning anyType, because that would signify that we have matched the - // whole pattern and that T (above) is 'any'. - if (allConstituentTypesHaveKind(iterable, 1 /* Any */)) { - return undefined; - } + return elementType || anyType; + } + /** + * We want to treat type as an iterable, and get the type it is an iterable of. The iterable + * must have the following structure (annotated with the names of the variables below): + * + * { // iterable + * [Symbol.iterator]: { // iteratorFunction + * (): Iterator + * } + * } + * + * T is the type we are after. At every level that involves analyzing return types + * of signatures, we union the return types of all the signatures. + * + * Another thing to note is that at any step of this process, we could run into a dead end, + * meaning either the property is missing, or we run into the anyType. If either of these things + * happens, we return undefined to signal that we could not find the iterated type. If a property + * is missing, and the previous step did not result in 'any', then we also give an error if the + * caller requested it. Then the caller can decide what to do in the case where there is no iterated + * type. This is different from returning anyType, because that would signify that we have matched the + * whole pattern and that T (above) is 'any'. + */ + function getElementTypeOfIterable(type, errorNode) { + if (type.flags & 1 /* Any */) { + return undefined; + } + var typeAsIterable = type; + if (!typeAsIterable.iterableElementType) { // As an optimization, if the type is instantiated directly using the globalIterableType (Iterable), // then just grab its type argument. - if ((iterable.flags & 4096 /* Reference */) && iterable.target === globalIterableType) { - return iterable.typeArguments[0]; + if ((type.flags & 4096 /* Reference */) && type.target === globalIterableType) { + typeAsIterable.iterableElementType = type.typeArguments[0]; } - var iteratorFunction = getTypeOfPropertyOfType(iterable, ts.getPropertyNameForKnownSymbolName("iterator")); - if (iteratorFunction && allConstituentTypesHaveKind(iteratorFunction, 1 /* Any */)) { - return undefined; - } - var iteratorFunctionSignatures = iteratorFunction ? getSignaturesOfType(iteratorFunction, 0 /* Call */) : emptyArray; - if (iteratorFunctionSignatures.length === 0) { - if (errorNode) { - error(errorNode, ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator); + else { + var iteratorFunction = getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("iterator")); + if (iteratorFunction && iteratorFunction.flags & 1 /* Any */) { + return undefined; } - return undefined; - } - var iterator = getUnionType(ts.map(iteratorFunctionSignatures, getReturnTypeOfSignature)); - if (allConstituentTypesHaveKind(iterator, 1 /* Any */)) { - return undefined; - } - var iteratorNextFunction = getTypeOfPropertyOfType(iterator, "next"); - if (iteratorNextFunction && allConstituentTypesHaveKind(iteratorNextFunction, 1 /* Any */)) { - return undefined; - } - var iteratorNextFunctionSignatures = iteratorNextFunction ? getSignaturesOfType(iteratorNextFunction, 0 /* Call */) : emptyArray; - if (iteratorNextFunctionSignatures.length === 0) { - if (errorNode) { - error(errorNode, ts.Diagnostics.An_iterator_must_have_a_next_method); + var iteratorFunctionSignatures = iteratorFunction ? getSignaturesOfType(iteratorFunction, 0 /* Call */) : emptyArray; + if (iteratorFunctionSignatures.length === 0) { + if (errorNode) { + error(errorNode, ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator); + } + return undefined; } - return undefined; + typeAsIterable.iterableElementType = getElementTypeOfIterator(getUnionType(ts.map(iteratorFunctionSignatures, getReturnTypeOfSignature)), errorNode); } - var iteratorNextResult = getUnionType(ts.map(iteratorNextFunctionSignatures, getReturnTypeOfSignature)); - if (allConstituentTypesHaveKind(iteratorNextResult, 1 /* Any */)) { - return undefined; - } - var iteratorNextValue = getTypeOfPropertyOfType(iteratorNextResult, "value"); - if (!iteratorNextValue) { - if (errorNode) { - error(errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property); - } - return undefined; - } - return iteratorNextValue; } + return typeAsIterable.iterableElementType; + } + /** + * This function has very similar logic as getElementTypeOfIterable, except that it operates on + * Iterators instead of Iterables. Here is the structure: + * + * { // iterator + * next: { // iteratorNextFunction + * (): { // iteratorNextResult + * value: T // iteratorNextValue + * } + * } + * } + * + */ + function getElementTypeOfIterator(type, errorNode) { + if (type.flags & 1 /* Any */) { + return undefined; + } + var typeAsIterator = type; + if (!typeAsIterator.iteratorElementType) { + // As an optimization, if the type is instantiated directly using the globalIteratorType (Iterator), + // then just grab its type argument. + if ((type.flags & 4096 /* Reference */) && type.target === globalIteratorType) { + typeAsIterator.iteratorElementType = type.typeArguments[0]; + } + else { + var iteratorNextFunction = getTypeOfPropertyOfType(type, "next"); + if (iteratorNextFunction && iteratorNextFunction.flags & 1 /* Any */) { + return undefined; + } + var iteratorNextFunctionSignatures = iteratorNextFunction ? getSignaturesOfType(iteratorNextFunction, 0 /* Call */) : emptyArray; + if (iteratorNextFunctionSignatures.length === 0) { + if (errorNode) { + error(errorNode, ts.Diagnostics.An_iterator_must_have_a_next_method); + } + return undefined; + } + var iteratorNextResult = getUnionType(ts.map(iteratorNextFunctionSignatures, getReturnTypeOfSignature)); + if (iteratorNextResult.flags & 1 /* Any */) { + return undefined; + } + var iteratorNextValue = getTypeOfPropertyOfType(iteratorNextResult, "value"); + if (!iteratorNextValue) { + if (errorNode) { + error(errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property); + } + return undefined; + } + typeAsIterator.iteratorElementType = iteratorNextValue; + } + } + return typeAsIterator.iteratorElementType; + } + function getElementTypeOfIterableIterator(type) { + if (type.flags & 1 /* Any */) { + return undefined; + } + // As an optimization, if the type is instantiated directly using the globalIterableIteratorType (IterableIterator), + // then just grab its type argument. + if ((type.flags & 4096 /* Reference */) && type.target === globalIterableIteratorType) { + return type.typeArguments[0]; + } + return getElementTypeOfIterable(type, undefined) || + getElementTypeOfIterator(type, undefined); } /** * This function does the following steps: @@ -19637,19 +20821,24 @@ var ts; if (func) { var returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func)); var exprType = checkExpressionCached(node.expression); + if (func.asteriskToken) { + // A generator does not need its return expressions checked against its return type. + // Instead, the yield expressions are checked against the element type. + // TODO: Check return expressions of generators when return type tracking is added + // for generators. + return; + } if (func.kind === 138 /* SetAccessor */) { error(node.expression, ts.Diagnostics.Setters_cannot_return_a_value); } - else { - if (func.kind === 136 /* Constructor */) { - if (!isTypeAssignableTo(exprType, returnType)) { - error(node.expression, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); - } - } - else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) { - checkTypeAssignableTo(exprType, returnType, node.expression, undefined); + else if (func.kind === 136 /* Constructor */) { + if (!isTypeAssignableTo(exprType, returnType)) { + error(node.expression, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } + else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) { + checkTypeAssignableTo(exprType, returnType, node.expression, undefined); + } } } } @@ -19870,9 +21059,6 @@ var ts; function checkClassDeclaration(node) { checkGrammarDeclarationNameInStrictMode(node); // Grammar checking - if (node.parent.kind !== 207 /* ModuleBlock */ && node.parent.kind !== 228 /* SourceFile */) { - grammarErrorOnNode(node, ts.Diagnostics.class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration); - } if (!node.name && !(node.flags & 256 /* Default */)) { grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } @@ -20978,87 +22164,6 @@ var ts; } return node.parent && node.parent.kind === 177 /* ExpressionWithTypeArguments */; } - function isTypeNode(node) { - if (142 /* FirstTypeNode */ <= node.kind && node.kind <= 150 /* LastTypeNode */) { - return true; - } - switch (node.kind) { - case 112 /* AnyKeyword */: - case 120 /* NumberKeyword */: - case 122 /* StringKeyword */: - case 113 /* BooleanKeyword */: - case 123 /* SymbolKeyword */: - return true; - case 99 /* VoidKeyword */: - return node.parent.kind !== 167 /* VoidExpression */; - case 8 /* StringLiteral */: - // Specialized signatures can have string literals as their parameters' type names - return node.parent.kind === 130 /* Parameter */; - case 177 /* ExpressionWithTypeArguments */: - return true; - // Identifiers and qualified names may be type nodes, depending on their context. Climb - // above them to find the lowest container - case 65 /* Identifier */: - // If the identifier is the RHS of a qualified name, then it's a type iff its parent is. - if (node.parent.kind === 127 /* QualifiedName */ && node.parent.right === node) { - node = node.parent; - } - else if (node.parent.kind === 156 /* PropertyAccessExpression */ && node.parent.name === node) { - node = node.parent; - } - // fall through - case 127 /* QualifiedName */: - case 156 /* PropertyAccessExpression */: - // At this point, node is either a qualified name or an identifier - ts.Debug.assert(node.kind === 65 /* Identifier */ || node.kind === 127 /* QualifiedName */ || node.kind === 156 /* PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'."); - var parent_5 = node.parent; - if (parent_5.kind === 145 /* TypeQuery */) { - return false; - } - // Do not recursively call isTypeNode on the parent. In the example: - // - // let a: A.B.C; - // - // Calling isTypeNode would consider the qualified name A.B a type node. Only C or - // A.B.C is a type node. - if (142 /* FirstTypeNode */ <= parent_5.kind && parent_5.kind <= 150 /* LastTypeNode */) { - return true; - } - switch (parent_5.kind) { - case 177 /* ExpressionWithTypeArguments */: - return true; - case 129 /* TypeParameter */: - return node === parent_5.constraint; - case 133 /* PropertyDeclaration */: - case 132 /* PropertySignature */: - case 130 /* Parameter */: - case 199 /* VariableDeclaration */: - return node === parent_5.type; - case 201 /* FunctionDeclaration */: - case 163 /* FunctionExpression */: - case 164 /* ArrowFunction */: - case 136 /* Constructor */: - case 135 /* MethodDeclaration */: - case 134 /* MethodSignature */: - case 137 /* GetAccessor */: - case 138 /* SetAccessor */: - return node === parent_5.type; - case 139 /* CallSignature */: - case 140 /* ConstructSignature */: - case 141 /* IndexSignature */: - return node === parent_5.type; - case 161 /* TypeAssertionExpression */: - return node === parent_5.type; - case 158 /* CallExpression */: - case 159 /* NewExpression */: - return parent_5.typeArguments && ts.indexOf(parent_5.typeArguments, node) >= 0; - case 160 /* TaggedTemplateExpression */: - // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments. - return false; - } - } - return false; - } function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide) { while (nodeOnRightSide.parent.kind === 127 /* QualifiedName */) { nodeOnRightSide = nodeOnRightSide.parent; @@ -21201,7 +22306,7 @@ var ts; // We cannot answer semantic questions within a with block, do not proceed any further return unknownType; } - if (isTypeNode(node)) { + if (ts.isTypeNode(node)) { return getTypeFromTypeNode(node); } if (ts.isExpression(node)) { @@ -21255,9 +22360,9 @@ var ts; function getRootSymbols(symbol) { if (symbol.flags & 268435456 /* UnionProperty */) { var symbols = []; - var name_10 = symbol.name; + var name_13 = symbol.name; ts.forEach(getSymbolLinks(symbol).unionType.types, function (t) { - symbols.push(getPropertyOfType(t, name_10)); + symbols.push(getPropertyOfType(t, name_13)); }); return symbols; } @@ -21712,8 +22817,7 @@ var ts; getSymbolLinks(unknownSymbol).type = unknownType; globals[undefinedSymbol.name] = undefinedSymbol; // Initialize special types - globalArraySymbol = getGlobalTypeSymbol("Array"); - globalArrayType = getTypeOfGlobalSymbol(globalArraySymbol, 1); + globalArrayType = getGlobalType("Array", 1); globalObjectType = getGlobalType("Object"); globalFunctionType = getGlobalType("Function"); globalStringType = getGlobalType("String"); @@ -21731,6 +22835,8 @@ var ts; globalESSymbolType = getGlobalType("Symbol"); globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol"); globalIterableType = getGlobalType("Iterable", 1); + globalIteratorType = getGlobalType("Iterator", 1); + globalIterableIteratorType = getGlobalType("IterableIterator", 1); } else { globalTemplateStringsArrayType = unknownType; @@ -21739,6 +22845,9 @@ var ts; // a global Symbol already, particularly if it is a class. globalESSymbolType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); globalESSymbolConstructorSymbol = undefined; + globalIterableType = emptyGenericType; + globalIteratorType = emptyGenericType; + globalIterableIteratorType = emptyGenericType; } anyArrayType = createArrayType(anyType); } @@ -21763,20 +22872,20 @@ var ts; if (impotClause.namedBindings) { var nameBindings = impotClause.namedBindings; if (nameBindings.kind === 212 /* NamespaceImport */) { - var name_11 = nameBindings.name; - if (isReservedWordInStrictMode(name_11)) { - var nameText = ts.declarationNameToString(name_11); - return grammarErrorOnNode(name_11, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); + var name_14 = nameBindings.name; + if (isReservedWordInStrictMode(name_14)) { + var nameText = ts.declarationNameToString(name_14); + return grammarErrorOnNode(name_14, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); } } else if (nameBindings.kind === 213 /* NamedImports */) { var reportError = false; for (var _i = 0, _a = nameBindings.elements; _i < _a.length; _i++) { var element = _a[_i]; - var name_12 = element.name; - if (isReservedWordInStrictMode(name_12)) { - var nameText = ts.declarationNameToString(name_12); - reportError = reportError || grammarErrorOnNode(name_12, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); + var name_15 = element.name; + if (isReservedWordInStrictMode(name_15)) { + var nameText = ts.declarationNameToString(name_15); + reportError = reportError || grammarErrorOnNode(name_15, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); } } return reportError; @@ -21902,19 +23011,28 @@ var ts; case 135 /* MethodDeclaration */: case 134 /* MethodSignature */: case 141 /* IndexSignature */: - case 202 /* ClassDeclaration */: - case 203 /* InterfaceDeclaration */: case 206 /* ModuleDeclaration */: - case 205 /* EnumDeclaration */: - case 181 /* VariableStatement */: - case 201 /* FunctionDeclaration */: - case 204 /* TypeAliasDeclaration */: case 210 /* ImportDeclaration */: case 209 /* ImportEqualsDeclaration */: case 216 /* ExportDeclaration */: case 215 /* ExportAssignment */: case 130 /* Parameter */: break; + case 202 /* ClassDeclaration */: + case 203 /* InterfaceDeclaration */: + case 181 /* VariableStatement */: + case 201 /* FunctionDeclaration */: + case 204 /* TypeAliasDeclaration */: + if (node.modifiers && node.parent.kind !== 207 /* ModuleBlock */ && node.parent.kind !== 228 /* SourceFile */) { + return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here); + } + break; + case 205 /* EnumDeclaration */: + if (node.modifiers && (node.modifiers.length > 1 || node.modifiers[0].kind !== 70 /* ConstKeyword */) && + node.parent.kind !== 207 /* ModuleBlock */ && node.parent.kind !== 228 /* SourceFile */) { + return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here); + } + break; default: return false; } @@ -22012,9 +23130,6 @@ var ts; else if ((node.kind === 210 /* ImportDeclaration */ || node.kind === 209 /* ImportEqualsDeclaration */) && flags & 2 /* Ambient */) { return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_declare_modifier_cannot_be_used_with_an_import_declaration, "declare"); } - else if (node.kind === 203 /* InterfaceDeclaration */ && flags & 2 /* Ambient */) { - return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_declare_modifier_cannot_be_used_with_an_interface_declaration, "declare"); - } else if (node.kind === 130 /* Parameter */ && (flags & 112 /* AccessibilityModifier */) && ts.isBindingPattern(node.name)) { return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_may_not_be_a_binding_pattern); } @@ -22231,7 +23346,18 @@ var ts; } function checkGrammarForGenerator(node) { if (node.asteriskToken) { - return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_currently_supported); + ts.Debug.assert(node.kind === 201 /* FunctionDeclaration */ || + node.kind === 163 /* FunctionExpression */ || + node.kind === 135 /* MethodDeclaration */); + if (ts.isInAmbientContext(node)) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_allowed_in_an_ambient_context); + } + if (!node.body) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator); + } + if (languageVersion < 2 /* ES6 */) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_only_available_when_targeting_ECMAScript_6_or_higher); + } } } function checkGrammarFunctionName(name) { @@ -22252,11 +23378,11 @@ var ts; var inStrictMode = (node.parserContextFlags & 1 /* StrictMode */) !== 0; for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var prop = _a[_i]; - var name_13 = prop.name; + var name_16 = prop.name; if (prop.kind === 176 /* OmittedExpression */ || - name_13.kind === 128 /* ComputedPropertyName */) { + name_16.kind === 128 /* ComputedPropertyName */) { // If the name is not a ComputedPropertyName, the grammar checking will skip it - checkGrammarComputedPropertyName(name_13); + checkGrammarComputedPropertyName(name_16); continue; } // ECMA-262 11.1.5 Object Initialiser @@ -22271,8 +23397,8 @@ var ts; if (prop.kind === 225 /* PropertyAssignment */ || prop.kind === 226 /* ShorthandPropertyAssignment */) { // Grammar checking for computedPropertName and shorthandPropertyAssignment checkGrammarForInvalidQuestionMark(prop, prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional); - if (name_13.kind === 7 /* NumericLiteral */) { - checkGrammarNumericLiteral(name_13); + if (name_16.kind === 7 /* NumericLiteral */) { + checkGrammarNumericLiteral(name_16); } currentKind = Property; } @@ -22288,26 +23414,26 @@ var ts; else { ts.Debug.fail("Unexpected syntax kind:" + prop.kind); } - if (!ts.hasProperty(seen, name_13.text)) { - seen[name_13.text] = currentKind; + if (!ts.hasProperty(seen, name_16.text)) { + seen[name_16.text] = currentKind; } else { - var existingKind = seen[name_13.text]; + var existingKind = seen[name_16.text]; if (currentKind === Property && existingKind === Property) { if (inStrictMode) { - grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode); + grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode); } } else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { - seen[name_13.text] = currentKind | existingKind; + seen[name_16.text] = currentKind | existingKind; } else { - return grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); + return grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); } } else { - return grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name); + return grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name); } } } @@ -23168,9 +24294,9 @@ var ts; } var count = 0; while (true) { - var name_14 = baseName + "_" + (++count); - if (!ts.hasProperty(currentSourceFile.identifiers, name_14)) { - return name_14; + var name_17 = baseName + "_" + (++count); + if (!ts.hasProperty(currentSourceFile.identifiers, name_17)) { + return name_17; } } } @@ -24379,9 +25505,9 @@ var ts; tempFlags++; // Skip over 'i' and 'n' if (count !== 8 && count !== 13) { - var name_15 = count < 26 ? "_" + String.fromCharCode(97 /* a */ + count) : "_" + (count - 26); - if (isUniqueName(name_15)) { - return name_15; + var name_18 = count < 26 ? "_" + String.fromCharCode(97 /* a */ + count) : "_" + (count - 26); + if (isUniqueName(name_18)) { + return name_18; } } } @@ -24414,9 +25540,9 @@ var ts; } function generateNameForModuleOrEnum(node) { if (node.name.kind === 65 /* Identifier */) { - var name_16 = node.name.text; + var name_19 = node.name.text; // Use module/enum name itself if it is unique, otherwise make a unique variation - assignGeneratedName(node, isUniqueLocalName(name_16, node) ? name_16 : makeUniqueName(name_16)); + assignGeneratedName(node, isUniqueLocalName(name_19, node) ? name_19 : makeUniqueName(name_19)); } } function generateNameForImportOrExportDeclaration(node) { @@ -24635,8 +25761,8 @@ var ts; // Child scopes are always shown with a dot (even if they have no name), // unless it is a computed property. Then it is shown with brackets, // but the brackets are included in the name. - var name_17 = node.name; - if (!name_17 || name_17.kind !== 128 /* ComputedPropertyName */) { + var name_20 = node.name; + if (!name_20 || name_20.kind !== 128 /* ComputedPropertyName */) { scopeName = "." + scopeName; } scopeName = sourceMapData.sourceMapNames[parentIndex] + scopeName; @@ -24665,10 +25791,10 @@ var ts; node.kind === 205 /* EnumDeclaration */) { // Declaration and has associated name use it if (node.name) { - var name_18 = node.name; + var name_21 = node.name; // For computed property names, the text will include the brackets - scopeName = name_18.kind === 128 /* ComputedPropertyName */ - ? ts.getTextOfNode(name_18) + scopeName = name_21.kind === 128 /* ComputedPropertyName */ + ? ts.getTextOfNode(name_21) : node.name.text; } recordScopeNameStart(scopeName); @@ -25369,16 +26495,16 @@ var ts; } return true; } - function emitListWithSpread(elements, alwaysCopy, multiLine, trailingComma) { + function emitListWithSpread(elements, needsUniqueCopy, multiLine, trailingComma, useConcat) { var pos = 0; var group = 0; var length = elements.length; while (pos < length) { // Emit using the pattern .concat(, , ...) - if (group === 1) { + if (group === 1 && useConcat) { write(".concat("); } - else if (group > 1) { + else if (group > 0) { write(", "); } var e = elements[pos]; @@ -25386,7 +26512,7 @@ var ts; e = e.expression; emitParenthesizedIf(e, group === 0 && needsParenthesisForPropertyAccessOrInvocation(e)); pos++; - if (pos === length && group === 0 && alwaysCopy && e.kind !== 154 /* ArrayLiteralExpression */) { + if (pos === length && group === 0 && needsUniqueCopy && e.kind !== 154 /* ArrayLiteralExpression */) { write(".slice()"); } } @@ -25409,7 +26535,9 @@ var ts; group++; } if (group > 1) { - write(")"); + if (useConcat) { + write(")"); + } } } function isSpreadElementExpression(node) { @@ -25427,7 +26555,7 @@ var ts; } else { emitListWithSpread(elements, true, (node.flags & 512 /* MultiLine */) !== 0, - /*trailingComma*/ elements.hasTrailingComma); + /*trailingComma*/ elements.hasTrailingComma, true); } } function emitObjectLiteralBody(node, numElements) { @@ -25798,7 +26926,7 @@ var ts; write("void 0"); } write(", "); - emitListWithSpread(node.arguments, false, false, false); + emitListWithSpread(node.arguments, false, false, false, true); write(")"); } function emitCallExpression(node) { @@ -25832,11 +26960,42 @@ var ts; } function emitNewExpression(node) { write("new "); - emit(node.expression); - if (node.arguments) { + // Spread operator logic can be supported in new expressions in ES5 using a combination + // of Function.prototype.bind() and Function.prototype.apply(). + // + // Example: + // + // var arguments = [1, 2, 3, 4, 5]; + // new Array(...arguments); + // + // Could be transpiled into ES5: + // + // var arguments = [1, 2, 3, 4, 5]; + // new (Array.bind.apply(Array, [void 0].concat(arguments))); + // + // `[void 0]` is the first argument which represents `thisArg` to the bind method above. + // And `thisArg` will be set to the return value of the constructor when instantiated + // with the new operator — regardless of any value we set `thisArg` to. Thus, we set it + // to an undefined, `void 0`. + if (languageVersion === 1 /* ES5 */ && + node.arguments && + hasSpreadElement(node.arguments)) { write("("); - emitCommaList(node.arguments); - write(")"); + var target = emitCallTarget(node.expression); + write(".bind.apply("); + emit(target); + write(", [void 0].concat("); + emitListWithSpread(node.arguments, false, false, false, false); + write(")))"); + write("()"); + } + else { + emit(node.expression); + if (node.arguments) { + write("("); + emitCommaList(node.arguments); + write(")"); + } } } function emitTaggedTemplateExpression(node) { @@ -26136,9 +27295,10 @@ var ts; write(")"); emitEmbeddedStatement(node.statement); } - /* Returns true if start of variable declaration list was emitted. - * Return false if nothing was written - this can happen for source file level variable declarations - * in system modules - such variable declarations are hoisted. + /** + * Returns true if start of variable declaration list was emitted. + * Returns false if nothing was written - this can happen for source file level variable declarations + * in system modules where such variable declarations are hoisted. */ function tryEmitStartOfVariableDeclarationList(decl, startPos) { if (shouldHoistVariable(decl, true)) { @@ -26901,15 +28061,35 @@ var ts; ts.forEach(node.declarationList.declarations, emitExportVariableAssignments); } } + function shouldEmitLeadingAndTrailingCommentsForVariableStatement(node) { + // If we're not exporting the variables, there's nothing special here. + // Always emit comments for these nodes. + if (!(node.flags & 1 /* Export */)) { + return true; + } + // If we are exporting, but it's a top-level ES6 module exports, + // we'll emit the declaration list verbatim, so emit comments too. + if (isES6ExportedDeclaration(node)) { + return true; + } + // Otherwise, only emit if we have at least one initializer present. + for (var _a = 0, _b = node.declarationList.declarations; _a < _b.length; _a++) { + var declaration = _b[_a]; + if (declaration.initializer) { + return true; + } + } + return false; + } function emitParameter(node) { if (languageVersion < 2 /* ES6 */) { if (ts.isBindingPattern(node.name)) { - var name_19 = createTempVariable(0 /* Auto */); + var name_22 = createTempVariable(0 /* Auto */); if (!tempParameters) { tempParameters = []; } - tempParameters.push(name_19); - emit(name_19); + tempParameters.push(name_22); + emit(name_22); } else { emit(node.name); @@ -28577,8 +29757,8 @@ var ts; // export { x, y } for (var _c = 0, _d = node.exportClause.elements; _c < _d.length; _c++) { var specifier = _d[_c]; - var name_20 = (specifier.propertyName || specifier.name).text; - (exportSpecifiers[name_20] || (exportSpecifiers[name_20] = [])).push(specifier); + var name_23 = (specifier.propertyName || specifier.name).text; + (exportSpecifiers[name_23] || (exportSpecifiers[name_23] = [])).push(specifier); } } break; @@ -28778,12 +29958,12 @@ var ts; var seen = {}; for (var i = 0; i < hoistedVars.length; ++i) { var local = hoistedVars[i]; - var name_21 = local.kind === 65 /* Identifier */ + var name_24 = local.kind === 65 /* Identifier */ ? local : local.name; - if (name_21) { + if (name_24) { // do not emit duplicate entries (in case of declaration merging) in the list of hoisted variables - var text = ts.unescapeIdentifier(name_21.text); + var text = ts.unescapeIdentifier(name_24.text); if (ts.hasProperty(seen, text)) { continue; } @@ -28862,15 +30042,15 @@ var ts; } if (node.kind === 199 /* VariableDeclaration */ || node.kind === 153 /* BindingElement */) { if (shouldHoistVariable(node, false)) { - var name_22 = node.name; - if (name_22.kind === 65 /* Identifier */) { + var name_25 = node.name; + if (name_25.kind === 65 /* Identifier */) { if (!hoistedVars) { hoistedVars = []; } - hoistedVars.push(name_22); + hoistedVars.push(name_25); } else { - ts.forEachChild(name_22, visit); + ts.forEachChild(name_25, visit); } } return; @@ -29329,6 +30509,8 @@ var ts; case 204 /* TypeAliasDeclaration */: case 215 /* ExportAssignment */: return false; + case 181 /* VariableStatement */: + return shouldEmitLeadingAndTrailingCommentsForVariableStatement(node); case 206 /* ModuleDeclaration */: // Only emit the leading/trailing comments for a module if we're actually // emitting the module as well. @@ -30710,28 +31892,28 @@ var ts; switch (n.kind) { case 180 /* Block */: if (!ts.isFunctionBlock(n)) { - var parent_6 = n.parent; + var parent_7 = n.parent; var openBrace = ts.findChildOfKind(n, 14 /* OpenBraceToken */, sourceFile); var closeBrace = ts.findChildOfKind(n, 15 /* CloseBraceToken */, sourceFile); // Check if the block is standalone, or 'attached' to some parent statement. // If the latter, we want to collaps the block, but consider its hint span // to be the entire span of the parent. - if (parent_6.kind === 185 /* DoStatement */ || - parent_6.kind === 188 /* ForInStatement */ || - parent_6.kind === 189 /* ForOfStatement */ || - parent_6.kind === 187 /* ForStatement */ || - parent_6.kind === 184 /* IfStatement */ || - parent_6.kind === 186 /* WhileStatement */ || - parent_6.kind === 193 /* WithStatement */ || - parent_6.kind === 224 /* CatchClause */) { - addOutliningSpan(parent_6, openBrace, closeBrace, autoCollapse(n)); + if (parent_7.kind === 185 /* DoStatement */ || + parent_7.kind === 188 /* ForInStatement */ || + parent_7.kind === 189 /* ForOfStatement */ || + parent_7.kind === 187 /* ForStatement */ || + parent_7.kind === 184 /* IfStatement */ || + parent_7.kind === 186 /* WhileStatement */ || + parent_7.kind === 193 /* WithStatement */ || + parent_7.kind === 224 /* CatchClause */) { + addOutliningSpan(parent_7, openBrace, closeBrace, autoCollapse(n)); break; } - if (parent_6.kind === 197 /* TryStatement */) { + if (parent_7.kind === 197 /* TryStatement */) { // Could be the try-block, or the finally-block. - var tryStatement = parent_6; + var tryStatement = parent_7; if (tryStatement.tryBlock === n) { - addOutliningSpan(parent_6, openBrace, closeBrace, autoCollapse(n)); + addOutliningSpan(parent_7, openBrace, closeBrace, autoCollapse(n)); break; } else if (tryStatement.finallyBlock === n) { @@ -30798,12 +31980,12 @@ var ts; ts.forEach(program.getSourceFiles(), function (sourceFile) { cancellationToken.throwIfCancellationRequested(); var nameToDeclarations = sourceFile.getNamedDeclarations(); - for (var name_23 in nameToDeclarations) { - var declarations = ts.getProperty(nameToDeclarations, name_23); + for (var name_26 in nameToDeclarations) { + var declarations = ts.getProperty(nameToDeclarations, name_26); if (declarations) { // First do a quick check to see if the name of the declaration matches the // last portion of the (possibly) dotted name they're searching for. - var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_23); + var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_26); if (!matches) { continue; } @@ -30816,14 +31998,14 @@ var ts; if (!containers) { return undefined; } - matches = patternMatcher.getMatches(containers, name_23); + matches = patternMatcher.getMatches(containers, name_26); if (!matches) { continue; } } var fileName = sourceFile.fileName; var matchKind = bestMatchKind(matches); - rawItems.push({ name: name_23, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); + rawItems.push({ name: name_26, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); } } } @@ -31206,9 +32388,9 @@ var ts; case 199 /* VariableDeclaration */: case 153 /* BindingElement */: var variableDeclarationNode; - var name_24; + var name_27; if (node.kind === 153 /* BindingElement */) { - name_24 = node.name; + name_27 = node.name; variableDeclarationNode = node; // binding elements are added only for variable declarations // bubble up to the containing variable declaration @@ -31220,16 +32402,16 @@ var ts; else { ts.Debug.assert(!ts.isBindingPattern(node.name)); variableDeclarationNode = node; - name_24 = node.name; + name_27 = node.name; } if (ts.isConst(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.constElement); + return createItem(node, getTextOfNode(name_27), ts.ScriptElementKind.constElement); } else if (ts.isLet(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.letElement); + return createItem(node, getTextOfNode(name_27), ts.ScriptElementKind.letElement); } else { - return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.variableElement); + return createItem(node, getTextOfNode(name_27), ts.ScriptElementKind.variableElement); } case 136 /* Constructor */: return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); @@ -32751,7 +33933,7 @@ var ts; // for the position of the relevant node (or comma). var syntaxList = ts.forEach(node.parent.getChildren(), function (c) { // find syntax list that covers the span of the node - if (c.kind === 229 /* SyntaxList */ && c.pos <= node.pos && c.end >= node.end) { + if (c.kind === 251 /* SyntaxList */ && c.pos <= node.pos && c.end >= node.end) { return c; } }); @@ -33158,10 +34340,6 @@ var ts; }); } ts.signatureToDisplayParts = signatureToDisplayParts; - function isJavaScript(fileName) { - return ts.fileExtensionIs(fileName, ".js"); - } - ts.isJavaScript = isJavaScript; })(ts || (ts = {})); /// /// @@ -33644,7 +34822,7 @@ var ts; this.NoSpaceBeforeOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* OpenBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); this.NoSpaceAfterOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create3(18 /* OpenBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); this.NoSpaceBeforeCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 19 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); - this.NoSpaceAfterCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* CloseBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + this.NoSpaceAfterCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* CloseBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBeforeBlockInFunctionDeclarationContext), 8 /* Delete */)); // Place a space before open brace in a function declaration this.FunctionOpenBraceLeftTokenRange = formatting.Shared.TokenRange.AnyIncludingMultilineComments; this.SpaceBeforeOpenBraceInFunction = new formatting.Rule(formatting.RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, 14 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext, Rules.IsBeforeBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */); @@ -33727,6 +34905,10 @@ var ts; this.SpaceBeforeAt = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 52 /* AtToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); this.NoSpaceAfterAt = new formatting.Rule(formatting.RuleDescriptor.create3(52 /* AtToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); this.SpaceAfterDecorator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([65 /* Identifier */, 78 /* ExportKeyword */, 73 /* DefaultKeyword */, 69 /* ClassKeyword */, 109 /* StaticKeyword */, 108 /* PublicKeyword */, 106 /* PrivateKeyword */, 107 /* ProtectedKeyword */, 116 /* GetKeyword */, 121 /* SetKeyword */, 18 /* OpenBracketToken */, 35 /* AsteriskToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsEndOfDecoratorContextOnSameLine), 2 /* Space */)); + this.NoSpaceBetweenFunctionKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(83 /* FunctionKeyword */, 35 /* AsteriskToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 8 /* Delete */)); + this.SpaceAfterStarInGeneratorDeclaration = new formatting.Rule(formatting.RuleDescriptor.create3(35 /* AsteriskToken */, formatting.Shared.TokenRange.FromTokens([65 /* Identifier */, 16 /* OpenParenToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 2 /* Space */)); + this.NoSpaceBetweenYieldKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(110 /* YieldKeyword */, 35 /* AsteriskToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 8 /* Delete */)); + this.SpaceBetweenYieldOrYieldStarAndOperand = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([110 /* YieldKeyword */, 35 /* AsteriskToken */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 2 /* Space */)); // These rules are higher in priority than user-configurable rules. this.HighPriorityCommonRules = [ @@ -33744,7 +34926,9 @@ var ts; this.NoSpaceAfterCloseBrace, this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NewLineBeforeCloseBraceInBlockContext, this.SpaceAfterCloseBrace, this.SpaceBetweenCloseBraceAndElse, this.SpaceBetweenCloseBraceAndWhile, this.NoSpaceBetweenEmptyBraceBrackets, + this.NoSpaceBetweenFunctionKeywordAndStar, this.SpaceAfterStarInGeneratorDeclaration, this.SpaceAfterFunctionInFuncDecl, this.NewLineAfterOpenBraceInBlockContext, this.SpaceAfterGetSetInMember, + this.NoSpaceBetweenYieldKeywordAndStar, this.SpaceBetweenYieldOrYieldStarAndOperand, this.NoSpaceBetweenReturnAndSemicolon, this.SpaceAfterCertainKeywords, this.SpaceAfterLetConstInVariableDeclaration, @@ -33816,9 +35000,9 @@ var ts; } Rules.prototype.getRuleName = function (rule) { var o = this; - for (var name_25 in o) { - if (o[name_25] === rule) { - return name_25; + for (var name_28 in o) { + if (o[name_28] === rule) { + return name_28; } } throw new Error("Unknown rule"); @@ -33937,6 +35121,9 @@ var ts; } return false; }; + Rules.IsFunctionDeclarationOrFunctionExpressionContext = function (context) { + return context.contextNode.kind === 201 /* FunctionDeclaration */ || context.contextNode.kind === 163 /* FunctionExpression */; + }; Rules.IsTypeScriptDeclWithBlockContext = function (context) { return Rules.NodeIsTypeScriptDeclWithBlockContext(context.contextNode); }; @@ -34001,6 +35188,9 @@ var ts; Rules.IsSameLineTokenContext = function (context) { return context.TokensAreOnSameLine(); }; + Rules.IsNotBeforeBlockInFunctionDeclarationContext = function (context) { + return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context); + }; Rules.IsEndOfDecoratorContextOnSameLine = function (context) { return context.TokensAreOnSameLine() && context.contextNode.decorators && @@ -34055,6 +35245,9 @@ var ts; Rules.IsVoidOpContext = function (context) { return context.currentTokenSpan.kind === 99 /* VoidKeyword */ && context.currentTokenParent.kind === 167 /* VoidExpression */; }; + Rules.IsYieldOrYieldStarWithOperand = function (context) { + return context.contextNode.kind === 173 /* YieldExpression */ && context.contextNode.expression !== undefined; + }; return Rules; })(); formatting.Rules = Rules; @@ -35759,7 +36952,7 @@ var ts; return pos; }; NodeObject.prototype.createSyntaxList = function (nodes) { - var list = createNode(229 /* SyntaxList */, nodes.pos, nodes.end, 1024 /* Synthetic */, this); + var list = createNode(251 /* SyntaxList */, nodes.pos, nodes.end, 1024 /* Synthetic */, this); list._children = []; var pos = nodes.pos; for (var _i = 0; _i < nodes.length; _i++) { @@ -36557,9 +37750,9 @@ var ts; return false; } // If the parent is not sourceFile or module block it is local variable - for (var parent_7 = declaration.parent; !ts.isFunctionBlock(parent_7); parent_7 = parent_7.parent) { + for (var parent_8 = declaration.parent; !ts.isFunctionBlock(parent_8); parent_8 = parent_8.parent) { // Reached source file or module block - if (parent_7.kind === 228 /* SourceFile */ || parent_7.kind === 207 /* ModuleBlock */) { + if (parent_8.kind === 228 /* SourceFile */ || parent_8.kind === 207 /* ModuleBlock */) { return false; } } @@ -37537,7 +38730,7 @@ var ts; return true; } if (parameter.questionToken) { - diagnostics.push(ts.createDiagnosticForNode(parameter.questionToken, ts.Diagnostics.can_only_be_used_in_a_ts_file)); + diagnostics.push(ts.createDiagnosticForNode(parameter.questionToken, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, '?')); return true; } if (parameter.type) { @@ -37919,12 +39112,12 @@ var ts; function getContainingObjectLiteralApplicableForCompletion(previousToken) { // The locations in an object literal expression that are applicable for completion are property name definition locations. if (previousToken) { - var parent_8 = previousToken.parent; + var parent_9 = previousToken.parent; switch (previousToken.kind) { case 14 /* OpenBraceToken */: // let x = { | case 23 /* CommaToken */: - if (parent_8 && parent_8.kind === 155 /* ObjectLiteralExpression */) { - return parent_8; + if (parent_9 && parent_9.kind === 155 /* ObjectLiteralExpression */) { + return parent_9; } break; } @@ -38107,10 +39300,10 @@ var ts; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; var nameTable = getNameTable(sourceFile); - for (var name_26 in nameTable) { - if (!allNames[name_26]) { - allNames[name_26] = name_26; - var displayName = getCompletionEntryDisplayName(name_26, target, true); + for (var name_29 in nameTable) { + if (!allNames[name_29]) { + allNames[name_29] = name_29; + var displayName = getCompletionEntryDisplayName(name_29, target, true); if (displayName) { var entry = { name: displayName, @@ -39018,19 +40211,19 @@ var ts; function getThrowStatementOwner(throwStatement) { var child = throwStatement; while (child.parent) { - var parent_9 = child.parent; - if (ts.isFunctionBlock(parent_9) || parent_9.kind === 228 /* SourceFile */) { - return parent_9; + var parent_10 = child.parent; + if (ts.isFunctionBlock(parent_10) || parent_10.kind === 228 /* SourceFile */) { + return parent_10; } // A throw-statement is only owned by a try-statement if the try-statement has // a catch clause, and if the throw-statement occurs within the try block. - if (parent_9.kind === 197 /* TryStatement */) { - var tryStatement = parent_9; + if (parent_10.kind === 197 /* TryStatement */) { + var tryStatement = parent_10; if (tryStatement.tryBlock === child && tryStatement.catchClause) { return child; } } - child = parent_9; + child = parent_10; } return undefined; } @@ -39992,19 +41185,19 @@ var ts; if (isNameOfPropertyAssignment(node)) { var objectLiteral = node.parent.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name_27 = node.text; + var name_30 = node.text; if (contextualType) { if (contextualType.flags & 16384 /* Union */) { // This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types) // if not, search the constituent types for the property - var unionProperty = contextualType.getProperty(name_27); + var unionProperty = contextualType.getProperty(name_30); if (unionProperty) { return [unionProperty]; } else { var result_4 = []; ts.forEach(contextualType.types, function (t) { - var symbol = t.getProperty(name_27); + var symbol = t.getProperty(name_30); if (symbol) { result_4.push(symbol); } @@ -40013,7 +41206,7 @@ var ts; } } else { - var symbol_1 = contextualType.getProperty(name_27); + var symbol_1 = contextualType.getProperty(name_30); if (symbol_1) { return [symbol_1]; } @@ -40994,7 +42187,7 @@ var ts; var lastEnd = 0; for (var i = 0, n = dense.length; i < n; i += 3) { var start = dense[i]; - var length_1 = dense[i + 1]; + var length_2 = dense[i + 1]; var type = dense[i + 2]; // Make a whitespace entry between the last item and this one. if (lastEnd >= 0) { @@ -41003,8 +42196,8 @@ var ts; entries.push({ length: whitespaceLength_1, classification: TokenClass.Whitespace }); } } - entries.push({ length: length_1, classification: convertClassification(type) }); - lastEnd = start + length_1; + entries.push({ length: length_2, classification: convertClassification(type) }); + lastEnd = start + length_2; } var whitespaceLength = text.length - lastEnd; if (whitespaceLength > 0) { diff --git a/bin/typescriptServices.d.ts b/bin/typescriptServices.d.ts index 558504fcede..0d54e446d8f 100644 --- a/bin/typescriptServices.d.ts +++ b/bin/typescriptServices.d.ts @@ -251,8 +251,30 @@ declare module ts { ShorthandPropertyAssignment = 226, EnumMember = 227, SourceFile = 228, - SyntaxList = 229, - Count = 230, + JSDocTypeExpression = 229, + JSDocAllType = 230, + JSDocUnknownType = 231, + JSDocArrayType = 232, + JSDocUnionType = 233, + JSDocTupleType = 234, + JSDocNullableType = 235, + JSDocNonNullableType = 236, + JSDocRecordType = 237, + JSDocRecordMember = 238, + JSDocTypeReference = 239, + JSDocOptionalType = 240, + JSDocFunctionType = 241, + JSDocVariadicType = 242, + JSDocConstructorType = 243, + JSDocThisType = 244, + JSDocComment = 245, + JSDocTag = 246, + JSDocParameterTag = 247, + JSDocReturnTag = 248, + JSDocTypeTag = 249, + JSDocTemplateTag = 250, + SyntaxList = 251, + Count = 252, FirstAssignment = 53, LastAssignment = 64, FirstReservedWord = 66, @@ -495,7 +517,7 @@ declare module ts { } interface YieldExpression extends Expression { asteriskToken?: Node; - expression: Expression; + expression?: Expression; } interface BinaryExpression extends Expression { left: Expression; @@ -666,7 +688,7 @@ declare module ts { interface ClassElement extends Declaration { _classElementBrand: any; } - interface InterfaceDeclaration extends Declaration, ModuleElement { + interface InterfaceDeclaration extends Declaration, Statement { name: Identifier; typeParameters?: NodeArray; heritageClauses?: NodeArray; @@ -676,7 +698,7 @@ declare module ts { token: SyntaxKind; types?: NodeArray; } - interface TypeAliasDeclaration extends Declaration, ModuleElement { + interface TypeAliasDeclaration extends Declaration, Statement { name: Identifier; type: TypeNode; } @@ -684,7 +706,7 @@ declare module ts { name: DeclarationName; initializer?: Expression; } - interface EnumDeclaration extends Declaration, ModuleElement { + interface EnumDeclaration extends Declaration, Statement { name: Identifier; members: NodeArray; } @@ -739,6 +761,82 @@ declare module ts { hasTrailingNewLine?: boolean; kind: SyntaxKind; } + interface JSDocTypeExpression extends Node { + type: JSDocType; + } + interface JSDocType extends TypeNode { + _jsDocTypeBrand: any; + } + interface JSDocAllType extends JSDocType { + _JSDocAllTypeBrand: any; + } + interface JSDocUnknownType extends JSDocType { + _JSDocUnknownTypeBrand: any; + } + interface JSDocArrayType extends JSDocType { + elementType: JSDocType; + } + interface JSDocUnionType extends JSDocType { + types: NodeArray; + } + interface JSDocTupleType extends JSDocType { + types: NodeArray; + } + interface JSDocNonNullableType extends JSDocType { + type: JSDocType; + } + interface JSDocNullableType extends JSDocType { + type: JSDocType; + } + interface JSDocRecordType extends JSDocType, TypeLiteralNode { + members: NodeArray; + } + interface JSDocTypeReference extends JSDocType { + name: EntityName; + typeArguments: NodeArray; + } + interface JSDocOptionalType extends JSDocType { + type: JSDocType; + } + interface JSDocFunctionType extends JSDocType, SignatureDeclaration { + parameters: NodeArray; + type: JSDocType; + } + interface JSDocVariadicType extends JSDocType { + type: JSDocType; + } + interface JSDocConstructorType extends JSDocType { + type: JSDocType; + } + interface JSDocThisType extends JSDocType { + type: JSDocType; + } + interface JSDocRecordMember extends PropertyDeclaration { + name: Identifier | LiteralExpression; + type?: JSDocType; + } + interface JSDocComment extends Node { + tags: NodeArray; + } + interface JSDocTag extends Node { + atToken: Node; + tagName: Identifier; + } + interface JSDocTemplateTag extends JSDocTag { + typeParameters: NodeArray; + } + interface JSDocReturnTag extends JSDocTag { + typeExpression: JSDocTypeExpression; + } + interface JSDocTypeTag extends JSDocTag { + typeExpression: JSDocTypeExpression; + } + interface JSDocParameterTag extends JSDocTag { + preParameterName?: Identifier; + typeExpression?: JSDocTypeExpression; + postParameterName?: Identifier; + isBracketed: boolean; + } interface SourceFile extends Declaration { statements: NodeArray; endOfFileToken: Node; @@ -1011,6 +1109,8 @@ declare module ts { } interface InterfaceType extends ObjectType { typeParameters: TypeParameter[]; + outerTypeParameters: TypeParameter[]; + localTypeParameters: TypeParameter[]; } interface InterfaceTypeWithBaseTypes extends InterfaceType { baseTypes: ObjectType[]; @@ -1227,8 +1327,6 @@ declare module ts { function getTrailingCommentRanges(text: string, pos: number): CommentRange[]; function isIdentifierStart(ch: number, languageVersion: ScriptTarget): boolean; function isIdentifierPart(ch: number, languageVersion: ScriptTarget): boolean; - /** Creates a scanner over a (possibly unspecified) range of a piece of text. */ - function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, text?: string, onError?: ErrorCallback, start?: number, length?: number): Scanner; } declare module ts { function getDefaultLibFileName(options: CompilerOptions): string; @@ -1257,8 +1355,10 @@ declare module ts { * Vn. */ function collapseTextChangeRangesAcrossMultipleVersions(changes: TextChangeRange[]): TextChangeRange; + function getTypeParameterOwner(d: Declaration): Declaration; } declare module ts { + var throwOnJSDocErrors: boolean; function getNodeConstructor(kind: SyntaxKind): new () => Node; function createNode(kind: SyntaxKind): Node; function forEachChild(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T; diff --git a/bin/typescriptServices.js b/bin/typescriptServices.js index f91570ad95f..1b5c7949463 100644 --- a/bin/typescriptServices.js +++ b/bin/typescriptServices.js @@ -270,10 +270,35 @@ var ts; SyntaxKind[SyntaxKind["EnumMember"] = 227] = "EnumMember"; // Top-level nodes SyntaxKind[SyntaxKind["SourceFile"] = 228] = "SourceFile"; + // JSDoc nodes. + SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 229] = "JSDocTypeExpression"; + // The * type. + SyntaxKind[SyntaxKind["JSDocAllType"] = 230] = "JSDocAllType"; + // The ? type. + SyntaxKind[SyntaxKind["JSDocUnknownType"] = 231] = "JSDocUnknownType"; + SyntaxKind[SyntaxKind["JSDocArrayType"] = 232] = "JSDocArrayType"; + SyntaxKind[SyntaxKind["JSDocUnionType"] = 233] = "JSDocUnionType"; + SyntaxKind[SyntaxKind["JSDocTupleType"] = 234] = "JSDocTupleType"; + SyntaxKind[SyntaxKind["JSDocNullableType"] = 235] = "JSDocNullableType"; + SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 236] = "JSDocNonNullableType"; + SyntaxKind[SyntaxKind["JSDocRecordType"] = 237] = "JSDocRecordType"; + SyntaxKind[SyntaxKind["JSDocRecordMember"] = 238] = "JSDocRecordMember"; + SyntaxKind[SyntaxKind["JSDocTypeReference"] = 239] = "JSDocTypeReference"; + SyntaxKind[SyntaxKind["JSDocOptionalType"] = 240] = "JSDocOptionalType"; + SyntaxKind[SyntaxKind["JSDocFunctionType"] = 241] = "JSDocFunctionType"; + SyntaxKind[SyntaxKind["JSDocVariadicType"] = 242] = "JSDocVariadicType"; + SyntaxKind[SyntaxKind["JSDocConstructorType"] = 243] = "JSDocConstructorType"; + SyntaxKind[SyntaxKind["JSDocThisType"] = 244] = "JSDocThisType"; + SyntaxKind[SyntaxKind["JSDocComment"] = 245] = "JSDocComment"; + SyntaxKind[SyntaxKind["JSDocTag"] = 246] = "JSDocTag"; + SyntaxKind[SyntaxKind["JSDocParameterTag"] = 247] = "JSDocParameterTag"; + SyntaxKind[SyntaxKind["JSDocReturnTag"] = 248] = "JSDocReturnTag"; + SyntaxKind[SyntaxKind["JSDocTypeTag"] = 249] = "JSDocTypeTag"; + SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 250] = "JSDocTemplateTag"; // Synthesized list - SyntaxKind[SyntaxKind["SyntaxList"] = 229] = "SyntaxList"; + SyntaxKind[SyntaxKind["SyntaxList"] = 251] = "SyntaxList"; // Enum value count - SyntaxKind[SyntaxKind["Count"] = 230] = "Count"; + SyntaxKind[SyntaxKind["Count"] = 252] = "Count"; // Markers SyntaxKind[SyntaxKind["FirstAssignment"] = 53] = "FirstAssignment"; SyntaxKind[SyntaxKind["LastAssignment"] = 64] = "LastAssignment"; @@ -323,6 +348,7 @@ var ts; var NodeFlags = ts.NodeFlags; /* @internal */ (function (ParserContextFlags) { + ParserContextFlags[ParserContextFlags["None"] = 0] = "None"; // Set if this node was parsed in strict mode. Used for grammar error checks, as well as // checking if the node can be reused in incremental settings. ParserContextFlags[ParserContextFlags["StrictMode"] = 1] = "StrictMode"; @@ -338,14 +364,17 @@ var ts; // the parser only sets this directly on the node it creates right after encountering the // error. ParserContextFlags[ParserContextFlags["ThisNodeHasError"] = 32] = "ThisNodeHasError"; + // This node was parsed in a JavaScript file and can be processed differently. For example + // its type can be specified usign a JSDoc comment. + ParserContextFlags[ParserContextFlags["JavaScriptFile"] = 64] = "JavaScriptFile"; // Context flags set directly by the parser. ParserContextFlags[ParserContextFlags["ParserGeneratedFlags"] = 63] = "ParserGeneratedFlags"; // Context flags computed by aggregating child flags upwards. // Used during incremental parsing to determine if this node or any of its children had an // error. Computed only once and then cached. - ParserContextFlags[ParserContextFlags["ThisNodeOrAnySubNodesHasError"] = 64] = "ThisNodeOrAnySubNodesHasError"; + ParserContextFlags[ParserContextFlags["ThisNodeOrAnySubNodesHasError"] = 128] = "ThisNodeOrAnySubNodesHasError"; // Used to know if we've computed data from children and cached it in this node. - ParserContextFlags[ParserContextFlags["HasAggregatedChildData"] = 128] = "HasAggregatedChildData"; + ParserContextFlags[ParserContextFlags["HasAggregatedChildData"] = 256] = "HasAggregatedChildData"; })(ts.ParserContextFlags || (ts.ParserContextFlags = {})); var ParserContextFlags = ts.ParserContextFlags; /* @internal */ @@ -826,6 +855,16 @@ var ts; } } ts.addRange = addRange; + function rangeEquals(array1, array2, pos, end) { + while (pos < end) { + if (array1[pos] !== array2[pos]) { + return false; + } + pos++; + } + return true; + } + ts.rangeEquals = rangeEquals; /** * Returns the last element of an array if non-empty, undefined otherwise. */ @@ -995,8 +1034,10 @@ var ts; var end = start + length; Debug.assert(start >= 0, "start must be non-negative, is " + start); Debug.assert(length >= 0, "length must be non-negative, is " + length); - Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); - Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + if (file) { + Debug.assert(start <= file.text.length, "start must be within the bounds of the file. " + start + " > " + file.text.length); + Debug.assert(end <= file.text.length, "end must be the bounds of the file. " + end + " > " + file.text.length); + } var text = getLocaleSpecificMessage(message.key); if (arguments.length > 4) { text = formatStringFromArgs(text, arguments, 4); @@ -1584,7 +1625,7 @@ var ts; for (var _i = 0; _i < files.length; _i++) { var current = files[_i]; var name = ts.combinePaths(path, current); - var stat = _fs.lstatSync(name); + var stat = _fs.statSync(name); if (stat.isFile()) { if (!extension || ts.fileExtensionIs(name, extension)) { result.push(name); @@ -1790,7 +1831,7 @@ var ts; Unterminated_template_literal: { code: 1160, category: ts.DiagnosticCategory.Error, key: "Unterminated template literal." }, Unterminated_regular_expression_literal: { code: 1161, category: ts.DiagnosticCategory.Error, key: "Unterminated regular expression literal." }, An_object_member_cannot_be_declared_optional: { code: 1162, category: ts.DiagnosticCategory.Error, key: "An object member cannot be declared optional." }, - yield_expression_must_be_contained_within_a_generator_declaration: { code: 1163, category: ts.DiagnosticCategory.Error, key: "'yield' expression must be contained_within a generator declaration." }, + A_yield_expression_is_only_allowed_in_a_generator_body: { code: 1163, category: ts.DiagnosticCategory.Error, key: "A 'yield' expression is only allowed in a generator body." }, Computed_property_names_are_not_allowed_in_enums: { code: 1164, category: ts.DiagnosticCategory.Error, key: "Computed property names are not allowed in enums." }, A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol: { code: 1165, category: ts.DiagnosticCategory.Error, key: "A computed property name in an ambient context must directly refer to a built-in symbol." }, A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol: { code: 1166, category: ts.DiagnosticCategory.Error, key: "A computed property name in a class property declaration must directly refer to a built-in symbol." }, @@ -1845,6 +1886,10 @@ var ts; Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: ts.DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." }, Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: ts.DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." }, Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning: { code: 1219, category: ts.DiagnosticCategory.Error, key: "Experimental support for decorators is a feature that is subject to change in a future release. Specify '--experimentalDecorators' to remove this warning." }, + Generators_are_only_available_when_targeting_ECMAScript_6_or_higher: { code: 1220, category: ts.DiagnosticCategory.Error, key: "Generators are only available when targeting ECMAScript 6 or higher." }, + Generators_are_not_allowed_in_an_ambient_context: { code: 1221, category: ts.DiagnosticCategory.Error, key: "Generators are not allowed in an ambient context." }, + An_overload_signature_cannot_be_declared_as_a_generator: { code: 1222, category: ts.DiagnosticCategory.Error, key: "An overload signature cannot be declared as a generator." }, + _0_tag_already_specified: { code: 1223, category: ts.DiagnosticCategory.Error, key: "'{0}' tag already specified." }, Duplicate_identifier_0: { code: 2300, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: ts.DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: ts.DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, @@ -2005,7 +2050,7 @@ var ts; The_0_operator_cannot_be_applied_to_type_symbol: { code: 2469, category: ts.DiagnosticCategory.Error, key: "The '{0}' operator cannot be applied to type 'symbol'." }, Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: { code: 2470, category: ts.DiagnosticCategory.Error, key: "'Symbol' reference does not refer to the global Symbol constructor object." }, A_computed_property_name_of_the_form_0_must_be_of_type_symbol: { code: 2471, category: ts.DiagnosticCategory.Error, key: "A computed property name of the form '{0}' must be of type 'symbol'." }, - Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher: { code: 2472, category: ts.DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 6 and higher." }, + Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: { code: 2472, category: ts.DiagnosticCategory.Error, key: "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher." }, Enum_declarations_must_all_be_const_or_non_const: { code: 2473, category: ts.DiagnosticCategory.Error, key: "Enum declarations must all be const or non-const." }, In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 2474, category: ts.DiagnosticCategory.Error, key: "In 'const' enum declarations member initializer must be constant expression." }, const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: { code: 2475, category: ts.DiagnosticCategory.Error, key: "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment." }, @@ -2036,6 +2081,8 @@ var ts; A_rest_element_cannot_contain_a_binding_pattern: { code: 2501, category: ts.DiagnosticCategory.Error, key: "A rest element cannot contain a binding pattern." }, _0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: { code: 2502, category: ts.DiagnosticCategory.Error, key: "'{0}' is referenced directly or indirectly in its own type annotation." }, Cannot_find_namespace_0: { code: 2503, category: ts.DiagnosticCategory.Error, key: "Cannot find namespace '{0}'." }, + No_best_common_type_exists_among_yield_expressions: { code: 2504, category: ts.DiagnosticCategory.Error, key: "No best common type exists among yield expressions." }, + A_generator_cannot_have_a_void_type_annotation: { code: 2505, category: ts.DiagnosticCategory.Error, key: "A generator cannot have a 'void' type annotation." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: ts.DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: ts.DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, @@ -2196,6 +2243,7 @@ var ts; _0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: ts.DiagnosticCategory.Error, key: "'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer." }, _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7023, category: ts.DiagnosticCategory.Error, key: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: ts.DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, + Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: ts.DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." }, You_cannot_rename_this_element: { code: 8000, category: ts.DiagnosticCategory.Error, key: "You cannot rename this element." }, You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: ts.DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." }, import_can_only_be_used_in_a_ts_file: { code: 8002, category: ts.DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." }, @@ -2209,16 +2257,12 @@ var ts; types_can_only_be_used_in_a_ts_file: { code: 8010, category: ts.DiagnosticCategory.Error, key: "'types' can only be used in a .ts file." }, type_arguments_can_only_be_used_in_a_ts_file: { code: 8011, category: ts.DiagnosticCategory.Error, key: "'type arguments' can only be used in a .ts file." }, parameter_modifiers_can_only_be_used_in_a_ts_file: { code: 8012, category: ts.DiagnosticCategory.Error, key: "'parameter modifiers' can only be used in a .ts file." }, - can_only_be_used_in_a_ts_file: { code: 8013, category: ts.DiagnosticCategory.Error, key: "'?' can only be used in a .ts file." }, property_declarations_can_only_be_used_in_a_ts_file: { code: 8014, category: ts.DiagnosticCategory.Error, key: "'property declarations' can only be used in a .ts file." }, enum_declarations_can_only_be_used_in_a_ts_file: { code: 8015, category: ts.DiagnosticCategory.Error, key: "'enum declarations' can only be used in a .ts file." }, type_assertion_expressions_can_only_be_used_in_a_ts_file: { code: 8016, category: ts.DiagnosticCategory.Error, key: "'type assertion expressions' can only be used in a .ts file." }, decorators_can_only_be_used_in_a_ts_file: { code: 8017, category: ts.DiagnosticCategory.Error, key: "'decorators' can only be used in a .ts file." }, - yield_expressions_are_not_currently_supported: { code: 9000, category: ts.DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." }, - Generators_are_not_currently_supported: { code: 9001, category: ts.DiagnosticCategory.Error, key: "Generators are not currently supported." }, Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: ts.DiagnosticCategory.Error, key: "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses." }, - class_expressions_are_not_currently_supported: { code: 9003, category: ts.DiagnosticCategory.Error, key: "'class' expressions are not currently supported." }, - class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration: { code: 9004, category: ts.DiagnosticCategory.Error, key: "'class' declarations are only supported directly inside a module or as a top level declaration." } + class_expressions_are_not_currently_supported: { code: 9003, category: ts.DiagnosticCategory.Error, key: "'class' expressions are not currently supported." } }; })(ts || (ts = {})); /// @@ -2754,12 +2798,17 @@ var ts; ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierPart(ch, languageVersion); } ts.isIdentifierPart = isIdentifierPart; - /** Creates a scanner over a (possibly unspecified) range of a piece of text. */ + /* @internal */ + // Creates a scanner over a (possibly unspecified) range of a piece of text. function createScanner(languageVersion, skipTrivia, text, onError, start, length) { - var pos; // Current position (end position of text of current token) - var end; // end of text - var startPos; // Start position of whitespace before current token - var tokenPos; // Start position of text of current token + // Current position (end position of text of current token) + var pos; + // end of text + var end; + // Start position of whitespace before current token + var startPos; + // Start position of text of current token + var tokenPos; var token; var tokenValue; var precedingLineBreak; @@ -4071,17 +4120,17 @@ var ts; bindBlockScopedDeclaration(node, 32 /* Class */, 899583 /* ClassExcludes */); break; case 203 /* InterfaceDeclaration */: - bindDeclaration(node, 64 /* Interface */, 792992 /* InterfaceExcludes */, false); + bindBlockScopedDeclaration(node, 64 /* Interface */, 792992 /* InterfaceExcludes */); break; case 204 /* TypeAliasDeclaration */: - bindDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */, false); + bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */); break; case 205 /* EnumDeclaration */: if (ts.isConst(node)) { - bindDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */, false); + bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */); } else { - bindDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */, false); + bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */); } break; case 206 /* ModuleDeclaration */: @@ -4230,11 +4279,11 @@ var ts; // Returns true if this node contains a parse error anywhere underneath it. function containsParseError(node) { aggregateChildData(node); - return (node.parserContextFlags & 64 /* ThisNodeOrAnySubNodesHasError */) !== 0; + return (node.parserContextFlags & 128 /* ThisNodeOrAnySubNodesHasError */) !== 0; } ts.containsParseError = containsParseError; function aggregateChildData(node) { - if (!(node.parserContextFlags & 128 /* HasAggregatedChildData */)) { + if (!(node.parserContextFlags & 256 /* HasAggregatedChildData */)) { // A node is considered to contain a parse error if: // a) the parser explicitly marked that it had an error // b) any of it's children reported that it had an error. @@ -4242,12 +4291,12 @@ var ts; ts.forEachChild(node, containsParseError); // If so, mark ourselves accordingly. if (thisNodeOrAnySubNodesHasError) { - node.parserContextFlags |= 64 /* ThisNodeOrAnySubNodesHasError */; + node.parserContextFlags |= 128 /* ThisNodeOrAnySubNodesHasError */; } // Also mark that we've propogated the child information to this node. This way we can // always consult the bit directly on this node without needing to check its children // again. - node.parserContextFlags |= 128 /* HasAggregatedChildData */; + node.parserContextFlags |= 256 /* HasAggregatedChildData */; } } function getSourceFileOfNode(node) { @@ -4534,6 +4583,88 @@ var ts; } ts.getJsDocComments = getJsDocComments; ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; + function isTypeNode(node) { + if (142 /* FirstTypeNode */ <= node.kind && node.kind <= 150 /* LastTypeNode */) { + return true; + } + switch (node.kind) { + case 112 /* AnyKeyword */: + case 120 /* NumberKeyword */: + case 122 /* StringKeyword */: + case 113 /* BooleanKeyword */: + case 123 /* SymbolKeyword */: + return true; + case 99 /* VoidKeyword */: + return node.parent.kind !== 167 /* VoidExpression */; + case 8 /* StringLiteral */: + // Specialized signatures can have string literals as their parameters' type names + return node.parent.kind === 130 /* Parameter */; + case 177 /* ExpressionWithTypeArguments */: + return true; + // Identifiers and qualified names may be type nodes, depending on their context. Climb + // above them to find the lowest container + case 65 /* Identifier */: + // If the identifier is the RHS of a qualified name, then it's a type iff its parent is. + if (node.parent.kind === 127 /* QualifiedName */ && node.parent.right === node) { + node = node.parent; + } + else if (node.parent.kind === 156 /* PropertyAccessExpression */ && node.parent.name === node) { + node = node.parent; + } + // fall through + case 127 /* QualifiedName */: + case 156 /* PropertyAccessExpression */: + // At this point, node is either a qualified name or an identifier + ts.Debug.assert(node.kind === 65 /* Identifier */ || node.kind === 127 /* QualifiedName */ || node.kind === 156 /* PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'."); + var parent_1 = node.parent; + if (parent_1.kind === 145 /* TypeQuery */) { + return false; + } + // Do not recursively call isTypeNode on the parent. In the example: + // + // let a: A.B.C; + // + // Calling isTypeNode would consider the qualified name A.B a type node. Only C or + // A.B.C is a type node. + if (142 /* FirstTypeNode */ <= parent_1.kind && parent_1.kind <= 150 /* LastTypeNode */) { + return true; + } + switch (parent_1.kind) { + case 177 /* ExpressionWithTypeArguments */: + return true; + case 129 /* TypeParameter */: + return node === parent_1.constraint; + case 133 /* PropertyDeclaration */: + case 132 /* PropertySignature */: + case 130 /* Parameter */: + case 199 /* VariableDeclaration */: + return node === parent_1.type; + case 201 /* FunctionDeclaration */: + case 163 /* FunctionExpression */: + case 164 /* ArrowFunction */: + case 136 /* Constructor */: + case 135 /* MethodDeclaration */: + case 134 /* MethodSignature */: + case 137 /* GetAccessor */: + case 138 /* SetAccessor */: + return node === parent_1.type; + case 139 /* CallSignature */: + case 140 /* ConstructSignature */: + case 141 /* IndexSignature */: + return node === parent_1.type; + case 161 /* TypeAssertionExpression */: + return node === parent_1.type; + case 158 /* CallExpression */: + case 159 /* NewExpression */: + return parent_1.typeArguments && ts.indexOf(parent_1.typeArguments, node) >= 0; + case 160 /* TaggedTemplateExpression */: + // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments. + return false; + } + } + return false; + } + ts.isTypeNode = isTypeNode; // Warning: This has the same semantics as the forEach family of functions, // in that traversal terminates in the event that 'visitor' supplies a truthy value. function forEachReturnStatement(body, visitor) { @@ -4562,6 +4693,44 @@ var ts; } } ts.forEachReturnStatement = forEachReturnStatement; + function forEachYieldExpression(body, visitor) { + return traverse(body); + function traverse(node) { + switch (node.kind) { + case 173 /* YieldExpression */: + visitor(node); + var operand = node.expression; + if (operand) { + traverse(operand); + } + case 205 /* EnumDeclaration */: + case 203 /* InterfaceDeclaration */: + case 206 /* ModuleDeclaration */: + case 204 /* TypeAliasDeclaration */: + case 202 /* ClassDeclaration */: + // These are not allowed inside a generator now, but eventually they may be allowed + // as local types. Regardless, any yield statements contained within them should be + // skipped in this traversal. + return; + default: + if (isFunctionLike(node)) { + var name_3 = node.name; + if (name_3 && name_3.kind === 128 /* ComputedPropertyName */) { + // Note that we will not include methods/accessors of a class because they would require + // first descending into the class. This is by design. + traverse(name_3.expression); + return; + } + } + else if (!isTypeNode(node)) { + // This is the general case, which should include mostly expressions and statements. + // Also includes NodeArrays. + ts.forEachChild(node, traverse); + } + } + } + } + ts.forEachYieldExpression = forEachYieldExpression; function isVariableLike(node) { if (node) { switch (node.kind) { @@ -4590,6 +4759,12 @@ var ts; return false; } ts.isAccessor = isAccessor; + function isClassLike(node) { + if (node) { + return node.kind === 202 /* ClassDeclaration */ || node.kind === 175 /* ClassExpression */; + } + } + ts.isClassLike = isClassLike; function isFunctionLike(node) { if (node) { switch (node.kind) { @@ -4840,6 +5015,7 @@ var ts; case 172 /* TemplateExpression */: case 10 /* NoSubstitutionTemplateLiteral */: case 176 /* OmittedExpression */: + case 173 /* YieldExpression */: return true; case 127 /* QualifiedName */: while (node.parent.kind === 127 /* QualifiedName */) { @@ -4853,8 +5029,8 @@ var ts; // fall through case 7 /* NumericLiteral */: case 8 /* StringLiteral */: - var parent_1 = node.parent; - switch (parent_1.kind) { + var parent_2 = node.parent; + switch (parent_2.kind) { case 199 /* VariableDeclaration */: case 130 /* Parameter */: case 133 /* PropertyDeclaration */: @@ -4862,7 +5038,7 @@ var ts; case 227 /* EnumMember */: case 225 /* PropertyAssignment */: case 153 /* BindingElement */: - return parent_1.initializer === node; + return parent_2.initializer === node; case 183 /* ExpressionStatement */: case 184 /* IfStatement */: case 185 /* DoStatement */: @@ -4873,27 +5049,27 @@ var ts; case 221 /* CaseClause */: case 196 /* ThrowStatement */: case 194 /* SwitchStatement */: - return parent_1.expression === node; + return parent_2.expression === node; case 187 /* ForStatement */: - var forStatement = parent_1; + var forStatement = parent_2; return (forStatement.initializer === node && forStatement.initializer.kind !== 200 /* VariableDeclarationList */) || forStatement.condition === node || forStatement.incrementor === node; case 188 /* ForInStatement */: case 189 /* ForOfStatement */: - var forInStatement = parent_1; + var forInStatement = parent_2; return (forInStatement.initializer === node && forInStatement.initializer.kind !== 200 /* VariableDeclarationList */) || forInStatement.expression === node; case 161 /* TypeAssertionExpression */: - return node === parent_1.expression; + return node === parent_2.expression; case 178 /* TemplateSpan */: - return node === parent_1.expression; + return node === parent_2.expression; case 128 /* ComputedPropertyName */: - return node === parent_1.expression; + return node === parent_2.expression; case 131 /* Decorator */: return true; default: - if (isExpression(parent_1)) { + if (isExpression(parent_2)) { return true; } } @@ -4961,6 +5137,74 @@ var ts; return s.parameters.length > 0 && ts.lastOrUndefined(s.parameters).dotDotDotToken !== undefined; } ts.hasRestParameters = hasRestParameters; + function isJSDocConstructSignature(node) { + return node.kind === 241 /* JSDocFunctionType */ && + node.parameters.length > 0 && + node.parameters[0].type.kind === 243 /* JSDocConstructorType */; + } + ts.isJSDocConstructSignature = isJSDocConstructSignature; + function getJSDocTag(node, kind) { + if (node && node.jsDocComment) { + for (var _i = 0, _a = node.jsDocComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.kind === kind) { + return tag; + } + } + } + } + function getJSDocTypeTag(node) { + return getJSDocTag(node, 249 /* JSDocTypeTag */); + } + ts.getJSDocTypeTag = getJSDocTypeTag; + function getJSDocReturnTag(node) { + return getJSDocTag(node, 248 /* JSDocReturnTag */); + } + ts.getJSDocReturnTag = getJSDocReturnTag; + function getJSDocTemplateTag(node) { + return getJSDocTag(node, 250 /* JSDocTemplateTag */); + } + ts.getJSDocTemplateTag = getJSDocTemplateTag; + function getCorrespondingJSDocParameterTag(parameter) { + if (parameter.name && parameter.name.kind === 65 /* Identifier */) { + // If it's a parameter, see if the parent has a jsdoc comment with an @param + // annotation. + var parameterName = parameter.name.text; + var docComment = parameter.parent.jsDocComment; + if (docComment) { + return ts.forEach(docComment.tags, function (t) { + if (t.kind === 247 /* JSDocParameterTag */) { + var parameterTag = t; + var name_4 = parameterTag.preParameterName || parameterTag.postParameterName; + if (name_4.text === parameterName) { + return t; + } + } + }); + } + } + } + ts.getCorrespondingJSDocParameterTag = getCorrespondingJSDocParameterTag; + function hasRestParameter(s) { + return isRestParameter(ts.lastOrUndefined(s.parameters)); + } + ts.hasRestParameter = hasRestParameter; + function isRestParameter(node) { + if (node) { + if (node.parserContextFlags & 64 /* JavaScriptFile */) { + if (node.type && node.type.kind === 242 /* JSDocVariadicType */) { + return true; + } + var paramTag = getCorrespondingJSDocParameterTag(node); + if (paramTag && paramTag.typeExpression) { + return paramTag.typeExpression.type.kind === 242 /* JSDocVariadicType */; + } + } + return node.dotDotDotToken !== undefined; + } + return false; + } + ts.isRestParameter = isRestParameter; function isLiteralKind(kind) { return 7 /* FirstLiteralToken */ <= kind && kind <= 10 /* LastLiteralToken */; } @@ -5751,6 +5995,10 @@ var ts; return symbol && symbol.valueDeclaration && (symbol.valueDeclaration.flags & 256 /* Default */) ? symbol.valueDeclaration.localSymbol : undefined; } ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault; + function isJavaScript(fileName) { + return ts.fileExtensionIs(fileName, ".js"); + } + ts.isJavaScript = isJavaScript; /** * Replace each instance of non-ascii characters by one, two, three, or four escape sequences * representing the UTF-8 encoding of the character, and return the expanded char code list. @@ -6024,12 +6272,23 @@ var ts; return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), newEndN - oldStartN); } ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions; + function getTypeParameterOwner(d) { + if (d && d.kind === 129 /* TypeParameter */) { + for (var current = d; current; current = current.parent) { + if (ts.isFunctionLike(current) || ts.isClassLike(current) || current.kind === 203 /* InterfaceDeclaration */) { + return current; + } + } + } + } + ts.getTypeParameterOwner = getTypeParameterOwner; })(ts || (ts = {})); /// /// var ts; (function (ts) { - var nodeConstructors = new Array(230 /* Count */); + ts.throwOnJSDocErrors = false; + var nodeConstructors = new Array(252 /* Count */); /* @internal */ ts.parseTime = 0; function getNodeConstructor(kind) { return nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind)); @@ -6339,6 +6598,49 @@ var ts; return visitNode(cbNode, node.expression); case 219 /* MissingDeclaration */: return visitNodes(cbNodes, node.decorators); + case 229 /* JSDocTypeExpression */: + return visitNode(cbNode, node.type); + case 233 /* JSDocUnionType */: + return visitNodes(cbNodes, node.types); + case 234 /* JSDocTupleType */: + return visitNodes(cbNodes, node.types); + case 232 /* JSDocArrayType */: + return visitNode(cbNode, node.elementType); + case 236 /* JSDocNonNullableType */: + return visitNode(cbNode, node.type); + case 235 /* JSDocNullableType */: + return visitNode(cbNode, node.type); + case 237 /* JSDocRecordType */: + return visitNodes(cbNodes, node.members); + case 239 /* JSDocTypeReference */: + return visitNode(cbNode, node.name) || + visitNodes(cbNodes, node.typeArguments); + case 240 /* JSDocOptionalType */: + return visitNode(cbNode, node.type); + case 241 /* JSDocFunctionType */: + return visitNodes(cbNodes, node.parameters) || + visitNode(cbNode, node.type); + case 242 /* JSDocVariadicType */: + return visitNode(cbNode, node.type); + case 243 /* JSDocConstructorType */: + return visitNode(cbNode, node.type); + case 244 /* JSDocThisType */: + return visitNode(cbNode, node.type); + case 238 /* JSDocRecordMember */: + return visitNode(cbNode, node.name) || + visitNode(cbNode, node.type); + case 245 /* JSDocComment */: + return visitNodes(cbNodes, node.tags); + case 247 /* JSDocParameterTag */: + return visitNode(cbNode, node.preParameterName) || + visitNode(cbNode, node.typeExpression) || + visitNode(cbNode, node.postParameterName); + case 248 /* JSDocReturnTag */: + return visitNode(cbNode, node.typeExpression); + case 249 /* JSDocTypeTag */: + return visitNode(cbNode, node.typeExpression); + case 250 /* JSDocTemplateTag */: + return visitNodes(cbNodes, node.typeParameters); } } ts.forEachChild = forEachChild; @@ -6363,6 +6665,17 @@ var ts; return IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); } ts.updateSourceFile = updateSourceFile; + /* @internal */ + function parseIsolatedJSDocComment(content, start, length) { + return Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length); + } + ts.parseIsolatedJSDocComment = parseIsolatedJSDocComment; + /* @internal */ + // Exposed only for testing. + function parseJSDocTypeExpressionForTests(content, start, length) { + return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length); + } + ts.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests; // Implement the parser as a singleton module. We do this for perf reasons because creating // parser instances can actually be expensive enough to impact us on projects with many source // files. @@ -6373,6 +6686,7 @@ var ts; var scanner = ts.createScanner(2 /* Latest */, true); var disallowInAndDecoratorContext = 2 /* DisallowIn */ | 16 /* Decorator */; var sourceFile; + var parseDiagnostics; var syntaxCursor; var token; var sourceText; @@ -6426,7 +6740,7 @@ var ts; // Note: it should not be necessary to save/restore these flags during speculative/lookahead // parsing. These context flags are naturally stored and restored through normal recursive // descent parsing and unwinding. - var contextFlags = 0; + var contextFlags; // Whether or not we've had a parse error since creating the last AST node. If we have // encountered an error, it will be stored on the next AST node we create. Parse errors // can be broken down into three categories: @@ -6455,20 +6769,49 @@ var ts; // Note: any errors at the end of the file that do not precede a regular node, should get // attached to the EOF token. var parseErrorBeforeNextFinishedNode = false; + (function (StatementFlags) { + StatementFlags[StatementFlags["None"] = 0] = "None"; + StatementFlags[StatementFlags["Statement"] = 1] = "Statement"; + StatementFlags[StatementFlags["ModuleElement"] = 2] = "ModuleElement"; + StatementFlags[StatementFlags["StatementOrModuleElement"] = 3] = "StatementOrModuleElement"; + })(Parser.StatementFlags || (Parser.StatementFlags = {})); + var StatementFlags = Parser.StatementFlags; function parseSourceFile(fileName, _sourceText, languageVersion, _syntaxCursor, setParentNodes) { + initializeState(fileName, _sourceText, languageVersion, _syntaxCursor); + var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes); + clearState(); + return result; + } + Parser.parseSourceFile = parseSourceFile; + function initializeState(fileName, _sourceText, languageVersion, _syntaxCursor) { sourceText = _sourceText; syntaxCursor = _syntaxCursor; + parseDiagnostics = []; parsingContext = 0; identifiers = {}; identifierCount = 0; nodeCount = 0; - contextFlags = 0; + contextFlags = ts.isJavaScript(fileName) ? 64 /* JavaScriptFile */ : 0 /* None */; parseErrorBeforeNextFinishedNode = false; - createSourceFile(fileName, languageVersion); // Initialize and prime the scanner before parsing the source elements. scanner.setText(sourceText); scanner.setOnError(scanError); scanner.setScriptTarget(languageVersion); + } + function clearState() { + // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily. + scanner.setText(""); + scanner.setOnError(undefined); + // Clear any data. We don't want to accidently hold onto it for too long. + parseDiagnostics = undefined; + sourceFile = undefined; + identifiers = undefined; + syntaxCursor = undefined; + sourceText = undefined; + } + function parseSourceFileWorker(fileName, languageVersion, setParentNodes) { + sourceFile = createSourceFile(fileName, languageVersion); + // Prime the scanner. token = nextToken(); processReferenceComments(sourceFile); sourceFile.statements = parseList(0 /* SourceElements */, true, parseSourceElement); @@ -6478,22 +6821,45 @@ var ts; sourceFile.nodeCount = nodeCount; sourceFile.identifierCount = identifierCount; sourceFile.identifiers = identifiers; + sourceFile.parseDiagnostics = parseDiagnostics; if (setParentNodes) { fixupParentReferences(sourceFile); } - syntaxCursor = undefined; - // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily. - scanner.setText(""); - scanner.setOnError(undefined); - var result = sourceFile; - // Clear any data. We don't want to accidently hold onto it for too long. - sourceFile = undefined; - identifiers = undefined; - syntaxCursor = undefined; - sourceText = undefined; - return result; + // If this is a javascript file, proactively see if we can get JSDoc comments for + // relevant nodes in the file. We'll use these to provide typing informaion if they're + // available. + if (ts.isJavaScript(fileName)) { + addJSDocComments(); + } + return sourceFile; + } + function addJSDocComments() { + forEachChild(sourceFile, visit); + return; + function visit(node) { + // Add additional cases as necessary depending on how we see JSDoc comments used + // in the wild. + switch (node.kind) { + case 181 /* VariableStatement */: + case 201 /* FunctionDeclaration */: + case 130 /* Parameter */: + addJSDocComment(node); + } + forEachChild(node, visit); + } + } + function addJSDocComment(node) { + var comments = ts.getLeadingCommentRangesOfNode(node, sourceFile); + if (comments) { + for (var _i = 0; _i < comments.length; _i++) { + var comment = comments[_i]; + var jsDocComment = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); + if (jsDocComment) { + node.jsDocComment = jsDocComment; + } + } + } } - Parser.parseSourceFile = parseSourceFile; function fixupParentReferences(sourceFile) { // normally parent references are set during binding. However, for clients that only need // a syntax tree, and no semantic features, then the binding process is an unnecessary @@ -6515,16 +6881,17 @@ var ts; } } } + Parser.fixupParentReferences = fixupParentReferences; function createSourceFile(fileName, languageVersion) { - sourceFile = createNode(228 /* SourceFile */, 0); + var sourceFile = createNode(228 /* SourceFile */, 0); sourceFile.pos = 0; sourceFile.end = sourceText.length; sourceFile.text = sourceText; - sourceFile.parseDiagnostics = []; sourceFile.bindDiagnostics = []; sourceFile.languageVersion = languageVersion; sourceFile.fileName = ts.normalizePath(fileName); sourceFile.flags = ts.fileExtensionIs(sourceFile.fileName, ".d.ts") ? 2048 /* DeclarationFile */ : 0; + return sourceFile; } function setContextFlag(val, flag) { if (val) { @@ -6632,9 +6999,9 @@ var ts; } function parseErrorAtPosition(start, length, message, arg0) { // Don't report another error if it would just be at the same position as the last error. - var lastError = ts.lastOrUndefined(sourceFile.parseDiagnostics); + var lastError = ts.lastOrUndefined(parseDiagnostics); if (!lastError || start !== lastError.start) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0)); } // Mark that we've encountered an error. We'll set an appropriate bit on the next // node we finish so that it can't be reused incrementally. @@ -6669,7 +7036,7 @@ var ts; // Keep track of the state we'll need to rollback to if lookahead fails (or if the // caller asked us to always reset our state). var saveToken = token; - var saveParseDiagnosticsLength = sourceFile.parseDiagnostics.length; + var saveParseDiagnosticsLength = parseDiagnostics.length; var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; // Note: it is not actually necessary to save/restore the context flags here. That's // because the saving/restorating of these flags happens naturally through the recursive @@ -6687,7 +7054,7 @@ var ts; // then unconditionally restore us to where we were. if (!result || isLookAhead) { token = saveToken; - sourceFile.parseDiagnostics.length = saveParseDiagnosticsLength; + parseDiagnostics.length = saveParseDiagnosticsLength; parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; } return result; @@ -6783,8 +7150,8 @@ var ts; node.end = pos; return node; } - function finishNode(node) { - node.end = scanner.getStartPos(); + function finishNode(node, end) { + node.end = end === undefined ? scanner.getStartPos() : end; if (contextFlags) { node.parserContextFlags = contextFlags; } @@ -6840,15 +7207,24 @@ var ts; token === 8 /* StringLiteral */ || token === 7 /* NumericLiteral */; } - function parsePropertyName() { + function parsePropertyNameWorker(allowComputedPropertyNames) { if (token === 8 /* StringLiteral */ || token === 7 /* NumericLiteral */) { return parseLiteralNode(true); } - if (token === 18 /* OpenBracketToken */) { + if (allowComputedPropertyNames && token === 18 /* OpenBracketToken */) { return parseComputedPropertyName(); } return parseIdentifierName(); } + function parsePropertyName() { + return parsePropertyNameWorker(true); + } + function parseSimplePropertyName() { + return parsePropertyNameWorker(false); + } + function isSimplePropertyName() { + return token === 8 /* StringLiteral */ || token === 7 /* NumericLiteral */ || isIdentifierOrKeyword(); + } function parseComputedPropertyName() { // PropertyName[Yield,GeneratorParameter] : // LiteralPropertyName @@ -6917,10 +7293,17 @@ var ts; switch (parsingContext) { case 0 /* SourceElements */: case 1 /* ModuleElements */: - return isSourceElement(inErrorRecovery); + // If we're in error recovery, then we don't want to treat ';' as an empty statement. + // The problem is that ';' can show up in far too many contexts, and if we see one + // and assume it's a statement, then we may bail out inappropriately from whatever + // we're parsing. For example, if we have a semicolon in the middle of a class, then + // we really don't want to assume the class is over and we're on a statement in the + // outer module. We just want to consume and move on. + return !(token === 22 /* SemicolonToken */ && inErrorRecovery) && isStartOfModuleElement(); case 2 /* BlockStatements */: case 4 /* SwitchClauseStatements */: - return isStartOfStatement(inErrorRecovery); + // During error recovery we don't treat empty statements as statements + return !(token === 22 /* SemicolonToken */ && inErrorRecovery) && isStartOfStatement(); case 3 /* SwitchClauses */: return token === 67 /* CaseKeyword */ || token === 73 /* DefaultKeyword */; case 5 /* TypeMembers */: @@ -6972,6 +7355,12 @@ var ts; return isHeritageClause(); case 20 /* ImportOrExportSpecifiers */: return isIdentifierOrKeyword(); + case 21 /* JSDocFunctionParameters */: + case 22 /* JSDocTypeArguments */: + case 24 /* JSDocTupleTypes */: + return JSDocParser.isJSDocType(); + case 23 /* JSDocRecordMembers */: + return isSimplePropertyName(); } ts.Debug.fail("Non-exhaustive case in 'isListElement'."); } @@ -7046,6 +7435,14 @@ var ts; return token === 25 /* GreaterThanToken */ || token === 16 /* OpenParenToken */; case 19 /* HeritageClauses */: return token === 14 /* OpenBraceToken */ || token === 15 /* CloseBraceToken */; + case 21 /* JSDocFunctionParameters */: + return token === 17 /* CloseParenToken */ || token === 51 /* ColonToken */ || token === 15 /* CloseBraceToken */; + case 22 /* JSDocTypeArguments */: + return token === 25 /* GreaterThanToken */ || token === 15 /* CloseBraceToken */; + case 24 /* JSDocTupleTypes */: + return token === 19 /* CloseBracketToken */ || token === 15 /* CloseBraceToken */; + case 23 /* JSDocRecordMembers */: + return token === 15 /* CloseBraceToken */; } } function isVariableDeclaratorListTerminator() { @@ -7071,7 +7468,7 @@ var ts; } // True if positioned at element or terminator of the current list or any enclosing list function isInSomeParsingContext() { - for (var kind = 0; kind < 21 /* Count */; kind++) { + for (var kind = 0; kind < 25 /* Count */; kind++) { if (parsingContext & (1 << kind)) { if (isListElement(kind, true) || isListTerminator(kind)) { return true; @@ -7094,7 +7491,7 @@ var ts; // test elements only if we are not already in strict mode if (checkForStrictMode && !inStrictModeContext()) { if (ts.isPrologueDirective(element)) { - if (isUseStrictPrologueDirective(sourceFile, element)) { + if (isUseStrictPrologueDirective(element)) { setStrictModeContext(true); checkForStrictMode = false; } @@ -7115,9 +7512,9 @@ var ts; return result; } /// Should be called only on prologue directives (isPrologueDirective(node) should be true) - function isUseStrictPrologueDirective(sourceFile, node) { + function isUseStrictPrologueDirective(node) { ts.Debug.assert(ts.isPrologueDirective(node)); - var nodeText = ts.getSourceTextOfNodeFromSourceFile(sourceFile, node.expression); + var nodeText = ts.getTextOfNodeFromSourceText(sourceText, node.expression); // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the // string to contain unicode escapes (as per ES5). return nodeText === '"use strict"' || nodeText === "'use strict'"; @@ -7390,6 +7787,10 @@ var ts; case 18 /* TupleElementTypes */: return ts.Diagnostics.Type_expected; case 19 /* HeritageClauses */: return ts.Diagnostics.Unexpected_token_expected; case 20 /* ImportOrExportSpecifiers */: return ts.Diagnostics.Identifier_expected; + case 21 /* JSDocFunctionParameters */: return ts.Diagnostics.Parameter_declaration_expected; + case 22 /* JSDocTypeArguments */: return ts.Diagnostics.Type_argument_expected; + case 24 /* JSDocTupleTypes */: return ts.Diagnostics.Type_expected; + case 23 /* JSDocRecordMembers */: return ts.Diagnostics.Property_assignment_expected; } } ; @@ -8249,11 +8650,6 @@ var ts; nextToken(); return !scanner.hasPrecedingLineBreak() && isIdentifier(); } - function nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine() { - nextToken(); - return !scanner.hasPrecedingLineBreak() && - (isIdentifier() || token === 14 /* OpenBraceToken */ || token === 18 /* OpenBracketToken */); - } function parseYieldExpression() { var node = createNode(173 /* YieldExpression */); // YieldExpression[In] : @@ -8425,10 +8821,11 @@ var ts; if (token === 14 /* OpenBraceToken */) { return parseFunctionBlock(false, false); } - if (isStartOfStatement(true) && - !isStartOfExpressionStatement() && + if (token !== 22 /* SemicolonToken */ && token !== 83 /* FunctionKeyword */ && - token !== 69 /* ClassKeyword */) { + token !== 69 /* ClassKeyword */ && + isStartOfStatement() && + !isStartOfExpressionStatement()) { // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations) // // Here we try to recover from a potential error situation in the case where the @@ -9217,33 +9614,68 @@ var ts; return finishNode(expressionStatement); } } - function isStartOfStatement(inErrorRecovery) { - // Functions, variable statements and classes are allowed as a statement. But as per - // the grammar, they also allow modifiers. So we have to check for those statements - // that might be following modifiers.This ensures that things work properly when - // incrementally parsing as the parser will produce the same FunctionDeclaraiton, - // VariableStatement or ClassDeclaration, if it has the same text regardless of whether - // it is inside a block or not. - if (ts.isModifier(token)) { - var result = lookAhead(parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers); - if (result) { - return true; + function isIdentifierOrKeyword() { + return token >= 65 /* Identifier */; + } + function nextTokenIsIdentifierOrKeywordOnSameLine() { + nextToken(); + return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak(); + } + function parseDeclarationFlags() { + while (true) { + switch (token) { + case 98 /* VarKeyword */: + case 104 /* LetKeyword */: + case 70 /* ConstKeyword */: + case 83 /* FunctionKeyword */: + case 69 /* ClassKeyword */: + case 77 /* EnumKeyword */: + return 1 /* Statement */; + case 103 /* InterfaceKeyword */: + case 124 /* TypeKeyword */: + nextToken(); + return isIdentifierOrKeyword() ? 1 /* Statement */ : 0 /* None */; + case 117 /* ModuleKeyword */: + case 118 /* NamespaceKeyword */: + nextToken(); + return isIdentifierOrKeyword() || token === 8 /* StringLiteral */ ? 2 /* ModuleElement */ : 0 /* None */; + case 85 /* ImportKeyword */: + nextToken(); + return token === 8 /* StringLiteral */ || token === 35 /* AsteriskToken */ || + token === 14 /* OpenBraceToken */ || isIdentifierOrKeyword() ? + 2 /* ModuleElement */ : 0 /* None */; + case 78 /* ExportKeyword */: + nextToken(); + if (token === 53 /* EqualsToken */ || token === 35 /* AsteriskToken */ || + token === 14 /* OpenBraceToken */ || token === 73 /* DefaultKeyword */) { + return 2 /* ModuleElement */; + } + continue; + case 115 /* DeclareKeyword */: + case 108 /* PublicKeyword */: + case 106 /* PrivateKeyword */: + case 107 /* ProtectedKeyword */: + case 109 /* StaticKeyword */: + nextToken(); + continue; + default: + return 0 /* None */; } } + } + function getDeclarationFlags() { + return lookAhead(parseDeclarationFlags); + } + function getStatementFlags() { switch (token) { + case 52 /* AtToken */: case 22 /* SemicolonToken */: - // If we're in error recovery, then we don't want to treat ';' as an empty statement. - // The problem is that ';' can show up in far too many contexts, and if we see one - // and assume it's a statement, then we may bail out inappropriately from whatever - // we're parsing. For example, if we have a semicolon in the middle of a class, then - // we really don't want to assume the class is over and we're on a statement in the - // outer module. We just want to consume and move on. - return !inErrorRecovery; case 14 /* OpenBraceToken */: case 98 /* VarKeyword */: case 104 /* LetKeyword */: case 83 /* FunctionKeyword */: case 69 /* ClassKeyword */: + case 77 /* EnumKeyword */: case 84 /* IfKeyword */: case 75 /* DoKeyword */: case 100 /* WhileKeyword */: @@ -9260,58 +9692,72 @@ var ts; // however, we say they are here so that we may gracefully parse them and error later. case 68 /* CatchKeyword */: case 81 /* FinallyKeyword */: - return true; + return 1 /* Statement */; case 70 /* ConstKeyword */: - // const keyword can precede enum keyword when defining constant enums - // 'const enum' do not start statement. - // In ES 6 'enum' is a future reserved keyword, so it should not be used as identifier - var isConstEnum = lookAhead(nextTokenIsEnumKeyword); - return !isConstEnum; + case 78 /* ExportKeyword */: + case 85 /* ImportKeyword */: + return getDeclarationFlags(); + case 115 /* DeclareKeyword */: case 103 /* InterfaceKeyword */: case 117 /* ModuleKeyword */: case 118 /* NamespaceKeyword */: - case 77 /* EnumKeyword */: case 124 /* TypeKeyword */: - // When followed by an identifier, these do not start a statement but might - // instead be following declarations - if (isDeclarationStart()) { - return false; - } + // When these don't start a declaration, they're an identifier in an expression statement + return getDeclarationFlags() || 1 /* Statement */; case 108 /* PublicKeyword */: case 106 /* PrivateKeyword */: case 107 /* ProtectedKeyword */: case 109 /* StaticKeyword */: - // When followed by an identifier or keyword, these do not start a statement but - // might instead be following type members - if (lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine)) { - return false; - } + // When these don't start a declaration, they may be the start of a class member if an identifier + // immediately follows. Otherwise they're an identifier in an expression statement. + return getDeclarationFlags() || + (lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? 0 /* None */ : 1 /* Statement */); default: - return isStartOfExpression(); + return isStartOfExpression() ? 1 /* Statement */ : 0 /* None */; } } - function nextTokenIsEnumKeyword() { - nextToken(); - return token === 77 /* EnumKeyword */; + function isStartOfStatement() { + return (getStatementFlags() & 1 /* Statement */) !== 0; } - function nextTokenIsIdentifierOrKeywordOnSameLine() { + function isStartOfModuleElement() { + return (getStatementFlags() & 3 /* StatementOrModuleElement */) !== 0; + } + function nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine() { nextToken(); - return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak(); + return !scanner.hasPrecedingLineBreak() && + (isIdentifier() || token === 14 /* OpenBraceToken */ || token === 18 /* OpenBracketToken */); + } + function isLetDeclaration() { + // It is let declaration if in strict mode or next token is identifier\open bracket\open curly on same line. + // otherwise it needs to be treated like identifier + return inStrictModeContext() || lookAhead(nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine); } function parseStatement() { + return parseModuleElementOfKind(1 /* Statement */); + } + function parseModuleElement() { + return parseModuleElementOfKind(3 /* StatementOrModuleElement */); + } + function parseSourceElement() { + return parseModuleElementOfKind(3 /* StatementOrModuleElement */); + } + function parseModuleElementOfKind(flags) { switch (token) { + case 22 /* SemicolonToken */: + return parseEmptyStatement(); case 14 /* OpenBraceToken */: return parseBlock(false, false); case 98 /* VarKeyword */: - case 70 /* ConstKeyword */: - // const here should always be parsed as const declaration because of check in 'isStatement' return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + case 104 /* LetKeyword */: + if (isLetDeclaration()) { + return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + } + break; case 83 /* FunctionKeyword */: return parseFunctionDeclaration(scanner.getStartPos(), undefined, undefined); case 69 /* ClassKeyword */: return parseClassDeclaration(scanner.getStartPos(), undefined, undefined); - case 22 /* SemicolonToken */: - return parseEmptyStatement(); case 84 /* IfKeyword */: return parseIfStatement(); case 75 /* DoKeyword */: @@ -9339,54 +9785,68 @@ var ts; return parseTryStatement(); case 72 /* DebuggerKeyword */: return parseDebuggerStatement(); - case 104 /* LetKeyword */: - // If let follows identifier on the same line, it is declaration parse it as variable statement - if (isLetDeclaration()) { - return parseVariableStatement(scanner.getStartPos(), undefined, undefined); + case 52 /* AtToken */: + return parseDeclaration(); + case 70 /* ConstKeyword */: + case 115 /* DeclareKeyword */: + case 77 /* EnumKeyword */: + case 78 /* ExportKeyword */: + case 85 /* ImportKeyword */: + case 103 /* InterfaceKeyword */: + case 117 /* ModuleKeyword */: + case 118 /* NamespaceKeyword */: + case 106 /* PrivateKeyword */: + case 107 /* ProtectedKeyword */: + case 108 /* PublicKeyword */: + case 109 /* StaticKeyword */: + case 124 /* TypeKeyword */: + if (getDeclarationFlags() & flags) { + return parseDeclaration(); } - // Else parse it like identifier - fall through - default: - // Functions and variable statements are allowed as a statement. But as per - // the grammar, they also allow modifiers. So we have to check for those - // statements that might be following modifiers. This ensures that things - // work properly when incrementally parsing as the parser will produce the - // same FunctionDeclaraiton or VariableStatement if it has the same text - // regardless of whether it is inside a block or not. - // Even though variable statements and function declarations cannot have decorators, - // we parse them here to provide better error recovery. - if (ts.isModifier(token) || token === 52 /* AtToken */) { - var result = tryParse(parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers); - if (result) { - return result; - } - } - return parseExpressionOrLabeledStatement(); + break; } + return parseExpressionOrLabeledStatement(); } - function parseVariableStatementOrFunctionDeclarationOrClassDeclarationWithDecoratorsOrModifiers() { - var start = scanner.getStartPos(); + function parseDeclaration() { + var fullStart = getNodePos(); var decorators = parseDecorators(); var modifiers = parseModifiers(); switch (token) { - case 70 /* ConstKeyword */: - var nextTokenIsEnum = lookAhead(nextTokenIsEnumKeyword); - if (nextTokenIsEnum) { - return undefined; - } - return parseVariableStatement(start, decorators, modifiers); - case 104 /* LetKeyword */: - if (!isLetDeclaration()) { - return undefined; - } - return parseVariableStatement(start, decorators, modifiers); case 98 /* VarKeyword */: - return parseVariableStatement(start, decorators, modifiers); + case 104 /* LetKeyword */: + case 70 /* ConstKeyword */: + return parseVariableStatement(fullStart, decorators, modifiers); case 83 /* FunctionKeyword */: - return parseFunctionDeclaration(start, decorators, modifiers); + return parseFunctionDeclaration(fullStart, decorators, modifiers); case 69 /* ClassKeyword */: - return parseClassDeclaration(start, decorators, modifiers); + return parseClassDeclaration(fullStart, decorators, modifiers); + case 103 /* InterfaceKeyword */: + return parseInterfaceDeclaration(fullStart, decorators, modifiers); + case 124 /* TypeKeyword */: + return parseTypeAliasDeclaration(fullStart, decorators, modifiers); + case 77 /* EnumKeyword */: + return parseEnumDeclaration(fullStart, decorators, modifiers); + case 117 /* ModuleKeyword */: + case 118 /* NamespaceKeyword */: + return parseModuleDeclaration(fullStart, decorators, modifiers); + case 85 /* ImportKeyword */: + return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers); + case 78 /* ExportKeyword */: + nextToken(); + return token === 73 /* DefaultKeyword */ || token === 53 /* EqualsToken */ ? + parseExportAssignment(fullStart, decorators, modifiers) : + parseExportDeclaration(fullStart, decorators, modifiers); + default: + if (decorators) { + // We reached this point because we encountered decorators and/or modifiers and assumed a declaration + // would follow. For recovery and error reporting purposes, return an incomplete declaration. + var node = createMissingNode(219 /* MissingDeclaration */, true, ts.Diagnostics.Declaration_expected); + node.pos = fullStart; + node.decorators = decorators; + setModifiers(node, modifiers); + return finishNode(node); + } } - return undefined; } function parseFunctionBlockOrSemicolon(isGenerator, diagnosticMessage) { if (token !== 14 /* OpenBraceToken */ && canParseSemicolon()) { @@ -9541,7 +10001,18 @@ var ts; property.name = name; property.questionToken = questionToken; property.type = parseTypeAnnotation(); - property.initializer = allowInAnd(parseNonParameterInitializer); + // For instance properties specifically, since they are evaluated inside the constructor, + // we do *not * want to parse yield expressions, so we specifically turn the yield context + // off. The grammar would look something like this: + // + // MemberVariableDeclaration[Yield]: + // AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initialiser_opt[In]; + // AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initialiser_opt[In, ?Yield]; + // + // The checker may still error in the static case to explicitly disallow the yield expression. + property.initializer = modifiers && modifiers.flags & 128 /* Static */ + ? allowInAnd(parseNonParameterInitializer) + : doOutsideOfContext(4 /* Yield */ | 2 /* DisallowIn */, parseNonParameterInitializer); parseSemicolon(); return finishNode(property); } @@ -9711,17 +10182,17 @@ var ts; } if (decorators) { // treat this as a property declaration with a missing name. - var name_3 = createMissingNode(65 /* Identifier */, true, ts.Diagnostics.Declaration_expected); - return parsePropertyDeclaration(fullStart, decorators, modifiers, name_3, undefined); + var name_5 = createMissingNode(65 /* Identifier */, true, ts.Diagnostics.Declaration_expected); + return parsePropertyDeclaration(fullStart, decorators, modifiers, name_5, undefined); } // 'isClassMemberStart' should have hinted not to attempt parsing. ts.Debug.fail("Should not have attempted to parse class member declaration."); } function parseClassExpression() { return parseClassDeclarationOrExpression( - /*fullStart:*/ scanner.getStartPos(), - /*decorators:*/ undefined, - /*modifiers:*/ undefined, 175 /* ClassExpression */); + /*fullStart*/ scanner.getStartPos(), + /*decorators*/ undefined, + /*modifiers*/ undefined, 175 /* ClassExpression */); } function parseClassDeclaration(fullStart, decorators, modifiers) { return parseClassDeclarationOrExpression(fullStart, decorators, modifiers, 202 /* ClassDeclaration */); @@ -10063,136 +10534,6 @@ var ts; parseSemicolon(); return finishNode(node); } - function isLetDeclaration() { - // It is let declaration if in strict mode or next token is identifier\open bracket\open curly on same line. - // otherwise it needs to be treated like identifier - return inStrictModeContext() || lookAhead(nextTokenIsIdentifierOrStartOfDestructuringOnTheSameLine); - } - function isDeclarationStart(followsModifier) { - switch (token) { - case 98 /* VarKeyword */: - case 70 /* ConstKeyword */: - case 83 /* FunctionKeyword */: - return true; - case 104 /* LetKeyword */: - return isLetDeclaration(); - case 69 /* ClassKeyword */: - case 103 /* InterfaceKeyword */: - case 77 /* EnumKeyword */: - case 124 /* TypeKeyword */: - // Not true keywords so ensure an identifier follows - return lookAhead(nextTokenIsIdentifierOrKeyword); - case 85 /* ImportKeyword */: - // Not true keywords so ensure an identifier follows or is string literal or asterisk or open brace - return lookAhead(nextTokenCanFollowImportKeyword); - case 117 /* ModuleKeyword */: - case 118 /* NamespaceKeyword */: - // Not a true keyword so ensure an identifier or string literal follows - return lookAhead(nextTokenIsIdentifierOrKeywordOrStringLiteral); - case 78 /* ExportKeyword */: - // Check for export assignment or modifier on source element - return lookAhead(nextTokenCanFollowExportKeyword); - case 115 /* DeclareKeyword */: - case 108 /* PublicKeyword */: - case 106 /* PrivateKeyword */: - case 107 /* ProtectedKeyword */: - case 109 /* StaticKeyword */: - // Check for modifier on source element - return lookAhead(nextTokenIsDeclarationStart); - case 52 /* AtToken */: - // a lookahead here is too costly, and decorators are only valid on a declaration. - // We will assume we are parsing a declaration here and report an error later - return !followsModifier; - } - } - function isIdentifierOrKeyword() { - return token >= 65 /* Identifier */; - } - function nextTokenIsIdentifierOrKeyword() { - nextToken(); - return isIdentifierOrKeyword(); - } - function nextTokenIsIdentifierOrKeywordOrStringLiteral() { - nextToken(); - return isIdentifierOrKeyword() || token === 8 /* StringLiteral */; - } - function nextTokenCanFollowImportKeyword() { - nextToken(); - return isIdentifierOrKeyword() || token === 8 /* StringLiteral */ || - token === 35 /* AsteriskToken */ || token === 14 /* OpenBraceToken */; - } - function nextTokenCanFollowExportKeyword() { - nextToken(); - return token === 53 /* EqualsToken */ || token === 35 /* AsteriskToken */ || - token === 14 /* OpenBraceToken */ || token === 73 /* DefaultKeyword */ || isDeclarationStart(true); - } - function nextTokenIsDeclarationStart() { - nextToken(); - return isDeclarationStart(true); - } - function nextTokenIsAsKeyword() { - return nextToken() === 111 /* AsKeyword */; - } - function parseDeclaration() { - var fullStart = getNodePos(); - var decorators = parseDecorators(); - var modifiers = parseModifiers(); - if (token === 78 /* ExportKeyword */) { - nextToken(); - if (token === 73 /* DefaultKeyword */ || token === 53 /* EqualsToken */) { - return parseExportAssignment(fullStart, decorators, modifiers); - } - if (token === 35 /* AsteriskToken */ || token === 14 /* OpenBraceToken */) { - return parseExportDeclaration(fullStart, decorators, modifiers); - } - } - switch (token) { - case 98 /* VarKeyword */: - case 104 /* LetKeyword */: - case 70 /* ConstKeyword */: - return parseVariableStatement(fullStart, decorators, modifiers); - case 83 /* FunctionKeyword */: - return parseFunctionDeclaration(fullStart, decorators, modifiers); - case 69 /* ClassKeyword */: - return parseClassDeclaration(fullStart, decorators, modifiers); - case 103 /* InterfaceKeyword */: - return parseInterfaceDeclaration(fullStart, decorators, modifiers); - case 124 /* TypeKeyword */: - return parseTypeAliasDeclaration(fullStart, decorators, modifiers); - case 77 /* EnumKeyword */: - return parseEnumDeclaration(fullStart, decorators, modifiers); - case 117 /* ModuleKeyword */: - case 118 /* NamespaceKeyword */: - return parseModuleDeclaration(fullStart, decorators, modifiers); - case 85 /* ImportKeyword */: - return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers); - default: - if (decorators) { - // We reached this point because we encountered an AtToken and assumed a declaration would - // follow. For recovery and error reporting purposes, return an incomplete declaration. - var node = createMissingNode(219 /* MissingDeclaration */, true, ts.Diagnostics.Declaration_expected); - node.pos = fullStart; - node.decorators = decorators; - setModifiers(node, modifiers); - return finishNode(node); - } - ts.Debug.fail("Mismatch between isDeclarationStart and parseDeclaration"); - } - } - function isSourceElement(inErrorRecovery) { - return isDeclarationStart() || isStartOfStatement(inErrorRecovery); - } - function parseSourceElement() { - return parseSourceElementOrModuleElement(); - } - function parseModuleElement() { - return parseSourceElementOrModuleElement(); - } - function parseSourceElementOrModuleElement() { - return isDeclarationStart() - ? parseDeclaration() - : parseStatement(); - } function processReferenceComments(sourceFile) { var triviaScanner = ts.createScanner(sourceFile.languageVersion, false, sourceText); var referencedFiles = []; @@ -10220,7 +10561,7 @@ var ts; referencedFiles.push(fileReference); } if (diagnosticMessage) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); } } else { @@ -10228,7 +10569,7 @@ var ts; var amdModuleNameMatchResult = amdModuleNameRegEx.exec(comment); if (amdModuleNameMatchResult) { if (amdModuleName) { - sourceFile.parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); + parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); } amdModuleName = amdModuleNameMatchResult[2]; } @@ -10284,7 +10625,11 @@ var ts; ParsingContext[ParsingContext["TupleElementTypes"] = 18] = "TupleElementTypes"; ParsingContext[ParsingContext["HeritageClauses"] = 19] = "HeritageClauses"; ParsingContext[ParsingContext["ImportOrExportSpecifiers"] = 20] = "ImportOrExportSpecifiers"; - ParsingContext[ParsingContext["Count"] = 21] = "Count"; // Number of parsing contexts + ParsingContext[ParsingContext["JSDocFunctionParameters"] = 21] = "JSDocFunctionParameters"; + ParsingContext[ParsingContext["JSDocTypeArguments"] = 22] = "JSDocTypeArguments"; + ParsingContext[ParsingContext["JSDocRecordMembers"] = 23] = "JSDocRecordMembers"; + ParsingContext[ParsingContext["JSDocTupleTypes"] = 24] = "JSDocTupleTypes"; + ParsingContext[ParsingContext["Count"] = 25] = "Count"; // Number of parsing contexts })(ParsingContext || (ParsingContext = {})); var Tristate; (function (Tristate) { @@ -10292,6 +10637,552 @@ var ts; Tristate[Tristate["True"] = 1] = "True"; Tristate[Tristate["Unknown"] = 2] = "Unknown"; })(Tristate || (Tristate = {})); + var JSDocParser; + (function (JSDocParser) { + function isJSDocType() { + switch (token) { + case 35 /* AsteriskToken */: + case 50 /* QuestionToken */: + case 16 /* OpenParenToken */: + case 18 /* OpenBracketToken */: + case 46 /* ExclamationToken */: + case 14 /* OpenBraceToken */: + case 83 /* FunctionKeyword */: + case 21 /* DotDotDotToken */: + case 88 /* NewKeyword */: + case 93 /* ThisKeyword */: + return true; + } + return isIdentifierOrKeyword(); + } + JSDocParser.isJSDocType = isJSDocType; + function parseJSDocTypeExpressionForTests(content, start, length) { + initializeState("file.js", content, 2 /* Latest */, undefined); + var jsDocTypeExpression = parseJSDocTypeExpression(start, length); + var diagnostics = parseDiagnostics; + clearState(); + return jsDocTypeExpression ? { jsDocTypeExpression: jsDocTypeExpression, diagnostics: diagnostics } : undefined; + } + JSDocParser.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests; + // Parses out a JSDoc type expression. The starting position should be right at the open + // curly in the type expression. Returns 'undefined' if it encounters any errors while parsing. + /* @internal */ + function parseJSDocTypeExpression(start, length) { + scanner.setText(sourceText, start, length); + // Prime the first token for us to start processing. + token = nextToken(); + var result = createNode(229 /* JSDocTypeExpression */); + parseExpected(14 /* OpenBraceToken */); + result.type = parseJSDocTopLevelType(); + parseExpected(15 /* CloseBraceToken */); + fixupParentReferences(result); + return finishNode(result); + } + JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression; + function setError(message) { + parseErrorAtCurrentToken(message); + if (ts.throwOnJSDocErrors) { + throw new Error(message.key); + } + } + function parseJSDocTopLevelType() { + var type = parseJSDocType(); + if (token === 44 /* BarToken */) { + var unionType = createNode(233 /* JSDocUnionType */, type.pos); + unionType.types = parseJSDocTypeList(type); + type = finishNode(unionType); + } + if (token === 53 /* EqualsToken */) { + var optionalType = createNode(240 /* JSDocOptionalType */, type.pos); + nextToken(); + optionalType.type = type; + type = finishNode(optionalType); + } + return type; + } + function parseJSDocType() { + var type = parseBasicTypeExpression(); + while (true) { + if (token === 18 /* OpenBracketToken */) { + var arrayType = createNode(232 /* JSDocArrayType */, type.pos); + arrayType.elementType = type; + nextToken(); + parseExpected(19 /* CloseBracketToken */); + type = finishNode(arrayType); + } + else if (token === 50 /* QuestionToken */) { + var nullableType = createNode(235 /* JSDocNullableType */, type.pos); + nullableType.type = type; + nextToken(); + type = finishNode(nullableType); + } + else if (token === 46 /* ExclamationToken */) { + var nonNullableType = createNode(236 /* JSDocNonNullableType */, type.pos); + nonNullableType.type = type; + nextToken(); + type = finishNode(nonNullableType); + } + else { + break; + } + } + return type; + } + function parseBasicTypeExpression() { + switch (token) { + case 35 /* AsteriskToken */: + return parseJSDocAllType(); + case 50 /* QuestionToken */: + return parseJSDocUnknownOrNullableType(); + case 16 /* OpenParenToken */: + return parseJSDocUnionType(); + case 18 /* OpenBracketToken */: + return parseJSDocTupleType(); + case 46 /* ExclamationToken */: + return parseJSDocNonNullableType(); + case 14 /* OpenBraceToken */: + return parseJSDocRecordType(); + case 83 /* FunctionKeyword */: + return parseJSDocFunctionType(); + case 21 /* DotDotDotToken */: + return parseJSDocVariadicType(); + case 88 /* NewKeyword */: + return parseJSDocConstructorType(); + case 93 /* ThisKeyword */: + return parseJSDocThisType(); + case 112 /* AnyKeyword */: + case 122 /* StringKeyword */: + case 120 /* NumberKeyword */: + case 113 /* BooleanKeyword */: + case 123 /* SymbolKeyword */: + case 99 /* VoidKeyword */: + return parseTokenNode(); + } + return parseJSDocTypeReference(); + } + function parseJSDocThisType() { + var result = createNode(244 /* JSDocThisType */); + nextToken(); + parseExpected(51 /* ColonToken */); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocConstructorType() { + var result = createNode(243 /* JSDocConstructorType */); + nextToken(); + parseExpected(51 /* ColonToken */); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocVariadicType() { + var result = createNode(242 /* JSDocVariadicType */); + nextToken(); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocFunctionType() { + var result = createNode(241 /* JSDocFunctionType */); + nextToken(); + parseExpected(16 /* OpenParenToken */); + result.parameters = parseDelimitedList(21 /* JSDocFunctionParameters */, parseJSDocParameter); + checkForTrailingComma(result.parameters); + parseExpected(17 /* CloseParenToken */); + if (token === 51 /* ColonToken */) { + nextToken(); + result.type = parseJSDocType(); + } + return finishNode(result); + } + function parseJSDocParameter() { + var parameter = createNode(130 /* Parameter */); + parameter.type = parseJSDocType(); + return finishNode(parameter); + } + function parseJSDocOptionalType(type) { + var result = createNode(240 /* JSDocOptionalType */, type.pos); + nextToken(); + result.type = type; + return finishNode(result); + } + function parseJSDocTypeReference() { + var result = createNode(239 /* JSDocTypeReference */); + result.name = parseSimplePropertyName(); + while (parseOptional(20 /* DotToken */)) { + if (token === 24 /* LessThanToken */) { + result.typeArguments = parseTypeArguments(); + break; + } + else { + result.name = parseQualifiedName(result.name); + } + } + return finishNode(result); + } + function parseTypeArguments() { + // Move past the < + nextToken(); + var typeArguments = parseDelimitedList(22 /* JSDocTypeArguments */, parseJSDocType); + checkForTrailingComma(typeArguments); + checkForEmptyTypeArgumentList(typeArguments); + parseExpected(25 /* GreaterThanToken */); + return typeArguments; + } + function checkForEmptyTypeArgumentList(typeArguments) { + if (parseDiagnostics.length === 0 && typeArguments && typeArguments.length === 0) { + var start = typeArguments.pos - "<".length; + var end = ts.skipTrivia(sourceText, typeArguments.end) + ">".length; + return parseErrorAtPosition(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty); + } + } + function parseQualifiedName(left) { + var result = createNode(127 /* QualifiedName */, left.pos); + result.left = left; + result.right = parseIdentifierName(); + return finishNode(result); + } + function parseJSDocRecordType() { + var result = createNode(237 /* JSDocRecordType */); + nextToken(); + result.members = parseDelimitedList(23 /* JSDocRecordMembers */, parseJSDocRecordMember); + checkForTrailingComma(result.members); + parseExpected(15 /* CloseBraceToken */); + return finishNode(result); + } + function parseJSDocRecordMember() { + var result = createNode(238 /* JSDocRecordMember */); + result.name = parseSimplePropertyName(); + if (token === 51 /* ColonToken */) { + nextToken(); + result.type = parseJSDocType(); + } + return finishNode(result); + } + function parseJSDocNonNullableType() { + var result = createNode(236 /* JSDocNonNullableType */); + nextToken(); + result.type = parseJSDocType(); + return finishNode(result); + } + function parseJSDocTupleType() { + var result = createNode(234 /* JSDocTupleType */); + nextToken(); + result.types = parseDelimitedList(24 /* JSDocTupleTypes */, parseJSDocType); + checkForTrailingComma(result.types); + parseExpected(19 /* CloseBracketToken */); + return finishNode(result); + } + function checkForTrailingComma(list) { + if (parseDiagnostics.length === 0 && list.hasTrailingComma) { + var start = list.end - ",".length; + parseErrorAtPosition(start, ",".length, ts.Diagnostics.Trailing_comma_not_allowed); + } + } + function parseJSDocUnionType() { + var result = createNode(233 /* JSDocUnionType */); + nextToken(); + result.types = parseJSDocTypeList(parseJSDocType()); + parseExpected(17 /* CloseParenToken */); + return finishNode(result); + } + function parseJSDocTypeList(firstType) { + ts.Debug.assert(!!firstType); + var types = []; + types.pos = firstType.pos; + types.push(firstType); + while (parseOptional(44 /* BarToken */)) { + types.push(parseJSDocType()); + } + types.end = scanner.getStartPos(); + return types; + } + function parseJSDocAllType() { + var result = createNode(230 /* JSDocAllType */); + nextToken(); + return finishNode(result); + } + function parseJSDocUnknownOrNullableType() { + var pos = scanner.getStartPos(); + // skip the ? + nextToken(); + // Need to lookahead to decide if this is a nullable or unknown type. + // Here are cases where we'll pick the unknown type: + // + // Foo(?, + // { a: ? } + // Foo(?) + // Foo + // Foo(?= + // (?| + if (token === 23 /* CommaToken */ || + token === 15 /* CloseBraceToken */ || + token === 17 /* CloseParenToken */ || + token === 25 /* GreaterThanToken */ || + token === 53 /* EqualsToken */ || + token === 44 /* BarToken */) { + var result = createNode(231 /* JSDocUnknownType */, pos); + return finishNode(result); + } + else { + var result = createNode(235 /* JSDocNullableType */, pos); + result.type = parseJSDocType(); + return finishNode(result); + } + } + function parseIsolatedJSDocComment(content, start, length) { + initializeState("file.js", content, 2 /* Latest */, undefined); + var jsDocComment = parseJSDocComment(undefined, start, length); + var diagnostics = parseDiagnostics; + clearState(); + return jsDocComment ? { jsDocComment: jsDocComment, diagnostics: diagnostics } : undefined; + } + JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment; + function parseJSDocComment(parent, start, length) { + var comment = parseJSDocCommentWorker(start, length); + if (comment) { + fixupParentReferences(comment); + comment.parent = parent; + } + return comment; + } + JSDocParser.parseJSDocComment = parseJSDocComment; + function parseJSDocCommentWorker(start, length) { + var content = sourceText; + start = start || 0; + var end = length === undefined ? content.length : start + length; + length = end - start; + ts.Debug.assert(start >= 0); + ts.Debug.assert(start <= end); + ts.Debug.assert(end <= content.length); + var tags; + var pos; + // NOTE(cyrusn): This is essentially a handwritten scanner for JSDocComments. I + // considered using an actual Scanner, but this would complicate things. The + // scanner would need to know it was in a Doc Comment. Otherwise, it would then + // produce comments *inside* the doc comment. In the end it was just easier to + // write a simple scanner rather than go that route. + if (length >= "/** */".length) { + if (content.charCodeAt(start) === 47 /* slash */ && + content.charCodeAt(start + 1) === 42 /* asterisk */ && + content.charCodeAt(start + 2) === 42 /* asterisk */ && + content.charCodeAt(start + 3) !== 42 /* asterisk */) { + // Initially we can parse out a tag. We also have seen a starting asterisk. + // This is so that /** * @type */ doesn't parse. + var canParseTag = true; + var seenAsterisk = true; + for (pos = start + "/**".length; pos < end;) { + var ch = content.charCodeAt(pos); + pos++; + if (ch === 64 /* at */ && canParseTag) { + parseTag(); + // Once we parse out a tag, we cannot keep parsing out tags on this line. + canParseTag = false; + continue; + } + if (ts.isLineBreak(ch)) { + // After a line break, we can parse a tag, and we haven't seen as asterisk + // on the next line yet. + canParseTag = true; + seenAsterisk = false; + continue; + } + if (ts.isWhiteSpace(ch)) { + // Whitespace doesn't affect any of our parsing. + continue; + } + // Ignore the first asterisk on a line. + if (ch === 42 /* asterisk */) { + if (seenAsterisk) { + // If we've already seen an asterisk, then we can no longer parse a tag + // on this line. + canParseTag = false; + } + seenAsterisk = true; + continue; + } + // Anything else is doc comment text. We can't do anything with it. Because it + // wasn't a tag, we can no longer parse a tag on this line until we hit the next + // line break. + canParseTag = false; + } + } + } + return createJSDocComment(); + function createJSDocComment() { + if (!tags) { + return undefined; + } + var result = createNode(245 /* JSDocComment */, start); + result.tags = tags; + return finishNode(result, end); + } + function skipWhitespace() { + while (pos < end && ts.isWhiteSpace(content.charCodeAt(pos))) { + pos++; + } + } + function parseTag() { + ts.Debug.assert(content.charCodeAt(pos - 1) === 64 /* at */); + var atToken = createNode(52 /* AtToken */, pos - 1); + atToken.end = pos; + var startPos = pos; + var tagName = scanIdentifier(); + if (!tagName) { + return; + } + var tag = handleTag(atToken, tagName) || handleUnknownTag(atToken, tagName); + addTag(tag); + } + function handleTag(atToken, tagName) { + if (tagName) { + switch (tagName.text) { + case "param": + return handleParamTag(atToken, tagName); + case "return": + case "returns": + return handleReturnTag(atToken, tagName); + case "template": + return handleTemplateTag(atToken, tagName); + case "type": + return handleTypeTag(atToken, tagName); + } + } + return undefined; + } + function handleUnknownTag(atToken, tagName) { + var result = createNode(246 /* JSDocTag */, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + return finishNode(result, pos); + } + function addTag(tag) { + if (tag) { + if (!tags) { + tags = []; + tags.pos = tag.pos; + } + tags.push(tag); + tags.end = tag.end; + } + } + function tryParseTypeExpression() { + skipWhitespace(); + if (content.charCodeAt(pos) !== 123 /* openBrace */) { + return undefined; + } + var typeExpression = parseJSDocTypeExpression(pos, end - pos); + pos = typeExpression.end; + return typeExpression; + } + function handleParamTag(atToken, tagName) { + var typeExpression = tryParseTypeExpression(); + skipWhitespace(); + var name; + var isBracketed; + if (content.charCodeAt(pos) === 91 /* openBracket */) { + pos++; + skipWhitespace(); + name = scanIdentifier(); + isBracketed = true; + } + else { + name = scanIdentifier(); + } + if (!name) { + parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); + return undefined; + } + var preName, postName; + if (typeExpression) { + postName = name; + } + else { + preName = name; + } + if (!typeExpression) { + typeExpression = tryParseTypeExpression(); + } + var result = createNode(247 /* JSDocParameterTag */, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.preParameterName = preName; + result.typeExpression = typeExpression; + result.postParameterName = postName; + result.isBracketed = isBracketed; + return finishNode(result, pos); + } + function handleReturnTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 248 /* JSDocReturnTag */; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var result = createNode(248 /* JSDocReturnTag */, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeExpression = tryParseTypeExpression(); + return finishNode(result, pos); + } + function handleTypeTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 249 /* JSDocTypeTag */; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var result = createNode(249 /* JSDocTypeTag */, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeExpression = tryParseTypeExpression(); + return finishNode(result, pos); + } + function handleTemplateTag(atToken, tagName) { + if (ts.forEach(tags, function (t) { return t.kind === 250 /* JSDocTemplateTag */; })) { + parseErrorAtPosition(tagName.pos, pos - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.text); + } + var typeParameters = []; + typeParameters.pos = pos; + while (true) { + skipWhitespace(); + var startPos = pos; + var name_6 = scanIdentifier(); + if (!name_6) { + parseErrorAtPosition(startPos, 0, ts.Diagnostics.Identifier_expected); + return undefined; + } + var typeParameter = createNode(129 /* TypeParameter */, name_6.pos); + typeParameter.name = name_6; + finishNode(typeParameter, pos); + typeParameters.push(typeParameter); + skipWhitespace(); + if (content.charCodeAt(pos) !== 44 /* comma */) { + break; + } + pos++; + } + typeParameters.end = pos; + var result = createNode(250 /* JSDocTemplateTag */, atToken.pos); + result.atToken = atToken; + result.tagName = tagName; + result.typeParameters = typeParameters; + return finishNode(result, pos); + } + function scanIdentifier() { + var startPos = pos; + for (; pos < end; pos++) { + var ch = content.charCodeAt(pos); + if (pos === startPos && ts.isIdentifierStart(ch, 2 /* Latest */)) { + continue; + } + else if (pos > startPos && ts.isIdentifierPart(ch, 2 /* Latest */)) { + continue; + } + break; + } + if (startPos === pos) { + return undefined; + } + var result = createNode(65 /* Identifier */, startPos); + result.text = content.substring(startPos, pos); + return finishNode(result, pos); + } + } + JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker; + })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {})); })(Parser || (Parser = {})); var IncrementalParser; (function (IncrementalParser) { @@ -10379,7 +11270,12 @@ var ts; } // Ditch any existing LS children we may have created. This way we can avoid // moving them forward. - node._children = undefined; + if (node._children) { + node._children = undefined; + } + if (node.jsDocComment) { + node.jsDocComment = undefined; + } node.pos += delta; node.end += delta; if (aggressiveChecks && shouldCheckNode(node)) { @@ -10839,13 +11735,15 @@ var ts; var undefinedType = createIntrinsicType(32 /* Undefined */ | 262144 /* ContainsUndefinedOrNull */, "undefined"); var nullType = createIntrinsicType(64 /* Null */ | 262144 /* ContainsUndefinedOrNull */, "null"); var unknownType = createIntrinsicType(1 /* Any */, "unknown"); + var circularType = createIntrinsicType(1 /* Any */, "__circular__"); var emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + var emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + emptyGenericType.instantiations = {}; var anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); var noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); var anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, false, false); var unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false); var globals = {}; - var globalArraySymbol; var globalESSymbolConstructorSymbol; var globalObjectType; var globalFunctionType; @@ -10857,6 +11755,8 @@ var ts; var globalTemplateStringsArrayType; var globalESSymbolType; var globalIterableType; + var globalIteratorType; + var globalIterableIteratorType; var anyArrayType; var getGlobalClassDecoratorType; var getGlobalParameterDecoratorType; @@ -11083,7 +11983,15 @@ var ts; // Locals of a source file are not in scope (because they get merged into the global symbol table) if (location.locals && !isGlobalSourceFile(location)) { if (result = getSymbol(location.locals, name, meaning)) { - break loop; + // Type parameters of a function are in scope in the entire function declaration, including the parameter + // list and return type. However, local types are only in scope in the function body. + if (!(meaning & 793056 /* Type */) || + !(result.flags & (793056 /* Type */ & ~262144 /* TypeParameter */)) || + !ts.isFunctionLike(location) || + lastLocation === location.body) { + break loop; + } + result = undefined; } } switch (location.kind) { @@ -11385,15 +12293,15 @@ var ts; var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier); var targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier); if (targetSymbol) { - var name_4 = specifier.propertyName || specifier.name; - if (name_4.text) { - var symbolFromModule = getExportOfModule(targetSymbol, name_4.text); - var symbolFromVariable = getPropertyOfVariable(targetSymbol, name_4.text); + var name_7 = specifier.propertyName || specifier.name; + if (name_7.text) { + var symbolFromModule = getExportOfModule(targetSymbol, name_7.text); + var symbolFromVariable = getPropertyOfVariable(targetSymbol, name_7.text); var symbol = symbolFromModule && symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { - error(name_4, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name_4)); + error(name_7, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name_7)); } return symbol; } @@ -12150,17 +13058,54 @@ var ts; writeType(types[i], union ? 64 /* InElementType */ : 0 /* None */); } } + function writeSymbolTypeReference(symbol, typeArguments, pos, end) { + // Unnamed function expressions, arrow functions, and unnamed class expressions have reserved names that + // we don't want to display + if (!isReservedMemberName(symbol.name)) { + buildSymbolDisplay(symbol, writer, enclosingDeclaration, 793056 /* Type */); + } + if (pos < end) { + writePunctuation(writer, 24 /* LessThanToken */); + writeType(typeArguments[pos++], 0 /* None */); + while (pos < end) { + writePunctuation(writer, 23 /* CommaToken */); + writeSpace(writer); + writeType(typeArguments[pos++], 0 /* None */); + } + writePunctuation(writer, 25 /* GreaterThanToken */); + } + } function writeTypeReference(type, flags) { + var typeArguments = type.typeArguments; if (type.target === globalArrayType && !(flags & 1 /* WriteArrayAsGenericType */)) { - writeType(type.typeArguments[0], 64 /* InElementType */); + writeType(typeArguments[0], 64 /* InElementType */); writePunctuation(writer, 18 /* OpenBracketToken */); writePunctuation(writer, 19 /* CloseBracketToken */); } else { - buildSymbolDisplay(type.target.symbol, writer, enclosingDeclaration, 793056 /* Type */); - writePunctuation(writer, 24 /* LessThanToken */); - writeTypeList(type.typeArguments, false); - writePunctuation(writer, 25 /* GreaterThanToken */); + // Write the type reference in the format f.g.C where A and B are type arguments + // for outer type parameters, and f and g are the respective declaring containers of those + // type parameters. + var outerTypeParameters = type.target.outerTypeParameters; + var i = 0; + if (outerTypeParameters) { + var length_1 = outerTypeParameters.length; + while (i < length_1) { + // Find group of type arguments for type parameters with the same declaring container. + var start = i; + var parent_3 = getParentSymbolOfTypeParameter(outerTypeParameters[i]); + do { + i++; + } while (i < length_1 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent_3); + // When type parameters are their own type arguments for the whole group (i.e. we have + // the default outer type arguments), we don't show the group. + if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) { + writeSymbolTypeReference(parent_3, typeArguments, start, i); + writePunctuation(writer, 20 /* DotToken */); + } + } + } + writeSymbolTypeReference(type.symbol, typeArguments, i, typeArguments.length); } } function writeTupleType(type) { @@ -12348,7 +13293,7 @@ var ts; function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */) { - buildDisplayForTypeParametersAndDelimiters(getTypeParametersOfClassOrInterface(symbol), writer, enclosingDeclaraiton, flags); + buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterface(symbol), writer, enclosingDeclaraiton, flags); } } function buildTypeParameterDisplay(tp, writer, enclosingDeclaration, flags, typeStack) { @@ -12521,14 +13466,14 @@ var ts; case 201 /* FunctionDeclaration */: case 205 /* EnumDeclaration */: case 209 /* ImportEqualsDeclaration */: - var parent_2 = getDeclarationContainer(node); + var parent_4 = getDeclarationContainer(node); // If the node is not exported or it is not ambient module element (except import declaration) if (!(ts.getCombinedNodeFlags(node) & 1 /* Export */) && - !(node.kind !== 209 /* ImportEqualsDeclaration */ && parent_2.kind !== 228 /* SourceFile */ && ts.isInAmbientContext(parent_2))) { - return isGlobalSourceFile(parent_2); + !(node.kind !== 209 /* ImportEqualsDeclaration */ && parent_4.kind !== 228 /* SourceFile */ && ts.isInAmbientContext(parent_4))) { + return isGlobalSourceFile(parent_4); } // Exported members/ambient module elements (exception import declaration) are visible if parent is visible - return isDeclarationVisible(parent_2); + return isDeclarationVisible(parent_4); case 133 /* PropertyDeclaration */: case 132 /* PropertySignature */: case 137 /* GetAccessor */: @@ -12679,14 +13624,14 @@ var ts; var type; if (pattern.kind === 151 /* ObjectBindingPattern */) { // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form) - var name_5 = declaration.propertyName || declaration.name; + var name_8 = declaration.propertyName || declaration.name; // Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature, // or otherwise the type of the string index signature. - type = getTypeOfPropertyOfType(parentType, name_5.text) || - isNumericLiteralName(name_5.text) && getIndexTypeOfType(parentType, 1 /* Number */) || + type = getTypeOfPropertyOfType(parentType, name_8.text) || + isNumericLiteralName(name_8.text) && getIndexTypeOfType(parentType, 1 /* Number */) || getIndexTypeOfType(parentType, 0 /* String */); if (!type) { - error(name_5, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_5)); + error(name_8, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_8)); return unknownType; } } @@ -12731,7 +13676,7 @@ var ts; // checkRightHandSideOfForOf will return undefined if the for-of expression type was // missing properties/signatures required to get its iteratedType (like // [Symbol.iterator] or next). This may be because we accessed properties from anyType, - // or it may have led to an error inside getIteratedType. + // or it may have led to an error inside getElementTypeOfIterable. return checkRightHandSideOfForOf(declaration.parent.parent.expression) || anyType; } if (ts.isBindingPattern(declaration.parent)) { @@ -13024,29 +13969,65 @@ var ts; return target === checkBase || ts.forEach(getBaseTypes(target), check); } } - // Return combined list of type parameters from all declarations of a class or interface. Elsewhere we check they're all - // the same, but even if they're not we still need the complete list to ensure instantiations supply type arguments - // for all type parameters. - function getTypeParametersOfClassOrInterface(symbol) { - var result; - ts.forEach(symbol.declarations, function (node) { - if (node.kind === 203 /* InterfaceDeclaration */ || node.kind === 202 /* ClassDeclaration */) { - var declaration = node; - if (declaration.typeParameters && declaration.typeParameters.length) { - ts.forEach(declaration.typeParameters, function (node) { - var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node)); - if (!result) { - result = [tp]; - } - else if (!ts.contains(result, tp)) { - result.push(tp); - } - }); + // Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set. + // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set + // in-place and returns the same array. + function appendTypeParameters(typeParameters, declarations) { + for (var _i = 0; _i < declarations.length; _i++) { + var declaration = declarations[_i]; + var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); + if (!typeParameters) { + typeParameters = [tp]; + } + else if (!ts.contains(typeParameters, tp)) { + typeParameters.push(tp); + } + } + return typeParameters; + } + // Appends the outer type parameters of a node to a set of type parameters and returns the resulting set. The function + // allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set in-place and + // returns the same array. + function appendOuterTypeParameters(typeParameters, node) { + while (true) { + node = node.parent; + if (!node) { + return typeParameters; + } + if (node.kind === 202 /* ClassDeclaration */ || node.kind === 201 /* FunctionDeclaration */ || + node.kind === 163 /* FunctionExpression */ || node.kind === 135 /* MethodDeclaration */ || + node.kind === 164 /* ArrowFunction */) { + var declarations = node.typeParameters; + if (declarations) { + return appendTypeParameters(appendOuterTypeParameters(typeParameters, node), declarations); } } - }); + } + } + // The outer type parameters are those defined by enclosing generic classes, methods, or functions. + function getOuterTypeParametersOfClassOrInterface(symbol) { + var kind = symbol.flags & 32 /* Class */ ? 202 /* ClassDeclaration */ : 203 /* InterfaceDeclaration */; + return appendOuterTypeParameters(undefined, ts.getDeclarationOfKind(symbol, kind)); + } + // The local type parameters are the combined set of type parameters from all declarations of the class or interface. + function getLocalTypeParametersOfClassOrInterface(symbol) { + var result; + for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { + var node = _a[_i]; + if (node.kind === 203 /* InterfaceDeclaration */ || node.kind === 202 /* ClassDeclaration */) { + var declaration = node; + if (declaration.typeParameters) { + result = appendTypeParameters(result, declaration.typeParameters); + } + } + } return result; } + // The full set of type parameters for a generic class or interface type consists of its outer type parameters plus + // its locally declared type parameters. + function getTypeParametersOfClassOrInterface(symbol) { + return ts.concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterface(symbol)); + } function getBaseTypes(type) { var typeWithBaseTypes = type; if (!typeWithBaseTypes.baseTypes) { @@ -13113,10 +14094,13 @@ var ts; if (!links.declaredType) { var kind = symbol.flags & 32 /* Class */ ? 1024 /* Class */ : 2048 /* Interface */; var type = links.declaredType = createObjectType(kind, symbol); - var typeParameters = getTypeParametersOfClassOrInterface(symbol); - if (typeParameters) { + var outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol); + var localTypeParameters = getLocalTypeParametersOfClassOrInterface(symbol); + if (outerTypeParameters || localTypeParameters) { type.flags |= 4096 /* Reference */; - type.typeParameters = typeParameters; + type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters); + type.outerTypeParameters = outerTypeParameters; + type.localTypeParameters = localTypeParameters; type.instantiations = {}; type.instantiations[getTypeListId(type.typeParameters)] = type; type.target = type; @@ -13294,12 +14278,12 @@ var ts; return ts.map(baseSignatures, function (baseSignature) { var signature = baseType.flags & 4096 /* Reference */ ? getSignatureInstantiation(baseSignature, baseType.typeArguments) : cloneSignature(baseSignature); - signature.typeParameters = classType.typeParameters; + signature.typeParameters = classType.localTypeParameters; signature.resolvedReturnType = classType; return signature; }); } - return [createSignature(undefined, classType.typeParameters, emptyArray, classType, 0, false, false)]; + return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, 0, false, false)]; } function createTupleTypeMemberSymbols(memberTypes) { var members = {}; @@ -13627,7 +14611,7 @@ var ts; var links = getNodeLinks(declaration); if (!links.resolvedSignature) { var classType = declaration.kind === 136 /* Constructor */ ? getDeclaredTypeOfClassOrInterface(declaration.parent.symbol) : undefined; - var typeParameters = classType ? classType.typeParameters : + var typeParameters = classType ? classType.localTypeParameters : declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) : undefined; var parameters = []; var hasStringLiterals = false; @@ -13814,6 +14798,9 @@ var ts; } return type.constraint === noConstraintType ? undefined : type.constraint; } + function getParentSymbolOfTypeParameter(typeParameter) { + return getSymbolOfNode(ts.getDeclarationOfKind(typeParameter.symbol, 129 /* TypeParameter */).parent); + } function getTypeListId(types) { switch (types.length) { case 1: @@ -13919,12 +14906,21 @@ var ts; else { type = getDeclaredTypeOfSymbol(symbol); if (type.flags & (1024 /* Class */ | 2048 /* Interface */) && type.flags & 4096 /* Reference */) { - var typeParameters = type.typeParameters; - if (node.typeArguments && node.typeArguments.length === typeParameters.length) { - type = createTypeReference(type, ts.map(node.typeArguments, getTypeFromTypeNode)); + // In a type reference, the outer type parameters of the referenced class or interface are automatically + // supplied as type arguments and the type reference only specifies arguments for the local type parameters + // of the class or interface. + var localTypeParameters = type.localTypeParameters; + var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; + var typeArgCount = node.typeArguments ? node.typeArguments.length : 0; + if (typeArgCount === expectedTypeArgCount) { + // When no type arguments are expected we already have the right type because all outer type parameters + // have themselves as default type arguments. + if (typeArgCount) { + type = createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(node.typeArguments, getTypeFromTypeNode))); + } } else { - error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1 /* WriteArrayAsGenericType */), typeParameters.length); + error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1 /* WriteArrayAsGenericType */), expectedTypeArgCount); type = undefined; } } @@ -13966,16 +14962,16 @@ var ts; } } if (!symbol) { - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } var type = getDeclaredTypeOfSymbol(symbol); if (!(type.flags & 48128 /* ObjectType */)) { error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, symbol.name); - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } if ((type.typeParameters ? type.typeParameters.length : 0) !== arity) { error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbol.name, arity); - return emptyObjectType; + return arity ? emptyGenericType : emptyObjectType; } return type; } @@ -13995,15 +14991,20 @@ var ts; function getGlobalESSymbolConstructorSymbol() { return globalESSymbolConstructorSymbol || (globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol")); } + /** + * Instantiates a global type that is generic with some element type, and returns that instantiation. + */ + function createTypeFromGenericGlobalType(genericGlobalType, elementType) { + return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, [elementType]) : emptyObjectType; + } function createIterableType(elementType) { - return globalIterableType !== emptyObjectType ? createTypeReference(globalIterableType, [elementType]) : emptyObjectType; + return createTypeFromGenericGlobalType(globalIterableType, elementType); + } + function createIterableIteratorType(elementType) { + return createTypeFromGenericGlobalType(globalIterableIteratorType, elementType); } function createArrayType(elementType) { - // globalArrayType will be undefined if we get here during creation of the Array type. This for example happens if - // user code augments the Array type with call or construct signatures that have an array type as the return type. - // We instead use globalArraySymbol to obtain the (not yet fully constructed) Array type. - var arrayType = globalArrayType || getDeclaredTypeOfSymbol(globalArraySymbol); - return arrayType !== emptyObjectType ? createTypeReference(arrayType, [elementType]) : emptyObjectType; + return createTypeFromGenericGlobalType(globalArrayType, elementType); } function getTypeFromArrayTypeNode(node) { var links = getNodeLinks(node); @@ -14058,17 +15059,7 @@ var ts; } return false; } - // Since removeSubtypes checks the subtype relation, and the subtype relation on a union - // may attempt to reduce a union, it is possible that removeSubtypes could be called - // recursively on the same set of types. The removeSubtypesStack is used to track which - // sets of types are currently undergoing subtype reduction. - var removeSubtypesStack = []; function removeSubtypes(types) { - var typeListId = getTypeListId(types); - if (removeSubtypesStack.lastIndexOf(typeListId) >= 0) { - return; - } - removeSubtypesStack.push(typeListId); var i = types.length; while (i > 0) { i--; @@ -14076,7 +15067,6 @@ var ts; types.splice(i, 1); } } - removeSubtypesStack.pop(); } function containsAnyType(types) { for (var _i = 0; _i < types.length; _i++) { @@ -14128,10 +15118,20 @@ var ts; } return type; } + // Subtype reduction is basically an optimization we do to avoid excessively large union types, which take longer + // to process and look strange in quick info and error messages. Semantically there is no difference between the + // reduced type and the type itself. So, when we detect a circularity we simply say that the reduced type is the + // type itself. function getReducedTypeOfUnionType(type) { - // If union type was created without subtype reduction, perform the deferred reduction now if (!type.reducedType) { - type.reducedType = getUnionType(type.types, false); + type.reducedType = circularType; + var reducedType = getUnionType(type.types, false); + if (type.reducedType === circularType) { + type.reducedType = reducedType; + } + } + else if (type.reducedType === circularType) { + type.reducedType = type; } return type.reducedType; } @@ -14323,6 +15323,18 @@ var ts; return result; } function instantiateAnonymousType(type, mapper) { + // If this type has already been instantiated using this mapper, returned the cached result. This guards against + // infinite instantiations of cyclic types, e.g. "var x: { a: T, b: typeof x };" + if (mapper.mappings) { + var cached = mapper.mappings[type.id]; + if (cached) { + return cached; + } + } + else { + mapper.mappings = {}; + } + // Instantiate the given type using the given mapper and cache the result var result = createObjectType(32768 /* Anonymous */, type.symbol); result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol); result.members = createSymbolTable(result.properties); @@ -14334,6 +15346,7 @@ var ts; result.stringIndexType = instantiateType(stringIndexType, mapper); if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper); + mapper.mappings[type.id] = result; return result; } function instantiateType(type, mapper) { @@ -14342,7 +15355,7 @@ var ts; return mapper(type); } if (type.flags & 32768 /* Anonymous */) { - return type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) ? + return type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) ? instantiateAnonymousType(type, mapper) : type; } if (type.flags & 4096 /* Reference */) { @@ -15617,10 +16630,10 @@ var ts; // Resolve location from top down towards node if it is a context sensitive expression // That helps in making sure not assigning types as any when resolved out of order var containerNodes = []; - for (var parent_3 = node.parent; parent_3; parent_3 = parent_3.parent) { - if ((ts.isExpression(parent_3) || ts.isObjectLiteralMethod(node)) && - isContextSensitive(parent_3)) { - containerNodes.unshift(parent_3); + for (var parent_5 = node.parent; parent_5; parent_5 = parent_5.parent) { + if ((ts.isExpression(parent_5) || ts.isObjectLiteralMethod(node)) && + isContextSensitive(parent_5)) { + containerNodes.unshift(parent_5); } } ts.forEach(containerNodes, function (node) { getTypeOfNode(node); }); @@ -16105,22 +17118,40 @@ var ts; return undefined; } function getContextualTypeForReturnExpression(node) { + var func = ts.getContainingFunction(node); + if (func && !func.asteriskToken) { + return getContextualReturnType(func); + } + return undefined; + } + function getContextualTypeForYieldOperand(node) { var func = ts.getContainingFunction(node); if (func) { - // If the containing function has a return type annotation, is a constructor, or is a get accessor whose - // corresponding set accessor has a type annotation, return statements in the function are contextually typed - if (func.type || func.kind === 136 /* Constructor */ || func.kind === 137 /* GetAccessor */ && getSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(func.symbol, 138 /* SetAccessor */))) { - return getReturnTypeOfSignature(getSignatureFromDeclaration(func)); - } - // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature - // and that call signature is non-generic, return statements are contextually typed by the return type of the signature - var signature = getContextualSignatureForFunctionLikeDeclaration(func); - if (signature) { - return getReturnTypeOfSignature(signature); + var contextualReturnType = getContextualReturnType(func); + if (contextualReturnType) { + return node.asteriskToken + ? contextualReturnType + : getElementTypeOfIterableIterator(contextualReturnType); } } return undefined; } + function getContextualReturnType(functionDecl) { + // If the containing function has a return type annotation, is a constructor, or is a get accessor whose + // corresponding set accessor has a type annotation, return statements in the function are contextually typed + if (functionDecl.type || + functionDecl.kind === 136 /* Constructor */ || + functionDecl.kind === 137 /* GetAccessor */ && getSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(functionDecl.symbol, 138 /* SetAccessor */))) { + return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl)); + } + // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature + // and that call signature is non-generic, return statements are contextually typed by the return type of the signature + var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); + if (signature) { + return getReturnTypeOfSignature(signature); + } + return undefined; + } // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter. function getContextualTypeForArgument(callTarget, arg) { var args = getEffectiveCallArguments(callTarget); @@ -16242,7 +17273,7 @@ var ts; var index = ts.indexOf(arrayLiteral.elements, node); return getTypeOfPropertyOfContextualType(type, "" + index) || getIndexTypeOfContextualType(type, 1 /* Number */) - || (languageVersion >= 2 /* ES6 */ ? checkIteratedType(type, undefined) : undefined); + || (languageVersion >= 2 /* ES6 */ ? getElementTypeOfIterable(type, undefined) : undefined); } return undefined; } @@ -16272,6 +17303,8 @@ var ts; case 164 /* ArrowFunction */: case 192 /* ReturnStatement */: return getContextualTypeForReturnExpression(node); + case 173 /* YieldExpression */: + return getContextualTypeForYieldOperand(parent); case 158 /* CallExpression */: case 159 /* NewExpression */: return getContextualTypeForArgument(parent, node); @@ -16308,8 +17341,10 @@ var ts; return node.kind === 163 /* FunctionExpression */ || node.kind === 164 /* ArrowFunction */; } function getContextualSignatureForFunctionLikeDeclaration(node) { - // Only function expressions and arrow functions are contextually typed. - return isFunctionExpressionOrArrowFunction(node) ? getContextualSignature(node) : undefined; + // Only function expressions, arrow functions, and object literal methods are contextually typed. + return isFunctionExpressionOrArrowFunction(node) || ts.isObjectLiteralMethod(node) + ? getContextualSignature(node) + : undefined; } // Return the contextual signature for a given expression node. A contextual type provides a // contextual signature if it has a single call signature and if that call signature is non-generic. @@ -16419,7 +17454,7 @@ var ts; // if there is no index type / iterated type. var restArrayType = checkExpression(e.expression, contextualMapper); var restElementType = getIndexTypeOfType(restArrayType, 1 /* Number */) || - (languageVersion >= 2 /* ES6 */ ? checkIteratedType(restArrayType, undefined) : undefined); + (languageVersion >= 2 /* ES6 */ ? getElementTypeOfIterable(restArrayType, undefined) : undefined); if (restElementType) { elementTypes.push(restElementType); } @@ -16707,15 +17742,15 @@ var ts; // - Otherwise, if IndexExpr is of type Any, the String or Number primitive type, or an enum type, the property access is of type Any. // See if we can index as a property. if (node.argumentExpression) { - var name_6 = getPropertyNameForIndexedAccess(node.argumentExpression, indexType); - if (name_6 !== undefined) { - var prop = getPropertyOfType(objectType, name_6); + var name_9 = getPropertyNameForIndexedAccess(node.argumentExpression, indexType); + if (name_9 !== undefined) { + var prop = getPropertyOfType(objectType, name_9); if (prop) { getNodeLinks(node).resolvedSymbol = prop; return getTypeOfSymbol(prop); } else if (isConstEnum) { - error(node.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_const_enum_1, name_6, symbolToString(objectType.symbol)); + error(node.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_const_enum_1, name_9, symbolToString(objectType.symbol)); return unknownType; } } @@ -16836,13 +17871,13 @@ var ts; for (var _i = 0; _i < signatures.length; _i++) { var signature = signatures[_i]; var symbol = signature.declaration && getSymbolOfNode(signature.declaration); - var parent_4 = signature.declaration && signature.declaration.parent; + var parent_6 = signature.declaration && signature.declaration.parent; if (!lastSymbol || symbol === lastSymbol) { - if (lastParent && parent_4 === lastParent) { + if (lastParent && parent_6 === lastParent) { index++; } else { - lastParent = parent_4; + lastParent = parent_6; index = cutoffIndex; } } @@ -16850,7 +17885,7 @@ var ts; // current declaration belongs to a different symbol // set cutoffIndex so re-orderings in the future won't change result set from 0 to cutoffIndex index = cutoffIndex = result.length; - lastParent = parent_4; + lastParent = parent_6; } lastSymbol = symbol; // specialized signatures always need to be placed before non-specialized signatures regardless @@ -17335,10 +18370,10 @@ var ts; return resolveCall(node, callSignatures, candidatesOutArray); } function resolveNewExpression(node, candidatesOutArray) { - if (node.arguments && languageVersion < 2 /* ES6 */) { + if (node.arguments && languageVersion < 1 /* ES5 */) { var spreadIndex = getSpreadArgumentIndex(node.arguments); if (spreadIndex >= 0) { - error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_6_and_higher); + error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher); } } var expressionType = checkExpression(node.expression); @@ -17354,7 +18389,7 @@ var ts; // If ConstructExpr's apparent type(section 3.8.1) is an object type with one or // more construct signatures, the expression is processed in the same manner as a // function call, but using the construct signatures as the initial set of candidate - // signatures for overload resolution.The result type of the function call becomes + // signatures for overload resolution. The result type of the function call becomes // the result type of the operation. expressionType = getApparentType(expressionType); if (expressionType === unknownType) { @@ -17490,17 +18525,39 @@ var ts; type = checkExpressionCached(func.body, contextualMapper); } else { - // Aggregate the types of expressions within all the return statements. - var types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper); - if (types.length === 0) { - return voidType; + var types; + var funcIsGenerator = !!func.asteriskToken; + if (funcIsGenerator) { + types = checkAndAggregateYieldOperandTypes(func.body, contextualMapper); + if (types.length === 0) { + var iterableIteratorAny = createIterableIteratorType(anyType); + if (compilerOptions.noImplicitAny) { + error(func.asteriskToken, ts.Diagnostics.Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type, typeToString(iterableIteratorAny)); + } + return iterableIteratorAny; + } } - // When return statements are contextually typed we allow the return type to be a union type. Otherwise we require the - // return expressions to have a best common supertype. + else { + types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper); + if (types.length === 0) { + return voidType; + } + } + // When yield/return statements are contextually typed we allow the return type to be a union type. + // Otherwise we require the yield/return expressions to have a best common supertype. type = contextualSignature ? getUnionType(types) : getCommonSupertype(types); if (!type) { - error(func, ts.Diagnostics.No_best_common_type_exists_among_return_expressions); - return unknownType; + if (funcIsGenerator) { + error(func, ts.Diagnostics.No_best_common_type_exists_among_yield_expressions); + return createIterableIteratorType(unknownType); + } + else { + error(func, ts.Diagnostics.No_best_common_type_exists_among_return_expressions); + return unknownType; + } + } + if (funcIsGenerator) { + type = createIterableIteratorType(type); } } if (!contextualSignature) { @@ -17508,7 +18565,23 @@ var ts; } return getWidenedType(type); } - /// Returns a set of types relating to every return expression relating to a function block. + function checkAndAggregateYieldOperandTypes(body, contextualMapper) { + var aggregatedTypes = []; + ts.forEachYieldExpression(body, function (yieldExpression) { + var expr = yieldExpression.expression; + if (expr) { + var type = checkExpressionCached(expr, contextualMapper); + if (yieldExpression.asteriskToken) { + // A yield* expression effectively yields everything that its operand yields + type = checkElementTypeOfIterable(type, yieldExpression.expression); + } + if (!ts.contains(aggregatedTypes, type)) { + aggregatedTypes.push(type); + } + } + }); + return aggregatedTypes; + } function checkAndAggregateReturnExpressionTypes(body, contextualMapper) { var aggregatedTypes = []; ts.forEachReturnStatement(body, function (returnStatement) { @@ -17677,8 +18750,8 @@ var ts; var index = n.argumentExpression; var symbol = findSymbol(n.expression); if (symbol && index && index.kind === 8 /* StringLiteral */) { - var name_7 = index.text; - var prop = getPropertyOfType(getTypeOfSymbol(symbol), name_7); + var name_10 = index.text; + var prop = getPropertyOfType(getTypeOfSymbol(symbol), name_10); return prop && (prop.flags & 3 /* Variable */) !== 0 && (getDeclarationFlagsFromSymbol(prop) & 8192 /* Const */) !== 0; } return false; @@ -17836,16 +18909,16 @@ var ts; var p = properties[_i]; if (p.kind === 225 /* PropertyAssignment */ || p.kind === 226 /* ShorthandPropertyAssignment */) { // TODO(andersh): Computed property support - var name_8 = p.name; + var name_11 = p.name; var type = sourceType.flags & 1 /* Any */ ? sourceType : - getTypeOfPropertyOfType(sourceType, name_8.text) || - isNumericLiteralName(name_8.text) && getIndexTypeOfType(sourceType, 1 /* Number */) || + getTypeOfPropertyOfType(sourceType, name_11.text) || + isNumericLiteralName(name_11.text) && getIndexTypeOfType(sourceType, 1 /* Number */) || getIndexTypeOfType(sourceType, 0 /* String */); if (type) { - checkDestructuringAssignment(p.initializer || name_8, type); + checkDestructuringAssignment(p.initializer || name_11, type); } else { - error(name_8, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), ts.declarationNameToString(name_8)); + error(name_11, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), ts.declarationNameToString(name_11)); } } else { @@ -18095,14 +19168,53 @@ var ts; error(node, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(node.operatorToken.kind), typeToString(leftType), typeToString(rightType)); } } + function isYieldExpressionInClass(node) { + var current = node; + var parent = node.parent; + while (parent) { + if (ts.isFunctionLike(parent) && current === parent.body) { + return false; + } + else if (current.kind === 202 /* ClassDeclaration */ || current.kind === 175 /* ClassExpression */) { + return true; + } + current = parent; + parent = parent.parent; + } + return false; + } function checkYieldExpression(node) { // Grammar checking - if (!(node.parserContextFlags & 4 /* Yield */)) { - grammarErrorOnFirstToken(node, ts.Diagnostics.yield_expression_must_be_contained_within_a_generator_declaration); + if (!(node.parserContextFlags & 4 /* Yield */) || isYieldExpressionInClass(node)) { + grammarErrorOnFirstToken(node, ts.Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body); } - else { - grammarErrorOnFirstToken(node, ts.Diagnostics.yield_expressions_are_not_currently_supported); + if (node.expression) { + var func = ts.getContainingFunction(node); + // If the user's code is syntactically correct, the func should always have a star. After all, + // we are in a yield context. + if (func && func.asteriskToken) { + var expressionType = checkExpressionCached(node.expression, undefined); + var expressionElementType; + var nodeIsYieldStar = !!node.asteriskToken; + if (nodeIsYieldStar) { + expressionElementType = checkElementTypeOfIterable(expressionType, node.expression); + } + // There is no point in doing an assignability check if the function + // has no explicit return type because the return type is directly computed + // from the yield expressions. + if (func.type) { + var signatureElementType = getElementTypeOfIterableIterator(getTypeFromTypeNode(func.type)) || anyType; + if (nodeIsYieldStar) { + checkTypeAssignableTo(expressionElementType, signatureElementType, node.expression, undefined); + } + else { + checkTypeAssignableTo(expressionType, signatureElementType, node.expression, undefined); + } + } + } } + // Both yield and yield* expressions have type 'any' + return anyType; } function checkConditionalExpression(node, contextualMapper) { checkExpression(node.condition); @@ -18273,8 +19385,7 @@ var ts; case 176 /* OmittedExpression */: return undefinedType; case 173 /* YieldExpression */: - checkYieldExpression(node); - return unknownType; + return checkYieldExpression(node); } return unknownType; } @@ -18318,6 +19429,14 @@ var ts; error(node, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type); } } + function isSyntacticallyValidGenerator(node) { + if (!node.asteriskToken || !node.body) { + return false; + } + return node.kind === 135 /* MethodDeclaration */ || + node.kind === 201 /* FunctionDeclaration */ || + node.kind === 163 /* FunctionExpression */; + } function checkSignatureDeclaration(node) { // Grammar checking if (node.kind === 141 /* IndexSignature */) { @@ -18345,6 +19464,25 @@ var ts; break; } } + if (node.type) { + if (languageVersion >= 2 /* ES6 */ && isSyntacticallyValidGenerator(node)) { + var returnType = getTypeFromTypeNode(node.type); + if (returnType === voidType) { + error(node.type, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation); + } + else { + var generatorElementType = getElementTypeOfIterableIterator(returnType) || anyType; + var iterableIteratorInstantiation = createIterableIteratorType(generatorElementType); + // Naively, one could check that IterableIterator is assignable to the return type annotation. + // However, that would not catch the error in the following case. + // + // interface BadGenerator extends Iterable, Iterator { } + // function* g(): BadGenerator { } // Iterable and Iterator have different types! + // + checkTypeAssignableTo(iterableIteratorInstantiation, returnType, node.type); + } + } + } } checkSpecializedSignatureDeclaration(node); } @@ -18984,7 +20122,6 @@ var ts; function checkFunctionDeclaration(node) { if (produceDiagnostics) { checkFunctionLikeDeclaration(node) || - checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarFunctionName(node.name) || checkGrammarForGenerator(node); checkCollisionWithCapturedSuperVariable(node, node.name); @@ -19027,10 +20164,18 @@ var ts; if (node.type && !isAccessor(node.kind) && !node.asteriskToken) { checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } - // Report an implicit any error if there is no body, no explicit return type, and node is not a private method - // in an ambient context - if (compilerOptions.noImplicitAny && ts.nodeIsMissing(node.body) && !node.type && !isPrivateWithinAmbient(node)) { - reportImplicitAnyError(node, anyType); + if (produceDiagnostics && !node.type) { + // Report an implicit any error if there is no body, no explicit return type, and node is not a private method + // in an ambient context + if (compilerOptions.noImplicitAny && ts.nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) { + reportImplicitAnyError(node, anyType); + } + if (node.asteriskToken && ts.nodeIsPresent(node.body)) { + // A generator with a body and no type annotation can still cause errors. It can error if the + // yielded values have no common supertype, or it can give an implicit any error if it has no + // yielded values. The only way to trigger these errors is to try checking its return type. + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } } } function checkBlock(node) { @@ -19191,8 +20336,8 @@ var ts; // otherwise if variable has an initializer - show error that initialization will fail // since LHS will be block scoped name instead of function scoped if (!namesShareScope) { - var name_9 = symbolToString(localDeclarationSymbol); - error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name_9, name_9); + var name_12 = symbolToString(localDeclarationSymbol); + error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name_12, name_12); } } } @@ -19302,7 +20447,7 @@ var ts; } function checkVariableStatement(node) { // Grammar checking - checkGrammarDecorators(node) || checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node); + checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node); ts.forEach(node.declarationList.declarations, checkSourceElement); } function checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node) { @@ -19392,7 +20537,7 @@ var ts; // iteratedType will be undefined if the rightType was missing properties/signatures // required to get its iteratedType (like [Symbol.iterator] or next). This may be // because we accessed properties from anyType, or it may have led to an error inside - // getIteratedType. + // getElementTypeOfIterable. if (iteratedType) { checkTypeAssignableTo(iteratedType, leftType, varExpr, undefined); } @@ -19458,7 +20603,7 @@ var ts; return inputType; } if (languageVersion >= 2 /* ES6 */) { - return checkIteratedType(inputType, errorNode) || anyType; + return checkElementTypeOfIterable(inputType, errorNode); } if (allowStringInput) { return checkElementTypeOfArrayOrString(inputType, errorNode); @@ -19475,88 +20620,127 @@ var ts; /** * When errorNode is undefined, it means we should not report any errors. */ - function checkIteratedType(iterable, errorNode) { - ts.Debug.assert(languageVersion >= 2 /* ES6 */); - var iteratedType = getIteratedType(iterable, errorNode); + function checkElementTypeOfIterable(iterable, errorNode) { + var elementType = getElementTypeOfIterable(iterable, errorNode); // Now even though we have extracted the iteratedType, we will have to validate that the type // passed in is actually an Iterable. - if (errorNode && iteratedType) { - checkTypeAssignableTo(iterable, createIterableType(iteratedType), errorNode); + if (errorNode && elementType) { + checkTypeAssignableTo(iterable, createIterableType(elementType), errorNode); } - return iteratedType; - function getIteratedType(iterable, errorNode) { - // We want to treat type as an iterable, and get the type it is an iterable of. The iterable - // must have the following structure (annotated with the names of the variables below): - // - // { // iterable - // [Symbol.iterator]: { // iteratorFunction - // (): { // iterator - // next: { // iteratorNextFunction - // (): { // iteratorNextResult - // value: T // iteratorNextValue - // } - // } - // } - // } - // } - // - // T is the type we are after. At every level that involves analyzing return types - // of signatures, we union the return types of all the signatures. - // - // Another thing to note is that at any step of this process, we could run into a dead end, - // meaning either the property is missing, or we run into the anyType. If either of these things - // happens, we return undefined to signal that we could not find the iterated type. If a property - // is missing, and the previous step did not result in 'any', then we also give an error if the - // caller requested it. Then the caller can decide what to do in the case where there is no iterated - // type. This is different from returning anyType, because that would signify that we have matched the - // whole pattern and that T (above) is 'any'. - if (allConstituentTypesHaveKind(iterable, 1 /* Any */)) { - return undefined; - } + return elementType || anyType; + } + /** + * We want to treat type as an iterable, and get the type it is an iterable of. The iterable + * must have the following structure (annotated with the names of the variables below): + * + * { // iterable + * [Symbol.iterator]: { // iteratorFunction + * (): Iterator + * } + * } + * + * T is the type we are after. At every level that involves analyzing return types + * of signatures, we union the return types of all the signatures. + * + * Another thing to note is that at any step of this process, we could run into a dead end, + * meaning either the property is missing, or we run into the anyType. If either of these things + * happens, we return undefined to signal that we could not find the iterated type. If a property + * is missing, and the previous step did not result in 'any', then we also give an error if the + * caller requested it. Then the caller can decide what to do in the case where there is no iterated + * type. This is different from returning anyType, because that would signify that we have matched the + * whole pattern and that T (above) is 'any'. + */ + function getElementTypeOfIterable(type, errorNode) { + if (type.flags & 1 /* Any */) { + return undefined; + } + var typeAsIterable = type; + if (!typeAsIterable.iterableElementType) { // As an optimization, if the type is instantiated directly using the globalIterableType (Iterable), // then just grab its type argument. - if ((iterable.flags & 4096 /* Reference */) && iterable.target === globalIterableType) { - return iterable.typeArguments[0]; + if ((type.flags & 4096 /* Reference */) && type.target === globalIterableType) { + typeAsIterable.iterableElementType = type.typeArguments[0]; } - var iteratorFunction = getTypeOfPropertyOfType(iterable, ts.getPropertyNameForKnownSymbolName("iterator")); - if (iteratorFunction && allConstituentTypesHaveKind(iteratorFunction, 1 /* Any */)) { - return undefined; - } - var iteratorFunctionSignatures = iteratorFunction ? getSignaturesOfType(iteratorFunction, 0 /* Call */) : emptyArray; - if (iteratorFunctionSignatures.length === 0) { - if (errorNode) { - error(errorNode, ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator); + else { + var iteratorFunction = getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("iterator")); + if (iteratorFunction && iteratorFunction.flags & 1 /* Any */) { + return undefined; } - return undefined; - } - var iterator = getUnionType(ts.map(iteratorFunctionSignatures, getReturnTypeOfSignature)); - if (allConstituentTypesHaveKind(iterator, 1 /* Any */)) { - return undefined; - } - var iteratorNextFunction = getTypeOfPropertyOfType(iterator, "next"); - if (iteratorNextFunction && allConstituentTypesHaveKind(iteratorNextFunction, 1 /* Any */)) { - return undefined; - } - var iteratorNextFunctionSignatures = iteratorNextFunction ? getSignaturesOfType(iteratorNextFunction, 0 /* Call */) : emptyArray; - if (iteratorNextFunctionSignatures.length === 0) { - if (errorNode) { - error(errorNode, ts.Diagnostics.An_iterator_must_have_a_next_method); + var iteratorFunctionSignatures = iteratorFunction ? getSignaturesOfType(iteratorFunction, 0 /* Call */) : emptyArray; + if (iteratorFunctionSignatures.length === 0) { + if (errorNode) { + error(errorNode, ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator); + } + return undefined; } - return undefined; + typeAsIterable.iterableElementType = getElementTypeOfIterator(getUnionType(ts.map(iteratorFunctionSignatures, getReturnTypeOfSignature)), errorNode); } - var iteratorNextResult = getUnionType(ts.map(iteratorNextFunctionSignatures, getReturnTypeOfSignature)); - if (allConstituentTypesHaveKind(iteratorNextResult, 1 /* Any */)) { - return undefined; - } - var iteratorNextValue = getTypeOfPropertyOfType(iteratorNextResult, "value"); - if (!iteratorNextValue) { - if (errorNode) { - error(errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property); - } - return undefined; - } - return iteratorNextValue; } + return typeAsIterable.iterableElementType; + } + /** + * This function has very similar logic as getElementTypeOfIterable, except that it operates on + * Iterators instead of Iterables. Here is the structure: + * + * { // iterator + * next: { // iteratorNextFunction + * (): { // iteratorNextResult + * value: T // iteratorNextValue + * } + * } + * } + * + */ + function getElementTypeOfIterator(type, errorNode) { + if (type.flags & 1 /* Any */) { + return undefined; + } + var typeAsIterator = type; + if (!typeAsIterator.iteratorElementType) { + // As an optimization, if the type is instantiated directly using the globalIteratorType (Iterator), + // then just grab its type argument. + if ((type.flags & 4096 /* Reference */) && type.target === globalIteratorType) { + typeAsIterator.iteratorElementType = type.typeArguments[0]; + } + else { + var iteratorNextFunction = getTypeOfPropertyOfType(type, "next"); + if (iteratorNextFunction && iteratorNextFunction.flags & 1 /* Any */) { + return undefined; + } + var iteratorNextFunctionSignatures = iteratorNextFunction ? getSignaturesOfType(iteratorNextFunction, 0 /* Call */) : emptyArray; + if (iteratorNextFunctionSignatures.length === 0) { + if (errorNode) { + error(errorNode, ts.Diagnostics.An_iterator_must_have_a_next_method); + } + return undefined; + } + var iteratorNextResult = getUnionType(ts.map(iteratorNextFunctionSignatures, getReturnTypeOfSignature)); + if (iteratorNextResult.flags & 1 /* Any */) { + return undefined; + } + var iteratorNextValue = getTypeOfPropertyOfType(iteratorNextResult, "value"); + if (!iteratorNextValue) { + if (errorNode) { + error(errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property); + } + return undefined; + } + typeAsIterator.iteratorElementType = iteratorNextValue; + } + } + return typeAsIterator.iteratorElementType; + } + function getElementTypeOfIterableIterator(type) { + if (type.flags & 1 /* Any */) { + return undefined; + } + // As an optimization, if the type is instantiated directly using the globalIterableIteratorType (IterableIterator), + // then just grab its type argument. + if ((type.flags & 4096 /* Reference */) && type.target === globalIterableIteratorType) { + return type.typeArguments[0]; + } + return getElementTypeOfIterable(type, undefined) || + getElementTypeOfIterator(type, undefined); } /** * This function does the following steps: @@ -19637,19 +20821,24 @@ var ts; if (func) { var returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func)); var exprType = checkExpressionCached(node.expression); + if (func.asteriskToken) { + // A generator does not need its return expressions checked against its return type. + // Instead, the yield expressions are checked against the element type. + // TODO: Check return expressions of generators when return type tracking is added + // for generators. + return; + } if (func.kind === 138 /* SetAccessor */) { error(node.expression, ts.Diagnostics.Setters_cannot_return_a_value); } - else { - if (func.kind === 136 /* Constructor */) { - if (!isTypeAssignableTo(exprType, returnType)) { - error(node.expression, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); - } - } - else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) { - checkTypeAssignableTo(exprType, returnType, node.expression, undefined); + else if (func.kind === 136 /* Constructor */) { + if (!isTypeAssignableTo(exprType, returnType)) { + error(node.expression, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } + else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) { + checkTypeAssignableTo(exprType, returnType, node.expression, undefined); + } } } } @@ -19870,9 +21059,6 @@ var ts; function checkClassDeclaration(node) { checkGrammarDeclarationNameInStrictMode(node); // Grammar checking - if (node.parent.kind !== 207 /* ModuleBlock */ && node.parent.kind !== 228 /* SourceFile */) { - grammarErrorOnNode(node, ts.Diagnostics.class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration); - } if (!node.name && !(node.flags & 256 /* Default */)) { grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } @@ -20978,87 +22164,6 @@ var ts; } return node.parent && node.parent.kind === 177 /* ExpressionWithTypeArguments */; } - function isTypeNode(node) { - if (142 /* FirstTypeNode */ <= node.kind && node.kind <= 150 /* LastTypeNode */) { - return true; - } - switch (node.kind) { - case 112 /* AnyKeyword */: - case 120 /* NumberKeyword */: - case 122 /* StringKeyword */: - case 113 /* BooleanKeyword */: - case 123 /* SymbolKeyword */: - return true; - case 99 /* VoidKeyword */: - return node.parent.kind !== 167 /* VoidExpression */; - case 8 /* StringLiteral */: - // Specialized signatures can have string literals as their parameters' type names - return node.parent.kind === 130 /* Parameter */; - case 177 /* ExpressionWithTypeArguments */: - return true; - // Identifiers and qualified names may be type nodes, depending on their context. Climb - // above them to find the lowest container - case 65 /* Identifier */: - // If the identifier is the RHS of a qualified name, then it's a type iff its parent is. - if (node.parent.kind === 127 /* QualifiedName */ && node.parent.right === node) { - node = node.parent; - } - else if (node.parent.kind === 156 /* PropertyAccessExpression */ && node.parent.name === node) { - node = node.parent; - } - // fall through - case 127 /* QualifiedName */: - case 156 /* PropertyAccessExpression */: - // At this point, node is either a qualified name or an identifier - ts.Debug.assert(node.kind === 65 /* Identifier */ || node.kind === 127 /* QualifiedName */ || node.kind === 156 /* PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isTypeNode'."); - var parent_5 = node.parent; - if (parent_5.kind === 145 /* TypeQuery */) { - return false; - } - // Do not recursively call isTypeNode on the parent. In the example: - // - // let a: A.B.C; - // - // Calling isTypeNode would consider the qualified name A.B a type node. Only C or - // A.B.C is a type node. - if (142 /* FirstTypeNode */ <= parent_5.kind && parent_5.kind <= 150 /* LastTypeNode */) { - return true; - } - switch (parent_5.kind) { - case 177 /* ExpressionWithTypeArguments */: - return true; - case 129 /* TypeParameter */: - return node === parent_5.constraint; - case 133 /* PropertyDeclaration */: - case 132 /* PropertySignature */: - case 130 /* Parameter */: - case 199 /* VariableDeclaration */: - return node === parent_5.type; - case 201 /* FunctionDeclaration */: - case 163 /* FunctionExpression */: - case 164 /* ArrowFunction */: - case 136 /* Constructor */: - case 135 /* MethodDeclaration */: - case 134 /* MethodSignature */: - case 137 /* GetAccessor */: - case 138 /* SetAccessor */: - return node === parent_5.type; - case 139 /* CallSignature */: - case 140 /* ConstructSignature */: - case 141 /* IndexSignature */: - return node === parent_5.type; - case 161 /* TypeAssertionExpression */: - return node === parent_5.type; - case 158 /* CallExpression */: - case 159 /* NewExpression */: - return parent_5.typeArguments && ts.indexOf(parent_5.typeArguments, node) >= 0; - case 160 /* TaggedTemplateExpression */: - // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments. - return false; - } - } - return false; - } function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide) { while (nodeOnRightSide.parent.kind === 127 /* QualifiedName */) { nodeOnRightSide = nodeOnRightSide.parent; @@ -21201,7 +22306,7 @@ var ts; // We cannot answer semantic questions within a with block, do not proceed any further return unknownType; } - if (isTypeNode(node)) { + if (ts.isTypeNode(node)) { return getTypeFromTypeNode(node); } if (ts.isExpression(node)) { @@ -21255,9 +22360,9 @@ var ts; function getRootSymbols(symbol) { if (symbol.flags & 268435456 /* UnionProperty */) { var symbols = []; - var name_10 = symbol.name; + var name_13 = symbol.name; ts.forEach(getSymbolLinks(symbol).unionType.types, function (t) { - symbols.push(getPropertyOfType(t, name_10)); + symbols.push(getPropertyOfType(t, name_13)); }); return symbols; } @@ -21712,8 +22817,7 @@ var ts; getSymbolLinks(unknownSymbol).type = unknownType; globals[undefinedSymbol.name] = undefinedSymbol; // Initialize special types - globalArraySymbol = getGlobalTypeSymbol("Array"); - globalArrayType = getTypeOfGlobalSymbol(globalArraySymbol, 1); + globalArrayType = getGlobalType("Array", 1); globalObjectType = getGlobalType("Object"); globalFunctionType = getGlobalType("Function"); globalStringType = getGlobalType("String"); @@ -21731,6 +22835,8 @@ var ts; globalESSymbolType = getGlobalType("Symbol"); globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol"); globalIterableType = getGlobalType("Iterable", 1); + globalIteratorType = getGlobalType("Iterator", 1); + globalIterableIteratorType = getGlobalType("IterableIterator", 1); } else { globalTemplateStringsArrayType = unknownType; @@ -21739,6 +22845,9 @@ var ts; // a global Symbol already, particularly if it is a class. globalESSymbolType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); globalESSymbolConstructorSymbol = undefined; + globalIterableType = emptyGenericType; + globalIteratorType = emptyGenericType; + globalIterableIteratorType = emptyGenericType; } anyArrayType = createArrayType(anyType); } @@ -21763,20 +22872,20 @@ var ts; if (impotClause.namedBindings) { var nameBindings = impotClause.namedBindings; if (nameBindings.kind === 212 /* NamespaceImport */) { - var name_11 = nameBindings.name; - if (isReservedWordInStrictMode(name_11)) { - var nameText = ts.declarationNameToString(name_11); - return grammarErrorOnNode(name_11, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); + var name_14 = nameBindings.name; + if (isReservedWordInStrictMode(name_14)) { + var nameText = ts.declarationNameToString(name_14); + return grammarErrorOnNode(name_14, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); } } else if (nameBindings.kind === 213 /* NamedImports */) { var reportError = false; for (var _i = 0, _a = nameBindings.elements; _i < _a.length; _i++) { var element = _a[_i]; - var name_12 = element.name; - if (isReservedWordInStrictMode(name_12)) { - var nameText = ts.declarationNameToString(name_12); - reportError = reportError || grammarErrorOnNode(name_12, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); + var name_15 = element.name; + if (isReservedWordInStrictMode(name_15)) { + var nameText = ts.declarationNameToString(name_15); + reportError = reportError || grammarErrorOnNode(name_15, ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode, nameText); } } return reportError; @@ -21902,19 +23011,28 @@ var ts; case 135 /* MethodDeclaration */: case 134 /* MethodSignature */: case 141 /* IndexSignature */: - case 202 /* ClassDeclaration */: - case 203 /* InterfaceDeclaration */: case 206 /* ModuleDeclaration */: - case 205 /* EnumDeclaration */: - case 181 /* VariableStatement */: - case 201 /* FunctionDeclaration */: - case 204 /* TypeAliasDeclaration */: case 210 /* ImportDeclaration */: case 209 /* ImportEqualsDeclaration */: case 216 /* ExportDeclaration */: case 215 /* ExportAssignment */: case 130 /* Parameter */: break; + case 202 /* ClassDeclaration */: + case 203 /* InterfaceDeclaration */: + case 181 /* VariableStatement */: + case 201 /* FunctionDeclaration */: + case 204 /* TypeAliasDeclaration */: + if (node.modifiers && node.parent.kind !== 207 /* ModuleBlock */ && node.parent.kind !== 228 /* SourceFile */) { + return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here); + } + break; + case 205 /* EnumDeclaration */: + if (node.modifiers && (node.modifiers.length > 1 || node.modifiers[0].kind !== 70 /* ConstKeyword */) && + node.parent.kind !== 207 /* ModuleBlock */ && node.parent.kind !== 228 /* SourceFile */) { + return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here); + } + break; default: return false; } @@ -22012,9 +23130,6 @@ var ts; else if ((node.kind === 210 /* ImportDeclaration */ || node.kind === 209 /* ImportEqualsDeclaration */) && flags & 2 /* Ambient */) { return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_declare_modifier_cannot_be_used_with_an_import_declaration, "declare"); } - else if (node.kind === 203 /* InterfaceDeclaration */ && flags & 2 /* Ambient */) { - return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_declare_modifier_cannot_be_used_with_an_interface_declaration, "declare"); - } else if (node.kind === 130 /* Parameter */ && (flags & 112 /* AccessibilityModifier */) && ts.isBindingPattern(node.name)) { return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_may_not_be_a_binding_pattern); } @@ -22231,7 +23346,18 @@ var ts; } function checkGrammarForGenerator(node) { if (node.asteriskToken) { - return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_currently_supported); + ts.Debug.assert(node.kind === 201 /* FunctionDeclaration */ || + node.kind === 163 /* FunctionExpression */ || + node.kind === 135 /* MethodDeclaration */); + if (ts.isInAmbientContext(node)) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_allowed_in_an_ambient_context); + } + if (!node.body) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator); + } + if (languageVersion < 2 /* ES6 */) { + return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_only_available_when_targeting_ECMAScript_6_or_higher); + } } } function checkGrammarFunctionName(name) { @@ -22252,11 +23378,11 @@ var ts; var inStrictMode = (node.parserContextFlags & 1 /* StrictMode */) !== 0; for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var prop = _a[_i]; - var name_13 = prop.name; + var name_16 = prop.name; if (prop.kind === 176 /* OmittedExpression */ || - name_13.kind === 128 /* ComputedPropertyName */) { + name_16.kind === 128 /* ComputedPropertyName */) { // If the name is not a ComputedPropertyName, the grammar checking will skip it - checkGrammarComputedPropertyName(name_13); + checkGrammarComputedPropertyName(name_16); continue; } // ECMA-262 11.1.5 Object Initialiser @@ -22271,8 +23397,8 @@ var ts; if (prop.kind === 225 /* PropertyAssignment */ || prop.kind === 226 /* ShorthandPropertyAssignment */) { // Grammar checking for computedPropertName and shorthandPropertyAssignment checkGrammarForInvalidQuestionMark(prop, prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional); - if (name_13.kind === 7 /* NumericLiteral */) { - checkGrammarNumericLiteral(name_13); + if (name_16.kind === 7 /* NumericLiteral */) { + checkGrammarNumericLiteral(name_16); } currentKind = Property; } @@ -22288,26 +23414,26 @@ var ts; else { ts.Debug.fail("Unexpected syntax kind:" + prop.kind); } - if (!ts.hasProperty(seen, name_13.text)) { - seen[name_13.text] = currentKind; + if (!ts.hasProperty(seen, name_16.text)) { + seen[name_16.text] = currentKind; } else { - var existingKind = seen[name_13.text]; + var existingKind = seen[name_16.text]; if (currentKind === Property && existingKind === Property) { if (inStrictMode) { - grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode); + grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode); } } else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) { if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) { - seen[name_13.text] = currentKind | existingKind; + seen[name_16.text] = currentKind | existingKind; } else { - return grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); + return grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); } } else { - return grammarErrorOnNode(name_13, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name); + return grammarErrorOnNode(name_16, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name); } } } @@ -23168,9 +24294,9 @@ var ts; } var count = 0; while (true) { - var name_14 = baseName + "_" + (++count); - if (!ts.hasProperty(currentSourceFile.identifiers, name_14)) { - return name_14; + var name_17 = baseName + "_" + (++count); + if (!ts.hasProperty(currentSourceFile.identifiers, name_17)) { + return name_17; } } } @@ -24379,9 +25505,9 @@ var ts; tempFlags++; // Skip over 'i' and 'n' if (count !== 8 && count !== 13) { - var name_15 = count < 26 ? "_" + String.fromCharCode(97 /* a */ + count) : "_" + (count - 26); - if (isUniqueName(name_15)) { - return name_15; + var name_18 = count < 26 ? "_" + String.fromCharCode(97 /* a */ + count) : "_" + (count - 26); + if (isUniqueName(name_18)) { + return name_18; } } } @@ -24414,9 +25540,9 @@ var ts; } function generateNameForModuleOrEnum(node) { if (node.name.kind === 65 /* Identifier */) { - var name_16 = node.name.text; + var name_19 = node.name.text; // Use module/enum name itself if it is unique, otherwise make a unique variation - assignGeneratedName(node, isUniqueLocalName(name_16, node) ? name_16 : makeUniqueName(name_16)); + assignGeneratedName(node, isUniqueLocalName(name_19, node) ? name_19 : makeUniqueName(name_19)); } } function generateNameForImportOrExportDeclaration(node) { @@ -24635,8 +25761,8 @@ var ts; // Child scopes are always shown with a dot (even if they have no name), // unless it is a computed property. Then it is shown with brackets, // but the brackets are included in the name. - var name_17 = node.name; - if (!name_17 || name_17.kind !== 128 /* ComputedPropertyName */) { + var name_20 = node.name; + if (!name_20 || name_20.kind !== 128 /* ComputedPropertyName */) { scopeName = "." + scopeName; } scopeName = sourceMapData.sourceMapNames[parentIndex] + scopeName; @@ -24665,10 +25791,10 @@ var ts; node.kind === 205 /* EnumDeclaration */) { // Declaration and has associated name use it if (node.name) { - var name_18 = node.name; + var name_21 = node.name; // For computed property names, the text will include the brackets - scopeName = name_18.kind === 128 /* ComputedPropertyName */ - ? ts.getTextOfNode(name_18) + scopeName = name_21.kind === 128 /* ComputedPropertyName */ + ? ts.getTextOfNode(name_21) : node.name.text; } recordScopeNameStart(scopeName); @@ -25369,16 +26495,16 @@ var ts; } return true; } - function emitListWithSpread(elements, alwaysCopy, multiLine, trailingComma) { + function emitListWithSpread(elements, needsUniqueCopy, multiLine, trailingComma, useConcat) { var pos = 0; var group = 0; var length = elements.length; while (pos < length) { // Emit using the pattern .concat(, , ...) - if (group === 1) { + if (group === 1 && useConcat) { write(".concat("); } - else if (group > 1) { + else if (group > 0) { write(", "); } var e = elements[pos]; @@ -25386,7 +26512,7 @@ var ts; e = e.expression; emitParenthesizedIf(e, group === 0 && needsParenthesisForPropertyAccessOrInvocation(e)); pos++; - if (pos === length && group === 0 && alwaysCopy && e.kind !== 154 /* ArrayLiteralExpression */) { + if (pos === length && group === 0 && needsUniqueCopy && e.kind !== 154 /* ArrayLiteralExpression */) { write(".slice()"); } } @@ -25409,7 +26535,9 @@ var ts; group++; } if (group > 1) { - write(")"); + if (useConcat) { + write(")"); + } } } function isSpreadElementExpression(node) { @@ -25427,7 +26555,7 @@ var ts; } else { emitListWithSpread(elements, true, (node.flags & 512 /* MultiLine */) !== 0, - /*trailingComma*/ elements.hasTrailingComma); + /*trailingComma*/ elements.hasTrailingComma, true); } } function emitObjectLiteralBody(node, numElements) { @@ -25798,7 +26926,7 @@ var ts; write("void 0"); } write(", "); - emitListWithSpread(node.arguments, false, false, false); + emitListWithSpread(node.arguments, false, false, false, true); write(")"); } function emitCallExpression(node) { @@ -25832,11 +26960,42 @@ var ts; } function emitNewExpression(node) { write("new "); - emit(node.expression); - if (node.arguments) { + // Spread operator logic can be supported in new expressions in ES5 using a combination + // of Function.prototype.bind() and Function.prototype.apply(). + // + // Example: + // + // var arguments = [1, 2, 3, 4, 5]; + // new Array(...arguments); + // + // Could be transpiled into ES5: + // + // var arguments = [1, 2, 3, 4, 5]; + // new (Array.bind.apply(Array, [void 0].concat(arguments))); + // + // `[void 0]` is the first argument which represents `thisArg` to the bind method above. + // And `thisArg` will be set to the return value of the constructor when instantiated + // with the new operator — regardless of any value we set `thisArg` to. Thus, we set it + // to an undefined, `void 0`. + if (languageVersion === 1 /* ES5 */ && + node.arguments && + hasSpreadElement(node.arguments)) { write("("); - emitCommaList(node.arguments); - write(")"); + var target = emitCallTarget(node.expression); + write(".bind.apply("); + emit(target); + write(", [void 0].concat("); + emitListWithSpread(node.arguments, false, false, false, false); + write(")))"); + write("()"); + } + else { + emit(node.expression); + if (node.arguments) { + write("("); + emitCommaList(node.arguments); + write(")"); + } } } function emitTaggedTemplateExpression(node) { @@ -26136,9 +27295,10 @@ var ts; write(")"); emitEmbeddedStatement(node.statement); } - /* Returns true if start of variable declaration list was emitted. - * Return false if nothing was written - this can happen for source file level variable declarations - * in system modules - such variable declarations are hoisted. + /** + * Returns true if start of variable declaration list was emitted. + * Returns false if nothing was written - this can happen for source file level variable declarations + * in system modules where such variable declarations are hoisted. */ function tryEmitStartOfVariableDeclarationList(decl, startPos) { if (shouldHoistVariable(decl, true)) { @@ -26901,15 +28061,35 @@ var ts; ts.forEach(node.declarationList.declarations, emitExportVariableAssignments); } } + function shouldEmitLeadingAndTrailingCommentsForVariableStatement(node) { + // If we're not exporting the variables, there's nothing special here. + // Always emit comments for these nodes. + if (!(node.flags & 1 /* Export */)) { + return true; + } + // If we are exporting, but it's a top-level ES6 module exports, + // we'll emit the declaration list verbatim, so emit comments too. + if (isES6ExportedDeclaration(node)) { + return true; + } + // Otherwise, only emit if we have at least one initializer present. + for (var _a = 0, _b = node.declarationList.declarations; _a < _b.length; _a++) { + var declaration = _b[_a]; + if (declaration.initializer) { + return true; + } + } + return false; + } function emitParameter(node) { if (languageVersion < 2 /* ES6 */) { if (ts.isBindingPattern(node.name)) { - var name_19 = createTempVariable(0 /* Auto */); + var name_22 = createTempVariable(0 /* Auto */); if (!tempParameters) { tempParameters = []; } - tempParameters.push(name_19); - emit(name_19); + tempParameters.push(name_22); + emit(name_22); } else { emit(node.name); @@ -28577,8 +29757,8 @@ var ts; // export { x, y } for (var _c = 0, _d = node.exportClause.elements; _c < _d.length; _c++) { var specifier = _d[_c]; - var name_20 = (specifier.propertyName || specifier.name).text; - (exportSpecifiers[name_20] || (exportSpecifiers[name_20] = [])).push(specifier); + var name_23 = (specifier.propertyName || specifier.name).text; + (exportSpecifiers[name_23] || (exportSpecifiers[name_23] = [])).push(specifier); } } break; @@ -28778,12 +29958,12 @@ var ts; var seen = {}; for (var i = 0; i < hoistedVars.length; ++i) { var local = hoistedVars[i]; - var name_21 = local.kind === 65 /* Identifier */ + var name_24 = local.kind === 65 /* Identifier */ ? local : local.name; - if (name_21) { + if (name_24) { // do not emit duplicate entries (in case of declaration merging) in the list of hoisted variables - var text = ts.unescapeIdentifier(name_21.text); + var text = ts.unescapeIdentifier(name_24.text); if (ts.hasProperty(seen, text)) { continue; } @@ -28862,15 +30042,15 @@ var ts; } if (node.kind === 199 /* VariableDeclaration */ || node.kind === 153 /* BindingElement */) { if (shouldHoistVariable(node, false)) { - var name_22 = node.name; - if (name_22.kind === 65 /* Identifier */) { + var name_25 = node.name; + if (name_25.kind === 65 /* Identifier */) { if (!hoistedVars) { hoistedVars = []; } - hoistedVars.push(name_22); + hoistedVars.push(name_25); } else { - ts.forEachChild(name_22, visit); + ts.forEachChild(name_25, visit); } } return; @@ -29329,6 +30509,8 @@ var ts; case 204 /* TypeAliasDeclaration */: case 215 /* ExportAssignment */: return false; + case 181 /* VariableStatement */: + return shouldEmitLeadingAndTrailingCommentsForVariableStatement(node); case 206 /* ModuleDeclaration */: // Only emit the leading/trailing comments for a module if we're actually // emitting the module as well. @@ -30710,28 +31892,28 @@ var ts; switch (n.kind) { case 180 /* Block */: if (!ts.isFunctionBlock(n)) { - var parent_6 = n.parent; + var parent_7 = n.parent; var openBrace = ts.findChildOfKind(n, 14 /* OpenBraceToken */, sourceFile); var closeBrace = ts.findChildOfKind(n, 15 /* CloseBraceToken */, sourceFile); // Check if the block is standalone, or 'attached' to some parent statement. // If the latter, we want to collaps the block, but consider its hint span // to be the entire span of the parent. - if (parent_6.kind === 185 /* DoStatement */ || - parent_6.kind === 188 /* ForInStatement */ || - parent_6.kind === 189 /* ForOfStatement */ || - parent_6.kind === 187 /* ForStatement */ || - parent_6.kind === 184 /* IfStatement */ || - parent_6.kind === 186 /* WhileStatement */ || - parent_6.kind === 193 /* WithStatement */ || - parent_6.kind === 224 /* CatchClause */) { - addOutliningSpan(parent_6, openBrace, closeBrace, autoCollapse(n)); + if (parent_7.kind === 185 /* DoStatement */ || + parent_7.kind === 188 /* ForInStatement */ || + parent_7.kind === 189 /* ForOfStatement */ || + parent_7.kind === 187 /* ForStatement */ || + parent_7.kind === 184 /* IfStatement */ || + parent_7.kind === 186 /* WhileStatement */ || + parent_7.kind === 193 /* WithStatement */ || + parent_7.kind === 224 /* CatchClause */) { + addOutliningSpan(parent_7, openBrace, closeBrace, autoCollapse(n)); break; } - if (parent_6.kind === 197 /* TryStatement */) { + if (parent_7.kind === 197 /* TryStatement */) { // Could be the try-block, or the finally-block. - var tryStatement = parent_6; + var tryStatement = parent_7; if (tryStatement.tryBlock === n) { - addOutliningSpan(parent_6, openBrace, closeBrace, autoCollapse(n)); + addOutliningSpan(parent_7, openBrace, closeBrace, autoCollapse(n)); break; } else if (tryStatement.finallyBlock === n) { @@ -30798,12 +31980,12 @@ var ts; ts.forEach(program.getSourceFiles(), function (sourceFile) { cancellationToken.throwIfCancellationRequested(); var nameToDeclarations = sourceFile.getNamedDeclarations(); - for (var name_23 in nameToDeclarations) { - var declarations = ts.getProperty(nameToDeclarations, name_23); + for (var name_26 in nameToDeclarations) { + var declarations = ts.getProperty(nameToDeclarations, name_26); if (declarations) { // First do a quick check to see if the name of the declaration matches the // last portion of the (possibly) dotted name they're searching for. - var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_23); + var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name_26); if (!matches) { continue; } @@ -30816,14 +31998,14 @@ var ts; if (!containers) { return undefined; } - matches = patternMatcher.getMatches(containers, name_23); + matches = patternMatcher.getMatches(containers, name_26); if (!matches) { continue; } } var fileName = sourceFile.fileName; var matchKind = bestMatchKind(matches); - rawItems.push({ name: name_23, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); + rawItems.push({ name: name_26, fileName: fileName, matchKind: matchKind, isCaseSensitive: allMatchesAreCaseSensitive(matches), declaration: declaration }); } } } @@ -31206,9 +32388,9 @@ var ts; case 199 /* VariableDeclaration */: case 153 /* BindingElement */: var variableDeclarationNode; - var name_24; + var name_27; if (node.kind === 153 /* BindingElement */) { - name_24 = node.name; + name_27 = node.name; variableDeclarationNode = node; // binding elements are added only for variable declarations // bubble up to the containing variable declaration @@ -31220,16 +32402,16 @@ var ts; else { ts.Debug.assert(!ts.isBindingPattern(node.name)); variableDeclarationNode = node; - name_24 = node.name; + name_27 = node.name; } if (ts.isConst(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.constElement); + return createItem(node, getTextOfNode(name_27), ts.ScriptElementKind.constElement); } else if (ts.isLet(variableDeclarationNode)) { - return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.letElement); + return createItem(node, getTextOfNode(name_27), ts.ScriptElementKind.letElement); } else { - return createItem(node, getTextOfNode(name_24), ts.ScriptElementKind.variableElement); + return createItem(node, getTextOfNode(name_27), ts.ScriptElementKind.variableElement); } case 136 /* Constructor */: return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); @@ -32751,7 +33933,7 @@ var ts; // for the position of the relevant node (or comma). var syntaxList = ts.forEach(node.parent.getChildren(), function (c) { // find syntax list that covers the span of the node - if (c.kind === 229 /* SyntaxList */ && c.pos <= node.pos && c.end >= node.end) { + if (c.kind === 251 /* SyntaxList */ && c.pos <= node.pos && c.end >= node.end) { return c; } }); @@ -33158,10 +34340,6 @@ var ts; }); } ts.signatureToDisplayParts = signatureToDisplayParts; - function isJavaScript(fileName) { - return ts.fileExtensionIs(fileName, ".js"); - } - ts.isJavaScript = isJavaScript; })(ts || (ts = {})); /// /// @@ -33644,7 +34822,7 @@ var ts; this.NoSpaceBeforeOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* OpenBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); this.NoSpaceAfterOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create3(18 /* OpenBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); this.NoSpaceBeforeCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 19 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); - this.NoSpaceAfterCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* CloseBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); + this.NoSpaceAfterCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* CloseBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBeforeBlockInFunctionDeclarationContext), 8 /* Delete */)); // Place a space before open brace in a function declaration this.FunctionOpenBraceLeftTokenRange = formatting.Shared.TokenRange.AnyIncludingMultilineComments; this.SpaceBeforeOpenBraceInFunction = new formatting.Rule(formatting.RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, 14 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext, Rules.IsBeforeBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */); @@ -33727,6 +34905,10 @@ var ts; this.SpaceBeforeAt = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 52 /* AtToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */)); this.NoSpaceAfterAt = new formatting.Rule(formatting.RuleDescriptor.create3(52 /* AtToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */)); this.SpaceAfterDecorator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([65 /* Identifier */, 78 /* ExportKeyword */, 73 /* DefaultKeyword */, 69 /* ClassKeyword */, 109 /* StaticKeyword */, 108 /* PublicKeyword */, 106 /* PrivateKeyword */, 107 /* ProtectedKeyword */, 116 /* GetKeyword */, 121 /* SetKeyword */, 18 /* OpenBracketToken */, 35 /* AsteriskToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsEndOfDecoratorContextOnSameLine), 2 /* Space */)); + this.NoSpaceBetweenFunctionKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(83 /* FunctionKeyword */, 35 /* AsteriskToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 8 /* Delete */)); + this.SpaceAfterStarInGeneratorDeclaration = new formatting.Rule(formatting.RuleDescriptor.create3(35 /* AsteriskToken */, formatting.Shared.TokenRange.FromTokens([65 /* Identifier */, 16 /* OpenParenToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclarationOrFunctionExpressionContext), 2 /* Space */)); + this.NoSpaceBetweenYieldKeywordAndStar = new formatting.Rule(formatting.RuleDescriptor.create1(110 /* YieldKeyword */, 35 /* AsteriskToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 8 /* Delete */)); + this.SpaceBetweenYieldOrYieldStarAndOperand = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([110 /* YieldKeyword */, 35 /* AsteriskToken */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsYieldOrYieldStarWithOperand), 2 /* Space */)); // These rules are higher in priority than user-configurable rules. this.HighPriorityCommonRules = [ @@ -33744,7 +34926,9 @@ var ts; this.NoSpaceAfterCloseBrace, this.SpaceAfterOpenBrace, this.SpaceBeforeCloseBrace, this.NewLineBeforeCloseBraceInBlockContext, this.SpaceAfterCloseBrace, this.SpaceBetweenCloseBraceAndElse, this.SpaceBetweenCloseBraceAndWhile, this.NoSpaceBetweenEmptyBraceBrackets, + this.NoSpaceBetweenFunctionKeywordAndStar, this.SpaceAfterStarInGeneratorDeclaration, this.SpaceAfterFunctionInFuncDecl, this.NewLineAfterOpenBraceInBlockContext, this.SpaceAfterGetSetInMember, + this.NoSpaceBetweenYieldKeywordAndStar, this.SpaceBetweenYieldOrYieldStarAndOperand, this.NoSpaceBetweenReturnAndSemicolon, this.SpaceAfterCertainKeywords, this.SpaceAfterLetConstInVariableDeclaration, @@ -33816,9 +35000,9 @@ var ts; } Rules.prototype.getRuleName = function (rule) { var o = this; - for (var name_25 in o) { - if (o[name_25] === rule) { - return name_25; + for (var name_28 in o) { + if (o[name_28] === rule) { + return name_28; } } throw new Error("Unknown rule"); @@ -33937,6 +35121,9 @@ var ts; } return false; }; + Rules.IsFunctionDeclarationOrFunctionExpressionContext = function (context) { + return context.contextNode.kind === 201 /* FunctionDeclaration */ || context.contextNode.kind === 163 /* FunctionExpression */; + }; Rules.IsTypeScriptDeclWithBlockContext = function (context) { return Rules.NodeIsTypeScriptDeclWithBlockContext(context.contextNode); }; @@ -34001,6 +35188,9 @@ var ts; Rules.IsSameLineTokenContext = function (context) { return context.TokensAreOnSameLine(); }; + Rules.IsNotBeforeBlockInFunctionDeclarationContext = function (context) { + return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context); + }; Rules.IsEndOfDecoratorContextOnSameLine = function (context) { return context.TokensAreOnSameLine() && context.contextNode.decorators && @@ -34055,6 +35245,9 @@ var ts; Rules.IsVoidOpContext = function (context) { return context.currentTokenSpan.kind === 99 /* VoidKeyword */ && context.currentTokenParent.kind === 167 /* VoidExpression */; }; + Rules.IsYieldOrYieldStarWithOperand = function (context) { + return context.contextNode.kind === 173 /* YieldExpression */ && context.contextNode.expression !== undefined; + }; return Rules; })(); formatting.Rules = Rules; @@ -35759,7 +36952,7 @@ var ts; return pos; }; NodeObject.prototype.createSyntaxList = function (nodes) { - var list = createNode(229 /* SyntaxList */, nodes.pos, nodes.end, 1024 /* Synthetic */, this); + var list = createNode(251 /* SyntaxList */, nodes.pos, nodes.end, 1024 /* Synthetic */, this); list._children = []; var pos = nodes.pos; for (var _i = 0; _i < nodes.length; _i++) { @@ -36557,9 +37750,9 @@ var ts; return false; } // If the parent is not sourceFile or module block it is local variable - for (var parent_7 = declaration.parent; !ts.isFunctionBlock(parent_7); parent_7 = parent_7.parent) { + for (var parent_8 = declaration.parent; !ts.isFunctionBlock(parent_8); parent_8 = parent_8.parent) { // Reached source file or module block - if (parent_7.kind === 228 /* SourceFile */ || parent_7.kind === 207 /* ModuleBlock */) { + if (parent_8.kind === 228 /* SourceFile */ || parent_8.kind === 207 /* ModuleBlock */) { return false; } } @@ -37537,7 +38730,7 @@ var ts; return true; } if (parameter.questionToken) { - diagnostics.push(ts.createDiagnosticForNode(parameter.questionToken, ts.Diagnostics.can_only_be_used_in_a_ts_file)); + diagnostics.push(ts.createDiagnosticForNode(parameter.questionToken, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, '?')); return true; } if (parameter.type) { @@ -37919,12 +39112,12 @@ var ts; function getContainingObjectLiteralApplicableForCompletion(previousToken) { // The locations in an object literal expression that are applicable for completion are property name definition locations. if (previousToken) { - var parent_8 = previousToken.parent; + var parent_9 = previousToken.parent; switch (previousToken.kind) { case 14 /* OpenBraceToken */: // let x = { | case 23 /* CommaToken */: - if (parent_8 && parent_8.kind === 155 /* ObjectLiteralExpression */) { - return parent_8; + if (parent_9 && parent_9.kind === 155 /* ObjectLiteralExpression */) { + return parent_9; } break; } @@ -38107,10 +39300,10 @@ var ts; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; var nameTable = getNameTable(sourceFile); - for (var name_26 in nameTable) { - if (!allNames[name_26]) { - allNames[name_26] = name_26; - var displayName = getCompletionEntryDisplayName(name_26, target, true); + for (var name_29 in nameTable) { + if (!allNames[name_29]) { + allNames[name_29] = name_29; + var displayName = getCompletionEntryDisplayName(name_29, target, true); if (displayName) { var entry = { name: displayName, @@ -39018,19 +40211,19 @@ var ts; function getThrowStatementOwner(throwStatement) { var child = throwStatement; while (child.parent) { - var parent_9 = child.parent; - if (ts.isFunctionBlock(parent_9) || parent_9.kind === 228 /* SourceFile */) { - return parent_9; + var parent_10 = child.parent; + if (ts.isFunctionBlock(parent_10) || parent_10.kind === 228 /* SourceFile */) { + return parent_10; } // A throw-statement is only owned by a try-statement if the try-statement has // a catch clause, and if the throw-statement occurs within the try block. - if (parent_9.kind === 197 /* TryStatement */) { - var tryStatement = parent_9; + if (parent_10.kind === 197 /* TryStatement */) { + var tryStatement = parent_10; if (tryStatement.tryBlock === child && tryStatement.catchClause) { return child; } } - child = parent_9; + child = parent_10; } return undefined; } @@ -39992,19 +41185,19 @@ var ts; if (isNameOfPropertyAssignment(node)) { var objectLiteral = node.parent.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name_27 = node.text; + var name_30 = node.text; if (contextualType) { if (contextualType.flags & 16384 /* Union */) { // This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types) // if not, search the constituent types for the property - var unionProperty = contextualType.getProperty(name_27); + var unionProperty = contextualType.getProperty(name_30); if (unionProperty) { return [unionProperty]; } else { var result_4 = []; ts.forEach(contextualType.types, function (t) { - var symbol = t.getProperty(name_27); + var symbol = t.getProperty(name_30); if (symbol) { result_4.push(symbol); } @@ -40013,7 +41206,7 @@ var ts; } } else { - var symbol_1 = contextualType.getProperty(name_27); + var symbol_1 = contextualType.getProperty(name_30); if (symbol_1) { return [symbol_1]; } @@ -40994,7 +42187,7 @@ var ts; var lastEnd = 0; for (var i = 0, n = dense.length; i < n; i += 3) { var start = dense[i]; - var length_1 = dense[i + 1]; + var length_2 = dense[i + 1]; var type = dense[i + 2]; // Make a whitespace entry between the last item and this one. if (lastEnd >= 0) { @@ -41003,8 +42196,8 @@ var ts; entries.push({ length: whitespaceLength_1, classification: TokenClass.Whitespace }); } } - entries.push({ length: length_1, classification: convertClassification(type) }); - lastEnd = start + length_1; + entries.push({ length: length_2, classification: convertClassification(type) }); + lastEnd = start + length_2; } var whitespaceLength = text.length - lastEnd; if (whitespaceLength > 0) { From 70675162dc0c6ed377bc1b2d7ff1d756156639fd Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Mon, 1 Jun 2015 17:45:28 -0700 Subject: [PATCH 087/194] Add tests for projectinfo command --- src/harness/fourslash.ts | 15 +++++++++++++++ src/server/client.ts | 15 +++++++++++++++ src/server/protocol.d.ts | 16 ++++++++++------ src/server/session.ts | 9 +++++---- tests/cases/fourslash/fourslash.ts | 4 ++++ tests/cases/fourslash/server/projectInfo.ts | 10 ++++++++++ 6 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 tests/cases/fourslash/server/projectInfo.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 110e59c46e1..8d313c9a1a6 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1818,6 +1818,21 @@ module FourSlash { } } + private verifyProjectInfo(expected: string[]) { + if (this.testType == FourSlashTestType.Server) { + let actual = (this.languageService).getProjectInfo( + this.activeFile.fileName, + /* needFileNameList */ true + ); + assert.equal( + expected.join(","), + actual.fileNameList.map( file => { + return file.replace(this.basePath + "/", "") + }).join(",") + ); + } + } + public verifySemanticClassifications(expected: { classificationType: string; text: string }[]) { var actual = this.languageService.getSemanticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length)); diff --git a/src/server/client.ts b/src/server/client.ts index 3582d508322..2cfd911b7b5 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -171,6 +171,21 @@ module ts.server { documentation: [{ kind: "text", text: response.body.documentation }] }; } + + getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo { + var args: protocol.ProjectInfoRequestArgs = { + file: fileName, + needFileNameList: !!needFileNameList + }; + + var request = this.processRequest(CommandNames.ProjectInfo, args); + var response = this.processResponse(request); + + return { + configFileName: response.body.configFileName, + fileNameList: response.body.fileNameList + }; + } getCompletionsAtPosition(fileName: string, position: number): CompletionInfo { var lineOffset = this.positionToOneBasedLineOffset(fileName, position); diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index 6df5b420243..41e25661112 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -90,25 +90,29 @@ declare module ts.server.protocol { /** * Arguments for ProjectInfoResponse messages. */ - export interface ProjectInfoRequestArgs { - /** - * The file for the request (absolute pathname required). - */ - file: string; + export interface ProjectInfoRequestArgs extends FileRequestArgs { /** * Indicate if the file name list of the project is needed */ needFileNameList: boolean; } + export interface ProjectInfoRequest extends Request { + arguments: ProjectInfoRequestArgs + } + /** * Response message for "projectInfo" request */ - export interface ProjectInfoResponse { + export interface ProjectInfo { configFileName: string; fileNameList?: string[]; } + export interface ProjectInfoResponse extends Response { + body?: ProjectInfo; + } + /** * Request whose sole parameter is a file name. */ diff --git a/src/server/session.ts b/src/server/session.ts index 621edd35f4f..a4cb3e59b4e 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -339,18 +339,19 @@ module ts.server { }); } - getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfoResponse { + getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo { fileName = ts.normalizePath(fileName) let project = this.projectService.getProjectForFile(fileName) - let projectInfoResponse: protocol.ProjectInfoResponse = { + let projectInfo: protocol.ProjectInfo = { configFileName: project.projectFilename } if (needFileNameList) { - projectInfoResponse.fileNameList = project.getFileNameList(); + projectInfo.fileNameList = project.getFileNameList(); } - return projectInfoResponse; + + return projectInfo; } getRenameLocations(line: number, offset: number, fileName: string,findInComments: boolean, findInStrings: boolean): protocol.RenameResponseBody { diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 21c65c699ab..b3ffa96e1b6 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -455,6 +455,10 @@ module FourSlashInterface { public getSemanticDiagnostics(expected: string) { FourSlash.currentTestState.getSemanticDiagnostics(expected); } + + public ProjectInfo(expected: string []) { + FourSlash.currentTestState.verifyProjectInfo(expected); + } } export class edit { diff --git a/tests/cases/fourslash/server/projectInfo.ts b/tests/cases/fourslash/server/projectInfo.ts new file mode 100644 index 00000000000..d08c7dd85f1 --- /dev/null +++ b/tests/cases/fourslash/server/projectInfo.ts @@ -0,0 +1,10 @@ +/// + +// @Filename: a.ts +//// import test from "b" + +// @Filename: b.ts +//// export var test = "test String" + +goTo.file("a.ts") +verify.ProjectInfo(["lib.d.ts", "b.ts", "a.ts"]) From 465ab147aff671d526ec5f5daef61fb0aa6fccb5 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 2 Jun 2015 12:36:04 -0700 Subject: [PATCH 088/194] Fixed test that disturbingly wasn't doing anything. --- .../fourslash/completionListAfterRegularExpressionLiteral1.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral1.ts b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral1.ts index 870e83c5118..558b4d1e791 100644 --- a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral1.ts +++ b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral1.ts @@ -3,5 +3,5 @@ /////a/./**/ goTo.marker(); -//verify.not.memberListContains('alert'); -//verify.memberListContains('compile'); \ No newline at end of file +verify.not.memberListContains('alert'); +verify.memberListContains('compile'); \ No newline at end of file From dcfe9200641d7f6e0edf84705431cf8f8ea4c62e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 2 Jun 2015 12:36:42 -0700 Subject: [PATCH 089/194] Added leading digit. --- .../completionListAfterRegularExpressionLiteral01.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/cases/fourslash/completionListAfterRegularExpressionLiteral01.ts diff --git a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral01.ts b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral01.ts new file mode 100644 index 00000000000..558b4d1e791 --- /dev/null +++ b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral01.ts @@ -0,0 +1,7 @@ +/// + +/////a/./**/ + +goTo.marker(); +verify.not.memberListContains('alert'); +verify.memberListContains('compile'); \ No newline at end of file From 0a3cbe083b7e63518407bf593efcf413dfca5f4a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 2 Jun 2015 12:58:49 -0700 Subject: [PATCH 090/194] Added tests. --- .../completionListAfterRegularExpressionLiteral02.ts | 9 +++++++++ .../completionListAfterRegularExpressionLiteral03.ts | 10 ++++++++++ .../completionListAfterRegularExpressionLiteral04.ts | 9 +++++++++ 3 files changed, 28 insertions(+) create mode 100644 tests/cases/fourslash/completionListAfterRegularExpressionLiteral02.ts create mode 100644 tests/cases/fourslash/completionListAfterRegularExpressionLiteral03.ts create mode 100644 tests/cases/fourslash/completionListAfterRegularExpressionLiteral04.ts diff --git a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral02.ts b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral02.ts new file mode 100644 index 00000000000..677aae80513 --- /dev/null +++ b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral02.ts @@ -0,0 +1,9 @@ +/// + +////let x = /absidey//**/ + +// Should get nothing at the marker since it's +// going to be considered part of the regex flags. + +goTo.marker(); +verify.completionListIsEmpty(); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral03.ts b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral03.ts new file mode 100644 index 00000000000..7b767d5e008 --- /dev/null +++ b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral03.ts @@ -0,0 +1,10 @@ +/// + +////let x = /absidey/ +/////**/ + +// Should not be blocked since there is a +// newline separating us from the regex flags. + +goTo.marker(); +verify.not.completionListIsEmpty(); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral04.ts b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral04.ts new file mode 100644 index 00000000000..17a714c6f9d --- /dev/null +++ b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral04.ts @@ -0,0 +1,9 @@ +/// + +////let x = /absidey/ /**/ + +// Should not be blocked since there is a +// space separating us from the regex flags. + +goTo.marker(); +verify.not.completionListIsEmpty(); \ No newline at end of file From 21256a9de547adb0e5ec4765092f23d7cdea7066 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 14:56:30 -0700 Subject: [PATCH 091/194] Added tests. --- ...lassExpressionWithResolutionOfNamespaceOfSameName01.ts | 8 ++++++++ ...tionDeclarationWithResolutionOfTypeNamedArguments01.ts | 6 ++++++ ...functionDeclarationWithResolutionOfTypeOfSameName01.ts | 6 ++++++ ...ctionExpressionWithResolutionOfTypeNamedArguments01.ts | 6 ++++++ .../functionExpressionWithResolutionOfTypeOfSameName01.ts | 6 ++++++ 5 files changed, 32 insertions(+) create mode 100644 tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts create mode 100644 tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts create mode 100644 tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts create mode 100644 tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts create mode 100644 tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts diff --git a/tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts b/tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts new file mode 100644 index 00000000000..ce44c2bca43 --- /dev/null +++ b/tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts @@ -0,0 +1,8 @@ +namespace C { + export interface type { + } +} + +var x = class C { + prop: C.type; +} \ No newline at end of file diff --git a/tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts b/tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts new file mode 100644 index 00000000000..b9ceeb4740b --- /dev/null +++ b/tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts @@ -0,0 +1,6 @@ +interface arguments { +} + +function f() { + arguments; +} \ No newline at end of file diff --git a/tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts b/tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts new file mode 100644 index 00000000000..9dc0bf86943 --- /dev/null +++ b/tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts @@ -0,0 +1,6 @@ +interface f { +} + +function f() { + f; +} \ No newline at end of file diff --git a/tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts b/tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts new file mode 100644 index 00000000000..c1b99ee8f0e --- /dev/null +++ b/tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts @@ -0,0 +1,6 @@ +interface arguments { +} + +var x = function f() { + arguments; +} \ No newline at end of file diff --git a/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts b/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts new file mode 100644 index 00000000000..de4d0e3bb90 --- /dev/null +++ b/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts @@ -0,0 +1,6 @@ +interface f { +} + +var x = function f() { + f; +} \ No newline at end of file From e800e29af706184081ef1004147f7ef5e82348da Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 15:03:54 -0700 Subject: [PATCH 092/194] Accepted baselines for the only test that was expected to pass. --- ...onDeclarationWithResolutionOfTypeOfSameName01.js | 12 ++++++++++++ ...larationWithResolutionOfTypeOfSameName01.symbols | 12 ++++++++++++ ...eclarationWithResolutionOfTypeOfSameName01.types | 13 +++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.js create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.symbols create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.types diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.js b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.js new file mode 100644 index 00000000000..6f5bb2cacf9 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.js @@ -0,0 +1,12 @@ +//// [functionDeclarationWithResolutionOfTypeOfSameName01.ts] +interface f { +} + +function f() { + f; +} + +//// [functionDeclarationWithResolutionOfTypeOfSameName01.js] +function f() { + f; +} diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.symbols b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.symbols new file mode 100644 index 00000000000..aa51fad0538 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts === +interface f { +>f : Symbol(f, Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 0, 0), Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 1, 1)) +} + +function f() { +>f : Symbol(f, Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 0, 0), Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 1, 1)) + + f; +>f : Symbol(f, Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 0, 0), Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 1, 1)) +>f : Symbol(f, Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 0, 0), Decl(functionDeclarationWithResolutionOfTypeOfSameName01.ts, 1, 1)) +} diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.types b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.types new file mode 100644 index 00000000000..1067b8989c8 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeOfSameName01.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/functionDeclarationWithResolutionOfTypeOfSameName01.ts === +interface f { +>f : f +} + +function f() { +>f : () => void + + f; +>f : f +>f : f +>f : () => void +} From baf46a94a6277a3ac3e7a917f37e1c8c8ef66ed6 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 15:04:34 -0700 Subject: [PATCH 093/194] Only resolve 'arguments' and function/class expression names if the meaning permits it. --- src/compiler/checker.ts | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 528ee97602b..dfc5461c02f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -423,27 +423,33 @@ module ts { case SyntaxKind.SetAccessor: case SyntaxKind.FunctionDeclaration: case SyntaxKind.ArrowFunction: - if (name === "arguments") { - result = argumentsSymbol; - break loop; + if (meaning & SymbolFlags.Value) { + if (name === "arguments") { + result = argumentsSymbol; + break loop; + } } break; case SyntaxKind.FunctionExpression: - if (name === "arguments") { - result = argumentsSymbol; - break loop; - } - let functionName = (location).name; - if (functionName && name === functionName.text) { - result = location.symbol; - break loop; + if (meaning & SymbolFlags.Value) { + if (name === "arguments") { + result = argumentsSymbol; + break loop; + } + let functionName = (location).name; + if (functionName && name === functionName.text) { + result = location.symbol; + break loop; + } } break; case SyntaxKind.ClassExpression: - let className = (location).name; - if (className && name === className.text) { - result = location.symbol; - break loop; + if (meaning & (SymbolFlags.Value | SymbolFlags.Type)) { + let className = (location).name; + if (className && name === className.text) { + result = location.symbol; + break loop; + } } break; case SyntaxKind.Decorator: From eb95532bfa766550e98158dbfe278a5075dcb75f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 16:03:04 -0700 Subject: [PATCH 094/194] Don't use 'Value' or 'Type' as they have overlap. Instead test for the precise meaning. --- src/compiler/checker.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dfc5461c02f..58ea529cb72 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -423,19 +423,18 @@ module ts { case SyntaxKind.SetAccessor: case SyntaxKind.FunctionDeclaration: case SyntaxKind.ArrowFunction: - if (meaning & SymbolFlags.Value) { - if (name === "arguments") { - result = argumentsSymbol; - break loop; - } + if (meaning & SymbolFlags.Variable && name === "arguments") { + result = argumentsSymbol; + break loop; } break; case SyntaxKind.FunctionExpression: - if (meaning & SymbolFlags.Value) { - if (name === "arguments") { - result = argumentsSymbol; - break loop; - } + if (meaning & SymbolFlags.Variable && name === "arguments") { + result = argumentsSymbol; + break loop; + } + + if (meaning & SymbolFlags.Function) { let functionName = (location).name; if (functionName && name === functionName.text) { result = location.symbol; @@ -444,7 +443,7 @@ module ts { } break; case SyntaxKind.ClassExpression: - if (meaning & (SymbolFlags.Value | SymbolFlags.Type)) { + if (meaning & SymbolFlags.Class) { let className = (location).name; if (className && name === className.text) { result = location.symbol; From 589a01c51f704dc35791f9a3cdb8e25a0f640190 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 2 Jun 2015 13:01:44 -0700 Subject: [PATCH 095/194] Block completion when in trailing flags of a regex. --- src/services/services.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index b5871711aa7..980c22f529d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3130,16 +3130,20 @@ module ts { if (previousToken.kind === SyntaxKind.StringLiteral || previousToken.kind === SyntaxKind.RegularExpressionLiteral || isTemplateLiteralKind(previousToken.kind)) { - // The position has to be either: 1. entirely within the token text, or - // 2. at the end position of an unterminated token. let start = previousToken.getStart(); let end = previousToken.getEnd(); + // To be "in" one of these literals, the position has to be: + // 1. entirely within the token text. + // 2. at the end position of an unterminated token. + // 3. at the end of a regular expression (due to trailing flags like '/foo/g'). if (start < position && position < end) { return true; } - else if (position === end) { - return !!(previousToken).isUnterminated; + + if (position === end) { + return !!(previousToken).isUnterminated || + previousToken.kind === SyntaxKind.RegularExpressionLiteral; } } From 2b20d3092b2d523114fc120327d0fd43f340e650 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 16:03:27 -0700 Subject: [PATCH 096/194] Accepted baselines. --- ...hResolutionOfNamespaceOfSameName01.errors.txt | 14 ++++++++++++++ ...ssionWithResolutionOfNamespaceOfSameName01.js | 16 ++++++++++++++++ ...rationWithResolutionOfTypeNamedArguments01.js | 12 ++++++++++++ ...nWithResolutionOfTypeNamedArguments01.symbols | 12 ++++++++++++ ...ionWithResolutionOfTypeNamedArguments01.types | 13 +++++++++++++ ...essionWithResolutionOfTypeNamedArguments01.js | 12 ++++++++++++ ...nWithResolutionOfTypeNamedArguments01.symbols | 13 +++++++++++++ ...ionWithResolutionOfTypeNamedArguments01.types | 15 +++++++++++++++ ...ExpressionWithResolutionOfTypeOfSameName01.js | 12 ++++++++++++ ...ssionWithResolutionOfTypeOfSameName01.symbols | 13 +++++++++++++ ...ressionWithResolutionOfTypeOfSameName01.types | 15 +++++++++++++++ 11 files changed, 147 insertions(+) create mode 100644 tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.errors.txt create mode 100644 tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.js create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.js create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.symbols create mode 100644 tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.types create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.js create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.symbols create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.types create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.js create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.symbols create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.types diff --git a/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.errors.txt b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.errors.txt new file mode 100644 index 00000000000..8edc1d8f74b --- /dev/null +++ b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts(6,15): error TS9003: 'class' expressions are not currently supported. + + +==== tests/cases/compiler/classExpressionWithResolutionOfNamespaceOfSameName01.ts (1 errors) ==== + namespace C { + export interface type { + } + } + + var x = class C { + ~ +!!! error TS9003: 'class' expressions are not currently supported. + prop: C.type; + } \ No newline at end of file diff --git a/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.js b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.js new file mode 100644 index 00000000000..7c9f25cdfe6 --- /dev/null +++ b/tests/baselines/reference/classExpressionWithResolutionOfNamespaceOfSameName01.js @@ -0,0 +1,16 @@ +//// [classExpressionWithResolutionOfNamespaceOfSameName01.ts] +namespace C { + export interface type { + } +} + +var x = class C { + prop: C.type; +} + +//// [classExpressionWithResolutionOfNamespaceOfSameName01.js] +var x = (function () { + function C() { + } + return C; +})(); diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.js b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.js new file mode 100644 index 00000000000..3659f3fd9f9 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.js @@ -0,0 +1,12 @@ +//// [functionDeclarationWithResolutionOfTypeNamedArguments01.ts] +interface arguments { +} + +function f() { + arguments; +} + +//// [functionDeclarationWithResolutionOfTypeNamedArguments01.js] +function f() { + arguments; +} diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.symbols b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.symbols new file mode 100644 index 00000000000..8a36f146001 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts === +interface arguments { +>arguments : Symbol(arguments, Decl(functionDeclarationWithResolutionOfTypeNamedArguments01.ts, 0, 0)) +} + +function f() { +>f : Symbol(f, Decl(functionDeclarationWithResolutionOfTypeNamedArguments01.ts, 1, 1)) + + arguments; +>arguments : Symbol(arguments, Decl(functionDeclarationWithResolutionOfTypeNamedArguments01.ts, 0, 0)) +>arguments : Symbol(arguments) +} diff --git a/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.types b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.types new file mode 100644 index 00000000000..72dbbf8ec69 --- /dev/null +++ b/tests/baselines/reference/functionDeclarationWithResolutionOfTypeNamedArguments01.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/functionDeclarationWithResolutionOfTypeNamedArguments01.ts === +interface arguments { +>arguments : arguments +} + +function f() { +>f : () => void + + arguments; +>arguments : arguments +>arguments : arguments +>arguments : IArguments +} diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.js b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.js new file mode 100644 index 00000000000..43b38f2dd39 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.js @@ -0,0 +1,12 @@ +//// [functionExpressionWithResolutionOfTypeNamedArguments01.ts] +interface arguments { +} + +var x = function f() { + arguments; +} + +//// [functionExpressionWithResolutionOfTypeNamedArguments01.js] +var x = function f() { + arguments; +}; diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.symbols b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.symbols new file mode 100644 index 00000000000..d2455fd0106 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts === +interface arguments { +>arguments : Symbol(arguments, Decl(functionExpressionWithResolutionOfTypeNamedArguments01.ts, 0, 0)) +} + +var x = function f() { +>x : Symbol(x, Decl(functionExpressionWithResolutionOfTypeNamedArguments01.ts, 3, 3)) +>f : Symbol(f, Decl(functionExpressionWithResolutionOfTypeNamedArguments01.ts, 3, 7)) + + arguments; +>arguments : Symbol(arguments, Decl(functionExpressionWithResolutionOfTypeNamedArguments01.ts, 0, 0)) +>arguments : Symbol(arguments) +} diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.types b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.types new file mode 100644 index 00000000000..1a65010a4f6 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeNamedArguments01.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeNamedArguments01.ts === +interface arguments { +>arguments : arguments +} + +var x = function f() { +>x : () => void +>function f() { arguments;} : () => void +>f : () => void + + arguments; +>arguments : arguments +>arguments : arguments +>arguments : IArguments +} diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.js b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.js new file mode 100644 index 00000000000..c9af7ab3297 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.js @@ -0,0 +1,12 @@ +//// [functionExpressionWithResolutionOfTypeOfSameName01.ts] +interface f { +} + +var x = function f() { + f; +} + +//// [functionExpressionWithResolutionOfTypeOfSameName01.js] +var x = function f() { + f; +}; diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.symbols b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.symbols new file mode 100644 index 00000000000..cd2248c6018 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts === +interface f { +>f : Symbol(f, Decl(functionExpressionWithResolutionOfTypeOfSameName01.ts, 0, 0)) +} + +var x = function f() { +>x : Symbol(x, Decl(functionExpressionWithResolutionOfTypeOfSameName01.ts, 3, 3)) +>f : Symbol(f, Decl(functionExpressionWithResolutionOfTypeOfSameName01.ts, 3, 7)) + + f; +>f : Symbol(f, Decl(functionExpressionWithResolutionOfTypeOfSameName01.ts, 0, 0)) +>f : Symbol(f, Decl(functionExpressionWithResolutionOfTypeOfSameName01.ts, 3, 7)) +} diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.types b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.types new file mode 100644 index 00000000000..08b51f35226 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName01.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName01.ts === +interface f { +>f : f +} + +var x = function f() { +>x : () => void +>function f() { f;} : () => void +>f : () => void + + f; +>f : f +>f : f +>f : () => void +} From 0229788c65d329ecb084de2b49e568515980c1de Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 16:30:44 -0700 Subject: [PATCH 097/194] Added another test. --- .../functionExpressionWithResolutionOfTypeOfSameName02.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts diff --git a/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts b/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts new file mode 100644 index 00000000000..041195271fb --- /dev/null +++ b/tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts @@ -0,0 +1,6 @@ +interface Foo { +} + +var x = function Foo() { + var x: Foo; +} \ No newline at end of file From 068a4f3fc3c72d558f5311c9cfa6ebe360acdbe5 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 27 May 2015 16:34:39 -0700 Subject: [PATCH 098/194] Accepted baselines. --- ...onExpressionWithResolutionOfTypeOfSameName02.js | 12 ++++++++++++ ...ressionWithResolutionOfTypeOfSameName02.symbols | 13 +++++++++++++ ...xpressionWithResolutionOfTypeOfSameName02.types | 14 ++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.js create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.symbols create mode 100644 tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.types diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.js b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.js new file mode 100644 index 00000000000..ada96c63a56 --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.js @@ -0,0 +1,12 @@ +//// [functionExpressionWithResolutionOfTypeOfSameName02.ts] +interface Foo { +} + +var x = function Foo() { + var x: Foo; +} + +//// [functionExpressionWithResolutionOfTypeOfSameName02.js] +var x = function Foo() { + var x; +}; diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.symbols b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.symbols new file mode 100644 index 00000000000..89b46c99b4e --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts === +interface Foo { +>Foo : Symbol(Foo, Decl(functionExpressionWithResolutionOfTypeOfSameName02.ts, 0, 0)) +} + +var x = function Foo() { +>x : Symbol(x, Decl(functionExpressionWithResolutionOfTypeOfSameName02.ts, 3, 3)) +>Foo : Symbol(Foo, Decl(functionExpressionWithResolutionOfTypeOfSameName02.ts, 3, 7)) + + var x: Foo; +>x : Symbol(x, Decl(functionExpressionWithResolutionOfTypeOfSameName02.ts, 4, 7)) +>Foo : Symbol(Foo, Decl(functionExpressionWithResolutionOfTypeOfSameName02.ts, 0, 0)) +} diff --git a/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.types b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.types new file mode 100644 index 00000000000..218276a95ea --- /dev/null +++ b/tests/baselines/reference/functionExpressionWithResolutionOfTypeOfSameName02.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/functionExpressionWithResolutionOfTypeOfSameName02.ts === +interface Foo { +>Foo : Foo +} + +var x = function Foo() { +>x : () => void +>function Foo() { var x: Foo;} : () => void +>Foo : () => void + + var x: Foo; +>x : Foo +>Foo : Foo +} From a71a826b5b2585b8eb2a9c4aeda2e806acca6c86 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 2 Jun 2015 13:40:38 -0700 Subject: [PATCH 099/194] Use declared variables to confirm completion. --- .../fourslash/completionListAfterRegularExpressionLiteral01.ts | 3 ++- .../fourslash/completionListAfterRegularExpressionLiteral02.ts | 1 + .../fourslash/completionListAfterRegularExpressionLiteral03.ts | 3 ++- .../fourslash/completionListAfterRegularExpressionLiteral04.ts | 3 ++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral01.ts b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral01.ts index 558b4d1e791..ac8568d13f5 100644 --- a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral01.ts +++ b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral01.ts @@ -1,7 +1,8 @@ /// +////let v = 100; /////a/./**/ goTo.marker(); -verify.not.memberListContains('alert'); +verify.not.memberListContains('v'); verify.memberListContains('compile'); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral02.ts b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral02.ts index 677aae80513..2719d747d58 100644 --- a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral02.ts +++ b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral02.ts @@ -1,5 +1,6 @@ /// +////let v = 100; ////let x = /absidey//**/ // Should get nothing at the marker since it's diff --git a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral03.ts b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral03.ts index 7b767d5e008..7c0e4d51446 100644 --- a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral03.ts +++ b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral03.ts @@ -1,5 +1,6 @@ /// +////let v = 100; ////let x = /absidey/ /////**/ @@ -7,4 +8,4 @@ // newline separating us from the regex flags. goTo.marker(); -verify.not.completionListIsEmpty(); \ No newline at end of file +verify.completionListContains("v"); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral04.ts b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral04.ts index 17a714c6f9d..06f31b8175b 100644 --- a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral04.ts +++ b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral04.ts @@ -1,9 +1,10 @@ /// +////let v = 100; ////let x = /absidey/ /**/ // Should not be blocked since there is a // space separating us from the regex flags. goTo.marker(); -verify.not.completionListIsEmpty(); \ No newline at end of file +verify.completionListContains("v"); \ No newline at end of file From 8b63795a55ab94e0509f96ea5436515f9cd5401a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 2 Jun 2015 13:41:45 -0700 Subject: [PATCH 100/194] Added test where one trailing flag exists. --- .../completionListAfterRegularExpressionLiteral05.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/cases/fourslash/completionListAfterRegularExpressionLiteral05.ts diff --git a/tests/cases/fourslash/completionListAfterRegularExpressionLiteral05.ts b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral05.ts new file mode 100644 index 00000000000..7ac0d1cd71c --- /dev/null +++ b/tests/cases/fourslash/completionListAfterRegularExpressionLiteral05.ts @@ -0,0 +1,10 @@ +/// + +////let v = 100; +////let x = /absidey/g/**/ + +// Should get nothing at the marker since it's +// going to be considered part of the regex flags. + +goTo.marker(); +verify.completionListIsEmpty() \ No newline at end of file From 513183e7b1758a11d68a4f6a168da3180a39e911 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Jun 2015 13:58:49 -0700 Subject: [PATCH 101/194] PR feedback. --- src/services/services.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 427c8db8cc9..cac897ed9ee 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2958,7 +2958,7 @@ module ts { // the individual types have in common, we also include all the members that // each individual type has. This is because we're going to add all identifiers // anyways. So we might as well elevate the members that were at least part - // of the individual types to a higher status than since we know what they are. + // of the individual types to a higher status since we know what they are. let unionType = type; for (let elementType of unionType.types) { addTypeProperties(elementType); @@ -6147,10 +6147,10 @@ module ts { if (kind === SyntaxKind.MultiLineCommentTrivia) { // See if this is a doc comment. If so, we'll classify certain portions of it // specially. - let jsDocComment = parseIsolatedJSDocComment(sourceFile.text, start, width); - if (jsDocComment && jsDocComment.jsDocComment) { - jsDocComment.jsDocComment.parent = token; - classifyJSDocComment(jsDocComment.jsDocComment); + let docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width); + if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDocComment) { + docCommentAndDiagnostics.jsDocComment.parent = token; + classifyJSDocComment(docCommentAndDiagnostics.jsDocComment); return; } } @@ -6167,6 +6167,8 @@ module ts { let pos = docComment.pos; for (let tag of docComment.tags) { + // As we walk through each tag, classify the portion of text from the end of + // the last tag (or the start of the entire doc comment) as 'comment'. if (tag.pos !== pos) { pushCommentRange(pos, tag.pos - pos); } From 8fcd29f843f1948b967678f62bc6a1d539f0f2eb Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Jun 2015 15:00:39 -0700 Subject: [PATCH 102/194] Adding tests. --- .../syntacticClassificationsDocComment2.ts | 26 +++++++++++++++++++ .../syntacticClassificationsDocComment3.ts | 20 ++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 tests/cases/fourslash/syntacticClassificationsDocComment2.ts create mode 100644 tests/cases/fourslash/syntacticClassificationsDocComment3.ts diff --git a/tests/cases/fourslash/syntacticClassificationsDocComment2.ts b/tests/cases/fourslash/syntacticClassificationsDocComment2.ts new file mode 100644 index 00000000000..201251dde6d --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsDocComment2.ts @@ -0,0 +1,26 @@ +/// + +//// /** @param foo { function(x): string } */ +//// var v; + + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("/** "), + c.punctuation("@"), + c.docCommentTagName("param"), + c.comment(" "), + c.parameterName("foo"), + c.comment(" "), + c.punctuation("{"), + c.keyword("function"), + c.punctuation("("), + c.text("x"), + c.punctuation(")"), + c.punctuation(":"), + c.keyword("string"), + c.punctuation("}"), + c.comment(" */"), + c.keyword("var"), + c.text("v"), + c.punctuation(";")); diff --git a/tests/cases/fourslash/syntacticClassificationsDocComment3.ts b/tests/cases/fourslash/syntacticClassificationsDocComment3.ts new file mode 100644 index 00000000000..bdc7faa470e --- /dev/null +++ b/tests/cases/fourslash/syntacticClassificationsDocComment3.ts @@ -0,0 +1,20 @@ +/// + +//// /** @param foo { number /* } */ +//// var v; + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("/** "), + c.punctuation("@"), + c.docCommentTagName("param"), + c.comment(" "), + c.parameterName("foo"), + c.comment(" "), + c.punctuation("{"), + c.keyword("number"), + c.comment(" /* } */"), + c.comment("/* } */"), + c.keyword("var"), + c.text("v"), + c.punctuation(";")); From a7550dbba170ee1e1fcda83354c593526cfad223 Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Tue, 2 Jun 2015 15:25:01 -0700 Subject: [PATCH 103/194] CR feedback --- src/server/client.ts | 2 +- src/server/protocol.d.ts | 17 +++++++++++++++-- tests/cases/fourslash/server/projectInfo.ts | 20 +++++++++++++++++--- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/server/client.ts b/src/server/client.ts index 2cfd911b7b5..f1c5e424d47 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -175,7 +175,7 @@ module ts.server { getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo { var args: protocol.ProjectInfoRequestArgs = { file: fileName, - needFileNameList: !!needFileNameList + needFileNameList: needFileNameList }; var request = this.processRequest(CommandNames.ProjectInfo, args); diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index 41e25661112..ef9ad7984f6 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -88,7 +88,7 @@ declare module ts.server.protocol { } /** - * Arguments for ProjectInfoResponse messages. + * Arguments for ProjectInfoRequest request. */ export interface ProjectInfoRequestArgs extends FileRequestArgs { /** @@ -97,18 +97,31 @@ declare module ts.server.protocol { needFileNameList: boolean; } + /** + * A request to get the project information of the current file + */ export interface ProjectInfoRequest extends Request { arguments: ProjectInfoRequestArgs } /** - * Response message for "projectInfo" request + * Response message body for "projectInfo" request */ export interface ProjectInfo { + /** + * For configured project, this is the normalized path of the 'tsconfig.json' file + * For inferred project, this is undefined + */ configFileName: string; + /** + * The list of normalized file name in the project, including 'lib.d.ts' + */ fileNameList?: string[]; } + /** + * Response message for "projectInfo" request + */ export interface ProjectInfoResponse extends Response { body?: ProjectInfo; } diff --git a/tests/cases/fourslash/server/projectInfo.ts b/tests/cases/fourslash/server/projectInfo.ts index d08c7dd85f1..656647715f0 100644 --- a/tests/cases/fourslash/server/projectInfo.ts +++ b/tests/cases/fourslash/server/projectInfo.ts @@ -1,10 +1,24 @@ /// // @Filename: a.ts -//// import test from "b" +////export var test = "test String" // @Filename: b.ts -//// export var test = "test String" +////import test from "a" + +// @Filename: c.ts +/////// +/////// + +// @Filename: d.ts +////console.log("nothing"); goTo.file("a.ts") -verify.ProjectInfo(["lib.d.ts", "b.ts", "a.ts"]) +verify.ProjectInfo(["lib.d.ts", "a.ts"]) +goTo.file("b.ts") +verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts"]) +goTo.file("c.ts") +verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts", "c.ts"]) +goTo.file("d.ts") +verify.ProjectInfo(["lib.d.ts", "d.ts"]) + From e93b7a75ce38177c57ee0df1684fdc94d01f418e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 2 Jun 2015 14:59:46 -0700 Subject: [PATCH 104/194] Added tests. --- .../asiPreventsParsingAsAmbientExternalModule01.ts | 8 ++++++++ .../asiPreventsParsingAsAmbientExternalModule02.ts | 10 ++++++++++ .../asiPreventsParsingAsNamespace01.ts | 7 +++++++ .../asiPreventsParsingAsNamespace02.ts | 7 +++++++ .../asiPreventsParsingAsNamespace03.ts | 9 +++++++++ .../typeAliases/asiPreventsParsingAsTypeAlias01.ts | 7 +++++++ .../typeAliases/asiPreventsParsingAsTypeAlias02.ts | 9 +++++++++ 7 files changed, 57 insertions(+) create mode 100644 tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule01.ts create mode 100644 tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule02.ts create mode 100644 tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace01.ts create mode 100644 tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace02.ts create mode 100644 tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace03.ts create mode 100644 tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias01.ts create mode 100644 tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias02.ts diff --git a/tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule01.ts b/tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule01.ts new file mode 100644 index 00000000000..73dcd821f65 --- /dev/null +++ b/tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule01.ts @@ -0,0 +1,8 @@ + +var declare: number; +var module: string; + +declare // this is the identifier 'declare' +module // this is the identifier 'module' +"my external module" // this is just a string +{ } // this is a block body \ No newline at end of file diff --git a/tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule02.ts b/tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule02.ts new file mode 100644 index 00000000000..ba0b2d48d62 --- /dev/null +++ b/tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule02.ts @@ -0,0 +1,10 @@ + +var declare: number; +var module: string; + +module container { + declare // this is the identifier 'declare' + module // this is the identifier 'module' + "my external module" // this is just a string + { } // this is a block body +} \ No newline at end of file diff --git a/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace01.ts b/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace01.ts new file mode 100644 index 00000000000..f3bced2be48 --- /dev/null +++ b/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace01.ts @@ -0,0 +1,7 @@ + +var namespace: number; +var n: string; + +namespace // this is the identifier 'namespace' +n // this is the identifier 'n' +{ } // this is a block body \ No newline at end of file diff --git a/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace02.ts b/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace02.ts new file mode 100644 index 00000000000..63004ef3b62 --- /dev/null +++ b/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace02.ts @@ -0,0 +1,7 @@ + +var module: number; +var m: string; + +module // this is the identifier 'namespace' +m // this is the identifier 'm' +{ } // this is a block body \ No newline at end of file diff --git a/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace03.ts b/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace03.ts new file mode 100644 index 00000000000..de560b7fff4 --- /dev/null +++ b/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace03.ts @@ -0,0 +1,9 @@ + +var namespace: number; +var n: string; + +namespace container { + namespace // this is the identifier 'namespace' + n // this is the identifier 'n' + { } // this is a block body +} \ No newline at end of file diff --git a/tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias01.ts b/tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias01.ts new file mode 100644 index 00000000000..8c4bc6e5420 --- /dev/null +++ b/tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias01.ts @@ -0,0 +1,7 @@ + +var type; +var string; +var Foo; + +type +Foo = string; \ No newline at end of file diff --git a/tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias02.ts b/tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias02.ts new file mode 100644 index 00000000000..9357dbbfe09 --- /dev/null +++ b/tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias02.ts @@ -0,0 +1,9 @@ + +var type; +var string; +var Foo; + +namespace container { + type + Foo = string; +} \ No newline at end of file From 448e8bf0c7d5adae72cfb0e12bfdae1e2a01bc4d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 2 Jun 2015 15:47:23 -0700 Subject: [PATCH 105/194] Added baselines. --- ...PreventsParsingAsAmbientExternalModule01.js | 13 +++++++++++++ ...ntsParsingAsAmbientExternalModule01.symbols | 12 ++++++++++++ ...ventsParsingAsAmbientExternalModule01.types | 12 ++++++++++++ ...ParsingAsAmbientExternalModule02.errors.txt | 16 ++++++++++++++++ ...PreventsParsingAsAmbientExternalModule02.js | 15 +++++++++++++++ .../asiPreventsParsingAsNamespace01.js | 12 ++++++++++++ .../asiPreventsParsingAsNamespace01.symbols | 13 +++++++++++++ .../asiPreventsParsingAsNamespace01.types | 13 +++++++++++++ .../asiPreventsParsingAsNamespace02.js | 12 ++++++++++++ .../asiPreventsParsingAsNamespace02.symbols | 13 +++++++++++++ .../asiPreventsParsingAsNamespace02.types | 13 +++++++++++++ .../asiPreventsParsingAsNamespace03.js | 14 ++++++++++++++ .../asiPreventsParsingAsNamespace03.symbols | 17 +++++++++++++++++ .../asiPreventsParsingAsNamespace03.types | 17 +++++++++++++++++ .../asiPreventsParsingAsTypeAlias01.js | 13 +++++++++++++ .../asiPreventsParsingAsTypeAlias01.symbols | 15 +++++++++++++++ .../asiPreventsParsingAsTypeAlias01.types | 15 +++++++++++++++ .../asiPreventsParsingAsTypeAlias02.js | 15 +++++++++++++++ .../asiPreventsParsingAsTypeAlias02.symbols | 18 ++++++++++++++++++ .../asiPreventsParsingAsTypeAlias02.types | 18 ++++++++++++++++++ 20 files changed, 286 insertions(+) create mode 100644 tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.js create mode 100644 tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.symbols create mode 100644 tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.types create mode 100644 tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.errors.txt create mode 100644 tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.js create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace01.js create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace01.symbols create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace01.types create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace02.js create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace02.symbols create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace02.types create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace03.js create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace03.symbols create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace03.types create mode 100644 tests/baselines/reference/asiPreventsParsingAsTypeAlias01.js create mode 100644 tests/baselines/reference/asiPreventsParsingAsTypeAlias01.symbols create mode 100644 tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types create mode 100644 tests/baselines/reference/asiPreventsParsingAsTypeAlias02.js create mode 100644 tests/baselines/reference/asiPreventsParsingAsTypeAlias02.symbols create mode 100644 tests/baselines/reference/asiPreventsParsingAsTypeAlias02.types diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.js b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.js new file mode 100644 index 00000000000..efd82f27d1f --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.js @@ -0,0 +1,13 @@ +//// [asiPreventsParsingAsAmbientExternalModule01.ts] + +var declare: number; +var module: string; + +declare // this is the identifier 'declare' +module // this is the identifier 'module' +"my external module" // this is just a string +{ } // this is a block body + +//// [asiPreventsParsingAsAmbientExternalModule01.js] +var declare; +var module; diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.symbols b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.symbols new file mode 100644 index 00000000000..87eb8daf7e2 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule01.ts === + +var declare: number; +>declare : Symbol(declare, Decl(asiPreventsParsingAsAmbientExternalModule01.ts, 1, 3)) + +var module: string; +>module : Symbol(module, Decl(asiPreventsParsingAsAmbientExternalModule01.ts, 2, 3)) + +declare // this is the identifier 'declare' +module // this is the identifier 'module' +"my external module" // this is just a string +{ } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.types b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.types new file mode 100644 index 00000000000..94a2cc8d6a1 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.types @@ -0,0 +1,12 @@ +=== tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule01.ts === + +var declare: number; +>declare : number + +var module: string; +>module : string + +declare // this is the identifier 'declare' +module // this is the identifier 'module' +"my external module" // this is just a string +{ } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.errors.txt b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.errors.txt new file mode 100644 index 00000000000..3064b137a19 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.errors.txt @@ -0,0 +1,16 @@ +tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule02.ts(8,5): error TS2435: Ambient modules cannot be nested in other modules. + + +==== tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule02.ts (1 errors) ==== + + var declare: number; + var module: string; + + module container { + declare // this is the identifier 'declare' + module // this is the identifier 'module' + "my external module" // this is just a string + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2435: Ambient modules cannot be nested in other modules. + { } // this is a block body + } \ No newline at end of file diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.js b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.js new file mode 100644 index 00000000000..444b4b392c9 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.js @@ -0,0 +1,15 @@ +//// [asiPreventsParsingAsAmbientExternalModule02.ts] + +var declare: number; +var module: string; + +module container { + declare // this is the identifier 'declare' + module // this is the identifier 'module' + "my external module" // this is just a string + { } // this is a block body +} + +//// [asiPreventsParsingAsAmbientExternalModule02.js] +var declare; +var module; diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace01.js b/tests/baselines/reference/asiPreventsParsingAsNamespace01.js new file mode 100644 index 00000000000..eed9769da69 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace01.js @@ -0,0 +1,12 @@ +//// [asiPreventsParsingAsNamespace01.ts] + +var namespace: number; +var n: string; + +namespace // this is the identifier 'namespace' +n // this is the identifier 'n' +{ } // this is a block body + +//// [asiPreventsParsingAsNamespace01.js] +var namespace; +var n; diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace01.symbols b/tests/baselines/reference/asiPreventsParsingAsNamespace01.symbols new file mode 100644 index 00000000000..a2494904bed --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace01.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace01.ts === + +var namespace: number; +>namespace : Symbol(namespace, Decl(asiPreventsParsingAsNamespace01.ts, 1, 3)) + +var n: string; +>n : Symbol(n, Decl(asiPreventsParsingAsNamespace01.ts, 2, 3), Decl(asiPreventsParsingAsNamespace01.ts, 2, 14)) + +namespace // this is the identifier 'namespace' +n // this is the identifier 'n' +>n : Symbol(n, Decl(asiPreventsParsingAsNamespace01.ts, 2, 3), Decl(asiPreventsParsingAsNamespace01.ts, 2, 14)) + +{ } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace01.types b/tests/baselines/reference/asiPreventsParsingAsNamespace01.types new file mode 100644 index 00000000000..87044c58066 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace01.types @@ -0,0 +1,13 @@ +=== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace01.ts === + +var namespace: number; +>namespace : number + +var n: string; +>n : string + +namespace // this is the identifier 'namespace' +n // this is the identifier 'n' +>n : string + +{ } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace02.js b/tests/baselines/reference/asiPreventsParsingAsNamespace02.js new file mode 100644 index 00000000000..de2bdfa8a9e --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace02.js @@ -0,0 +1,12 @@ +//// [asiPreventsParsingAsNamespace02.ts] + +var module: number; +var m: string; + +module // this is the identifier 'namespace' +m // this is the identifier 'm' +{ } // this is a block body + +//// [asiPreventsParsingAsNamespace02.js] +var module; +var m; diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace02.symbols b/tests/baselines/reference/asiPreventsParsingAsNamespace02.symbols new file mode 100644 index 00000000000..70024a8de62 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace02.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace02.ts === + +var module: number; +>module : Symbol(module, Decl(asiPreventsParsingAsNamespace02.ts, 1, 3)) + +var m: string; +>m : Symbol(m, Decl(asiPreventsParsingAsNamespace02.ts, 2, 3), Decl(asiPreventsParsingAsNamespace02.ts, 2, 14)) + +module // this is the identifier 'namespace' +m // this is the identifier 'm' +>m : Symbol(m, Decl(asiPreventsParsingAsNamespace02.ts, 2, 3), Decl(asiPreventsParsingAsNamespace02.ts, 2, 14)) + +{ } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace02.types b/tests/baselines/reference/asiPreventsParsingAsNamespace02.types new file mode 100644 index 00000000000..8f6dec87a00 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace02.types @@ -0,0 +1,13 @@ +=== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace02.ts === + +var module: number; +>module : number + +var m: string; +>m : string + +module // this is the identifier 'namespace' +m // this is the identifier 'm' +>m : string + +{ } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace03.js b/tests/baselines/reference/asiPreventsParsingAsNamespace03.js new file mode 100644 index 00000000000..6d8b8970977 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace03.js @@ -0,0 +1,14 @@ +//// [asiPreventsParsingAsNamespace03.ts] + +var namespace: number; +var n: string; + +namespace container { + namespace // this is the identifier 'namespace' + n // this is the identifier 'n' + { } // this is a block body +} + +//// [asiPreventsParsingAsNamespace03.js] +var namespace; +var n; diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace03.symbols b/tests/baselines/reference/asiPreventsParsingAsNamespace03.symbols new file mode 100644 index 00000000000..8dfa30c17a4 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace03.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace03.ts === + +var namespace: number; +>namespace : Symbol(namespace, Decl(asiPreventsParsingAsNamespace03.ts, 1, 3)) + +var n: string; +>n : Symbol(n, Decl(asiPreventsParsingAsNamespace03.ts, 2, 3)) + +namespace container { +>container : Symbol(container, Decl(asiPreventsParsingAsNamespace03.ts, 2, 14)) + + namespace // this is the identifier 'namespace' + n // this is the identifier 'n' +>n : Symbol(n, Decl(asiPreventsParsingAsNamespace03.ts, 4, 21)) + + { } // this is a block body +} diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace03.types b/tests/baselines/reference/asiPreventsParsingAsNamespace03.types new file mode 100644 index 00000000000..37423757159 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace03.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace03.ts === + +var namespace: number; +>namespace : number + +var n: string; +>n : string + +namespace container { +>container : any + + namespace // this is the identifier 'namespace' + n // this is the identifier 'n' +>n : any + + { } // this is a block body +} diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.js b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.js new file mode 100644 index 00000000000..33e3895fab4 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.js @@ -0,0 +1,13 @@ +//// [asiPreventsParsingAsTypeAlias01.ts] + +var type; +var string; +var Foo; + +type +Foo = string; + +//// [asiPreventsParsingAsTypeAlias01.js] +var type; +var string; +var Foo; diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.symbols b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.symbols new file mode 100644 index 00000000000..d11c9ff5c13 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.symbols @@ -0,0 +1,15 @@ +=== tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias01.ts === + +var type; +>type : Symbol(type, Decl(asiPreventsParsingAsTypeAlias01.ts, 1, 3)) + +var string; +>string : Symbol(string, Decl(asiPreventsParsingAsTypeAlias01.ts, 2, 3)) + +var Foo; +>Foo : Symbol(Foo, Decl(asiPreventsParsingAsTypeAlias01.ts, 3, 3), Decl(asiPreventsParsingAsTypeAlias01.ts, 3, 8)) + +type +Foo = string; +>Foo : Symbol(Foo, Decl(asiPreventsParsingAsTypeAlias01.ts, 3, 3), Decl(asiPreventsParsingAsTypeAlias01.ts, 3, 8)) + diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types new file mode 100644 index 00000000000..d112022afa4 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types @@ -0,0 +1,15 @@ +=== tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias01.ts === + +var type; +>type : any + +var string; +>string : any + +var Foo; +>Foo : any + +type +Foo = string; +>Foo : string + diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.js b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.js new file mode 100644 index 00000000000..4a8298b2bdf --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.js @@ -0,0 +1,15 @@ +//// [asiPreventsParsingAsTypeAlias02.ts] + +var type; +var string; +var Foo; + +namespace container { + type + Foo = string; +} + +//// [asiPreventsParsingAsTypeAlias02.js] +var type; +var string; +var Foo; diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.symbols b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.symbols new file mode 100644 index 00000000000..0da88560109 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.symbols @@ -0,0 +1,18 @@ +=== tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias02.ts === + +var type; +>type : Symbol(type, Decl(asiPreventsParsingAsTypeAlias02.ts, 1, 3)) + +var string; +>string : Symbol(string, Decl(asiPreventsParsingAsTypeAlias02.ts, 2, 3)) + +var Foo; +>Foo : Symbol(Foo, Decl(asiPreventsParsingAsTypeAlias02.ts, 3, 3)) + +namespace container { +>container : Symbol(container, Decl(asiPreventsParsingAsTypeAlias02.ts, 3, 8)) + + type + Foo = string; +>Foo : Symbol(Foo, Decl(asiPreventsParsingAsTypeAlias02.ts, 5, 21)) +} diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.types b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.types new file mode 100644 index 00000000000..4af0721ec24 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.types @@ -0,0 +1,18 @@ +=== tests/cases/conformance/types/typeAliases/asiPreventsParsingAsTypeAlias02.ts === + +var type; +>type : any + +var string; +>string : any + +var Foo; +>Foo : any + +namespace container { +>container : any + + type + Foo = string; +>Foo : string +} From a10cd1e8226d97c904b35dffcd5d7890f4cbb062 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 2 Jun 2015 15:48:59 -0700 Subject: [PATCH 106/194] Update LKG --- bin/tsc.js | 24 ++++++++++++++---------- bin/tsserver.js | 24 ++++++++++++++---------- bin/typescript.js | 24 ++++++++++++++---------- bin/typescriptServices.js | 24 ++++++++++++++---------- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/bin/tsc.js b/bin/tsc.js index 8c1542d6c7b..01d312f2083 100644 --- a/bin/tsc.js +++ b/bin/tsc.js @@ -8892,27 +8892,31 @@ var ts; case 138: case 201: case 164: - if (name === "arguments") { + if (meaning & 3 && name === "arguments") { result = argumentsSymbol; break loop; } break; case 163: - if (name === "arguments") { + if (meaning & 3 && name === "arguments") { result = argumentsSymbol; break loop; } - var functionName = location.name; - if (functionName && name === functionName.text) { - result = location.symbol; - break loop; + if (meaning & 16) { + var functionName = location.name; + if (functionName && name === functionName.text) { + result = location.symbol; + break loop; + } } break; case 175: - var className = location.name; - if (className && name === className.text) { - result = location.symbol; - break loop; + if (meaning & 32) { + var className = location.name; + if (className && name === className.text) { + result = location.symbol; + break loop; + } } break; case 131: diff --git a/bin/tsserver.js b/bin/tsserver.js index 4f175eee95b..6cdb8f9560c 100644 --- a/bin/tsserver.js +++ b/bin/tsserver.js @@ -9282,27 +9282,31 @@ var ts; case 138: case 201: case 164: - if (name === "arguments") { + if (meaning & 3 && name === "arguments") { result = argumentsSymbol; break loop; } break; case 163: - if (name === "arguments") { + if (meaning & 3 && name === "arguments") { result = argumentsSymbol; break loop; } - var functionName = location.name; - if (functionName && name === functionName.text) { - result = location.symbol; - break loop; + if (meaning & 16) { + var functionName = location.name; + if (functionName && name === functionName.text) { + result = location.symbol; + break loop; + } } break; case 175: - var className = location.name; - if (className && name === className.text) { - result = location.symbol; - break loop; + if (meaning & 32) { + var className = location.name; + if (className && name === className.text) { + result = location.symbol; + break loop; + } } break; case 131: diff --git a/bin/typescript.js b/bin/typescript.js index a60814cc7fd..dbede84a76e 100644 --- a/bin/typescript.js +++ b/bin/typescript.js @@ -11147,27 +11147,31 @@ var ts; case 138 /* SetAccessor */: case 201 /* FunctionDeclaration */: case 164 /* ArrowFunction */: - if (name === "arguments") { + if (meaning & 3 /* Variable */ && name === "arguments") { result = argumentsSymbol; break loop; } break; case 163 /* FunctionExpression */: - if (name === "arguments") { + if (meaning & 3 /* Variable */ && name === "arguments") { result = argumentsSymbol; break loop; } - var functionName = location.name; - if (functionName && name === functionName.text) { - result = location.symbol; - break loop; + if (meaning & 16 /* Function */) { + var functionName = location.name; + if (functionName && name === functionName.text) { + result = location.symbol; + break loop; + } } break; case 175 /* ClassExpression */: - var className = location.name; - if (className && name === className.text) { - result = location.symbol; - break loop; + if (meaning & 32 /* Class */) { + var className = location.name; + if (className && name === className.text) { + result = location.symbol; + break loop; + } } break; case 131 /* Decorator */: diff --git a/bin/typescriptServices.js b/bin/typescriptServices.js index a60814cc7fd..dbede84a76e 100644 --- a/bin/typescriptServices.js +++ b/bin/typescriptServices.js @@ -11147,27 +11147,31 @@ var ts; case 138 /* SetAccessor */: case 201 /* FunctionDeclaration */: case 164 /* ArrowFunction */: - if (name === "arguments") { + if (meaning & 3 /* Variable */ && name === "arguments") { result = argumentsSymbol; break loop; } break; case 163 /* FunctionExpression */: - if (name === "arguments") { + if (meaning & 3 /* Variable */ && name === "arguments") { result = argumentsSymbol; break loop; } - var functionName = location.name; - if (functionName && name === functionName.text) { - result = location.symbol; - break loop; + if (meaning & 16 /* Function */) { + var functionName = location.name; + if (functionName && name === functionName.text) { + result = location.symbol; + break loop; + } } break; case 175 /* ClassExpression */: - var className = location.name; - if (className && name === className.text) { - result = location.symbol; - break loop; + if (meaning & 32 /* Class */) { + var className = location.name; + if (className && name === className.text) { + result = location.symbol; + break loop; + } } break; case 131 /* Decorator */: From 7ef2cfeaebe48dc6e996f56b4d917591c0c9996a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Jun 2015 16:05:01 -0700 Subject: [PATCH 107/194] Simple changes to the compiler to make the jsDoc work easier. --- src/compiler/binder.ts | 10 ++--- src/compiler/checker.ts | 77 +++++++++++++++++++++++---------------- src/compiler/emitter.ts | 4 +- src/compiler/utilities.ts | 8 ---- 4 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 82cfd59a5d6..b6352d14efd 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -111,12 +111,12 @@ module ts { return (node.name).text; } switch (node.kind) { - case SyntaxKind.ConstructorType: case SyntaxKind.Constructor: return "__constructor"; case SyntaxKind.FunctionType: case SyntaxKind.CallSignature: return "__call"; + case SyntaxKind.ConstructorType: case SyntaxKind.ConstructSignature: return "__new"; case SyntaxKind.IndexSignature: @@ -380,7 +380,7 @@ module ts { let typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); typeLiteralSymbol.members = {}; - typeLiteralSymbol.members[node.kind === SyntaxKind.FunctionType ? "__call" : "__new"] = symbol + typeLiteralSymbol.members[symbol.name] = symbol } function bindAnonymousDeclaration(node: Declaration, symbolKind: SymbolFlags, name: string, isBlockScopeContainer: boolean) { @@ -592,10 +592,8 @@ module ts { bindChildren(node, 0, /*isBlockScopeContainer*/ true); break; default: - let saveParent = parent; - parent = node; - forEachChild(node, bind); - parent = saveParent; + bindChildren(node, 0, /*isBlockScopeContainer:*/ false); + break; } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c6c2373f706..fad7293412e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1799,11 +1799,12 @@ module ts { } function buildParameterDisplay(p: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { - if (hasDotDotDotToken(p.valueDeclaration)) { + let parameterNode = p.valueDeclaration; + if (isRestParameter(parameterNode)) { writePunctuation(writer, SyntaxKind.DotDotDotToken); } appendSymbolNameOnly(p, writer); - if (hasQuestionToken(p.valueDeclaration) || (p.valueDeclaration).initializer) { + if (isOptionalParameter(parameterNode)) { writePunctuation(writer, SyntaxKind.QuestionToken); } writePunctuation(writer, SyntaxKind.ColonToken); @@ -3197,6 +3198,10 @@ module ts { return result; } + function isOptionalParameter(node: ParameterDeclaration) { + return hasQuestionToken(node) || !!node.initializer; + } + function getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature { let links = getNodeLinks(declaration); if (!links.resolvedSignature) { @@ -3244,7 +3249,7 @@ module ts { } links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, - minArgumentCount, hasRestParameters(declaration), hasStringLiterals); + minArgumentCount, hasRestParameter(declaration), hasStringLiterals); } return links.resolvedSignature; } @@ -3520,42 +3525,50 @@ module ts { type = unknownType; } else { - type = getDeclaredTypeOfSymbol(symbol); - if (type.flags & (TypeFlags.Class | TypeFlags.Interface) && type.flags & TypeFlags.Reference) { - // In a type reference, the outer type parameters of the referenced class or interface are automatically - // supplied as type arguments and the type reference only specifies arguments for the local type parameters - // of the class or interface. - let localTypeParameters = (type).localTypeParameters; - let expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; - let typeArgCount = node.typeArguments ? node.typeArguments.length : 0; - if (typeArgCount === expectedTypeArgCount) { - // When no type arguments are expected we already have the right type because all outer type parameters - // have themselves as default type arguments. - if (typeArgCount) { - type = createTypeReference(type, concatenate((type).outerTypeParameters, - map(node.typeArguments, getTypeFromTypeNode))); - } - } - else { - error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), expectedTypeArgCount); - type = undefined; - } - } - else { - if (node.typeArguments) { - error(node, Diagnostics.Type_0_is_not_generic, typeToString(type)); - type = undefined; - } - } + type = createTypeReferenceIfGeneric( + getDeclaredTypeOfSymbol(symbol), + node, node.typeArguments); } } } links.resolvedType = type || unknownType; } + return links.resolvedType; } + function createTypeReferenceIfGeneric(type: Type, node: Node, typeArguments: NodeArray): Type { + if (type.flags & (TypeFlags.Class | TypeFlags.Interface) && type.flags & TypeFlags.Reference) { + // In a type reference, the outer type parameters of the referenced class or interface are automatically + // supplied as type arguments and the type reference only specifies arguments for the local type parameters + // of the class or interface. + let localTypeParameters = (type).localTypeParameters; + let expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; + let typeArgCount = typeArguments ? typeArguments.length : 0; + if (typeArgCount === expectedTypeArgCount) { + // When no type arguments are expected we already have the right type because all outer type parameters + // have themselves as default type arguments. + if (typeArgCount) { + return createTypeReference(type, concatenate((type).outerTypeParameters, + map(typeArguments, getTypeFromTypeNode))); + } + } + else { + error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), expectedTypeArgCount); + return undefined; + } + } + else { + if (typeArguments) { + error(node, Diagnostics.Type_0_is_not_generic, typeToString(type)); + return undefined; + } + } + + return type; + } + function getTypeFromTypeQueryNode(node: TypeQueryNode): Type { let links = getNodeLinks(node); if (!links.resolvedType) { @@ -5858,7 +5871,7 @@ module ts { let contextualSignature = getContextualSignature(func); if (contextualSignature) { - let funcHasRestParameters = hasRestParameters(func); + let funcHasRestParameters = hasRestParameter(func); let len = func.parameters.length - (funcHasRestParameters ? 1 : 0); let indexOfParameter = indexOf(func.parameters, parameter); if (indexOfParameter < len) { @@ -9330,7 +9343,7 @@ module ts { function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) { // no rest parameters \ declaration context \ overload - no codegen impact - if (!hasRestParameters(node) || isInAmbientContext(node) || nodeIsMissing((node).body)) { + if (!hasRestParameter(node) || isInAmbientContext(node) || nodeIsMissing((node).body)) { return; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 92afacdafca..d0d65aec2fb 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3205,7 +3205,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } function emitRestParameter(node: FunctionLikeDeclaration) { - if (languageVersion < ScriptTarget.ES6 && hasRestParameters(node)) { + if (languageVersion < ScriptTarget.ES6 && hasRestParameter(node)) { let restIndex = node.parameters.length - 1; let restParam = node.parameters[restIndex]; @@ -3333,7 +3333,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { write("("); if (node) { let parameters = node.parameters; - let omitCount = languageVersion < ScriptTarget.ES6 && hasRestParameters(node) ? 1 : 0; + let omitCount = languageVersion < ScriptTarget.ES6 && hasRestParameter(node) ? 1 : 0; emitList(parameters, 0, parameters.length - omitCount, /*multiLine*/ false, /*trailingComma*/ false); } write(")"); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6ac59b6a6ea..133be3d3d83 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -963,10 +963,6 @@ module ts { } } - export function hasDotDotDotToken(node: Node) { - return node && node.kind === SyntaxKind.Parameter && (node).dotDotDotToken !== undefined; - } - export function hasQuestionToken(node: Node) { if (node) { switch (node.kind) { @@ -986,10 +982,6 @@ module ts { return false; } - export function hasRestParameters(s: SignatureDeclaration): boolean { - return s.parameters.length > 0 && lastOrUndefined(s.parameters).dotDotDotToken !== undefined; - } - export function isJSDocConstructSignature(node: Node) { return node.kind === SyntaxKind.JSDocFunctionType && (node).parameters.length > 0 && From 77306a3ea6192c7eb56cd57371001ddcb156c71f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 2 Jun 2015 17:08:51 -0700 Subject: [PATCH 108/194] Added more tests. --- .../asiPreventsParsingAsNamespace04.ts | 3 +++ .../asiPreventsParsingAsNamespace05.ts | 10 ++++++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace04.ts create mode 100644 tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace05.ts diff --git a/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace04.ts b/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace04.ts new file mode 100644 index 00000000000..03021576ea5 --- /dev/null +++ b/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace04.ts @@ -0,0 +1,3 @@ + +let module = 10; +module in {} \ No newline at end of file diff --git a/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace05.ts b/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace05.ts new file mode 100644 index 00000000000..a821dbc363c --- /dev/null +++ b/tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace05.ts @@ -0,0 +1,10 @@ + +let namespace = 10; +namespace a.b { + export let c = 20; +} + +namespace +a.b.c +{ +} \ No newline at end of file From 70f74ad640a2f029b3df749273e58bcaa216b4f0 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 2 Jun 2015 17:31:20 -0700 Subject: [PATCH 109/194] Accepted more baselines. --- .../asiPreventsParsingAsNamespace04.errors.txt | 9 +++++++++ .../reference/asiPreventsParsingAsNamespace04.js | 8 ++++++++ .../reference/asiPreventsParsingAsNamespace05.js | 11 +++++++++++ .../asiPreventsParsingAsNamespace05.symbols | 12 ++++++++++++ .../reference/asiPreventsParsingAsNamespace05.types | 13 +++++++++++++ 5 files changed, 53 insertions(+) create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace04.errors.txt create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace04.js create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace05.js create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace05.symbols create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace05.types diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace04.errors.txt b/tests/baselines/reference/asiPreventsParsingAsNamespace04.errors.txt new file mode 100644 index 00000000000..d0a6be446aa --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace04.errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace04.ts(3,8): error TS1003: Identifier expected. + + +==== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace04.ts (1 errors) ==== + + let module = 10; + module in {} + ~~ +!!! error TS1003: Identifier expected. \ No newline at end of file diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace04.js b/tests/baselines/reference/asiPreventsParsingAsNamespace04.js new file mode 100644 index 00000000000..bcd8975d46d --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace04.js @@ -0,0 +1,8 @@ +//// [asiPreventsParsingAsNamespace04.ts] + +let module = 10; +module in {} + +//// [asiPreventsParsingAsNamespace04.js] +var module = 10; + in {}; diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace05.js b/tests/baselines/reference/asiPreventsParsingAsNamespace05.js new file mode 100644 index 00000000000..0a525179d2d --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace05.js @@ -0,0 +1,11 @@ +//// [asiPreventsParsingAsNamespace05.ts] + +let namespace = 10; + +namespace +a.b.c +{ +} + +//// [asiPreventsParsingAsNamespace05.js] +var namespace = 10; diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace05.symbols b/tests/baselines/reference/asiPreventsParsingAsNamespace05.symbols new file mode 100644 index 00000000000..65125806b61 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace05.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace05.ts === + +let namespace = 10; +>namespace : Symbol(namespace, Decl(asiPreventsParsingAsNamespace05.ts, 1, 3)) + +namespace +a.b.c +>a : Symbol(a, Decl(asiPreventsParsingAsNamespace05.ts, 1, 19)) +>b : Symbol(b, Decl(asiPreventsParsingAsNamespace05.ts, 4, 2)) +>c : Symbol(c, Decl(asiPreventsParsingAsNamespace05.ts, 4, 4)) +{ +} diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace05.types b/tests/baselines/reference/asiPreventsParsingAsNamespace05.types new file mode 100644 index 00000000000..f17ad1f2a1e --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace05.types @@ -0,0 +1,13 @@ +=== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace05.ts === + +let namespace = 10; +>namespace : number +>10 : number + +namespace +a.b.c +>a : any +>b : any +>c : any +{ +} From 1bd7f5274a370061fb22871abca0e0eac94ccc68 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 2 Jun 2015 17:33:57 -0700 Subject: [PATCH 110/194] Return expressions always need to be type checked --- src/compiler/checker.ts | 4 ++++ ...ltiLinePropertyAccessAndArrowFunctionIndent1.errors.txt | 5 ++++- .../reference/typeCheckReturnExpression.errors.txt | 7 +++++++ tests/baselines/reference/typeCheckReturnExpression.js | 5 +++++ tests/cases/compiler/typeCheckReturnExpression.ts | 2 ++ 5 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/typeCheckReturnExpression.errors.txt create mode 100644 tests/baselines/reference/typeCheckReturnExpression.js create mode 100644 tests/cases/compiler/typeCheckReturnExpression.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fad7293412e..4023a4412de 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7657,6 +7657,10 @@ module ts { } if (node.body) { + if (!node.type) { + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } + if (node.body.kind === SyntaxKind.Block) { checkSourceElement(node.body); } diff --git a/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt b/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt index 14b7769d22f..abf11dc9dba 100644 --- a/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt +++ b/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt @@ -1,12 +1,15 @@ tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(1,1): error TS1108: A 'return' statement can only be used within a function body. +tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(1,18): error TS2304: Cannot find name 'role'. tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(2,18): error TS2304: Cannot find name 'Role'. tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(4,26): error TS2503: Cannot find namespace 'ng'. -==== tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts (3 errors) ==== +==== tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts (4 errors) ==== return this.edit(role) ~~~~~~ !!! error TS1108: A 'return' statement can only be used within a function body. + ~~~~ +!!! error TS2304: Cannot find name 'role'. .then((role: Role) => ~~~~ !!! error TS2304: Cannot find name 'Role'. diff --git a/tests/baselines/reference/typeCheckReturnExpression.errors.txt b/tests/baselines/reference/typeCheckReturnExpression.errors.txt new file mode 100644 index 00000000000..c648c57799d --- /dev/null +++ b/tests/baselines/reference/typeCheckReturnExpression.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/typeCheckReturnExpression.ts(1,11): error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type. + + +==== tests/cases/compiler/typeCheckReturnExpression.ts (1 errors) ==== + var foo = () => undefined; + ~~~~~~~~~~~~~~~ +!!! error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type. \ No newline at end of file diff --git a/tests/baselines/reference/typeCheckReturnExpression.js b/tests/baselines/reference/typeCheckReturnExpression.js new file mode 100644 index 00000000000..ba71780b48d --- /dev/null +++ b/tests/baselines/reference/typeCheckReturnExpression.js @@ -0,0 +1,5 @@ +//// [typeCheckReturnExpression.ts] +var foo = () => undefined; + +//// [typeCheckReturnExpression.js] +var foo = function () { return undefined; }; diff --git a/tests/cases/compiler/typeCheckReturnExpression.ts b/tests/cases/compiler/typeCheckReturnExpression.ts new file mode 100644 index 00000000000..00f75912bd1 --- /dev/null +++ b/tests/cases/compiler/typeCheckReturnExpression.ts @@ -0,0 +1,2 @@ +//@noImplicitAny: true +var foo = () => undefined; \ No newline at end of file From 4c18b2bcf814b8d91c655eedcb1e5926634eb2dc Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Jun 2015 17:41:34 -0700 Subject: [PATCH 111/194] Simplify code. --- src/compiler/binder.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 1b65ccd63ec..ea589891241 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -513,13 +513,12 @@ module ts { // We do that by making an anonymous type literal symbol, and then setting the function // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable // from an actual type literal symbol you would have gotten had you used the long form. - let name = getDeclarationName(node); - let symbol = createSymbol(SymbolFlags.Signature, name); + let symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node)); addDeclarationToSymbol(symbol, node, SymbolFlags.Signature); let typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); - typeLiteralSymbol.members = { [name]: symbol }; + typeLiteralSymbol.members = { [symbol.name]: symbol }; } function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) { From 155d7f48fff84f93b1c1c8399486ed53aacb3a3e Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 2 Jun 2015 17:54:08 -0700 Subject: [PATCH 112/194] Add hopefully helpful comment --- src/compiler/checker.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4023a4412de..543ab532624 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7658,6 +7658,11 @@ module ts { if (node.body) { if (!node.type) { + // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors + // we need. An example is the noImplicitAny errors resulting from widening the return expression + // of a function. Because checking of function expression bodies is deferred, there was never an + // appropriate time to do this during the main walk of the file (see the comment at the top of + // checkFunctionExpressionBodies). So it must be done now. getReturnTypeOfSignature(getSignatureFromDeclaration(node)); } From 6902b050ca9cb94ba494d0900ad48a0780850ef4 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 2 Jun 2015 18:04:05 -0700 Subject: [PATCH 113/194] Respond to code review comments --- tests/cases/unittests/transpile.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/cases/unittests/transpile.ts b/tests/cases/unittests/transpile.ts index eca136649f2..c906c03a9e0 100644 --- a/tests/cases/unittests/transpile.ts +++ b/tests/cases/unittests/transpile.ts @@ -19,33 +19,33 @@ module ts { it("Generates correct compilerOptions diagnostics", () => { // Expecting 5047: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher." - runTest(`var x = 0;`, {}, /*expectedOutput*/ undefined, [5047]); + runTest(`var x = 0;`, {}, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ [5047]); }); it("Generates no diagnostics with valid inputs", () => { // No errors - runTest(`var x = 0;`, { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, []); + runTest(`var x = 0;`, { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []); }); it("Generates no diagnostics for missing file references", () => { runTest(`/// var x = 0;`, - { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, []); + { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []); }); it("Generates no diagnostics for missing module imports", () => { runTest(`import {a} from "module2";`, - { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, []); + { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []); }); it("Generates expected syntactic diagnostics", () => { runTest(`a b`, - { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, [1005]); /// 1005: ';' Expected + { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ [1005]); /// 1005: ';' Expected }); it("Does not generate semantic diagnostics", () => { runTest(`var x: string = 0;`, - { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, []); + { module: ModuleKind.CommonJS }, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []); }); it("Generates module output", () => { @@ -53,7 +53,7 @@ var x = 0;`, }); it("Uses correct newLine character", () => { - runTest(`var x = 0;`, { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed }, `var x = 0;\n`); + runTest(`var x = 0;`, { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed }, `var x = 0;\n`, /*expectedDiagnosticCodes*/ []); }); }); } From eb7290eb7008fa1a1ade9d3928c286616ccaa795 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 2 Jun 2015 18:06:05 -0700 Subject: [PATCH 114/194] Add test for object literal methods --- .../typeCheckReturnExpressionMethodBody.errors.txt | 7 +++++++ .../reference/typeCheckReturnExpressionMethodBody.js | 5 +++++ .../cases/compiler/typeCheckReturnExpressionMethodBody.ts | 2 ++ 3 files changed, 14 insertions(+) create mode 100644 tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt create mode 100644 tests/baselines/reference/typeCheckReturnExpressionMethodBody.js create mode 100644 tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts diff --git a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt b/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt new file mode 100644 index 00000000000..a32f6548c9f --- /dev/null +++ b/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts(1,13): error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. + + +==== tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts (1 errors) ==== + var foo = { bar() { return undefined } }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. \ No newline at end of file diff --git a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.js b/tests/baselines/reference/typeCheckReturnExpressionMethodBody.js new file mode 100644 index 00000000000..3050b05268f --- /dev/null +++ b/tests/baselines/reference/typeCheckReturnExpressionMethodBody.js @@ -0,0 +1,5 @@ +//// [typeCheckReturnExpressionMethodBody.ts] +var foo = { bar() { return undefined } }; + +//// [typeCheckReturnExpressionMethodBody.js] +var foo = { bar: function () { return undefined; } }; diff --git a/tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts b/tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts new file mode 100644 index 00000000000..316572466df --- /dev/null +++ b/tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts @@ -0,0 +1,2 @@ +//@noImplicitAny: true +var foo = { bar() { return undefined } }; \ No newline at end of file From f66b9c5d77a4d427af50b34ad7081ef854d05aba Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 2 Jun 2015 18:13:39 -0700 Subject: [PATCH 115/194] Fix error message typo --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticInformationMap.generated.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- tests/baselines/reference/for-of32.errors.txt | 4 ++-- tests/baselines/reference/for-of33.errors.txt | 4 ++-- tests/baselines/reference/for-of34.errors.txt | 4 ++-- tests/baselines/reference/for-of35.errors.txt | 4 ++-- .../reference/implicitAnyFromCircularInference.errors.txt | 4 ++-- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fad7293412e..2eedf6fb190 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2373,7 +2373,7 @@ module ts { // Variable has initializer that circularly references the variable itself type = anyType; if (compilerOptions.noImplicitAny) { - error(symbol.valueDeclaration, Diagnostics._0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, + error(symbol.valueDeclaration, Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol)); } } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 8ccc9d890e2..f0b46b26dc8 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -529,7 +529,7 @@ module ts { Object_literal_s_property_0_implicitly_has_an_1_type: { code: 7018, category: DiagnosticCategory.Error, key: "Object literal's property '{0}' implicitly has an '{1}' type." }, Rest_parameter_0_implicitly_has_an_any_type: { code: 7019, category: DiagnosticCategory.Error, key: "Rest parameter '{0}' implicitly has an 'any[]' type." }, Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: { code: 7020, category: DiagnosticCategory.Error, key: "Call signature, which lacks return-type annotation, implicitly has an 'any' return type." }, - _0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: DiagnosticCategory.Error, key: "'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer." }, + _0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: DiagnosticCategory.Error, key: "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer." }, _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7023, category: DiagnosticCategory.Error, key: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." }, Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index fb246955f73..4e322725946 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2107,7 +2107,7 @@ "category": "Error", "code": 7020 }, - "'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer.": { + "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.": { "category": "Error", "code": 7022 }, diff --git a/tests/baselines/reference/for-of32.errors.txt b/tests/baselines/reference/for-of32.errors.txt index 4b139d386c0..f382ea40984 100644 --- a/tests/baselines/reference/for-of32.errors.txt +++ b/tests/baselines/reference/for-of32.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/es6/for-ofStatements/for-of32.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/es6/for-ofStatements/for-of32.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. ==== tests/cases/conformance/es6/for-ofStatements/for-of32.ts (1 errors) ==== for (var v of v) { } ~ -!!! error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. \ No newline at end of file +!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. \ No newline at end of file diff --git a/tests/baselines/reference/for-of33.errors.txt b/tests/baselines/reference/for-of33.errors.txt index cd2d48566ab..ff1feacd7b3 100644 --- a/tests/baselines/reference/for-of33.errors.txt +++ b/tests/baselines/reference/for-of33.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/for-ofStatements/for-of33.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/es6/for-ofStatements/for-of33.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. tests/cases/conformance/es6/for-ofStatements/for-of33.ts(4,5): error TS7023: '[Symbol.iterator]' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. ==== tests/cases/conformance/es6/for-ofStatements/for-of33.ts (2 errors) ==== for (var v of new StringIterator) { } ~ -!!! error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. class StringIterator { [Symbol.iterator]() { diff --git a/tests/baselines/reference/for-of34.errors.txt b/tests/baselines/reference/for-of34.errors.txt index a4f55ed29ba..c378a8f5bb8 100644 --- a/tests/baselines/reference/for-of34.errors.txt +++ b/tests/baselines/reference/for-of34.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/for-ofStatements/for-of34.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/es6/for-ofStatements/for-of34.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. tests/cases/conformance/es6/for-ofStatements/for-of34.ts(4,5): error TS7023: 'next' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. ==== tests/cases/conformance/es6/for-ofStatements/for-of34.ts (2 errors) ==== for (var v of new StringIterator) { } ~ -!!! error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. class StringIterator { next() { diff --git a/tests/baselines/reference/for-of35.errors.txt b/tests/baselines/reference/for-of35.errors.txt index 65529752b9b..58fb5056fd7 100644 --- a/tests/baselines/reference/for-of35.errors.txt +++ b/tests/baselines/reference/for-of35.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/for-ofStatements/for-of35.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/conformance/es6/for-ofStatements/for-of35.ts(1,10): error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. tests/cases/conformance/es6/for-ofStatements/for-of35.ts(4,5): error TS7023: 'next' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. ==== tests/cases/conformance/es6/for-ofStatements/for-of35.ts (2 errors) ==== for (var v of new StringIterator) { } ~ -!!! error TS7022: 'v' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +!!! error TS7022: 'v' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. class StringIterator { next() { diff --git a/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt b/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt index 8d0aaf04c03..36538aef4f3 100644 --- a/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt +++ b/tests/baselines/reference/implicitAnyFromCircularInference.errors.txt @@ -7,7 +7,7 @@ tests/cases/compiler/implicitAnyFromCircularInference.ts(18,10): error TS7024: F tests/cases/compiler/implicitAnyFromCircularInference.ts(23,10): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. tests/cases/compiler/implicitAnyFromCircularInference.ts(26,10): error TS7023: 'h' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. tests/cases/compiler/implicitAnyFromCircularInference.ts(28,14): error TS7023: 'foo' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. -tests/cases/compiler/implicitAnyFromCircularInference.ts(41,5): error TS7022: 's' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +tests/cases/compiler/implicitAnyFromCircularInference.ts(41,5): error TS7022: 's' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. tests/cases/compiler/implicitAnyFromCircularInference.ts(46,5): error TS7023: 'x' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. @@ -72,7 +72,7 @@ tests/cases/compiler/implicitAnyFromCircularInference.ts(46,5): error TS7023: 'x // Error expected s = foo(this); ~~~~~~~~~~~~~~ -!!! error TS7022: 's' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer. +!!! error TS7022: 's' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. } class D { From f390133a126b5dd7232bb8d11aded3291fd5c201 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 2 Jun 2015 18:21:39 -0700 Subject: [PATCH 116/194] Rename new test --- .../reference/typeCheckObjectLiteralMethodBody.errors.txt | 7 +++++++ ...onMethodBody.js => typeCheckObjectLiteralMethodBody.js} | 4 ++-- .../typeCheckReturnExpressionMethodBody.errors.txt | 7 ------- ...onMethodBody.ts => typeCheckObjectLiteralMethodBody.ts} | 0 4 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/typeCheckObjectLiteralMethodBody.errors.txt rename tests/baselines/reference/{typeCheckReturnExpressionMethodBody.js => typeCheckObjectLiteralMethodBody.js} (50%) delete mode 100644 tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt rename tests/cases/compiler/{typeCheckReturnExpressionMethodBody.ts => typeCheckObjectLiteralMethodBody.ts} (100%) diff --git a/tests/baselines/reference/typeCheckObjectLiteralMethodBody.errors.txt b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.errors.txt new file mode 100644 index 00000000000..7db4c2506cc --- /dev/null +++ b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts(1,13): error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. + + +==== tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts (1 errors) ==== + var foo = { bar() { return undefined } }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. \ No newline at end of file diff --git a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.js b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.js similarity index 50% rename from tests/baselines/reference/typeCheckReturnExpressionMethodBody.js rename to tests/baselines/reference/typeCheckObjectLiteralMethodBody.js index 3050b05268f..1339315e93c 100644 --- a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.js +++ b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.js @@ -1,5 +1,5 @@ -//// [typeCheckReturnExpressionMethodBody.ts] +//// [typeCheckObjectLiteralMethodBody.ts] var foo = { bar() { return undefined } }; -//// [typeCheckReturnExpressionMethodBody.js] +//// [typeCheckObjectLiteralMethodBody.js] var foo = { bar: function () { return undefined; } }; diff --git a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt b/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt deleted file mode 100644 index a32f6548c9f..00000000000 --- a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts(1,13): error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. - - -==== tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts (1 errors) ==== - var foo = { bar() { return undefined } }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. \ No newline at end of file diff --git a/tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts b/tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts similarity index 100% rename from tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts rename to tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts From 8b62a326d4fbf06c69777984256f2b8df48d1709 Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Tue, 2 Jun 2015 19:22:03 -0700 Subject: [PATCH 117/194] Dom lib file bug fix Fix #3344; removed duplicated overloads for ``createEvent`` and some minor fixes. --- src/lib/dom.generated.d.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 5a4151c0c1c..d9daefa1aeb 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -7677,10 +7677,10 @@ declare var MediaQueryList: { interface MediaSource extends EventTarget { activeSourceBuffers: SourceBufferList; duration: number; - readyState: string; + readyState: number; sourceBuffers: SourceBufferList; addSourceBuffer(type: string): SourceBuffer; - endOfStream(error?: string): void; + endOfStream(error?: number): void; removeSourceBuffer(sourceBuffer: SourceBuffer): void; } @@ -8409,7 +8409,7 @@ declare var PopStateEvent: { interface Position { coords: Coordinates; - timestamp: Date; + timestamp: number; } declare var Position: { @@ -11090,6 +11090,7 @@ interface WebGLRenderingContext { stencilMaskSeparate(face: number, mask: number): void; stencilOp(fail: number, zfail: number, zpass: number): void; stencilOpSeparate(face: number, fail: number, zfail: number, zpass: number): void; + texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels: ArrayBufferView): void; texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels: ImageData): void; texParameterf(target: number, pname: number, param: number): void; texParameteri(target: number, pname: number, param: number): void; @@ -12332,12 +12333,14 @@ interface DocumentEvent { createEvent(eventInterface:"AriaRequestEvent"): AriaRequestEvent; createEvent(eventInterface:"AudioProcessingEvent"): AudioProcessingEvent; createEvent(eventInterface:"BeforeUnloadEvent"): BeforeUnloadEvent; + createEvent(eventInterface:"ClipboardEvent"): ClipboardEvent; createEvent(eventInterface:"CloseEvent"): CloseEvent; createEvent(eventInterface:"CommandEvent"): CommandEvent; createEvent(eventInterface:"CompositionEvent"): CompositionEvent; - createEvent(eventInterface: "CustomEvent"): CustomEvent; + createEvent(eventInterface:"CustomEvent"): CustomEvent; createEvent(eventInterface:"DeviceMotionEvent"): DeviceMotionEvent; createEvent(eventInterface:"DeviceOrientationEvent"): DeviceOrientationEvent; + createEvent(eventInterface:"DocumentEvent"): DocumentEvent; createEvent(eventInterface:"DragEvent"): DragEvent; createEvent(eventInterface:"ErrorEvent"): ErrorEvent; createEvent(eventInterface:"Event"): Event; @@ -12358,8 +12361,6 @@ interface DocumentEvent { createEvent(eventInterface:"MouseEvent"): MouseEvent; createEvent(eventInterface:"MouseEvents"): MouseEvent; createEvent(eventInterface:"MouseWheelEvent"): MouseWheelEvent; - createEvent(eventInterface:"MSGestureEvent"): MSGestureEvent; - createEvent(eventInterface:"MSPointerEvent"): MSPointerEvent; createEvent(eventInterface:"MutationEvent"): MutationEvent; createEvent(eventInterface:"MutationEvents"): MutationEvent; createEvent(eventInterface:"NavigationCompletedEvent"): NavigationCompletedEvent; @@ -12971,4 +12972,4 @@ declare function addEventListener(type: "unload", listener: (ev: Event) => any, declare function addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void; declare function addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void; declare function addEventListener(type: "wheel", listener: (ev: WheelEvent) => any, useCapture?: boolean): void; -declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; \ No newline at end of file +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; From c7ea876b721acf56e831cb2b73341a11fe3b5de9 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Jun 2015 20:14:40 -0700 Subject: [PATCH 118/194] Update LKG. --- bin/tsc.js | 535 ++++++++++++----------- bin/tsserver.js | 659 ++++++++++++++++------------ bin/typescript.d.ts | 8 +- bin/typescript.js | 836 ++++++++++++++++++++++-------------- bin/typescriptServices.d.ts | 8 +- bin/typescriptServices.js | 836 ++++++++++++++++++++++-------------- 6 files changed, 1691 insertions(+), 1191 deletions(-) diff --git a/bin/tsc.js b/bin/tsc.js index 3e08d6f7723..ef13d5d9e31 100644 --- a/bin/tsc.js +++ b/bin/tsc.js @@ -2783,34 +2783,30 @@ var ts; var symbolCount = 0; var Symbol = ts.objectAllocator.getSymbolConstructor(); if (!file.locals) { - file.locals = {}; - container = file; - setBlockScopeContainer(file, false); bind(file); file.symbolCount = symbolCount; } + return; function createSymbol(flags, name) { symbolCount++; return new Symbol(flags, name); } - function setBlockScopeContainer(node, cleanLocals) { - blockScopeContainer = node; - if (cleanLocals) { - blockScopeContainer.locals = undefined; - } - } - function addDeclarationToSymbol(symbol, node, symbolKind) { - symbol.flags |= symbolKind; - if (!symbol.declarations) - symbol.declarations = []; - symbol.declarations.push(node); - if (symbolKind & 1952 && !symbol.exports) - symbol.exports = {}; - if (symbolKind & 6240 && !symbol.members) - symbol.members = {}; + function addDeclarationToSymbol(symbol, node, symbolFlags) { + symbol.flags |= symbolFlags; node.symbol = symbol; - if (symbolKind & 107455 && !symbol.valueDeclaration) + if (!symbol.declarations) { + symbol.declarations = []; + } + symbol.declarations.push(node); + if (symbolFlags & 1952 && !symbol.exports) { + symbol.exports = {}; + } + if (symbolFlags & 6240 && !symbol.members) { + symbol.members = {}; + } + if (symbolFlags & 107455 && !symbol.valueDeclaration) { symbol.valueDeclaration = node; + } } function getDeclarationName(node) { if (node.name) { @@ -2825,12 +2821,12 @@ var ts; return node.name.text; } switch (node.kind) { - case 144: case 136: return "__constructor"; case 143: case 139: return "__call"; + case 144: case 140: return "__new"; case 141: @@ -2847,12 +2843,14 @@ var ts; function getDisplayName(node) { return node.name ? ts.declarationNameToString(node.name) : getDeclarationName(node); } - function declareSymbol(symbols, parent, node, includes, excludes) { + function declareSymbol(symbolTable, parent, node, includes, excludes) { ts.Debug.assert(!ts.hasDynamicName(node)); var name = node.flags & 256 && parent ? "default" : getDeclarationName(node); var symbol; if (name !== undefined) { - symbol = ts.hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(0, name)); + symbol = ts.hasProperty(symbolTable, name) + ? symbolTable[name] + : (symbolTable[name] = createSymbol(0, name)); if (symbol.flags & excludes) { if (node.name) { node.name.parent = node; @@ -2872,79 +2870,115 @@ var ts; } addDeclarationToSymbol(symbol, node, includes); symbol.parent = parent; - if ((node.kind === 202 || node.kind === 175) && symbol.exports) { - var prototypeSymbol = createSymbol(4 | 134217728, "prototype"); - if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) { - if (node.name) { - node.name.parent = node; - } - file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); - } - symbol.exports[prototypeSymbol.name] = prototypeSymbol; - prototypeSymbol.parent = symbol; - } return symbol; } - function declareModuleMember(node, symbolKind, symbolExcludes) { + function declareModuleMember(node, symbolFlags, symbolExcludes) { var hasExportModifier = ts.getCombinedNodeFlags(node) & 1; - if (symbolKind & 8388608) { + if (symbolFlags & 8388608) { if (node.kind === 218 || (node.kind === 209 && hasExportModifier)) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); } else { - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } else { if (hasExportModifier || container.flags & 65536) { - var exportKind = (symbolKind & 107455 ? 1048576 : 0) | - (symbolKind & 793056 ? 2097152 : 0) | - (symbolKind & 1536 ? 4194304 : 0); + var exportKind = (symbolFlags & 107455 ? 1048576 : 0) | + (symbolFlags & 793056 ? 2097152 : 0) | + (symbolFlags & 1536 ? 4194304 : 0); var local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes); - local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); node.localSymbol = local; + return local; } else { - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } } - function bindChildren(node, symbolKind, isBlockScopeContainer) { - if (symbolKind & 255504) { - node.locals = {}; - } + function bindChildren(node) { var saveParent = parent; var saveContainer = container; var savedBlockScopeContainer = blockScopeContainer; parent = node; - if (symbolKind & 262128) { - container = node; + var containerFlags = getContainerFlags(node); + if (containerFlags & 1) { + container = blockScopeContainer = node; + if (containerFlags & 4) { + container.locals = {}; + } addToContainerChain(container); } - if (isBlockScopeContainer) { - setBlockScopeContainer(node, (symbolKind & 255504) === 0 && node.kind !== 228); + else if (containerFlags & 2) { + blockScopeContainer = node; + blockScopeContainer.locals = undefined; } ts.forEachChild(node, bind); container = saveContainer; parent = saveParent; blockScopeContainer = savedBlockScopeContainer; } - function addToContainerChain(node) { - if (lastContainer) { - lastContainer.nextContainer = node; + function getContainerFlags(node) { + switch (node.kind) { + case 175: + case 202: + case 203: + case 205: + case 146: + case 155: + return 1; + case 139: + case 140: + case 141: + case 135: + case 134: + case 201: + case 136: + case 137: + case 138: + case 143: + case 144: + case 163: + case 164: + case 206: + case 228: + return 5; + case 224: + case 187: + case 188: + case 189: + case 208: + return 2; + case 180: + return ts.isFunctionLike(node.parent) ? 0 : 2; } - lastContainer = node; + return 0; } - function bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer) { + function addToContainerChain(next) { + if (lastContainer) { + lastContainer.nextContainer = next; + } + lastContainer = next; + } + function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) { + declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes); + } + function declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes) { switch (container.kind) { case 206: - declareModuleMember(node, symbolKind, symbolExcludes); - break; + return declareModuleMember(node, symbolFlags, symbolExcludes); case 228: - if (ts.isExternalModule(container)) { - declareModuleMember(node, symbolKind, symbolExcludes); - break; - } + return declareSourceFileMember(node, symbolFlags, symbolExcludes); + case 175: + case 202: + return declareClassMember(node, symbolFlags, symbolExcludes); + case 205: + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); + case 146: + case 155: + case 203: + return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); case 143: case 144: case 139: @@ -2958,29 +2992,24 @@ var ts; case 201: case 163: case 164: - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); - break; - case 175: - case 202: - if (node.flags & 128) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); - break; - } - case 146: - case 155: - case 203: - declareSymbol(container.symbol.members, container.symbol, node, symbolKind, symbolExcludes); - break; - case 205: - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); - break; + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolKind, isBlockScopeContainer); + } + function declareClassMember(node, symbolFlags, symbolExcludes) { + return node.flags & 128 + ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes) + : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); + } + function declareSourceFileMember(node, symbolFlags, symbolExcludes) { + return ts.isExternalModule(file) + ? declareModuleMember(node, symbolFlags, symbolExcludes) + : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes); } function isAmbientContext(node) { while (node) { - if (node.flags & 2) + if (node.flags & 2) { return true; + } node = node.parent; } return false; @@ -3008,15 +3037,15 @@ var ts; function bindModuleDeclaration(node) { setExportContextFlag(node); if (node.name.kind === 8) { - bindDeclaration(node, 512, 106639, true); + declareSymbolAndAddToSymbolTable(node, 512, 106639); } else { var state = getModuleInstanceState(node); if (state === 0) { - bindDeclaration(node, 1024, 0, true); + declareSymbolAndAddToSymbolTable(node, 1024, 0); } else { - bindDeclaration(node, 512, 106639, true); + declareSymbolAndAddToSymbolTable(node, 512, 106639); var currentModuleIsConstEnumOnly = state === 2; if (node.symbol.constEnumOnlyModule === undefined) { node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly; @@ -3028,36 +3057,25 @@ var ts; } } function bindFunctionOrConstructorType(node) { - // For a given function symbol "<...>(...) => T" we want to generate a symbol identical - // to the one we would get for: { <...>(...): T } - // - // We do that by making an anonymous type literal symbol, and then setting the function - // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable - // from an actual type literal symbol you would have gotten had you used the long form. var symbol = createSymbol(131072, getDeclarationName(node)); addDeclarationToSymbol(symbol, node, 131072); - bindChildren(node, 131072, false); var typeLiteralSymbol = createSymbol(2048, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, 2048); - typeLiteralSymbol.members = {}; - typeLiteralSymbol.members[node.kind === 143 ? "__call" : "__new"] = symbol; + typeLiteralSymbol.members = (_a = {}, _a[symbol.name] = symbol, _a); + var _a; } - function bindAnonymousDeclaration(node, symbolKind, name, isBlockScopeContainer) { - var symbol = createSymbol(symbolKind, name); - addDeclarationToSymbol(symbol, node, symbolKind); - bindChildren(node, symbolKind, isBlockScopeContainer); + function bindAnonymousDeclaration(node, symbolFlags, name) { + var symbol = createSymbol(symbolFlags, name); + addDeclarationToSymbol(symbol, node, symbolFlags); } - function bindCatchVariableDeclaration(node) { - bindChildren(node, 0, true); - } - function bindBlockScopedDeclaration(node, symbolKind, symbolExcludes) { + function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) { switch (blockScopeContainer.kind) { case 206: - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; case 228: if (ts.isExternalModule(container)) { - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; } default: @@ -3065,9 +3083,8 @@ var ts; blockScopeContainer.locals = {}; addToContainerChain(blockScopeContainer); } - declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, symbolExcludes); + declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolKind, false); } function bindBlockScopedVariableDeclaration(node) { bindBlockScopedDeclaration(node, 2, 107455); @@ -3077,158 +3094,143 @@ var ts; } function bind(node) { node.parent = parent; + bindWorker(node); + bindChildren(node); + } + function bindWorker(node) { switch (node.kind) { case 129: - bindDeclaration(node, 262144, 530912, false); - break; + return declareSymbolAndAddToSymbolTable(node, 262144, 530912); case 130: - bindParameter(node); - break; + return bindParameter(node); case 199: case 153: - if (ts.isBindingPattern(node.name)) { - bindChildren(node, 0, false); - } - else if (ts.isBlockOrCatchScoped(node)) { - bindBlockScopedVariableDeclaration(node); - } - else if (ts.isParameterDeclaration(node)) { - bindDeclaration(node, 1, 107455, false); - } - else { - bindDeclaration(node, 1, 107454, false); - } - break; + return bindVariableDeclarationOrBindingElement(node); case 133: case 132: - bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 107455, false); - break; + return bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 107455); case 225: case 226: - bindPropertyOrMethodOrAccessor(node, 4, 107455, false); - break; + return bindPropertyOrMethodOrAccessor(node, 4, 107455); case 227: - bindPropertyOrMethodOrAccessor(node, 8, 107455, false); - break; + return bindPropertyOrMethodOrAccessor(node, 8, 107455); case 139: case 140: case 141: - bindDeclaration(node, 131072, 0, false); - break; + return declareSymbolAndAddToSymbolTable(node, 131072, 0); case 135: case 134: - bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 107455 : 99263, true); - break; + return bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 107455 : 99263); case 201: - bindDeclaration(node, 16, 106927, true); - break; + return declareSymbolAndAddToSymbolTable(node, 16, 106927); case 136: - bindDeclaration(node, 16384, 0, true); - break; + return declareSymbolAndAddToSymbolTable(node, 16384, 0); case 137: - bindPropertyOrMethodOrAccessor(node, 32768, 41919, true); - break; + return bindPropertyOrMethodOrAccessor(node, 32768, 41919); case 138: - bindPropertyOrMethodOrAccessor(node, 65536, 74687, true); - break; + return bindPropertyOrMethodOrAccessor(node, 65536, 74687); case 143: case 144: - bindFunctionOrConstructorType(node); - break; + return bindFunctionOrConstructorType(node); case 146: - bindAnonymousDeclaration(node, 2048, "__type", false); - break; + return bindAnonymousDeclaration(node, 2048, "__type"); case 155: - bindAnonymousDeclaration(node, 4096, "__object", false); - break; + return bindAnonymousDeclaration(node, 4096, "__object"); case 163: case 164: - bindAnonymousDeclaration(node, 16, "__function", true); - break; + return bindAnonymousDeclaration(node, 16, "__function"); case 175: - bindAnonymousDeclaration(node, 32, "__class", false); - break; - case 224: - bindCatchVariableDeclaration(node); - break; case 202: - bindBlockScopedDeclaration(node, 32, 899583); - break; + return bindClassLikeDeclaration(node); case 203: - bindBlockScopedDeclaration(node, 64, 792992); - break; + return bindBlockScopedDeclaration(node, 64, 792992); case 204: - bindBlockScopedDeclaration(node, 524288, 793056); - break; + return bindBlockScopedDeclaration(node, 524288, 793056); case 205: - if (ts.isConst(node)) { - bindBlockScopedDeclaration(node, 128, 899967); - } - else { - bindBlockScopedDeclaration(node, 256, 899327); - } - break; + return bindEnumDeclaration(node); case 206: - bindModuleDeclaration(node); - break; + return bindModuleDeclaration(node); case 209: case 212: case 214: case 218: - bindDeclaration(node, 8388608, 8388608, false); - break; + return declareSymbolAndAddToSymbolTable(node, 8388608, 8388608); case 211: - if (node.name) { - bindDeclaration(node, 8388608, 8388608, false); - } - else { - bindChildren(node, 0, false); - } - break; + return bindImportClause(node); case 216: - if (!node.exportClause) { - declareSymbol(container.symbol.exports, container.symbol, node, 1073741824, 0); - } - bindChildren(node, 0, false); - break; + return bindExportDeclaration(node); case 215: - if (node.expression.kind === 65) { - declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 107455 | 8388608); - } - else { - declareSymbol(container.symbol.exports, container.symbol, node, 4, 107455 | 8388608); - } - bindChildren(node, 0, false); - break; + return bindExportAssignment(node); case 228: - setExportContextFlag(node); - if (ts.isExternalModule(node)) { - bindAnonymousDeclaration(node, 512, '"' + ts.removeFileExtension(node.fileName) + '"', true); - break; - } - case 180: - bindChildren(node, 0, !ts.isFunctionLike(node.parent)); - break; - case 224: - case 187: - case 188: - case 189: - case 208: - bindChildren(node, 0, true); - break; - default: - var saveParent = parent; - parent = node; - ts.forEachChild(node, bind); - parent = saveParent; + return bindSourceFileIfExternalModule(); + } + } + function bindSourceFileIfExternalModule() { + setExportContextFlag(file); + if (ts.isExternalModule(file)) { + bindAnonymousDeclaration(file, 512, '"' + ts.removeFileExtension(file.fileName) + '"'); + } + } + function bindExportAssignment(node) { + if (node.expression.kind === 65) { + declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 107455 | 8388608); + } + else { + declareSymbol(container.symbol.exports, container.symbol, node, 4, 107455 | 8388608); + } + } + function bindExportDeclaration(node) { + if (!node.exportClause) { + declareSymbol(container.symbol.exports, container.symbol, node, 1073741824, 0); + } + } + function bindImportClause(node) { + if (node.name) { + declareSymbolAndAddToSymbolTable(node, 8388608, 8388608); + } + } + function bindClassLikeDeclaration(node) { + if (node.kind === 202) { + bindBlockScopedDeclaration(node, 32, 899583); + } + else { + bindAnonymousDeclaration(node, 32, "__class"); + } + var symbol = node.symbol; + var prototypeSymbol = createSymbol(4 | 134217728, "prototype"); + if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) { + if (node.name) { + node.name.parent = node; + } + file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); + } + symbol.exports[prototypeSymbol.name] = prototypeSymbol; + prototypeSymbol.parent = symbol; + } + function bindEnumDeclaration(node) { + return ts.isConst(node) + ? bindBlockScopedDeclaration(node, 128, 899967) + : bindBlockScopedDeclaration(node, 256, 899327); + } + function bindVariableDeclarationOrBindingElement(node) { + if (!ts.isBindingPattern(node.name)) { + if (ts.isBlockOrCatchScoped(node)) { + bindBlockScopedVariableDeclaration(node); + } + else if (ts.isParameterDeclaration(node)) { + declareSymbolAndAddToSymbolTable(node, 1, 107455); + } + else { + declareSymbolAndAddToSymbolTable(node, 1, 107454); + } } } function bindParameter(node) { if (ts.isBindingPattern(node.name)) { - bindAnonymousDeclaration(node, 1, getDestructuringParameterName(node), false); + bindAnonymousDeclaration(node, 1, getDestructuringParameterName(node)); } else { - bindDeclaration(node, 1, 107455, false); + declareSymbolAndAddToSymbolTable(node, 1, 107455); } if (node.flags & 112 && node.parent.kind === 136 && @@ -3237,13 +3239,10 @@ var ts; declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4, 107455); } } - function bindPropertyOrMethodOrAccessor(node, symbolKind, symbolExcludes, isBlockScopeContainer) { - if (ts.hasDynamicName(node)) { - bindAnonymousDeclaration(node, symbolKind, "__computed", isBlockScopeContainer); - } - else { - bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer); - } + function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) { + return ts.hasDynamicName(node) + ? bindAnonymousDeclaration(node, symbolFlags, "__computed") + : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } } })(ts || (ts = {})); @@ -4020,10 +4019,6 @@ var ts; } } ts.getExternalModuleName = getExternalModuleName; - function hasDotDotDotToken(node) { - return node && node.kind === 130 && node.dotDotDotToken !== undefined; - } - ts.hasDotDotDotToken = hasDotDotDotToken; function hasQuestionToken(node) { if (node) { switch (node.kind) { @@ -4042,10 +4037,6 @@ var ts; return false; } ts.hasQuestionToken = hasQuestionToken; - function hasRestParameters(s) { - return s.parameters.length > 0 && ts.lastOrUndefined(s.parameters).dotDotDotToken !== undefined; - } - ts.hasRestParameters = hasRestParameters; function isJSDocConstructSignature(node) { return node.kind === 241 && node.parameters.length > 0 && @@ -5024,7 +5015,6 @@ var ts; /// var ts; (function (ts) { - ts.throwOnJSDocErrors = false; var nodeConstructors = new Array(252); ts.parseTime = 0; function getNodeConstructor(kind) { @@ -8570,12 +8560,6 @@ var ts; return finishNode(result); } JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression; - function setError(message) { - parseErrorAtCurrentToken(message); - if (ts.throwOnJSDocErrors) { - throw new Error(message.key); - } - } function parseJSDocTopLevelType() { var type = parseJSDocType(); if (token === 44) { @@ -9717,27 +9701,31 @@ var ts; case 138: case 201: case 164: - if (name === "arguments") { + if (meaning & 3 && name === "arguments") { result = argumentsSymbol; break loop; } break; case 163: - if (name === "arguments") { + if (meaning & 3 && name === "arguments") { result = argumentsSymbol; break loop; } - var functionName = location.name; - if (functionName && name === functionName.text) { - result = location.symbol; - break loop; + if (meaning & 16) { + var functionName = location.name; + if (functionName && name === functionName.text) { + result = location.symbol; + break loop; + } } break; case 175: - var className = location.name; - if (className && name === className.text) { - result = location.symbol; - break loop; + if (meaning & 32) { + var className = location.name; + if (className && name === className.text) { + result = location.symbol; + break loop; + } } break; case 131: @@ -10771,11 +10759,12 @@ var ts; } } function buildParameterDisplay(p, writer, enclosingDeclaration, flags, typeStack) { - if (ts.hasDotDotDotToken(p.valueDeclaration)) { + var parameterNode = p.valueDeclaration; + if (ts.isRestParameter(parameterNode)) { writePunctuation(writer, 21); } appendSymbolNameOnly(p, writer); - if (ts.hasQuestionToken(p.valueDeclaration) || p.valueDeclaration.initializer) { + if (isOptionalParameter(parameterNode)) { writePunctuation(writer, 50); } writePunctuation(writer, 51); @@ -11933,6 +11922,9 @@ var ts; } return result; } + function isOptionalParameter(node) { + return ts.hasQuestionToken(node) || !!node.initializer; + } function getSignatureFromDeclaration(declaration) { var links = getNodeLinks(declaration); if (!links.resolvedSignature) { @@ -11973,7 +11965,7 @@ var ts; returnType = anyType; } } - links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, ts.hasRestParameters(declaration), hasStringLiterals); + links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, ts.hasRestParameter(declaration), hasStringLiterals); } return links.resolvedSignature; } @@ -12202,27 +12194,7 @@ var ts; type = unknownType; } else { - type = getDeclaredTypeOfSymbol(symbol); - if (type.flags & (1024 | 2048) && type.flags & 4096) { - var localTypeParameters = type.localTypeParameters; - var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; - var typeArgCount = node.typeArguments ? node.typeArguments.length : 0; - if (typeArgCount === expectedTypeArgCount) { - if (typeArgCount) { - type = createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(node.typeArguments, getTypeFromTypeNode))); - } - } - else { - error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1), expectedTypeArgCount); - type = undefined; - } - } - else { - if (node.typeArguments) { - error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); - type = undefined; - } - } + type = createTypeReferenceIfGeneric(getDeclaredTypeOfSymbol(symbol), node, node.typeArguments); } } } @@ -12230,6 +12202,29 @@ var ts; } return links.resolvedType; } + function createTypeReferenceIfGeneric(type, node, typeArguments) { + if (type.flags & (1024 | 2048) && type.flags & 4096) { + var localTypeParameters = type.localTypeParameters; + var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; + var typeArgCount = typeArguments ? typeArguments.length : 0; + if (typeArgCount === expectedTypeArgCount) { + if (typeArgCount) { + return createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(typeArguments, getTypeFromTypeNode))); + } + } + else { + error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1), expectedTypeArgCount); + return undefined; + } + } + else { + if (typeArguments) { + error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); + return undefined; + } + } + return type; + } function getTypeFromTypeQueryNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { @@ -14173,7 +14168,7 @@ var ts; if (isContextSensitive(func)) { var contextualSignature = getContextualSignature(func); if (contextualSignature) { - var funcHasRestParameters = ts.hasRestParameters(func); + var funcHasRestParameters = ts.hasRestParameter(func); var len = func.parameters.length - (funcHasRestParameters ? 1 : 0); var indexOfParameter = ts.indexOf(func.parameters, parameter); if (indexOfParameter < len) { @@ -16687,7 +16682,7 @@ var ts; } } function checkCollisionWithArgumentsInGeneratedCode(node) { - if (!ts.hasRestParameters(node) || ts.isInAmbientContext(node) || ts.nodeIsMissing(node.body)) { + if (!ts.hasRestParameter(node) || ts.isInAmbientContext(node) || ts.nodeIsMissing(node.body)) { return; } ts.forEach(node.parameters, function (p) { @@ -23709,7 +23704,7 @@ var ts; } } function emitRestParameter(node) { - if (languageVersion < 2 && ts.hasRestParameters(node)) { + if (languageVersion < 2 && ts.hasRestParameter(node)) { var restIndex = node.parameters.length - 1; var restParam = node.parameters[restIndex]; if (ts.isBindingPattern(restParam.name)) { @@ -23817,7 +23812,7 @@ var ts; write("("); if (node) { var parameters = node.parameters; - var omitCount = languageVersion < 2 && ts.hasRestParameters(node) ? 1 : 0; + var omitCount = languageVersion < 2 && ts.hasRestParameter(node) ? 1 : 0; emitList(parameters, 0, parameters.length - omitCount, false, false); } write(")"); diff --git a/bin/tsserver.js b/bin/tsserver.js index 5795b1e7e36..a6d4dc601d7 100644 --- a/bin/tsserver.js +++ b/bin/tsserver.js @@ -3894,10 +3894,6 @@ var ts; } } ts.getExternalModuleName = getExternalModuleName; - function hasDotDotDotToken(node) { - return node && node.kind === 130 && node.dotDotDotToken !== undefined; - } - ts.hasDotDotDotToken = hasDotDotDotToken; function hasQuestionToken(node) { if (node) { switch (node.kind) { @@ -3916,10 +3912,6 @@ var ts; return false; } ts.hasQuestionToken = hasQuestionToken; - function hasRestParameters(s) { - return s.parameters.length > 0 && ts.lastOrUndefined(s.parameters).dotDotDotToken !== undefined; - } - ts.hasRestParameters = hasRestParameters; function isJSDocConstructSignature(node) { return node.kind === 241 && node.parameters.length > 0 && @@ -4898,7 +4890,6 @@ var ts; /// var ts; (function (ts) { - ts.throwOnJSDocErrors = false; var nodeConstructors = new Array(252); ts.parseTime = 0; function getNodeConstructor(kind) { @@ -8444,12 +8435,6 @@ var ts; return finishNode(result); } JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression; - function setError(message) { - parseErrorAtCurrentToken(message); - if (ts.throwOnJSDocErrors) { - throw new Error(message.key); - } - } function parseJSDocTopLevelType() { var type = parseJSDocType(); if (token === 44) { @@ -9254,34 +9239,30 @@ var ts; var symbolCount = 0; var Symbol = ts.objectAllocator.getSymbolConstructor(); if (!file.locals) { - file.locals = {}; - container = file; - setBlockScopeContainer(file, false); bind(file); file.symbolCount = symbolCount; } + return; function createSymbol(flags, name) { symbolCount++; return new Symbol(flags, name); } - function setBlockScopeContainer(node, cleanLocals) { - blockScopeContainer = node; - if (cleanLocals) { - blockScopeContainer.locals = undefined; - } - } - function addDeclarationToSymbol(symbol, node, symbolKind) { - symbol.flags |= symbolKind; - if (!symbol.declarations) - symbol.declarations = []; - symbol.declarations.push(node); - if (symbolKind & 1952 && !symbol.exports) - symbol.exports = {}; - if (symbolKind & 6240 && !symbol.members) - symbol.members = {}; + function addDeclarationToSymbol(symbol, node, symbolFlags) { + symbol.flags |= symbolFlags; node.symbol = symbol; - if (symbolKind & 107455 && !symbol.valueDeclaration) + if (!symbol.declarations) { + symbol.declarations = []; + } + symbol.declarations.push(node); + if (symbolFlags & 1952 && !symbol.exports) { + symbol.exports = {}; + } + if (symbolFlags & 6240 && !symbol.members) { + symbol.members = {}; + } + if (symbolFlags & 107455 && !symbol.valueDeclaration) { symbol.valueDeclaration = node; + } } function getDeclarationName(node) { if (node.name) { @@ -9296,12 +9277,12 @@ var ts; return node.name.text; } switch (node.kind) { - case 144: case 136: return "__constructor"; case 143: case 139: return "__call"; + case 144: case 140: return "__new"; case 141: @@ -9318,12 +9299,14 @@ var ts; function getDisplayName(node) { return node.name ? ts.declarationNameToString(node.name) : getDeclarationName(node); } - function declareSymbol(symbols, parent, node, includes, excludes) { + function declareSymbol(symbolTable, parent, node, includes, excludes) { ts.Debug.assert(!ts.hasDynamicName(node)); var name = node.flags & 256 && parent ? "default" : getDeclarationName(node); var symbol; if (name !== undefined) { - symbol = ts.hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(0, name)); + symbol = ts.hasProperty(symbolTable, name) + ? symbolTable[name] + : (symbolTable[name] = createSymbol(0, name)); if (symbol.flags & excludes) { if (node.name) { node.name.parent = node; @@ -9343,79 +9326,115 @@ var ts; } addDeclarationToSymbol(symbol, node, includes); symbol.parent = parent; - if ((node.kind === 202 || node.kind === 175) && symbol.exports) { - var prototypeSymbol = createSymbol(4 | 134217728, "prototype"); - if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) { - if (node.name) { - node.name.parent = node; - } - file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); - } - symbol.exports[prototypeSymbol.name] = prototypeSymbol; - prototypeSymbol.parent = symbol; - } return symbol; } - function declareModuleMember(node, symbolKind, symbolExcludes) { + function declareModuleMember(node, symbolFlags, symbolExcludes) { var hasExportModifier = ts.getCombinedNodeFlags(node) & 1; - if (symbolKind & 8388608) { + if (symbolFlags & 8388608) { if (node.kind === 218 || (node.kind === 209 && hasExportModifier)) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); } else { - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } else { if (hasExportModifier || container.flags & 65536) { - var exportKind = (symbolKind & 107455 ? 1048576 : 0) | - (symbolKind & 793056 ? 2097152 : 0) | - (symbolKind & 1536 ? 4194304 : 0); + var exportKind = (symbolFlags & 107455 ? 1048576 : 0) | + (symbolFlags & 793056 ? 2097152 : 0) | + (symbolFlags & 1536 ? 4194304 : 0); var local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes); - local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); node.localSymbol = local; + return local; } else { - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } } - function bindChildren(node, symbolKind, isBlockScopeContainer) { - if (symbolKind & 255504) { - node.locals = {}; - } + function bindChildren(node) { var saveParent = parent; var saveContainer = container; var savedBlockScopeContainer = blockScopeContainer; parent = node; - if (symbolKind & 262128) { - container = node; + var containerFlags = getContainerFlags(node); + if (containerFlags & 1) { + container = blockScopeContainer = node; + if (containerFlags & 4) { + container.locals = {}; + } addToContainerChain(container); } - if (isBlockScopeContainer) { - setBlockScopeContainer(node, (symbolKind & 255504) === 0 && node.kind !== 228); + else if (containerFlags & 2) { + blockScopeContainer = node; + blockScopeContainer.locals = undefined; } ts.forEachChild(node, bind); container = saveContainer; parent = saveParent; blockScopeContainer = savedBlockScopeContainer; } - function addToContainerChain(node) { - if (lastContainer) { - lastContainer.nextContainer = node; + function getContainerFlags(node) { + switch (node.kind) { + case 175: + case 202: + case 203: + case 205: + case 146: + case 155: + return 1; + case 139: + case 140: + case 141: + case 135: + case 134: + case 201: + case 136: + case 137: + case 138: + case 143: + case 144: + case 163: + case 164: + case 206: + case 228: + return 5; + case 224: + case 187: + case 188: + case 189: + case 208: + return 2; + case 180: + return ts.isFunctionLike(node.parent) ? 0 : 2; } - lastContainer = node; + return 0; } - function bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer) { + function addToContainerChain(next) { + if (lastContainer) { + lastContainer.nextContainer = next; + } + lastContainer = next; + } + function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) { + declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes); + } + function declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes) { switch (container.kind) { case 206: - declareModuleMember(node, symbolKind, symbolExcludes); - break; + return declareModuleMember(node, symbolFlags, symbolExcludes); case 228: - if (ts.isExternalModule(container)) { - declareModuleMember(node, symbolKind, symbolExcludes); - break; - } + return declareSourceFileMember(node, symbolFlags, symbolExcludes); + case 175: + case 202: + return declareClassMember(node, symbolFlags, symbolExcludes); + case 205: + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); + case 146: + case 155: + case 203: + return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); case 143: case 144: case 139: @@ -9429,29 +9448,24 @@ var ts; case 201: case 163: case 164: - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); - break; - case 175: - case 202: - if (node.flags & 128) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); - break; - } - case 146: - case 155: - case 203: - declareSymbol(container.symbol.members, container.symbol, node, symbolKind, symbolExcludes); - break; - case 205: - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); - break; + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolKind, isBlockScopeContainer); + } + function declareClassMember(node, symbolFlags, symbolExcludes) { + return node.flags & 128 + ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes) + : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); + } + function declareSourceFileMember(node, symbolFlags, symbolExcludes) { + return ts.isExternalModule(file) + ? declareModuleMember(node, symbolFlags, symbolExcludes) + : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes); } function isAmbientContext(node) { while (node) { - if (node.flags & 2) + if (node.flags & 2) { return true; + } node = node.parent; } return false; @@ -9479,15 +9493,15 @@ var ts; function bindModuleDeclaration(node) { setExportContextFlag(node); if (node.name.kind === 8) { - bindDeclaration(node, 512, 106639, true); + declareSymbolAndAddToSymbolTable(node, 512, 106639); } else { var state = getModuleInstanceState(node); if (state === 0) { - bindDeclaration(node, 1024, 0, true); + declareSymbolAndAddToSymbolTable(node, 1024, 0); } else { - bindDeclaration(node, 512, 106639, true); + declareSymbolAndAddToSymbolTable(node, 512, 106639); var currentModuleIsConstEnumOnly = state === 2; if (node.symbol.constEnumOnlyModule === undefined) { node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly; @@ -9499,36 +9513,25 @@ var ts; } } function bindFunctionOrConstructorType(node) { - // For a given function symbol "<...>(...) => T" we want to generate a symbol identical - // to the one we would get for: { <...>(...): T } - // - // We do that by making an anonymous type literal symbol, and then setting the function - // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable - // from an actual type literal symbol you would have gotten had you used the long form. var symbol = createSymbol(131072, getDeclarationName(node)); addDeclarationToSymbol(symbol, node, 131072); - bindChildren(node, 131072, false); var typeLiteralSymbol = createSymbol(2048, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, 2048); - typeLiteralSymbol.members = {}; - typeLiteralSymbol.members[node.kind === 143 ? "__call" : "__new"] = symbol; + typeLiteralSymbol.members = (_a = {}, _a[symbol.name] = symbol, _a); + var _a; } - function bindAnonymousDeclaration(node, symbolKind, name, isBlockScopeContainer) { - var symbol = createSymbol(symbolKind, name); - addDeclarationToSymbol(symbol, node, symbolKind); - bindChildren(node, symbolKind, isBlockScopeContainer); + function bindAnonymousDeclaration(node, symbolFlags, name) { + var symbol = createSymbol(symbolFlags, name); + addDeclarationToSymbol(symbol, node, symbolFlags); } - function bindCatchVariableDeclaration(node) { - bindChildren(node, 0, true); - } - function bindBlockScopedDeclaration(node, symbolKind, symbolExcludes) { + function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) { switch (blockScopeContainer.kind) { case 206: - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; case 228: if (ts.isExternalModule(container)) { - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; } default: @@ -9536,9 +9539,8 @@ var ts; blockScopeContainer.locals = {}; addToContainerChain(blockScopeContainer); } - declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, symbolExcludes); + declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolKind, false); } function bindBlockScopedVariableDeclaration(node) { bindBlockScopedDeclaration(node, 2, 107455); @@ -9548,158 +9550,143 @@ var ts; } function bind(node) { node.parent = parent; + bindWorker(node); + bindChildren(node); + } + function bindWorker(node) { switch (node.kind) { case 129: - bindDeclaration(node, 262144, 530912, false); - break; + return declareSymbolAndAddToSymbolTable(node, 262144, 530912); case 130: - bindParameter(node); - break; + return bindParameter(node); case 199: case 153: - if (ts.isBindingPattern(node.name)) { - bindChildren(node, 0, false); - } - else if (ts.isBlockOrCatchScoped(node)) { - bindBlockScopedVariableDeclaration(node); - } - else if (ts.isParameterDeclaration(node)) { - bindDeclaration(node, 1, 107455, false); - } - else { - bindDeclaration(node, 1, 107454, false); - } - break; + return bindVariableDeclarationOrBindingElement(node); case 133: case 132: - bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 107455, false); - break; + return bindPropertyOrMethodOrAccessor(node, 4 | (node.questionToken ? 536870912 : 0), 107455); case 225: case 226: - bindPropertyOrMethodOrAccessor(node, 4, 107455, false); - break; + return bindPropertyOrMethodOrAccessor(node, 4, 107455); case 227: - bindPropertyOrMethodOrAccessor(node, 8, 107455, false); - break; + return bindPropertyOrMethodOrAccessor(node, 8, 107455); case 139: case 140: case 141: - bindDeclaration(node, 131072, 0, false); - break; + return declareSymbolAndAddToSymbolTable(node, 131072, 0); case 135: case 134: - bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 107455 : 99263, true); - break; + return bindPropertyOrMethodOrAccessor(node, 8192 | (node.questionToken ? 536870912 : 0), ts.isObjectLiteralMethod(node) ? 107455 : 99263); case 201: - bindDeclaration(node, 16, 106927, true); - break; + return declareSymbolAndAddToSymbolTable(node, 16, 106927); case 136: - bindDeclaration(node, 16384, 0, true); - break; + return declareSymbolAndAddToSymbolTable(node, 16384, 0); case 137: - bindPropertyOrMethodOrAccessor(node, 32768, 41919, true); - break; + return bindPropertyOrMethodOrAccessor(node, 32768, 41919); case 138: - bindPropertyOrMethodOrAccessor(node, 65536, 74687, true); - break; + return bindPropertyOrMethodOrAccessor(node, 65536, 74687); case 143: case 144: - bindFunctionOrConstructorType(node); - break; + return bindFunctionOrConstructorType(node); case 146: - bindAnonymousDeclaration(node, 2048, "__type", false); - break; + return bindAnonymousDeclaration(node, 2048, "__type"); case 155: - bindAnonymousDeclaration(node, 4096, "__object", false); - break; + return bindAnonymousDeclaration(node, 4096, "__object"); case 163: case 164: - bindAnonymousDeclaration(node, 16, "__function", true); - break; + return bindAnonymousDeclaration(node, 16, "__function"); case 175: - bindAnonymousDeclaration(node, 32, "__class", false); - break; - case 224: - bindCatchVariableDeclaration(node); - break; case 202: - bindBlockScopedDeclaration(node, 32, 899583); - break; + return bindClassLikeDeclaration(node); case 203: - bindBlockScopedDeclaration(node, 64, 792992); - break; + return bindBlockScopedDeclaration(node, 64, 792992); case 204: - bindBlockScopedDeclaration(node, 524288, 793056); - break; + return bindBlockScopedDeclaration(node, 524288, 793056); case 205: - if (ts.isConst(node)) { - bindBlockScopedDeclaration(node, 128, 899967); - } - else { - bindBlockScopedDeclaration(node, 256, 899327); - } - break; + return bindEnumDeclaration(node); case 206: - bindModuleDeclaration(node); - break; + return bindModuleDeclaration(node); case 209: case 212: case 214: case 218: - bindDeclaration(node, 8388608, 8388608, false); - break; + return declareSymbolAndAddToSymbolTable(node, 8388608, 8388608); case 211: - if (node.name) { - bindDeclaration(node, 8388608, 8388608, false); - } - else { - bindChildren(node, 0, false); - } - break; + return bindImportClause(node); case 216: - if (!node.exportClause) { - declareSymbol(container.symbol.exports, container.symbol, node, 1073741824, 0); - } - bindChildren(node, 0, false); - break; + return bindExportDeclaration(node); case 215: - if (node.expression.kind === 65) { - declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 107455 | 8388608); - } - else { - declareSymbol(container.symbol.exports, container.symbol, node, 4, 107455 | 8388608); - } - bindChildren(node, 0, false); - break; + return bindExportAssignment(node); case 228: - setExportContextFlag(node); - if (ts.isExternalModule(node)) { - bindAnonymousDeclaration(node, 512, '"' + ts.removeFileExtension(node.fileName) + '"', true); - break; - } - case 180: - bindChildren(node, 0, !ts.isFunctionLike(node.parent)); - break; - case 224: - case 187: - case 188: - case 189: - case 208: - bindChildren(node, 0, true); - break; - default: - var saveParent = parent; - parent = node; - ts.forEachChild(node, bind); - parent = saveParent; + return bindSourceFileIfExternalModule(); + } + } + function bindSourceFileIfExternalModule() { + setExportContextFlag(file); + if (ts.isExternalModule(file)) { + bindAnonymousDeclaration(file, 512, '"' + ts.removeFileExtension(file.fileName) + '"'); + } + } + function bindExportAssignment(node) { + if (node.expression.kind === 65) { + declareSymbol(container.symbol.exports, container.symbol, node, 8388608, 107455 | 8388608); + } + else { + declareSymbol(container.symbol.exports, container.symbol, node, 4, 107455 | 8388608); + } + } + function bindExportDeclaration(node) { + if (!node.exportClause) { + declareSymbol(container.symbol.exports, container.symbol, node, 1073741824, 0); + } + } + function bindImportClause(node) { + if (node.name) { + declareSymbolAndAddToSymbolTable(node, 8388608, 8388608); + } + } + function bindClassLikeDeclaration(node) { + if (node.kind === 202) { + bindBlockScopedDeclaration(node, 32, 899583); + } + else { + bindAnonymousDeclaration(node, 32, "__class"); + } + var symbol = node.symbol; + var prototypeSymbol = createSymbol(4 | 134217728, "prototype"); + if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) { + if (node.name) { + node.name.parent = node; + } + file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); + } + symbol.exports[prototypeSymbol.name] = prototypeSymbol; + prototypeSymbol.parent = symbol; + } + function bindEnumDeclaration(node) { + return ts.isConst(node) + ? bindBlockScopedDeclaration(node, 128, 899967) + : bindBlockScopedDeclaration(node, 256, 899327); + } + function bindVariableDeclarationOrBindingElement(node) { + if (!ts.isBindingPattern(node.name)) { + if (ts.isBlockOrCatchScoped(node)) { + bindBlockScopedVariableDeclaration(node); + } + else if (ts.isParameterDeclaration(node)) { + declareSymbolAndAddToSymbolTable(node, 1, 107455); + } + else { + declareSymbolAndAddToSymbolTable(node, 1, 107454); + } } } function bindParameter(node) { if (ts.isBindingPattern(node.name)) { - bindAnonymousDeclaration(node, 1, getDestructuringParameterName(node), false); + bindAnonymousDeclaration(node, 1, getDestructuringParameterName(node)); } else { - bindDeclaration(node, 1, 107455, false); + declareSymbolAndAddToSymbolTable(node, 1, 107455); } if (node.flags & 112 && node.parent.kind === 136 && @@ -9708,13 +9695,10 @@ var ts; declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4, 107455); } } - function bindPropertyOrMethodOrAccessor(node, symbolKind, symbolExcludes, isBlockScopeContainer) { - if (ts.hasDynamicName(node)) { - bindAnonymousDeclaration(node, symbolKind, "__computed", isBlockScopeContainer); - } - else { - bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer); - } + function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) { + return ts.hasDynamicName(node) + ? bindAnonymousDeclaration(node, symbolFlags, "__computed") + : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } } })(ts || (ts = {})); @@ -10107,27 +10091,31 @@ var ts; case 138: case 201: case 164: - if (name === "arguments") { + if (meaning & 3 && name === "arguments") { result = argumentsSymbol; break loop; } break; case 163: - if (name === "arguments") { + if (meaning & 3 && name === "arguments") { result = argumentsSymbol; break loop; } - var functionName = location.name; - if (functionName && name === functionName.text) { - result = location.symbol; - break loop; + if (meaning & 16) { + var functionName = location.name; + if (functionName && name === functionName.text) { + result = location.symbol; + break loop; + } } break; case 175: - var className = location.name; - if (className && name === className.text) { - result = location.symbol; - break loop; + if (meaning & 32) { + var className = location.name; + if (className && name === className.text) { + result = location.symbol; + break loop; + } } break; case 131: @@ -11161,11 +11149,12 @@ var ts; } } function buildParameterDisplay(p, writer, enclosingDeclaration, flags, typeStack) { - if (ts.hasDotDotDotToken(p.valueDeclaration)) { + var parameterNode = p.valueDeclaration; + if (ts.isRestParameter(parameterNode)) { writePunctuation(writer, 21); } appendSymbolNameOnly(p, writer); - if (ts.hasQuestionToken(p.valueDeclaration) || p.valueDeclaration.initializer) { + if (isOptionalParameter(parameterNode)) { writePunctuation(writer, 50); } writePunctuation(writer, 51); @@ -12323,6 +12312,9 @@ var ts; } return result; } + function isOptionalParameter(node) { + return ts.hasQuestionToken(node) || !!node.initializer; + } function getSignatureFromDeclaration(declaration) { var links = getNodeLinks(declaration); if (!links.resolvedSignature) { @@ -12363,7 +12355,7 @@ var ts; returnType = anyType; } } - links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, ts.hasRestParameters(declaration), hasStringLiterals); + links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, ts.hasRestParameter(declaration), hasStringLiterals); } return links.resolvedSignature; } @@ -12592,27 +12584,7 @@ var ts; type = unknownType; } else { - type = getDeclaredTypeOfSymbol(symbol); - if (type.flags & (1024 | 2048) && type.flags & 4096) { - var localTypeParameters = type.localTypeParameters; - var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; - var typeArgCount = node.typeArguments ? node.typeArguments.length : 0; - if (typeArgCount === expectedTypeArgCount) { - if (typeArgCount) { - type = createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(node.typeArguments, getTypeFromTypeNode))); - } - } - else { - error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1), expectedTypeArgCount); - type = undefined; - } - } - else { - if (node.typeArguments) { - error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); - type = undefined; - } - } + type = createTypeReferenceIfGeneric(getDeclaredTypeOfSymbol(symbol), node, node.typeArguments); } } } @@ -12620,6 +12592,29 @@ var ts; } return links.resolvedType; } + function createTypeReferenceIfGeneric(type, node, typeArguments) { + if (type.flags & (1024 | 2048) && type.flags & 4096) { + var localTypeParameters = type.localTypeParameters; + var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; + var typeArgCount = typeArguments ? typeArguments.length : 0; + if (typeArgCount === expectedTypeArgCount) { + if (typeArgCount) { + return createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(typeArguments, getTypeFromTypeNode))); + } + } + else { + error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1), expectedTypeArgCount); + return undefined; + } + } + else { + if (typeArguments) { + error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); + return undefined; + } + } + return type; + } function getTypeFromTypeQueryNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { @@ -14563,7 +14558,7 @@ var ts; if (isContextSensitive(func)) { var contextualSignature = getContextualSignature(func); if (contextualSignature) { - var funcHasRestParameters = ts.hasRestParameters(func); + var funcHasRestParameters = ts.hasRestParameter(func); var len = func.parameters.length - (funcHasRestParameters ? 1 : 0); var indexOfParameter = ts.indexOf(func.parameters, parameter); if (indexOfParameter < len) { @@ -17077,7 +17072,7 @@ var ts; } } function checkCollisionWithArgumentsInGeneratedCode(node) { - if (!ts.hasRestParameters(node) || ts.isInAmbientContext(node) || ts.nodeIsMissing(node.body)) { + if (!ts.hasRestParameter(node) || ts.isInAmbientContext(node) || ts.nodeIsMissing(node.body)) { return; } ts.forEach(node.parameters, function (p) { @@ -24099,7 +24094,7 @@ var ts; } } function emitRestParameter(node) { - if (languageVersion < 2 && ts.hasRestParameters(node)) { + if (languageVersion < 2 && ts.hasRestParameter(node)) { var restIndex = node.parameters.length - 1; var restParam = node.parameters[restIndex]; if (ts.isBindingPattern(restParam.name)) { @@ -24207,7 +24202,7 @@ var ts; write("("); if (node) { var parameters = node.parameters; - var omitCount = languageVersion < 2 && ts.hasRestParameters(node) ? 1 : 0; + var omitCount = languageVersion < 2 && ts.hasRestParameter(node) ? 1 : 0; emitList(parameters, 0, parameters.length - omitCount, false, false); } write(")"); @@ -32236,6 +32231,7 @@ var ts; ClassificationTypeNames.typeParameterName = "type parameter name"; ClassificationTypeNames.typeAliasName = "type alias name"; ClassificationTypeNames.parameterName = "parameter name"; + ClassificationTypeNames.docCommentTagName = "doc comment tag name"; return ClassificationTypeNames; })(); ts.ClassificationTypeNames = ClassificationTypeNames; @@ -32421,7 +32417,8 @@ var ts; } ts.transpile = transpile; function createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, setNodeParents) { - var sourceFile = ts.createSourceFile(fileName, scriptSnapshot.getText(0, scriptSnapshot.getLength()), scriptTarget, setNodeParents); + var text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); + var sourceFile = ts.createSourceFile(fileName, text, scriptTarget, setNodeParents); setSourceFileFields(sourceFile, scriptSnapshot, version); sourceFile.nameTable = sourceFile.identifiers; return sourceFile; @@ -32928,10 +32925,12 @@ var ts; } } } + hostCache = undefined; program = newProgram; program.getTypeChecker(); return; function getOrCreateSourceFile(fileName) { + ts.Debug.assert(hostCache !== undefined); var hostFileInformation = hostCache.getOrCreateEntry(fileName); if (!hostFileInformation) { return undefined; @@ -33186,6 +33185,7 @@ var ts; var typeChecker = program.getTypeChecker(); var syntacticStart = new Date().getTime(); var sourceFile = getValidSourceFile(fileName); + var isJavaScriptFile = ts.isJavaScript(fileName); var start = new Date().getTime(); var currentToken = ts.getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); @@ -33253,12 +33253,23 @@ var ts; } } var type = typeChecker.getTypeAtLocation(node); + addTypeProperties(type); + } + function addTypeProperties(type) { if (type) { - ts.forEach(type.getApparentProperties(), function (symbol) { + for (var _i = 0, _a = type.getApparentProperties(); _i < _a.length; _i++) { + var symbol = _a[_i]; if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); } - }); + } + if (isJavaScriptFile && type.flags & 16384) { + var unionType = type; + for (var _b = 0, _c = unionType.types; _b < _c.length; _b++) { + var elementType = _c[_b]; + addTypeProperties(elementType); + } + } } } function tryGetGlobalSymbols() { @@ -33385,8 +33396,9 @@ var ts; if (start_3 < position && position < end) { return true; } - else if (position === end) { - return !!previousToken.isUnterminated; + if (position === end) { + return !!previousToken.isUnterminated || + previousToken.kind === 9; } } return false; @@ -35615,6 +35627,7 @@ var ts; case 15: return ClassificationTypeNames.typeParameterName; case 16: return ClassificationTypeNames.typeAliasName; case 17: return ClassificationTypeNames.parameterName; + case 18: return ClassificationTypeNames.docCommentTagName; } } function convertClassifications(classifications) { @@ -35660,7 +35673,7 @@ var ts; } if (ts.textSpanIntersectsWith(span, start, width)) { if (ts.isComment(kind)) { - pushClassification(start, width, 1); + classifyComment(token, kind, start, width); continue; } if (kind === 6) { @@ -35676,6 +35689,74 @@ var ts; } } } + function classifyComment(token, kind, start, width) { + if (kind === 3) { + var docCommentAndDiagnostics = ts.parseIsolatedJSDocComment(sourceFile.text, start, width); + if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDocComment) { + docCommentAndDiagnostics.jsDocComment.parent = token; + classifyJSDocComment(docCommentAndDiagnostics.jsDocComment); + return; + } + } + pushCommentRange(start, width); + } + function pushCommentRange(start, width) { + pushClassification(start, width, 1); + } + function classifyJSDocComment(docComment) { + var pos = docComment.pos; + for (var _i = 0, _a = docComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.pos !== pos) { + pushCommentRange(pos, tag.pos - pos); + } + pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, 10); + pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, 18); + pos = tag.tagName.end; + switch (tag.kind) { + case 247: + processJSDocParameterTag(tag); + break; + case 250: + processJSDocTemplateTag(tag); + break; + case 249: + processElement(tag.typeExpression); + break; + case 248: + processElement(tag.typeExpression); + break; + } + pos = tag.end; + } + if (pos !== docComment.end) { + pushCommentRange(pos, docComment.end - pos); + } + return; + function processJSDocParameterTag(tag) { + if (tag.preParameterName) { + pushCommentRange(pos, tag.preParameterName.pos - pos); + pushClassification(tag.preParameterName.pos, tag.preParameterName.end - tag.preParameterName.pos, 17); + pos = tag.preParameterName.end; + } + if (tag.typeExpression) { + pushCommentRange(pos, tag.typeExpression.pos - pos); + processElement(tag.typeExpression); + pos = tag.typeExpression.end; + } + if (tag.postParameterName) { + pushCommentRange(pos, tag.postParameterName.pos - pos); + pushClassification(tag.postParameterName.pos, tag.postParameterName.end - tag.postParameterName.pos, 17); + pos = tag.postParameterName.end; + } + } + } + function processJSDocTemplateTag(tag) { + for (var _i = 0, _a = tag.getChildren(); _i < _a.length; _i++) { + var child = _a[_i]; + processElement(child); + } + } function classifyDisabledMergeCode(text, start, end) { for (var i = start; i < end; i++) { if (ts.isLineBreak(text.charCodeAt(i))) { @@ -35784,8 +35865,11 @@ var ts; } } function processElement(element) { + if (!element) { + return; + } if (ts.textSpanIntersectsWith(span, element.getFullStart(), element.getFullWidth())) { - var children = element.getChildren(); + var children = element.getChildren(sourceFile); for (var _i = 0; _i < children.length; _i++) { var child = children[_i]; if (ts.isToken(child)) { @@ -36501,6 +36585,7 @@ var ts; CommandNames.Saveto = "saveto"; CommandNames.SignatureHelp = "signatureHelp"; CommandNames.TypeDefinition = "typeDefinition"; + CommandNames.ProjectInfo = "projectInfo"; CommandNames.Unknown = "unknown"; })(CommandNames = server.CommandNames || (server.CommandNames = {})); var Errors; @@ -36714,6 +36799,17 @@ var ts; }; }); }; + Session.prototype.getProjectInfo = function (fileName, needFileNameList) { + fileName = ts.normalizePath(fileName); + var project = this.projectService.getProjectForFile(fileName); + var projectInfo = { + configFileName: project.projectFilename + }; + if (needFileNameList) { + projectInfo.fileNameList = project.getFileNameList(); + } + return projectInfo; + }; Session.prototype.getRenameLocations = function (line, offset, fileName, findInComments, findInStrings) { var file = ts.normalizePath(fileName); var project = this.projectService.getProjectForFile(file); @@ -37255,6 +37351,11 @@ var ts; response = this.getOccurrences(line, offset, fileName); break; } + case CommandNames.ProjectInfo: { + var _b = request.arguments, file = _b.file, needFileNameList = _b.needFileNameList; + response = this.getProjectInfo(file, needFileNameList); + break; + } default: { this.projectService.log("Unrecognized JSON command: " + message); this.output(undefined, CommandNames.Unknown, request.seq, "Unrecognized JSON command: " + request.command); @@ -37527,6 +37628,10 @@ var ts; Project.prototype.openReferencedFile = function (filename) { return this.projectService.openFile(filename, false); }; + Project.prototype.getFileNameList = function () { + var sourceFiles = this.program.getSourceFiles(); + return sourceFiles.map(function (sourceFile) { return sourceFile.fileName; }); + }; Project.prototype.getSourceFile = function (info) { return this.filenameToSourceFile[info.fileName]; }; diff --git a/bin/typescript.d.ts b/bin/typescript.d.ts index ede16aa7ed2..58b03102d38 100644 --- a/bin/typescript.d.ts +++ b/bin/typescript.d.ts @@ -999,6 +999,7 @@ declare module "typescript" { UseOnlyExternalAliasing = 2, } const enum SymbolFlags { + None = 0, FunctionScopedVariable = 1, BlockScopedVariable = 2, Property = 4, @@ -1057,10 +1058,8 @@ declare module "typescript" { AliasExcludes = 8388608, ModuleMember = 8914931, ExportHasLocal = 944, - HasLocals = 255504, HasExports = 1952, HasMembers = 6240, - IsContainer = 262128, PropertyOrAccessor = 98308, Export = 7340032, } @@ -1068,9 +1067,9 @@ declare module "typescript" { flags: SymbolFlags; name: string; declarations?: Declaration[]; + valueDeclaration?: Declaration; members?: SymbolTable; exports?: SymbolTable; - valueDeclaration?: Declaration; } interface SymbolTable { [index: string]: Symbol; @@ -1358,7 +1357,6 @@ declare module "typescript" { function getTypeParameterOwner(d: Declaration): Declaration; } declare module "typescript" { - var throwOnJSDocErrors: boolean; function getNodeConstructor(kind: SyntaxKind): new () => Node; function createNode(kind: SyntaxKind): Node; function forEachChild(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T; @@ -1913,6 +1911,7 @@ declare module "typescript" { static typeParameterName: string; static typeAliasName: string; static parameterName: string; + static docCommentTagName: string; } const enum ClassificationType { comment = 1, @@ -1932,6 +1931,7 @@ declare module "typescript" { typeParameterName = 15, typeAliasName = 16, parameterName = 17, + docCommentTagName = 18, } interface DisplayPartsSymbolWriter extends SymbolWriter { displayParts(): SymbolDisplayPart[]; diff --git a/bin/typescript.js b/bin/typescript.js index 1b5c7949463..2b3f25998a5 100644 --- a/bin/typescript.js +++ b/bin/typescript.js @@ -429,6 +429,7 @@ var ts; })(ts.SymbolAccessibility || (ts.SymbolAccessibility = {})); var SymbolAccessibility = ts.SymbolAccessibility; (function (SymbolFlags) { + SymbolFlags[SymbolFlags["None"] = 0] = "None"; SymbolFlags[SymbolFlags["FunctionScopedVariable"] = 1] = "FunctionScopedVariable"; SymbolFlags[SymbolFlags["BlockScopedVariable"] = 2] = "BlockScopedVariable"; SymbolFlags[SymbolFlags["Property"] = 4] = "Property"; @@ -491,10 +492,8 @@ var ts; SymbolFlags[SymbolFlags["AliasExcludes"] = 8388608] = "AliasExcludes"; SymbolFlags[SymbolFlags["ModuleMember"] = 8914931] = "ModuleMember"; SymbolFlags[SymbolFlags["ExportHasLocal"] = 944] = "ExportHasLocal"; - SymbolFlags[SymbolFlags["HasLocals"] = 255504] = "HasLocals"; SymbolFlags[SymbolFlags["HasExports"] = 1952] = "HasExports"; SymbolFlags[SymbolFlags["HasMembers"] = 6240] = "HasMembers"; - SymbolFlags[SymbolFlags["IsContainer"] = 262128] = "IsContainer"; SymbolFlags[SymbolFlags["PropertyOrAccessor"] = 98308] = "PropertyOrAccessor"; SymbolFlags[SymbolFlags["Export"] = 7340032] = "Export"; })(ts.SymbolFlags || (ts.SymbolFlags = {})); @@ -3688,6 +3687,27 @@ var ts; } } ts.getModuleInstanceState = getModuleInstanceState; + var ContainerFlags; + (function (ContainerFlags) { + // The current node is not a container, and no container manipulation should happen before + // recursing into it. + ContainerFlags[ContainerFlags["None"] = 0] = "None"; + // The current node is a container. It should be set as the current container (and block- + // container) before recursing into it. The current node does not have locals. Examples: + // + // Classes, ObjectLiterals, TypeLiterals, Interfaces... + ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer"; + // The current node is a block-scoped-container. It should be set as the current block- + // container before recursing into it. Examples: + // + // Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements... + ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer"; + ContainerFlags[ContainerFlags["HasLocals"] = 4] = "HasLocals"; + // If the current node is a container that also container that also contains locals. Examples: + // + // Functions, Methods, Modules, Source-files. + ContainerFlags[ContainerFlags["IsContainerWithLocals"] = 5] = "IsContainerWithLocals"; + })(ContainerFlags || (ContainerFlags = {})); function bindSourceFile(file) { var start = new Date().getTime(); bindSourceFileWorker(file); @@ -3702,34 +3722,30 @@ var ts; var symbolCount = 0; var Symbol = ts.objectAllocator.getSymbolConstructor(); if (!file.locals) { - file.locals = {}; - container = file; - setBlockScopeContainer(file, false); bind(file); file.symbolCount = symbolCount; } + return; function createSymbol(flags, name) { symbolCount++; return new Symbol(flags, name); } - function setBlockScopeContainer(node, cleanLocals) { - blockScopeContainer = node; - if (cleanLocals) { - blockScopeContainer.locals = undefined; - } - } - function addDeclarationToSymbol(symbol, node, symbolKind) { - symbol.flags |= symbolKind; - if (!symbol.declarations) - symbol.declarations = []; - symbol.declarations.push(node); - if (symbolKind & 1952 /* HasExports */ && !symbol.exports) - symbol.exports = {}; - if (symbolKind & 6240 /* HasMembers */ && !symbol.members) - symbol.members = {}; + function addDeclarationToSymbol(symbol, node, symbolFlags) { + symbol.flags |= symbolFlags; node.symbol = symbol; - if (symbolKind & 107455 /* Value */ && !symbol.valueDeclaration) + if (!symbol.declarations) { + symbol.declarations = []; + } + symbol.declarations.push(node); + if (symbolFlags & 1952 /* HasExports */ && !symbol.exports) { + symbol.exports = {}; + } + if (symbolFlags & 6240 /* HasMembers */ && !symbol.members) { + symbol.members = {}; + } + if (symbolFlags & 107455 /* Value */ && !symbol.valueDeclaration) { symbol.valueDeclaration = node; + } } // Should not be called on a declaration with a computed property name, // unless it is a well known Symbol. @@ -3746,12 +3762,12 @@ var ts; return node.name.text; } switch (node.kind) { - case 144 /* ConstructorType */: case 136 /* Constructor */: return "__constructor"; case 143 /* FunctionType */: case 139 /* CallSignature */: return "__call"; + case 144 /* ConstructorType */: case 140 /* ConstructSignature */: return "__new"; case 141 /* IndexSignature */: @@ -3768,13 +3784,33 @@ var ts; function getDisplayName(node) { return node.name ? ts.declarationNameToString(node.name) : getDeclarationName(node); } - function declareSymbol(symbols, parent, node, includes, excludes) { + function declareSymbol(symbolTable, parent, node, includes, excludes) { ts.Debug.assert(!ts.hasDynamicName(node)); // The exported symbol for an export default function/class node is always named "default" var name = node.flags & 256 /* Default */ && parent ? "default" : getDeclarationName(node); var symbol; if (name !== undefined) { - symbol = ts.hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(0, name)); + // Check and see if the symbol table already has a symbol with this name. If not, + // create a new symbol with this name and add it to the table. Note that we don't + // give the new symbol any flags *yet*. This ensures that it will not conflict + // witht he 'excludes' flags we pass in. + // + // If we do get an existing symbol, see if it conflicts with the new symbol we're + // creating. For example, a 'var' symbol and a 'class' symbol will conflict within + // the same symbol table. If we have a conflict, report the issue on each + // declaration we have for this symbol, and then create a new symbol for this + // declaration. + // + // If we created a new symbol, either because we didn't have a symbol with this name + // in the symbol table, or we conflicted with an existing symbol, then just add this + // node as the sole declaration of the new symbol. + // + // Otherwise, we'll be merging into a compatible existing symbol (for example when + // you have multiple 'vars' with the same name in the same container). In this case + // just add this node into the declarations list of the symbol. + symbol = ts.hasProperty(symbolTable, name) + ? symbolTable[name] + : (symbolTable[name] = createSymbol(0 /* None */, name)); if (symbol.flags & excludes) { if (node.name) { node.name.parent = node; @@ -3788,39 +3824,24 @@ var ts; file.bindDiagnostics.push(ts.createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration))); }); file.bindDiagnostics.push(ts.createDiagnosticForNode(node.name || node, message, getDisplayName(node))); - symbol = createSymbol(0, name); + symbol = createSymbol(0 /* None */, name); } } else { - symbol = createSymbol(0, "__missing"); + symbol = createSymbol(0 /* None */, "__missing"); } addDeclarationToSymbol(symbol, node, includes); symbol.parent = parent; - if ((node.kind === 202 /* ClassDeclaration */ || node.kind === 175 /* ClassExpression */) && symbol.exports) { - // TypeScript 1.0 spec (April 2014): 8.4 - // Every class automatically contains a static property member named 'prototype', - // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter. - // It is an error to explicitly declare a static property member with the name 'prototype'. - var prototypeSymbol = createSymbol(4 /* Property */ | 134217728 /* Prototype */, "prototype"); - if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) { - if (node.name) { - node.name.parent = node; - } - file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); - } - symbol.exports[prototypeSymbol.name] = prototypeSymbol; - prototypeSymbol.parent = symbol; - } return symbol; } - function declareModuleMember(node, symbolKind, symbolExcludes) { + function declareModuleMember(node, symbolFlags, symbolExcludes) { var hasExportModifier = ts.getCombinedNodeFlags(node) & 1 /* Export */; - if (symbolKind & 8388608 /* Alias */) { + if (symbolFlags & 8388608 /* Alias */) { if (node.kind === 218 /* ExportSpecifier */ || (node.kind === 209 /* ImportEqualsDeclaration */ && hasExportModifier)) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); } else { - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } else { @@ -3836,62 +3857,150 @@ var ts; // but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way // when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope. if (hasExportModifier || container.flags & 65536 /* ExportContext */) { - var exportKind = (symbolKind & 107455 /* Value */ ? 1048576 /* ExportValue */ : 0) | - (symbolKind & 793056 /* Type */ ? 2097152 /* ExportType */ : 0) | - (symbolKind & 1536 /* Namespace */ ? 4194304 /* ExportNamespace */ : 0); + var exportKind = (symbolFlags & 107455 /* Value */ ? 1048576 /* ExportValue */ : 0) | + (symbolFlags & 793056 /* Type */ ? 2097152 /* ExportType */ : 0) | + (symbolFlags & 1536 /* Namespace */ ? 4194304 /* ExportNamespace */ : 0); var local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes); - local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); node.localSymbol = local; + return local; } else { - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } } - // All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function - // in the type checker to validate that the local name used for a container is unique. - function bindChildren(node, symbolKind, isBlockScopeContainer) { - if (symbolKind & 255504 /* HasLocals */) { - node.locals = {}; - } + // All container nodes are kept on a linked list in declaration order. This list is used by + // the getLocalNameOfContainer function in the type checker to validate that the local name + // used for a container is unique. + function bindChildren(node) { + // Before we recurse into a node's chilren, we first save the existing parent, container + // and block-container. Then after we pop out of processing the children, we restore + // these saved values. var saveParent = parent; var saveContainer = container; var savedBlockScopeContainer = blockScopeContainer; + // This node will now be set as the parent of all of its children as we recurse into them. parent = node; - if (symbolKind & 262128 /* IsContainer */) { - container = node; + // Depending on what kind of node this is, we may have to adjust the current container + // and block-container. If the current node is a container, then it is automatically + // considered the current block-container as well. Also, for containers that we know + // may contain locals, we proactively initialize the .locals field. We do this because + // it's highly likely that the .locals will be needed to place some child in (for example, + // a parameter, or variable declaration). + // + // However, we do not proactively create the .locals for block-containers because it's + // totally normal and common for block-containers to never actually have a block-scoped + // variable in them. We don't want to end up allocating an object for every 'block' we + // run into when most of them won't be necessary. + // + // Finally, if this is a block-container, then we clear out any existing .locals object + // it may contain within it. This happens in incremental scenarios. Because we can be + // reusing a node from a previous compilation, that node may have had 'locals' created + // for it. We must clear this so we don't accidently move any stale data forward from + // a previous compilation. + var containerFlags = getContainerFlags(node); + if (containerFlags & 1 /* IsContainer */) { + container = blockScopeContainer = node; + if (containerFlags & 4 /* HasLocals */) { + container.locals = {}; + } addToContainerChain(container); } - if (isBlockScopeContainer) { - // in incremental scenarios we might reuse nodes that already have locals being allocated - // during the bind step these locals should be dropped to prevent using stale data. - // locals should always be dropped unless they were previously initialized by the binder - // these cases are: - // - node has locals (symbolKind & HasLocals) !== 0 - // - node is a source file - setBlockScopeContainer(node, (symbolKind & 255504 /* HasLocals */) === 0 && node.kind !== 228 /* SourceFile */); + else if (containerFlags & 2 /* IsBlockScopedContainer */) { + blockScopeContainer = node; + blockScopeContainer.locals = undefined; } ts.forEachChild(node, bind); container = saveContainer; parent = saveParent; blockScopeContainer = savedBlockScopeContainer; } - function addToContainerChain(node) { - if (lastContainer) { - lastContainer.nextContainer = node; - } - lastContainer = node; - } - function bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer) { - switch (container.kind) { + function getContainerFlags(node) { + switch (node.kind) { + case 175 /* ClassExpression */: + case 202 /* ClassDeclaration */: + case 203 /* InterfaceDeclaration */: + case 205 /* EnumDeclaration */: + case 146 /* TypeLiteral */: + case 155 /* ObjectLiteralExpression */: + return 1 /* IsContainer */; + case 139 /* CallSignature */: + case 140 /* ConstructSignature */: + case 141 /* IndexSignature */: + case 135 /* MethodDeclaration */: + case 134 /* MethodSignature */: + case 201 /* FunctionDeclaration */: + case 136 /* Constructor */: + case 137 /* GetAccessor */: + case 138 /* SetAccessor */: + case 143 /* FunctionType */: + case 144 /* ConstructorType */: + case 163 /* FunctionExpression */: + case 164 /* ArrowFunction */: case 206 /* ModuleDeclaration */: - declareModuleMember(node, symbolKind, symbolExcludes); - break; case 228 /* SourceFile */: - if (ts.isExternalModule(container)) { - declareModuleMember(node, symbolKind, symbolExcludes); - break; - } + return 5 /* IsContainerWithLocals */; + case 224 /* CatchClause */: + case 187 /* ForStatement */: + case 188 /* ForInStatement */: + case 189 /* ForOfStatement */: + case 208 /* CaseBlock */: + return 2 /* IsBlockScopedContainer */; + case 180 /* Block */: + // do not treat blocks directly inside a function as a block-scoped-container. + // Locals that reside in this block should go to the function locals. Othewise 'x' + // would not appear to be a redeclaration of a block scoped local in the following + // example: + // + // function foo() { + // var x; + // let x; + // } + // + // If we placed 'var x' into the function locals and 'let x' into the locals of + // the block, then there would be no collision. + // + // By not creating a new block-scoped-container here, we ensure that both 'var x' + // and 'let x' go into the Function-container's locals, and we do get a collision + // conflict. + return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */; + } + return 0 /* None */; + } + function addToContainerChain(next) { + if (lastContainer) { + lastContainer.nextContainer = next; + } + lastContainer = next; + } + function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) { + // Just call this directly so that the return type of this function stays "void". + declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes); + } + function declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes) { + switch (container.kind) { + // Modules, source files, and classes need specialized handling for how their + // members are declared (for example, a member of a class will go into a specific + // symbol table depending on if it is static or not). As such, we defer to + // specialized handlers to take care of declaring these child members. + case 206 /* ModuleDeclaration */: + return declareModuleMember(node, symbolFlags, symbolExcludes); + case 228 /* SourceFile */: + return declareSourceFileMember(node, symbolFlags, symbolExcludes); + case 175 /* ClassExpression */: + case 202 /* ClassDeclaration */: + return declareClassMember(node, symbolFlags, symbolExcludes); + case 205 /* EnumDeclaration */: + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); + case 146 /* TypeLiteral */: + case 155 /* ObjectLiteralExpression */: + case 203 /* InterfaceDeclaration */: + // Interface/Object-types always have their children added to the 'members' of + // their container. They are only accessible through an instance of their + // container, and are never in scope otherwise (even inside the body of the + // object / type / interface declaring them). + return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); case 143 /* FunctionType */: case 144 /* ConstructorType */: case 139 /* CallSignature */: @@ -3905,29 +4014,30 @@ var ts; case 201 /* FunctionDeclaration */: case 163 /* FunctionExpression */: case 164 /* ArrowFunction */: - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); - break; - case 175 /* ClassExpression */: - case 202 /* ClassDeclaration */: - if (node.flags & 128 /* Static */) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); - break; - } - case 146 /* TypeLiteral */: - case 155 /* ObjectLiteralExpression */: - case 203 /* InterfaceDeclaration */: - declareSymbol(container.symbol.members, container.symbol, node, symbolKind, symbolExcludes); - break; - case 205 /* EnumDeclaration */: - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); - break; + // All the children of these container types are never visible through another + // symbol (i.e. through another symbol's 'exports' or 'members'). Instead, + // they're only accessed 'lexically' (i.e. from code that exists underneath + // their container in the tree. To accomplish this, we simply add their declared + // symbol to the 'locals' of the container. These symbols can then be found as + // the type checker walks up the containers, checking them for matching names. + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolKind, isBlockScopeContainer); + } + function declareClassMember(node, symbolFlags, symbolExcludes) { + return node.flags & 128 /* Static */ + ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes) + : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); + } + function declareSourceFileMember(node, symbolFlags, symbolExcludes) { + return ts.isExternalModule(file) + ? declareModuleMember(node, symbolFlags, symbolExcludes) + : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes); } function isAmbientContext(node) { while (node) { - if (node.flags & 2 /* Ambient */) + if (node.flags & 2 /* Ambient */) { return true; + } node = node.parent; } return false; @@ -3957,15 +4067,15 @@ var ts; function bindModuleDeclaration(node) { setExportContextFlag(node); if (node.name.kind === 8 /* StringLiteral */) { - bindDeclaration(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */, true); + declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */); } else { var state = getModuleInstanceState(node); if (state === 0 /* NonInstantiated */) { - bindDeclaration(node, 1024 /* NamespaceModule */, 0 /* NamespaceModuleExcludes */, true); + declareSymbolAndAddToSymbolTable(node, 1024 /* NamespaceModule */, 0 /* NamespaceModuleExcludes */); } else { - bindDeclaration(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */, true); + declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */); var currentModuleIsConstEnumOnly = state === 2 /* ConstEnumOnly */; if (node.symbol.constEnumOnlyModule === undefined) { // non-merged case - use the current state @@ -3987,28 +4097,23 @@ var ts; // from an actual type literal symbol you would have gotten had you used the long form. var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node)); addDeclarationToSymbol(symbol, node, 131072 /* Signature */); - bindChildren(node, 131072 /* Signature */, false); var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */); - typeLiteralSymbol.members = {}; - typeLiteralSymbol.members[node.kind === 143 /* FunctionType */ ? "__call" : "__new"] = symbol; + typeLiteralSymbol.members = (_a = {}, _a[symbol.name] = symbol, _a); + var _a; } - function bindAnonymousDeclaration(node, symbolKind, name, isBlockScopeContainer) { - var symbol = createSymbol(symbolKind, name); - addDeclarationToSymbol(symbol, node, symbolKind); - bindChildren(node, symbolKind, isBlockScopeContainer); + function bindAnonymousDeclaration(node, symbolFlags, name) { + var symbol = createSymbol(symbolFlags, name); + addDeclarationToSymbol(symbol, node, symbolFlags); } - function bindCatchVariableDeclaration(node) { - bindChildren(node, 0, true); - } - function bindBlockScopedDeclaration(node, symbolKind, symbolExcludes) { + function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) { switch (blockScopeContainer.kind) { case 206 /* ModuleDeclaration */: - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; case 228 /* SourceFile */: if (ts.isExternalModule(container)) { - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; } // fall through. @@ -4017,9 +4122,8 @@ var ts; blockScopeContainer.locals = {}; addToContainerChain(blockScopeContainer); } - declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, symbolExcludes); + declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolKind, false); } function bindBlockScopedVariableDeclaration(node) { bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */); @@ -4029,182 +4133,182 @@ var ts; } function bind(node) { node.parent = parent; + // First we bind declaration nodes to a symbol if possible. We'll both create a symbol + // and then potentially add the symbol to an appropriate symbol table. Possible + // destination symbol tables are: + // + // 1) The 'exports' table of the current container's symbol. + // 2) The 'members' table of the current container's symbol. + // 3) The 'locals' table of the current container. + // + // However, not all symbols will end up in any of these tables. 'Anonymous' symbols + // (like TypeLiterals for example) will not be put in any table. + bindWorker(node); + // Then we recurse into the children of the node to bind them as well. For certain + // symbols we do specialized work when we recurse. For example, we'll keep track of + // the current 'container' node when it changes. This helps us know which symbol table + // a local should go into for example. + bindChildren(node); + } + function bindWorker(node) { switch (node.kind) { case 129 /* TypeParameter */: - bindDeclaration(node, 262144 /* TypeParameter */, 530912 /* TypeParameterExcludes */, false); - break; + return declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 530912 /* TypeParameterExcludes */); case 130 /* Parameter */: - bindParameter(node); - break; + return bindParameter(node); case 199 /* VariableDeclaration */: case 153 /* BindingElement */: - if (ts.isBindingPattern(node.name)) { - bindChildren(node, 0, false); - } - else if (ts.isBlockOrCatchScoped(node)) { - bindBlockScopedVariableDeclaration(node); - } - else if (ts.isParameterDeclaration(node)) { - // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration - // because its parent chain has already been set up, since parents are set before descending into children. - // - // If node is a binding element in parameter declaration, we need to use ParameterExcludes. - // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration - // For example: - // function foo([a,a]) {} // Duplicate Identifier error - // function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter - // // which correctly set excluded symbols - bindDeclaration(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */, false); - } - else { - bindDeclaration(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */, false); - } - break; + return bindVariableDeclarationOrBindingElement(node); case 133 /* PropertyDeclaration */: case 132 /* PropertySignature */: - bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0), 107455 /* PropertyExcludes */, false); - break; + return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), 107455 /* PropertyExcludes */); case 225 /* PropertyAssignment */: case 226 /* ShorthandPropertyAssignment */: - bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 107455 /* PropertyExcludes */, false); - break; + return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 107455 /* PropertyExcludes */); case 227 /* EnumMember */: - bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */, false); - break; + return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */); case 139 /* CallSignature */: case 140 /* ConstructSignature */: case 141 /* IndexSignature */: - bindDeclaration(node, 131072 /* Signature */, 0, false); - break; + return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */); case 135 /* MethodDeclaration */: case 134 /* MethodSignature */: // If this is an ObjectLiteralExpression method, then it sits in the same space // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes // so that it will conflict with any other object literal members with the same // name. - bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0), ts.isObjectLiteralMethod(node) ? 107455 /* PropertyExcludes */ : 99263 /* MethodExcludes */, true); - break; + return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 107455 /* PropertyExcludes */ : 99263 /* MethodExcludes */); case 201 /* FunctionDeclaration */: - bindDeclaration(node, 16 /* Function */, 106927 /* FunctionExcludes */, true); - break; + return declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 106927 /* FunctionExcludes */); case 136 /* Constructor */: - bindDeclaration(node, 16384 /* Constructor */, 0, true); - break; + return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, 0 /* None */); case 137 /* GetAccessor */: - bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */, true); - break; + return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */); case 138 /* SetAccessor */: - bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */, true); - break; + return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */); case 143 /* FunctionType */: case 144 /* ConstructorType */: - bindFunctionOrConstructorType(node); - break; + return bindFunctionOrConstructorType(node); case 146 /* TypeLiteral */: - bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type", false); - break; + return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type"); case 155 /* ObjectLiteralExpression */: - bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object", false); - break; + return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object"); case 163 /* FunctionExpression */: case 164 /* ArrowFunction */: - bindAnonymousDeclaration(node, 16 /* Function */, "__function", true); - break; + return bindAnonymousDeclaration(node, 16 /* Function */, "__function"); case 175 /* ClassExpression */: - bindAnonymousDeclaration(node, 32 /* Class */, "__class", false); - break; - case 224 /* CatchClause */: - bindCatchVariableDeclaration(node); - break; case 202 /* ClassDeclaration */: - bindBlockScopedDeclaration(node, 32 /* Class */, 899583 /* ClassExcludes */); - break; + return bindClassLikeDeclaration(node); case 203 /* InterfaceDeclaration */: - bindBlockScopedDeclaration(node, 64 /* Interface */, 792992 /* InterfaceExcludes */); - break; + return bindBlockScopedDeclaration(node, 64 /* Interface */, 792992 /* InterfaceExcludes */); case 204 /* TypeAliasDeclaration */: - bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */); - break; + return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */); case 205 /* EnumDeclaration */: - if (ts.isConst(node)) { - bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */); - } - else { - bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */); - } - break; + return bindEnumDeclaration(node); case 206 /* ModuleDeclaration */: - bindModuleDeclaration(node); - break; + return bindModuleDeclaration(node); case 209 /* ImportEqualsDeclaration */: case 212 /* NamespaceImport */: case 214 /* ImportSpecifier */: case 218 /* ExportSpecifier */: - bindDeclaration(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */, false); - break; + return declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */); case 211 /* ImportClause */: - if (node.name) { - bindDeclaration(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */, false); - } - else { - bindChildren(node, 0, false); - } - break; + return bindImportClause(node); case 216 /* ExportDeclaration */: - if (!node.exportClause) { - // All export * declarations are collected in an __export symbol - declareSymbol(container.symbol.exports, container.symbol, node, 1073741824 /* ExportStar */, 0); - } - bindChildren(node, 0, false); - break; + return bindExportDeclaration(node); case 215 /* ExportAssignment */: - if (node.expression.kind === 65 /* Identifier */) { - // An export default clause with an identifier exports all meanings of that identifier - declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); - } - else { - // An export default clause with an expression exports a value - declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); - } - bindChildren(node, 0, false); - break; + return bindExportAssignment(node); case 228 /* SourceFile */: - setExportContextFlag(node); - if (ts.isExternalModule(node)) { - bindAnonymousDeclaration(node, 512 /* ValueModule */, '"' + ts.removeFileExtension(node.fileName) + '"', true); - break; - } - case 180 /* Block */: - // do not treat function block a block-scope container - // all block-scope locals that reside in this block should go to the function locals. - // Otherwise this won't be considered as redeclaration of a block scoped local: - // function foo() { - // let x; - // let x; - // } - // 'let x' will be placed into the function locals and 'let x' - into the locals of the block - bindChildren(node, 0, !ts.isFunctionLike(node.parent)); - break; - case 224 /* CatchClause */: - case 187 /* ForStatement */: - case 188 /* ForInStatement */: - case 189 /* ForOfStatement */: - case 208 /* CaseBlock */: - bindChildren(node, 0, true); - break; - default: - var saveParent = parent; - parent = node; - ts.forEachChild(node, bind); - parent = saveParent; + return bindSourceFileIfExternalModule(); + } + } + function bindSourceFileIfExternalModule() { + setExportContextFlag(file); + if (ts.isExternalModule(file)) { + bindAnonymousDeclaration(file, 512 /* ValueModule */, '"' + ts.removeFileExtension(file.fileName) + '"'); + } + } + function bindExportAssignment(node) { + if (node.expression.kind === 65 /* Identifier */) { + // An export default clause with an identifier exports all meanings of that identifier + declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); + } + else { + // An export default clause with an expression exports a value + declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); + } + } + function bindExportDeclaration(node) { + if (!node.exportClause) { + // All export * declarations are collected in an __export symbol + declareSymbol(container.symbol.exports, container.symbol, node, 1073741824 /* ExportStar */, 0 /* None */); + } + } + function bindImportClause(node) { + if (node.name) { + declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */); + } + } + function bindClassLikeDeclaration(node) { + if (node.kind === 202 /* ClassDeclaration */) { + bindBlockScopedDeclaration(node, 32 /* Class */, 899583 /* ClassExcludes */); + } + else { + bindAnonymousDeclaration(node, 32 /* Class */, "__class"); + } + var symbol = node.symbol; + // TypeScript 1.0 spec (April 2014): 8.4 + // Every class automatically contains a static property member named 'prototype', the + // type of which is an instantiation of the class type with type Any supplied as a type + // argument for each type parameter. It is an error to explicitly declare a static + // property member with the name 'prototype'. + // + // Note: we check for this here because this class may be merging into a module. The + // module might have an exported variable called 'prototype'. We can't allow that as + // that would clash with the built-in 'prototype' for the class. + var prototypeSymbol = createSymbol(4 /* Property */ | 134217728 /* Prototype */, "prototype"); + if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) { + if (node.name) { + node.name.parent = node; + } + file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); + } + symbol.exports[prototypeSymbol.name] = prototypeSymbol; + prototypeSymbol.parent = symbol; + } + function bindEnumDeclaration(node) { + return ts.isConst(node) + ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */) + : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */); + } + function bindVariableDeclarationOrBindingElement(node) { + if (!ts.isBindingPattern(node.name)) { + if (ts.isBlockOrCatchScoped(node)) { + bindBlockScopedVariableDeclaration(node); + } + else if (ts.isParameterDeclaration(node)) { + // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration + // because its parent chain has already been set up, since parents are set before descending into children. + // + // If node is a binding element in parameter declaration, we need to use ParameterExcludes. + // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration + // For example: + // function foo([a,a]) {} // Duplicate Identifier error + // function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter + // // which correctly set excluded symbols + declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */); + } + else { + declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */); + } } } function bindParameter(node) { if (ts.isBindingPattern(node.name)) { - bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, getDestructuringParameterName(node), false); + bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, getDestructuringParameterName(node)); } else { - bindDeclaration(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */, false); + declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */); } // If this is a property-parameter, then also declare the property symbol into the // containing class. @@ -4215,13 +4319,10 @@ var ts; declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */); } } - function bindPropertyOrMethodOrAccessor(node, symbolKind, symbolExcludes, isBlockScopeContainer) { - if (ts.hasDynamicName(node)) { - bindAnonymousDeclaration(node, symbolKind, "__computed", isBlockScopeContainer); - } - else { - bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer); - } + function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) { + return ts.hasDynamicName(node) + ? bindAnonymousDeclaration(node, symbolFlags, "__computed") + : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } } })(ts || (ts = {})); @@ -5111,10 +5212,6 @@ var ts; } } ts.getExternalModuleName = getExternalModuleName; - function hasDotDotDotToken(node) { - return node && node.kind === 130 /* Parameter */ && node.dotDotDotToken !== undefined; - } - ts.hasDotDotDotToken = hasDotDotDotToken; function hasQuestionToken(node) { if (node) { switch (node.kind) { @@ -5133,10 +5230,6 @@ var ts; return false; } ts.hasQuestionToken = hasQuestionToken; - function hasRestParameters(s) { - return s.parameters.length > 0 && ts.lastOrUndefined(s.parameters).dotDotDotToken !== undefined; - } - ts.hasRestParameters = hasRestParameters; function isJSDocConstructSignature(node) { return node.kind === 241 /* JSDocFunctionType */ && node.parameters.length > 0 && @@ -6287,7 +6380,6 @@ var ts; /// var ts; (function (ts) { - ts.throwOnJSDocErrors = false; var nodeConstructors = new Array(252 /* Count */); /* @internal */ ts.parseTime = 0; function getNodeConstructor(kind) { @@ -10679,12 +10771,6 @@ var ts; return finishNode(result); } JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression; - function setError(message) { - parseErrorAtCurrentToken(message); - if (ts.throwOnJSDocErrors) { - throw new Error(message.key); - } - } function parseJSDocTopLevelType() { var type = parseJSDocType(); if (token === 44 /* BarToken */) { @@ -12076,27 +12162,31 @@ var ts; case 138 /* SetAccessor */: case 201 /* FunctionDeclaration */: case 164 /* ArrowFunction */: - if (name === "arguments") { + if (meaning & 3 /* Variable */ && name === "arguments") { result = argumentsSymbol; break loop; } break; case 163 /* FunctionExpression */: - if (name === "arguments") { + if (meaning & 3 /* Variable */ && name === "arguments") { result = argumentsSymbol; break loop; } - var functionName = location.name; - if (functionName && name === functionName.text) { - result = location.symbol; - break loop; + if (meaning & 16 /* Function */) { + var functionName = location.name; + if (functionName && name === functionName.text) { + result = location.symbol; + break loop; + } } break; case 175 /* ClassExpression */: - var className = location.name; - if (className && name === className.text) { - result = location.symbol; - break loop; + if (meaning & 32 /* Class */) { + var className = location.name; + if (className && name === className.text) { + result = location.symbol; + break loop; + } } break; case 131 /* Decorator */: @@ -13307,11 +13397,12 @@ var ts; } } function buildParameterDisplay(p, writer, enclosingDeclaration, flags, typeStack) { - if (ts.hasDotDotDotToken(p.valueDeclaration)) { + var parameterNode = p.valueDeclaration; + if (ts.isRestParameter(parameterNode)) { writePunctuation(writer, 21 /* DotDotDotToken */); } appendSymbolNameOnly(p, writer); - if (ts.hasQuestionToken(p.valueDeclaration) || p.valueDeclaration.initializer) { + if (isOptionalParameter(parameterNode)) { writePunctuation(writer, 50 /* QuestionToken */); } writePunctuation(writer, 51 /* ColonToken */); @@ -14607,6 +14698,9 @@ var ts; } return result; } + function isOptionalParameter(node) { + return ts.hasQuestionToken(node) || !!node.initializer; + } function getSignatureFromDeclaration(declaration) { var links = getNodeLinks(declaration); if (!links.resolvedSignature) { @@ -14649,7 +14743,7 @@ var ts; returnType = anyType; } } - links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, ts.hasRestParameters(declaration), hasStringLiterals); + links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, ts.hasRestParameter(declaration), hasStringLiterals); } return links.resolvedSignature; } @@ -14904,32 +14998,7 @@ var ts; type = unknownType; } else { - type = getDeclaredTypeOfSymbol(symbol); - if (type.flags & (1024 /* Class */ | 2048 /* Interface */) && type.flags & 4096 /* Reference */) { - // In a type reference, the outer type parameters of the referenced class or interface are automatically - // supplied as type arguments and the type reference only specifies arguments for the local type parameters - // of the class or interface. - var localTypeParameters = type.localTypeParameters; - var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; - var typeArgCount = node.typeArguments ? node.typeArguments.length : 0; - if (typeArgCount === expectedTypeArgCount) { - // When no type arguments are expected we already have the right type because all outer type parameters - // have themselves as default type arguments. - if (typeArgCount) { - type = createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(node.typeArguments, getTypeFromTypeNode))); - } - } - else { - error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1 /* WriteArrayAsGenericType */), expectedTypeArgCount); - type = undefined; - } - } - else { - if (node.typeArguments) { - error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); - type = undefined; - } - } + type = createTypeReferenceIfGeneric(getDeclaredTypeOfSymbol(symbol), node, node.typeArguments); } } } @@ -14937,6 +15006,34 @@ var ts; } return links.resolvedType; } + function createTypeReferenceIfGeneric(type, node, typeArguments) { + if (type.flags & (1024 /* Class */ | 2048 /* Interface */) && type.flags & 4096 /* Reference */) { + // In a type reference, the outer type parameters of the referenced class or interface are automatically + // supplied as type arguments and the type reference only specifies arguments for the local type parameters + // of the class or interface. + var localTypeParameters = type.localTypeParameters; + var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; + var typeArgCount = typeArguments ? typeArguments.length : 0; + if (typeArgCount === expectedTypeArgCount) { + // When no type arguments are expected we already have the right type because all outer type parameters + // have themselves as default type arguments. + if (typeArgCount) { + return createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(typeArguments, getTypeFromTypeNode))); + } + } + else { + error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1 /* WriteArrayAsGenericType */), expectedTypeArgCount); + return undefined; + } + } + else { + if (typeArguments) { + error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); + return undefined; + } + } + return type; + } function getTypeFromTypeQueryNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { @@ -17078,7 +17175,7 @@ var ts; if (isContextSensitive(func)) { var contextualSignature = getContextualSignature(func); if (contextualSignature) { - var funcHasRestParameters = ts.hasRestParameters(func); + var funcHasRestParameters = ts.hasRestParameter(func); var len = func.parameters.length - (funcHasRestParameters ? 1 : 0); var indexOfParameter = ts.indexOf(func.parameters, parameter); if (indexOfParameter < len) { @@ -20190,7 +20287,7 @@ var ts; } function checkCollisionWithArgumentsInGeneratedCode(node) { // no rest parameters \ declaration context \ overload - no codegen impact - if (!ts.hasRestParameters(node) || ts.isInAmbientContext(node) || ts.nodeIsMissing(node.body)) { + if (!ts.hasRestParameter(node) || ts.isInAmbientContext(node) || ts.nodeIsMissing(node.body)) { return; } ts.forEach(node.parameters, function (p) { @@ -28138,7 +28235,7 @@ var ts; } } function emitRestParameter(node) { - if (languageVersion < 2 /* ES6 */ && ts.hasRestParameters(node)) { + if (languageVersion < 2 /* ES6 */ && ts.hasRestParameter(node)) { var restIndex = node.parameters.length - 1; var restParam = node.parameters[restIndex]; // A rest parameter cannot have a binding pattern, so let's just ignore it if it does. @@ -28252,7 +28349,7 @@ var ts; write("("); if (node) { var parameters = node.parameters; - var omitCount = languageVersion < 2 /* ES6 */ && ts.hasRestParameters(node) ? 1 : 0; + var omitCount = languageVersion < 2 /* ES6 */ && ts.hasRestParameter(node) ? 1 : 0; emitList(parameters, 0, parameters.length - omitCount, false, false); } write(")"); @@ -37707,6 +37804,7 @@ var ts; ClassificationTypeNames.typeParameterName = "type parameter name"; ClassificationTypeNames.typeAliasName = "type alias name"; ClassificationTypeNames.parameterName = "parameter name"; + ClassificationTypeNames.docCommentTagName = "doc comment tag name"; return ClassificationTypeNames; })(); ts.ClassificationTypeNames = ClassificationTypeNames; @@ -37728,6 +37826,7 @@ var ts; ClassificationType[ClassificationType["typeParameterName"] = 15] = "typeParameterName"; ClassificationType[ClassificationType["typeAliasName"] = 16] = "typeAliasName"; ClassificationType[ClassificationType["parameterName"] = 17] = "parameterName"; + ClassificationType[ClassificationType["docCommentTagName"] = 18] = "docCommentTagName"; })(ts.ClassificationType || (ts.ClassificationType = {})); var ClassificationType = ts.ClassificationType; function displayPartsToString(displayParts) { @@ -37940,7 +38039,8 @@ var ts; } ts.transpile = transpile; function createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, setNodeParents) { - var sourceFile = ts.createSourceFile(fileName, scriptSnapshot.getText(0, scriptSnapshot.getLength()), scriptTarget, setNodeParents); + var text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); + var sourceFile = ts.createSourceFile(fileName, text, scriptTarget, setNodeParents); setSourceFileFields(sourceFile, scriptSnapshot, version); // after full parsing we can use table with interned strings as name table sourceFile.nameTable = sourceFile.identifiers; @@ -38534,12 +38634,16 @@ var ts; } } } + // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point. + // It needs to be cleared to allow all collected snapshots to be released + hostCache = undefined; program = newProgram; // Make sure all the nodes in the program are both bound, and have their parent // pointers set property. program.getTypeChecker(); return; function getOrCreateSourceFile(fileName) { + ts.Debug.assert(hostCache !== undefined); // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. @@ -38847,6 +38951,7 @@ var ts; var typeChecker = program.getTypeChecker(); var syntacticStart = new Date().getTime(); var sourceFile = getValidSourceFile(fileName); + var isJavaScriptFile = ts.isJavaScript(fileName); var start = new Date().getTime(); var currentToken = ts.getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); @@ -38929,13 +39034,29 @@ var ts; } } var type = typeChecker.getTypeAtLocation(node); + addTypeProperties(type); + } + function addTypeProperties(type) { if (type) { // Filter private properties - ts.forEach(type.getApparentProperties(), function (symbol) { + for (var _i = 0, _a = type.getApparentProperties(); _i < _a.length; _i++) { + var symbol = _a[_i]; if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); } - }); + } + if (isJavaScriptFile && type.flags & 16384 /* Union */) { + // In javascript files, for union types, we don't just get the members that + // the individual types have in common, we also include all the members that + // each individual type has. This is because we're going to add all identifiers + // anyways. So we might as well elevate the members that were at least part + // of the individual types to a higher status since we know what they are. + var unionType = type; + for (var _b = 0, _c = unionType.types; _b < _c.length; _b++) { + var elementType = _c[_b]; + addTypeProperties(elementType); + } + } } } function tryGetGlobalSymbols() { @@ -39096,15 +39217,18 @@ var ts; if (previousToken.kind === 8 /* StringLiteral */ || previousToken.kind === 9 /* RegularExpressionLiteral */ || ts.isTemplateLiteralKind(previousToken.kind)) { - // The position has to be either: 1. entirely within the token text, or - // 2. at the end position of an unterminated token. var start_3 = previousToken.getStart(); var end = previousToken.getEnd(); + // To be "in" one of these literals, the position has to be: + // 1. entirely within the token text. + // 2. at the end position of an unterminated token. + // 3. at the end of a regular expression (due to trailing flags like '/foo/g'). if (start_3 < position && position < end) { return true; } - else if (position === end) { - return !!previousToken.isUnterminated; + if (position === end) { + return !!previousToken.isUnterminated || + previousToken.kind === 9 /* RegularExpressionLiteral */; } } return false; @@ -41583,6 +41707,7 @@ var ts; case 15 /* typeParameterName */: return ClassificationTypeNames.typeParameterName; case 16 /* typeAliasName */: return ClassificationTypeNames.typeAliasName; case 17 /* parameterName */: return ClassificationTypeNames.parameterName; + case 18 /* docCommentTagName */: return ClassificationTypeNames.docCommentTagName; } } function convertClassifications(classifications) { @@ -41633,8 +41758,7 @@ var ts; // Only bother with the trivia if it at least intersects the span of interest. if (ts.textSpanIntersectsWith(span, start, width)) { if (ts.isComment(kind)) { - // Simple comment. Just add as is. - pushClassification(start, width, 1 /* comment */); + classifyComment(token, kind, start, width); continue; } if (kind === 6 /* ConflictMarkerTrivia */) { @@ -41654,6 +41778,79 @@ var ts; } } } + function classifyComment(token, kind, start, width) { + if (kind === 3 /* MultiLineCommentTrivia */) { + // See if this is a doc comment. If so, we'll classify certain portions of it + // specially. + var docCommentAndDiagnostics = ts.parseIsolatedJSDocComment(sourceFile.text, start, width); + if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDocComment) { + docCommentAndDiagnostics.jsDocComment.parent = token; + classifyJSDocComment(docCommentAndDiagnostics.jsDocComment); + return; + } + } + // Simple comment. Just add as is. + pushCommentRange(start, width); + } + function pushCommentRange(start, width) { + pushClassification(start, width, 1 /* comment */); + } + function classifyJSDocComment(docComment) { + var pos = docComment.pos; + for (var _i = 0, _a = docComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + // As we walk through each tag, classify the portion of text from the end of + // the last tag (or the start of the entire doc comment) as 'comment'. + if (tag.pos !== pos) { + pushCommentRange(pos, tag.pos - pos); + } + pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, 10 /* punctuation */); + pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, 18 /* docCommentTagName */); + pos = tag.tagName.end; + switch (tag.kind) { + case 247 /* JSDocParameterTag */: + processJSDocParameterTag(tag); + break; + case 250 /* JSDocTemplateTag */: + processJSDocTemplateTag(tag); + break; + case 249 /* JSDocTypeTag */: + processElement(tag.typeExpression); + break; + case 248 /* JSDocReturnTag */: + processElement(tag.typeExpression); + break; + } + pos = tag.end; + } + if (pos !== docComment.end) { + pushCommentRange(pos, docComment.end - pos); + } + return; + function processJSDocParameterTag(tag) { + if (tag.preParameterName) { + pushCommentRange(pos, tag.preParameterName.pos - pos); + pushClassification(tag.preParameterName.pos, tag.preParameterName.end - tag.preParameterName.pos, 17 /* parameterName */); + pos = tag.preParameterName.end; + } + if (tag.typeExpression) { + pushCommentRange(pos, tag.typeExpression.pos - pos); + processElement(tag.typeExpression); + pos = tag.typeExpression.end; + } + if (tag.postParameterName) { + pushCommentRange(pos, tag.postParameterName.pos - pos); + pushClassification(tag.postParameterName.pos, tag.postParameterName.end - tag.postParameterName.pos, 17 /* parameterName */); + pos = tag.postParameterName.end; + } + } + } + function processJSDocTemplateTag(tag) { + for (var _i = 0, _a = tag.getChildren(); _i < _a.length; _i++) { + var child = _a[_i]; + processElement(child); + } + } function classifyDisabledMergeCode(text, start, end) { // Classify the line that the ======= marker is on as a comment. Then just lex // all further tokens and add them to the result. @@ -41774,9 +41971,12 @@ var ts; } } function processElement(element) { + if (!element) { + return; + } // Ignore nodes that don't intersect the original span to classify. if (ts.textSpanIntersectsWith(span, element.getFullStart(), element.getFullWidth())) { - var children = element.getChildren(); + var children = element.getChildren(sourceFile); for (var _i = 0; _i < children.length; _i++) { var child = children[_i]; if (ts.isToken(child)) { diff --git a/bin/typescriptServices.d.ts b/bin/typescriptServices.d.ts index 0d54e446d8f..ea7d2a352ec 100644 --- a/bin/typescriptServices.d.ts +++ b/bin/typescriptServices.d.ts @@ -999,6 +999,7 @@ declare module ts { UseOnlyExternalAliasing = 2, } const enum SymbolFlags { + None = 0, FunctionScopedVariable = 1, BlockScopedVariable = 2, Property = 4, @@ -1057,10 +1058,8 @@ declare module ts { AliasExcludes = 8388608, ModuleMember = 8914931, ExportHasLocal = 944, - HasLocals = 255504, HasExports = 1952, HasMembers = 6240, - IsContainer = 262128, PropertyOrAccessor = 98308, Export = 7340032, } @@ -1068,9 +1067,9 @@ declare module ts { flags: SymbolFlags; name: string; declarations?: Declaration[]; + valueDeclaration?: Declaration; members?: SymbolTable; exports?: SymbolTable; - valueDeclaration?: Declaration; } interface SymbolTable { [index: string]: Symbol; @@ -1358,7 +1357,6 @@ declare module ts { function getTypeParameterOwner(d: Declaration): Declaration; } declare module ts { - var throwOnJSDocErrors: boolean; function getNodeConstructor(kind: SyntaxKind): new () => Node; function createNode(kind: SyntaxKind): Node; function forEachChild(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T; @@ -1913,6 +1911,7 @@ declare module ts { static typeParameterName: string; static typeAliasName: string; static parameterName: string; + static docCommentTagName: string; } const enum ClassificationType { comment = 1, @@ -1932,6 +1931,7 @@ declare module ts { typeParameterName = 15, typeAliasName = 16, parameterName = 17, + docCommentTagName = 18, } interface DisplayPartsSymbolWriter extends SymbolWriter { displayParts(): SymbolDisplayPart[]; diff --git a/bin/typescriptServices.js b/bin/typescriptServices.js index 1b5c7949463..2b3f25998a5 100644 --- a/bin/typescriptServices.js +++ b/bin/typescriptServices.js @@ -429,6 +429,7 @@ var ts; })(ts.SymbolAccessibility || (ts.SymbolAccessibility = {})); var SymbolAccessibility = ts.SymbolAccessibility; (function (SymbolFlags) { + SymbolFlags[SymbolFlags["None"] = 0] = "None"; SymbolFlags[SymbolFlags["FunctionScopedVariable"] = 1] = "FunctionScopedVariable"; SymbolFlags[SymbolFlags["BlockScopedVariable"] = 2] = "BlockScopedVariable"; SymbolFlags[SymbolFlags["Property"] = 4] = "Property"; @@ -491,10 +492,8 @@ var ts; SymbolFlags[SymbolFlags["AliasExcludes"] = 8388608] = "AliasExcludes"; SymbolFlags[SymbolFlags["ModuleMember"] = 8914931] = "ModuleMember"; SymbolFlags[SymbolFlags["ExportHasLocal"] = 944] = "ExportHasLocal"; - SymbolFlags[SymbolFlags["HasLocals"] = 255504] = "HasLocals"; SymbolFlags[SymbolFlags["HasExports"] = 1952] = "HasExports"; SymbolFlags[SymbolFlags["HasMembers"] = 6240] = "HasMembers"; - SymbolFlags[SymbolFlags["IsContainer"] = 262128] = "IsContainer"; SymbolFlags[SymbolFlags["PropertyOrAccessor"] = 98308] = "PropertyOrAccessor"; SymbolFlags[SymbolFlags["Export"] = 7340032] = "Export"; })(ts.SymbolFlags || (ts.SymbolFlags = {})); @@ -3688,6 +3687,27 @@ var ts; } } ts.getModuleInstanceState = getModuleInstanceState; + var ContainerFlags; + (function (ContainerFlags) { + // The current node is not a container, and no container manipulation should happen before + // recursing into it. + ContainerFlags[ContainerFlags["None"] = 0] = "None"; + // The current node is a container. It should be set as the current container (and block- + // container) before recursing into it. The current node does not have locals. Examples: + // + // Classes, ObjectLiterals, TypeLiterals, Interfaces... + ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer"; + // The current node is a block-scoped-container. It should be set as the current block- + // container before recursing into it. Examples: + // + // Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements... + ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer"; + ContainerFlags[ContainerFlags["HasLocals"] = 4] = "HasLocals"; + // If the current node is a container that also container that also contains locals. Examples: + // + // Functions, Methods, Modules, Source-files. + ContainerFlags[ContainerFlags["IsContainerWithLocals"] = 5] = "IsContainerWithLocals"; + })(ContainerFlags || (ContainerFlags = {})); function bindSourceFile(file) { var start = new Date().getTime(); bindSourceFileWorker(file); @@ -3702,34 +3722,30 @@ var ts; var symbolCount = 0; var Symbol = ts.objectAllocator.getSymbolConstructor(); if (!file.locals) { - file.locals = {}; - container = file; - setBlockScopeContainer(file, false); bind(file); file.symbolCount = symbolCount; } + return; function createSymbol(flags, name) { symbolCount++; return new Symbol(flags, name); } - function setBlockScopeContainer(node, cleanLocals) { - blockScopeContainer = node; - if (cleanLocals) { - blockScopeContainer.locals = undefined; - } - } - function addDeclarationToSymbol(symbol, node, symbolKind) { - symbol.flags |= symbolKind; - if (!symbol.declarations) - symbol.declarations = []; - symbol.declarations.push(node); - if (symbolKind & 1952 /* HasExports */ && !symbol.exports) - symbol.exports = {}; - if (symbolKind & 6240 /* HasMembers */ && !symbol.members) - symbol.members = {}; + function addDeclarationToSymbol(symbol, node, symbolFlags) { + symbol.flags |= symbolFlags; node.symbol = symbol; - if (symbolKind & 107455 /* Value */ && !symbol.valueDeclaration) + if (!symbol.declarations) { + symbol.declarations = []; + } + symbol.declarations.push(node); + if (symbolFlags & 1952 /* HasExports */ && !symbol.exports) { + symbol.exports = {}; + } + if (symbolFlags & 6240 /* HasMembers */ && !symbol.members) { + symbol.members = {}; + } + if (symbolFlags & 107455 /* Value */ && !symbol.valueDeclaration) { symbol.valueDeclaration = node; + } } // Should not be called on a declaration with a computed property name, // unless it is a well known Symbol. @@ -3746,12 +3762,12 @@ var ts; return node.name.text; } switch (node.kind) { - case 144 /* ConstructorType */: case 136 /* Constructor */: return "__constructor"; case 143 /* FunctionType */: case 139 /* CallSignature */: return "__call"; + case 144 /* ConstructorType */: case 140 /* ConstructSignature */: return "__new"; case 141 /* IndexSignature */: @@ -3768,13 +3784,33 @@ var ts; function getDisplayName(node) { return node.name ? ts.declarationNameToString(node.name) : getDeclarationName(node); } - function declareSymbol(symbols, parent, node, includes, excludes) { + function declareSymbol(symbolTable, parent, node, includes, excludes) { ts.Debug.assert(!ts.hasDynamicName(node)); // The exported symbol for an export default function/class node is always named "default" var name = node.flags & 256 /* Default */ && parent ? "default" : getDeclarationName(node); var symbol; if (name !== undefined) { - symbol = ts.hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(0, name)); + // Check and see if the symbol table already has a symbol with this name. If not, + // create a new symbol with this name and add it to the table. Note that we don't + // give the new symbol any flags *yet*. This ensures that it will not conflict + // witht he 'excludes' flags we pass in. + // + // If we do get an existing symbol, see if it conflicts with the new symbol we're + // creating. For example, a 'var' symbol and a 'class' symbol will conflict within + // the same symbol table. If we have a conflict, report the issue on each + // declaration we have for this symbol, and then create a new symbol for this + // declaration. + // + // If we created a new symbol, either because we didn't have a symbol with this name + // in the symbol table, or we conflicted with an existing symbol, then just add this + // node as the sole declaration of the new symbol. + // + // Otherwise, we'll be merging into a compatible existing symbol (for example when + // you have multiple 'vars' with the same name in the same container). In this case + // just add this node into the declarations list of the symbol. + symbol = ts.hasProperty(symbolTable, name) + ? symbolTable[name] + : (symbolTable[name] = createSymbol(0 /* None */, name)); if (symbol.flags & excludes) { if (node.name) { node.name.parent = node; @@ -3788,39 +3824,24 @@ var ts; file.bindDiagnostics.push(ts.createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration))); }); file.bindDiagnostics.push(ts.createDiagnosticForNode(node.name || node, message, getDisplayName(node))); - symbol = createSymbol(0, name); + symbol = createSymbol(0 /* None */, name); } } else { - symbol = createSymbol(0, "__missing"); + symbol = createSymbol(0 /* None */, "__missing"); } addDeclarationToSymbol(symbol, node, includes); symbol.parent = parent; - if ((node.kind === 202 /* ClassDeclaration */ || node.kind === 175 /* ClassExpression */) && symbol.exports) { - // TypeScript 1.0 spec (April 2014): 8.4 - // Every class automatically contains a static property member named 'prototype', - // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter. - // It is an error to explicitly declare a static property member with the name 'prototype'. - var prototypeSymbol = createSymbol(4 /* Property */ | 134217728 /* Prototype */, "prototype"); - if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) { - if (node.name) { - node.name.parent = node; - } - file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); - } - symbol.exports[prototypeSymbol.name] = prototypeSymbol; - prototypeSymbol.parent = symbol; - } return symbol; } - function declareModuleMember(node, symbolKind, symbolExcludes) { + function declareModuleMember(node, symbolFlags, symbolExcludes) { var hasExportModifier = ts.getCombinedNodeFlags(node) & 1 /* Export */; - if (symbolKind & 8388608 /* Alias */) { + if (symbolFlags & 8388608 /* Alias */) { if (node.kind === 218 /* ExportSpecifier */ || (node.kind === 209 /* ImportEqualsDeclaration */ && hasExportModifier)) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); } else { - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } else { @@ -3836,62 +3857,150 @@ var ts; // but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way // when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope. if (hasExportModifier || container.flags & 65536 /* ExportContext */) { - var exportKind = (symbolKind & 107455 /* Value */ ? 1048576 /* ExportValue */ : 0) | - (symbolKind & 793056 /* Type */ ? 2097152 /* ExportType */ : 0) | - (symbolKind & 1536 /* Namespace */ ? 4194304 /* ExportNamespace */ : 0); + var exportKind = (symbolFlags & 107455 /* Value */ ? 1048576 /* ExportValue */ : 0) | + (symbolFlags & 793056 /* Type */ ? 2097152 /* ExportType */ : 0) | + (symbolFlags & 1536 /* Namespace */ ? 4194304 /* ExportNamespace */ : 0); var local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes); - local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); + local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); node.localSymbol = local; + return local; } else { - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } } } - // All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function - // in the type checker to validate that the local name used for a container is unique. - function bindChildren(node, symbolKind, isBlockScopeContainer) { - if (symbolKind & 255504 /* HasLocals */) { - node.locals = {}; - } + // All container nodes are kept on a linked list in declaration order. This list is used by + // the getLocalNameOfContainer function in the type checker to validate that the local name + // used for a container is unique. + function bindChildren(node) { + // Before we recurse into a node's chilren, we first save the existing parent, container + // and block-container. Then after we pop out of processing the children, we restore + // these saved values. var saveParent = parent; var saveContainer = container; var savedBlockScopeContainer = blockScopeContainer; + // This node will now be set as the parent of all of its children as we recurse into them. parent = node; - if (symbolKind & 262128 /* IsContainer */) { - container = node; + // Depending on what kind of node this is, we may have to adjust the current container + // and block-container. If the current node is a container, then it is automatically + // considered the current block-container as well. Also, for containers that we know + // may contain locals, we proactively initialize the .locals field. We do this because + // it's highly likely that the .locals will be needed to place some child in (for example, + // a parameter, or variable declaration). + // + // However, we do not proactively create the .locals for block-containers because it's + // totally normal and common for block-containers to never actually have a block-scoped + // variable in them. We don't want to end up allocating an object for every 'block' we + // run into when most of them won't be necessary. + // + // Finally, if this is a block-container, then we clear out any existing .locals object + // it may contain within it. This happens in incremental scenarios. Because we can be + // reusing a node from a previous compilation, that node may have had 'locals' created + // for it. We must clear this so we don't accidently move any stale data forward from + // a previous compilation. + var containerFlags = getContainerFlags(node); + if (containerFlags & 1 /* IsContainer */) { + container = blockScopeContainer = node; + if (containerFlags & 4 /* HasLocals */) { + container.locals = {}; + } addToContainerChain(container); } - if (isBlockScopeContainer) { - // in incremental scenarios we might reuse nodes that already have locals being allocated - // during the bind step these locals should be dropped to prevent using stale data. - // locals should always be dropped unless they were previously initialized by the binder - // these cases are: - // - node has locals (symbolKind & HasLocals) !== 0 - // - node is a source file - setBlockScopeContainer(node, (symbolKind & 255504 /* HasLocals */) === 0 && node.kind !== 228 /* SourceFile */); + else if (containerFlags & 2 /* IsBlockScopedContainer */) { + blockScopeContainer = node; + blockScopeContainer.locals = undefined; } ts.forEachChild(node, bind); container = saveContainer; parent = saveParent; blockScopeContainer = savedBlockScopeContainer; } - function addToContainerChain(node) { - if (lastContainer) { - lastContainer.nextContainer = node; - } - lastContainer = node; - } - function bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer) { - switch (container.kind) { + function getContainerFlags(node) { + switch (node.kind) { + case 175 /* ClassExpression */: + case 202 /* ClassDeclaration */: + case 203 /* InterfaceDeclaration */: + case 205 /* EnumDeclaration */: + case 146 /* TypeLiteral */: + case 155 /* ObjectLiteralExpression */: + return 1 /* IsContainer */; + case 139 /* CallSignature */: + case 140 /* ConstructSignature */: + case 141 /* IndexSignature */: + case 135 /* MethodDeclaration */: + case 134 /* MethodSignature */: + case 201 /* FunctionDeclaration */: + case 136 /* Constructor */: + case 137 /* GetAccessor */: + case 138 /* SetAccessor */: + case 143 /* FunctionType */: + case 144 /* ConstructorType */: + case 163 /* FunctionExpression */: + case 164 /* ArrowFunction */: case 206 /* ModuleDeclaration */: - declareModuleMember(node, symbolKind, symbolExcludes); - break; case 228 /* SourceFile */: - if (ts.isExternalModule(container)) { - declareModuleMember(node, symbolKind, symbolExcludes); - break; - } + return 5 /* IsContainerWithLocals */; + case 224 /* CatchClause */: + case 187 /* ForStatement */: + case 188 /* ForInStatement */: + case 189 /* ForOfStatement */: + case 208 /* CaseBlock */: + return 2 /* IsBlockScopedContainer */; + case 180 /* Block */: + // do not treat blocks directly inside a function as a block-scoped-container. + // Locals that reside in this block should go to the function locals. Othewise 'x' + // would not appear to be a redeclaration of a block scoped local in the following + // example: + // + // function foo() { + // var x; + // let x; + // } + // + // If we placed 'var x' into the function locals and 'let x' into the locals of + // the block, then there would be no collision. + // + // By not creating a new block-scoped-container here, we ensure that both 'var x' + // and 'let x' go into the Function-container's locals, and we do get a collision + // conflict. + return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */; + } + return 0 /* None */; + } + function addToContainerChain(next) { + if (lastContainer) { + lastContainer.nextContainer = next; + } + lastContainer = next; + } + function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) { + // Just call this directly so that the return type of this function stays "void". + declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes); + } + function declareSymbolAndAddToSymbolTableWorker(node, symbolFlags, symbolExcludes) { + switch (container.kind) { + // Modules, source files, and classes need specialized handling for how their + // members are declared (for example, a member of a class will go into a specific + // symbol table depending on if it is static or not). As such, we defer to + // specialized handlers to take care of declaring these child members. + case 206 /* ModuleDeclaration */: + return declareModuleMember(node, symbolFlags, symbolExcludes); + case 228 /* SourceFile */: + return declareSourceFileMember(node, symbolFlags, symbolExcludes); + case 175 /* ClassExpression */: + case 202 /* ClassDeclaration */: + return declareClassMember(node, symbolFlags, symbolExcludes); + case 205 /* EnumDeclaration */: + return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); + case 146 /* TypeLiteral */: + case 155 /* ObjectLiteralExpression */: + case 203 /* InterfaceDeclaration */: + // Interface/Object-types always have their children added to the 'members' of + // their container. They are only accessible through an instance of their + // container, and are never in scope otherwise (even inside the body of the + // object / type / interface declaring them). + return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); case 143 /* FunctionType */: case 144 /* ConstructorType */: case 139 /* CallSignature */: @@ -3905,29 +4014,30 @@ var ts; case 201 /* FunctionDeclaration */: case 163 /* FunctionExpression */: case 164 /* ArrowFunction */: - declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes); - break; - case 175 /* ClassExpression */: - case 202 /* ClassDeclaration */: - if (node.flags & 128 /* Static */) { - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); - break; - } - case 146 /* TypeLiteral */: - case 155 /* ObjectLiteralExpression */: - case 203 /* InterfaceDeclaration */: - declareSymbol(container.symbol.members, container.symbol, node, symbolKind, symbolExcludes); - break; - case 205 /* EnumDeclaration */: - declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); - break; + // All the children of these container types are never visible through another + // symbol (i.e. through another symbol's 'exports' or 'members'). Instead, + // they're only accessed 'lexically' (i.e. from code that exists underneath + // their container in the tree. To accomplish this, we simply add their declared + // symbol to the 'locals' of the container. These symbols can then be found as + // the type checker walks up the containers, checking them for matching names. + return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolKind, isBlockScopeContainer); + } + function declareClassMember(node, symbolFlags, symbolExcludes) { + return node.flags & 128 /* Static */ + ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes) + : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); + } + function declareSourceFileMember(node, symbolFlags, symbolExcludes) { + return ts.isExternalModule(file) + ? declareModuleMember(node, symbolFlags, symbolExcludes) + : declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes); } function isAmbientContext(node) { while (node) { - if (node.flags & 2 /* Ambient */) + if (node.flags & 2 /* Ambient */) { return true; + } node = node.parent; } return false; @@ -3957,15 +4067,15 @@ var ts; function bindModuleDeclaration(node) { setExportContextFlag(node); if (node.name.kind === 8 /* StringLiteral */) { - bindDeclaration(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */, true); + declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */); } else { var state = getModuleInstanceState(node); if (state === 0 /* NonInstantiated */) { - bindDeclaration(node, 1024 /* NamespaceModule */, 0 /* NamespaceModuleExcludes */, true); + declareSymbolAndAddToSymbolTable(node, 1024 /* NamespaceModule */, 0 /* NamespaceModuleExcludes */); } else { - bindDeclaration(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */, true); + declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */); var currentModuleIsConstEnumOnly = state === 2 /* ConstEnumOnly */; if (node.symbol.constEnumOnlyModule === undefined) { // non-merged case - use the current state @@ -3987,28 +4097,23 @@ var ts; // from an actual type literal symbol you would have gotten had you used the long form. var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node)); addDeclarationToSymbol(symbol, node, 131072 /* Signature */); - bindChildren(node, 131072 /* Signature */, false); var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */); - typeLiteralSymbol.members = {}; - typeLiteralSymbol.members[node.kind === 143 /* FunctionType */ ? "__call" : "__new"] = symbol; + typeLiteralSymbol.members = (_a = {}, _a[symbol.name] = symbol, _a); + var _a; } - function bindAnonymousDeclaration(node, symbolKind, name, isBlockScopeContainer) { - var symbol = createSymbol(symbolKind, name); - addDeclarationToSymbol(symbol, node, symbolKind); - bindChildren(node, symbolKind, isBlockScopeContainer); + function bindAnonymousDeclaration(node, symbolFlags, name) { + var symbol = createSymbol(symbolFlags, name); + addDeclarationToSymbol(symbol, node, symbolFlags); } - function bindCatchVariableDeclaration(node) { - bindChildren(node, 0, true); - } - function bindBlockScopedDeclaration(node, symbolKind, symbolExcludes) { + function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) { switch (blockScopeContainer.kind) { case 206 /* ModuleDeclaration */: - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; case 228 /* SourceFile */: if (ts.isExternalModule(container)) { - declareModuleMember(node, symbolKind, symbolExcludes); + declareModuleMember(node, symbolFlags, symbolExcludes); break; } // fall through. @@ -4017,9 +4122,8 @@ var ts; blockScopeContainer.locals = {}; addToContainerChain(blockScopeContainer); } - declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, symbolExcludes); + declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes); } - bindChildren(node, symbolKind, false); } function bindBlockScopedVariableDeclaration(node) { bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */); @@ -4029,182 +4133,182 @@ var ts; } function bind(node) { node.parent = parent; + // First we bind declaration nodes to a symbol if possible. We'll both create a symbol + // and then potentially add the symbol to an appropriate symbol table. Possible + // destination symbol tables are: + // + // 1) The 'exports' table of the current container's symbol. + // 2) The 'members' table of the current container's symbol. + // 3) The 'locals' table of the current container. + // + // However, not all symbols will end up in any of these tables. 'Anonymous' symbols + // (like TypeLiterals for example) will not be put in any table. + bindWorker(node); + // Then we recurse into the children of the node to bind them as well. For certain + // symbols we do specialized work when we recurse. For example, we'll keep track of + // the current 'container' node when it changes. This helps us know which symbol table + // a local should go into for example. + bindChildren(node); + } + function bindWorker(node) { switch (node.kind) { case 129 /* TypeParameter */: - bindDeclaration(node, 262144 /* TypeParameter */, 530912 /* TypeParameterExcludes */, false); - break; + return declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 530912 /* TypeParameterExcludes */); case 130 /* Parameter */: - bindParameter(node); - break; + return bindParameter(node); case 199 /* VariableDeclaration */: case 153 /* BindingElement */: - if (ts.isBindingPattern(node.name)) { - bindChildren(node, 0, false); - } - else if (ts.isBlockOrCatchScoped(node)) { - bindBlockScopedVariableDeclaration(node); - } - else if (ts.isParameterDeclaration(node)) { - // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration - // because its parent chain has already been set up, since parents are set before descending into children. - // - // If node is a binding element in parameter declaration, we need to use ParameterExcludes. - // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration - // For example: - // function foo([a,a]) {} // Duplicate Identifier error - // function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter - // // which correctly set excluded symbols - bindDeclaration(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */, false); - } - else { - bindDeclaration(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */, false); - } - break; + return bindVariableDeclarationOrBindingElement(node); case 133 /* PropertyDeclaration */: case 132 /* PropertySignature */: - bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0), 107455 /* PropertyExcludes */, false); - break; + return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), 107455 /* PropertyExcludes */); case 225 /* PropertyAssignment */: case 226 /* ShorthandPropertyAssignment */: - bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 107455 /* PropertyExcludes */, false); - break; + return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 107455 /* PropertyExcludes */); case 227 /* EnumMember */: - bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */, false); - break; + return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */); case 139 /* CallSignature */: case 140 /* ConstructSignature */: case 141 /* IndexSignature */: - bindDeclaration(node, 131072 /* Signature */, 0, false); - break; + return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */); case 135 /* MethodDeclaration */: case 134 /* MethodSignature */: // If this is an ObjectLiteralExpression method, then it sits in the same space // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes // so that it will conflict with any other object literal members with the same // name. - bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0), ts.isObjectLiteralMethod(node) ? 107455 /* PropertyExcludes */ : 99263 /* MethodExcludes */, true); - break; + return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 536870912 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 107455 /* PropertyExcludes */ : 99263 /* MethodExcludes */); case 201 /* FunctionDeclaration */: - bindDeclaration(node, 16 /* Function */, 106927 /* FunctionExcludes */, true); - break; + return declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 106927 /* FunctionExcludes */); case 136 /* Constructor */: - bindDeclaration(node, 16384 /* Constructor */, 0, true); - break; + return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, 0 /* None */); case 137 /* GetAccessor */: - bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */, true); - break; + return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */); case 138 /* SetAccessor */: - bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */, true); - break; + return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */); case 143 /* FunctionType */: case 144 /* ConstructorType */: - bindFunctionOrConstructorType(node); - break; + return bindFunctionOrConstructorType(node); case 146 /* TypeLiteral */: - bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type", false); - break; + return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type"); case 155 /* ObjectLiteralExpression */: - bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object", false); - break; + return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object"); case 163 /* FunctionExpression */: case 164 /* ArrowFunction */: - bindAnonymousDeclaration(node, 16 /* Function */, "__function", true); - break; + return bindAnonymousDeclaration(node, 16 /* Function */, "__function"); case 175 /* ClassExpression */: - bindAnonymousDeclaration(node, 32 /* Class */, "__class", false); - break; - case 224 /* CatchClause */: - bindCatchVariableDeclaration(node); - break; case 202 /* ClassDeclaration */: - bindBlockScopedDeclaration(node, 32 /* Class */, 899583 /* ClassExcludes */); - break; + return bindClassLikeDeclaration(node); case 203 /* InterfaceDeclaration */: - bindBlockScopedDeclaration(node, 64 /* Interface */, 792992 /* InterfaceExcludes */); - break; + return bindBlockScopedDeclaration(node, 64 /* Interface */, 792992 /* InterfaceExcludes */); case 204 /* TypeAliasDeclaration */: - bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */); - break; + return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793056 /* TypeAliasExcludes */); case 205 /* EnumDeclaration */: - if (ts.isConst(node)) { - bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */); - } - else { - bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */); - } - break; + return bindEnumDeclaration(node); case 206 /* ModuleDeclaration */: - bindModuleDeclaration(node); - break; + return bindModuleDeclaration(node); case 209 /* ImportEqualsDeclaration */: case 212 /* NamespaceImport */: case 214 /* ImportSpecifier */: case 218 /* ExportSpecifier */: - bindDeclaration(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */, false); - break; + return declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */); case 211 /* ImportClause */: - if (node.name) { - bindDeclaration(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */, false); - } - else { - bindChildren(node, 0, false); - } - break; + return bindImportClause(node); case 216 /* ExportDeclaration */: - if (!node.exportClause) { - // All export * declarations are collected in an __export symbol - declareSymbol(container.symbol.exports, container.symbol, node, 1073741824 /* ExportStar */, 0); - } - bindChildren(node, 0, false); - break; + return bindExportDeclaration(node); case 215 /* ExportAssignment */: - if (node.expression.kind === 65 /* Identifier */) { - // An export default clause with an identifier exports all meanings of that identifier - declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); - } - else { - // An export default clause with an expression exports a value - declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); - } - bindChildren(node, 0, false); - break; + return bindExportAssignment(node); case 228 /* SourceFile */: - setExportContextFlag(node); - if (ts.isExternalModule(node)) { - bindAnonymousDeclaration(node, 512 /* ValueModule */, '"' + ts.removeFileExtension(node.fileName) + '"', true); - break; - } - case 180 /* Block */: - // do not treat function block a block-scope container - // all block-scope locals that reside in this block should go to the function locals. - // Otherwise this won't be considered as redeclaration of a block scoped local: - // function foo() { - // let x; - // let x; - // } - // 'let x' will be placed into the function locals and 'let x' - into the locals of the block - bindChildren(node, 0, !ts.isFunctionLike(node.parent)); - break; - case 224 /* CatchClause */: - case 187 /* ForStatement */: - case 188 /* ForInStatement */: - case 189 /* ForOfStatement */: - case 208 /* CaseBlock */: - bindChildren(node, 0, true); - break; - default: - var saveParent = parent; - parent = node; - ts.forEachChild(node, bind); - parent = saveParent; + return bindSourceFileIfExternalModule(); + } + } + function bindSourceFileIfExternalModule() { + setExportContextFlag(file); + if (ts.isExternalModule(file)) { + bindAnonymousDeclaration(file, 512 /* ValueModule */, '"' + ts.removeFileExtension(file.fileName) + '"'); + } + } + function bindExportAssignment(node) { + if (node.expression.kind === 65 /* Identifier */) { + // An export default clause with an identifier exports all meanings of that identifier + declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* Alias */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); + } + else { + // An export default clause with an expression exports a value + declareSymbol(container.symbol.exports, container.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */ | 8388608 /* AliasExcludes */); + } + } + function bindExportDeclaration(node) { + if (!node.exportClause) { + // All export * declarations are collected in an __export symbol + declareSymbol(container.symbol.exports, container.symbol, node, 1073741824 /* ExportStar */, 0 /* None */); + } + } + function bindImportClause(node) { + if (node.name) { + declareSymbolAndAddToSymbolTable(node, 8388608 /* Alias */, 8388608 /* AliasExcludes */); + } + } + function bindClassLikeDeclaration(node) { + if (node.kind === 202 /* ClassDeclaration */) { + bindBlockScopedDeclaration(node, 32 /* Class */, 899583 /* ClassExcludes */); + } + else { + bindAnonymousDeclaration(node, 32 /* Class */, "__class"); + } + var symbol = node.symbol; + // TypeScript 1.0 spec (April 2014): 8.4 + // Every class automatically contains a static property member named 'prototype', the + // type of which is an instantiation of the class type with type Any supplied as a type + // argument for each type parameter. It is an error to explicitly declare a static + // property member with the name 'prototype'. + // + // Note: we check for this here because this class may be merging into a module. The + // module might have an exported variable called 'prototype'. We can't allow that as + // that would clash with the built-in 'prototype' for the class. + var prototypeSymbol = createSymbol(4 /* Property */ | 134217728 /* Prototype */, "prototype"); + if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) { + if (node.name) { + node.name.parent = node; + } + file.bindDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name)); + } + symbol.exports[prototypeSymbol.name] = prototypeSymbol; + prototypeSymbol.parent = symbol; + } + function bindEnumDeclaration(node) { + return ts.isConst(node) + ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */) + : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */); + } + function bindVariableDeclarationOrBindingElement(node) { + if (!ts.isBindingPattern(node.name)) { + if (ts.isBlockOrCatchScoped(node)) { + bindBlockScopedVariableDeclaration(node); + } + else if (ts.isParameterDeclaration(node)) { + // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration + // because its parent chain has already been set up, since parents are set before descending into children. + // + // If node is a binding element in parameter declaration, we need to use ParameterExcludes. + // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration + // For example: + // function foo([a,a]) {} // Duplicate Identifier error + // function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter + // // which correctly set excluded symbols + declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */); + } + else { + declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */); + } } } function bindParameter(node) { if (ts.isBindingPattern(node.name)) { - bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, getDestructuringParameterName(node), false); + bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, getDestructuringParameterName(node)); } else { - bindDeclaration(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */, false); + declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */); } // If this is a property-parameter, then also declare the property symbol into the // containing class. @@ -4215,13 +4319,10 @@ var ts; declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */, 107455 /* PropertyExcludes */); } } - function bindPropertyOrMethodOrAccessor(node, symbolKind, symbolExcludes, isBlockScopeContainer) { - if (ts.hasDynamicName(node)) { - bindAnonymousDeclaration(node, symbolKind, "__computed", isBlockScopeContainer); - } - else { - bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer); - } + function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) { + return ts.hasDynamicName(node) + ? bindAnonymousDeclaration(node, symbolFlags, "__computed") + : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } } })(ts || (ts = {})); @@ -5111,10 +5212,6 @@ var ts; } } ts.getExternalModuleName = getExternalModuleName; - function hasDotDotDotToken(node) { - return node && node.kind === 130 /* Parameter */ && node.dotDotDotToken !== undefined; - } - ts.hasDotDotDotToken = hasDotDotDotToken; function hasQuestionToken(node) { if (node) { switch (node.kind) { @@ -5133,10 +5230,6 @@ var ts; return false; } ts.hasQuestionToken = hasQuestionToken; - function hasRestParameters(s) { - return s.parameters.length > 0 && ts.lastOrUndefined(s.parameters).dotDotDotToken !== undefined; - } - ts.hasRestParameters = hasRestParameters; function isJSDocConstructSignature(node) { return node.kind === 241 /* JSDocFunctionType */ && node.parameters.length > 0 && @@ -6287,7 +6380,6 @@ var ts; /// var ts; (function (ts) { - ts.throwOnJSDocErrors = false; var nodeConstructors = new Array(252 /* Count */); /* @internal */ ts.parseTime = 0; function getNodeConstructor(kind) { @@ -10679,12 +10771,6 @@ var ts; return finishNode(result); } JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression; - function setError(message) { - parseErrorAtCurrentToken(message); - if (ts.throwOnJSDocErrors) { - throw new Error(message.key); - } - } function parseJSDocTopLevelType() { var type = parseJSDocType(); if (token === 44 /* BarToken */) { @@ -12076,27 +12162,31 @@ var ts; case 138 /* SetAccessor */: case 201 /* FunctionDeclaration */: case 164 /* ArrowFunction */: - if (name === "arguments") { + if (meaning & 3 /* Variable */ && name === "arguments") { result = argumentsSymbol; break loop; } break; case 163 /* FunctionExpression */: - if (name === "arguments") { + if (meaning & 3 /* Variable */ && name === "arguments") { result = argumentsSymbol; break loop; } - var functionName = location.name; - if (functionName && name === functionName.text) { - result = location.symbol; - break loop; + if (meaning & 16 /* Function */) { + var functionName = location.name; + if (functionName && name === functionName.text) { + result = location.symbol; + break loop; + } } break; case 175 /* ClassExpression */: - var className = location.name; - if (className && name === className.text) { - result = location.symbol; - break loop; + if (meaning & 32 /* Class */) { + var className = location.name; + if (className && name === className.text) { + result = location.symbol; + break loop; + } } break; case 131 /* Decorator */: @@ -13307,11 +13397,12 @@ var ts; } } function buildParameterDisplay(p, writer, enclosingDeclaration, flags, typeStack) { - if (ts.hasDotDotDotToken(p.valueDeclaration)) { + var parameterNode = p.valueDeclaration; + if (ts.isRestParameter(parameterNode)) { writePunctuation(writer, 21 /* DotDotDotToken */); } appendSymbolNameOnly(p, writer); - if (ts.hasQuestionToken(p.valueDeclaration) || p.valueDeclaration.initializer) { + if (isOptionalParameter(parameterNode)) { writePunctuation(writer, 50 /* QuestionToken */); } writePunctuation(writer, 51 /* ColonToken */); @@ -14607,6 +14698,9 @@ var ts; } return result; } + function isOptionalParameter(node) { + return ts.hasQuestionToken(node) || !!node.initializer; + } function getSignatureFromDeclaration(declaration) { var links = getNodeLinks(declaration); if (!links.resolvedSignature) { @@ -14649,7 +14743,7 @@ var ts; returnType = anyType; } } - links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, ts.hasRestParameters(declaration), hasStringLiterals); + links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, ts.hasRestParameter(declaration), hasStringLiterals); } return links.resolvedSignature; } @@ -14904,32 +14998,7 @@ var ts; type = unknownType; } else { - type = getDeclaredTypeOfSymbol(symbol); - if (type.flags & (1024 /* Class */ | 2048 /* Interface */) && type.flags & 4096 /* Reference */) { - // In a type reference, the outer type parameters of the referenced class or interface are automatically - // supplied as type arguments and the type reference only specifies arguments for the local type parameters - // of the class or interface. - var localTypeParameters = type.localTypeParameters; - var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; - var typeArgCount = node.typeArguments ? node.typeArguments.length : 0; - if (typeArgCount === expectedTypeArgCount) { - // When no type arguments are expected we already have the right type because all outer type parameters - // have themselves as default type arguments. - if (typeArgCount) { - type = createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(node.typeArguments, getTypeFromTypeNode))); - } - } - else { - error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1 /* WriteArrayAsGenericType */), expectedTypeArgCount); - type = undefined; - } - } - else { - if (node.typeArguments) { - error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); - type = undefined; - } - } + type = createTypeReferenceIfGeneric(getDeclaredTypeOfSymbol(symbol), node, node.typeArguments); } } } @@ -14937,6 +15006,34 @@ var ts; } return links.resolvedType; } + function createTypeReferenceIfGeneric(type, node, typeArguments) { + if (type.flags & (1024 /* Class */ | 2048 /* Interface */) && type.flags & 4096 /* Reference */) { + // In a type reference, the outer type parameters of the referenced class or interface are automatically + // supplied as type arguments and the type reference only specifies arguments for the local type parameters + // of the class or interface. + var localTypeParameters = type.localTypeParameters; + var expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; + var typeArgCount = typeArguments ? typeArguments.length : 0; + if (typeArgCount === expectedTypeArgCount) { + // When no type arguments are expected we already have the right type because all outer type parameters + // have themselves as default type arguments. + if (typeArgCount) { + return createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(typeArguments, getTypeFromTypeNode))); + } + } + else { + error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1 /* WriteArrayAsGenericType */), expectedTypeArgCount); + return undefined; + } + } + else { + if (typeArguments) { + error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); + return undefined; + } + } + return type; + } function getTypeFromTypeQueryNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { @@ -17078,7 +17175,7 @@ var ts; if (isContextSensitive(func)) { var contextualSignature = getContextualSignature(func); if (contextualSignature) { - var funcHasRestParameters = ts.hasRestParameters(func); + var funcHasRestParameters = ts.hasRestParameter(func); var len = func.parameters.length - (funcHasRestParameters ? 1 : 0); var indexOfParameter = ts.indexOf(func.parameters, parameter); if (indexOfParameter < len) { @@ -20190,7 +20287,7 @@ var ts; } function checkCollisionWithArgumentsInGeneratedCode(node) { // no rest parameters \ declaration context \ overload - no codegen impact - if (!ts.hasRestParameters(node) || ts.isInAmbientContext(node) || ts.nodeIsMissing(node.body)) { + if (!ts.hasRestParameter(node) || ts.isInAmbientContext(node) || ts.nodeIsMissing(node.body)) { return; } ts.forEach(node.parameters, function (p) { @@ -28138,7 +28235,7 @@ var ts; } } function emitRestParameter(node) { - if (languageVersion < 2 /* ES6 */ && ts.hasRestParameters(node)) { + if (languageVersion < 2 /* ES6 */ && ts.hasRestParameter(node)) { var restIndex = node.parameters.length - 1; var restParam = node.parameters[restIndex]; // A rest parameter cannot have a binding pattern, so let's just ignore it if it does. @@ -28252,7 +28349,7 @@ var ts; write("("); if (node) { var parameters = node.parameters; - var omitCount = languageVersion < 2 /* ES6 */ && ts.hasRestParameters(node) ? 1 : 0; + var omitCount = languageVersion < 2 /* ES6 */ && ts.hasRestParameter(node) ? 1 : 0; emitList(parameters, 0, parameters.length - omitCount, false, false); } write(")"); @@ -37707,6 +37804,7 @@ var ts; ClassificationTypeNames.typeParameterName = "type parameter name"; ClassificationTypeNames.typeAliasName = "type alias name"; ClassificationTypeNames.parameterName = "parameter name"; + ClassificationTypeNames.docCommentTagName = "doc comment tag name"; return ClassificationTypeNames; })(); ts.ClassificationTypeNames = ClassificationTypeNames; @@ -37728,6 +37826,7 @@ var ts; ClassificationType[ClassificationType["typeParameterName"] = 15] = "typeParameterName"; ClassificationType[ClassificationType["typeAliasName"] = 16] = "typeAliasName"; ClassificationType[ClassificationType["parameterName"] = 17] = "parameterName"; + ClassificationType[ClassificationType["docCommentTagName"] = 18] = "docCommentTagName"; })(ts.ClassificationType || (ts.ClassificationType = {})); var ClassificationType = ts.ClassificationType; function displayPartsToString(displayParts) { @@ -37940,7 +38039,8 @@ var ts; } ts.transpile = transpile; function createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, setNodeParents) { - var sourceFile = ts.createSourceFile(fileName, scriptSnapshot.getText(0, scriptSnapshot.getLength()), scriptTarget, setNodeParents); + var text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); + var sourceFile = ts.createSourceFile(fileName, text, scriptTarget, setNodeParents); setSourceFileFields(sourceFile, scriptSnapshot, version); // after full parsing we can use table with interned strings as name table sourceFile.nameTable = sourceFile.identifiers; @@ -38534,12 +38634,16 @@ var ts; } } } + // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point. + // It needs to be cleared to allow all collected snapshots to be released + hostCache = undefined; program = newProgram; // Make sure all the nodes in the program are both bound, and have their parent // pointers set property. program.getTypeChecker(); return; function getOrCreateSourceFile(fileName) { + ts.Debug.assert(hostCache !== undefined); // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. @@ -38847,6 +38951,7 @@ var ts; var typeChecker = program.getTypeChecker(); var syntacticStart = new Date().getTime(); var sourceFile = getValidSourceFile(fileName); + var isJavaScriptFile = ts.isJavaScript(fileName); var start = new Date().getTime(); var currentToken = ts.getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); @@ -38929,13 +39034,29 @@ var ts; } } var type = typeChecker.getTypeAtLocation(node); + addTypeProperties(type); + } + function addTypeProperties(type) { if (type) { // Filter private properties - ts.forEach(type.getApparentProperties(), function (symbol) { + for (var _i = 0, _a = type.getApparentProperties(); _i < _a.length; _i++) { + var symbol = _a[_i]; if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { symbols.push(symbol); } - }); + } + if (isJavaScriptFile && type.flags & 16384 /* Union */) { + // In javascript files, for union types, we don't just get the members that + // the individual types have in common, we also include all the members that + // each individual type has. This is because we're going to add all identifiers + // anyways. So we might as well elevate the members that were at least part + // of the individual types to a higher status since we know what they are. + var unionType = type; + for (var _b = 0, _c = unionType.types; _b < _c.length; _b++) { + var elementType = _c[_b]; + addTypeProperties(elementType); + } + } } } function tryGetGlobalSymbols() { @@ -39096,15 +39217,18 @@ var ts; if (previousToken.kind === 8 /* StringLiteral */ || previousToken.kind === 9 /* RegularExpressionLiteral */ || ts.isTemplateLiteralKind(previousToken.kind)) { - // The position has to be either: 1. entirely within the token text, or - // 2. at the end position of an unterminated token. var start_3 = previousToken.getStart(); var end = previousToken.getEnd(); + // To be "in" one of these literals, the position has to be: + // 1. entirely within the token text. + // 2. at the end position of an unterminated token. + // 3. at the end of a regular expression (due to trailing flags like '/foo/g'). if (start_3 < position && position < end) { return true; } - else if (position === end) { - return !!previousToken.isUnterminated; + if (position === end) { + return !!previousToken.isUnterminated || + previousToken.kind === 9 /* RegularExpressionLiteral */; } } return false; @@ -41583,6 +41707,7 @@ var ts; case 15 /* typeParameterName */: return ClassificationTypeNames.typeParameterName; case 16 /* typeAliasName */: return ClassificationTypeNames.typeAliasName; case 17 /* parameterName */: return ClassificationTypeNames.parameterName; + case 18 /* docCommentTagName */: return ClassificationTypeNames.docCommentTagName; } } function convertClassifications(classifications) { @@ -41633,8 +41758,7 @@ var ts; // Only bother with the trivia if it at least intersects the span of interest. if (ts.textSpanIntersectsWith(span, start, width)) { if (ts.isComment(kind)) { - // Simple comment. Just add as is. - pushClassification(start, width, 1 /* comment */); + classifyComment(token, kind, start, width); continue; } if (kind === 6 /* ConflictMarkerTrivia */) { @@ -41654,6 +41778,79 @@ var ts; } } } + function classifyComment(token, kind, start, width) { + if (kind === 3 /* MultiLineCommentTrivia */) { + // See if this is a doc comment. If so, we'll classify certain portions of it + // specially. + var docCommentAndDiagnostics = ts.parseIsolatedJSDocComment(sourceFile.text, start, width); + if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDocComment) { + docCommentAndDiagnostics.jsDocComment.parent = token; + classifyJSDocComment(docCommentAndDiagnostics.jsDocComment); + return; + } + } + // Simple comment. Just add as is. + pushCommentRange(start, width); + } + function pushCommentRange(start, width) { + pushClassification(start, width, 1 /* comment */); + } + function classifyJSDocComment(docComment) { + var pos = docComment.pos; + for (var _i = 0, _a = docComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + // As we walk through each tag, classify the portion of text from the end of + // the last tag (or the start of the entire doc comment) as 'comment'. + if (tag.pos !== pos) { + pushCommentRange(pos, tag.pos - pos); + } + pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, 10 /* punctuation */); + pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, 18 /* docCommentTagName */); + pos = tag.tagName.end; + switch (tag.kind) { + case 247 /* JSDocParameterTag */: + processJSDocParameterTag(tag); + break; + case 250 /* JSDocTemplateTag */: + processJSDocTemplateTag(tag); + break; + case 249 /* JSDocTypeTag */: + processElement(tag.typeExpression); + break; + case 248 /* JSDocReturnTag */: + processElement(tag.typeExpression); + break; + } + pos = tag.end; + } + if (pos !== docComment.end) { + pushCommentRange(pos, docComment.end - pos); + } + return; + function processJSDocParameterTag(tag) { + if (tag.preParameterName) { + pushCommentRange(pos, tag.preParameterName.pos - pos); + pushClassification(tag.preParameterName.pos, tag.preParameterName.end - tag.preParameterName.pos, 17 /* parameterName */); + pos = tag.preParameterName.end; + } + if (tag.typeExpression) { + pushCommentRange(pos, tag.typeExpression.pos - pos); + processElement(tag.typeExpression); + pos = tag.typeExpression.end; + } + if (tag.postParameterName) { + pushCommentRange(pos, tag.postParameterName.pos - pos); + pushClassification(tag.postParameterName.pos, tag.postParameterName.end - tag.postParameterName.pos, 17 /* parameterName */); + pos = tag.postParameterName.end; + } + } + } + function processJSDocTemplateTag(tag) { + for (var _i = 0, _a = tag.getChildren(); _i < _a.length; _i++) { + var child = _a[_i]; + processElement(child); + } + } function classifyDisabledMergeCode(text, start, end) { // Classify the line that the ======= marker is on as a comment. Then just lex // all further tokens and add them to the result. @@ -41774,9 +41971,12 @@ var ts; } } function processElement(element) { + if (!element) { + return; + } // Ignore nodes that don't intersect the original span to classify. if (ts.textSpanIntersectsWith(span, element.getFullStart(), element.getFullWidth())) { - var children = element.getChildren(); + var children = element.getChildren(sourceFile); for (var _i = 0; _i < children.length; _i++) { var child = children[_i]; if (ts.isToken(child)) { From 9515947092941127079a06a8d3d6bac245898835 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Tue, 2 Jun 2015 12:49:07 +0800 Subject: [PATCH 119/194] Adds custom type guard --- src/compiler/checker.ts | 162 ++++++++++++++++-- .../diagnosticInformationMap.generated.ts | 5 + src/compiler/diagnosticMessages.json | 21 +++ src/compiler/parser.ts | 20 ++- src/compiler/scanner.ts | 1 + src/compiler/types.ts | 19 +- 6 files changed, 210 insertions(+), 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fad7293412e..a09a2736aac 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -97,8 +97,8 @@ module ts { let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); let noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - let anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, false, false); - let unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false); + let anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, false, false); + let unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, undefined, 0, false, false); let globals: SymbolTable = {}; @@ -2772,7 +2772,7 @@ module ts { function resolveDeclaredMembers(type: InterfaceType): InterfaceTypeWithDeclaredMembers { if (!(type).declaredProperties) { - var symbol = type.symbol; + let symbol = type.symbol; (type).declaredProperties = getNamedMembers(symbol.members); (type).declaredCallSignatures = getSignaturesOfSymbol(symbol.members["__call"]); (type).declaredConstructSignatures = getSignaturesOfSymbol(symbol.members["__new"]); @@ -2782,7 +2782,7 @@ module ts { return type; } - function resolveClassOrInterfaceMembers(type: InterfaceType): void { + function resolveClassOrInterfaceMembers(type: InterfaceType) { let target = resolveDeclaredMembers(type); let members = target.symbol.members; let callSignatures = target.declaredCallSignatures; @@ -2823,12 +2823,13 @@ module ts { } function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], parameters: Symbol[], - resolvedReturnType: Type, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature { + resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature { let sig = new Signature(checker); sig.declaration = declaration; sig.typeParameters = typeParameters; sig.parameters = parameters; sig.resolvedReturnType = resolvedReturnType; + sig.typePredicate = typePredicate; sig.minArgumentCount = minArgumentCount; sig.hasRestParameter = hasRestParameter; sig.hasStringLiterals = hasStringLiterals; @@ -2836,7 +2837,7 @@ module ts { } function cloneSignature(sig: Signature): Signature { - return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, + return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals); } @@ -2853,7 +2854,7 @@ module ts { return signature; }); } - return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, 0, false, false)]; + return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, false, false)]; } function createTupleTypeMemberSymbols(memberTypes: Type[]): SymbolTable { @@ -3229,7 +3230,24 @@ module ts { } let returnType: Type; - if (classType) { + let typePredicate: TypePredicate; + if (declaration.typePredicate) { + returnType = booleanType; + let typePredicateNode = declaration.typePredicate; + let links = getNodeLinks(typePredicateNode); + if (links.typePredicateParameterIndex === undefined) { + links.typePredicateParameterIndex = getTypePredicateParameterIndex(declaration.parameters, typePredicateNode.parameterName); + } + if (!links.typeFromTypePredicate) { + links.typeFromTypePredicate = getTypeFromTypeNode(declaration.typePredicate.type); + } + typePredicate = { + parameterName: typePredicateNode.parameterName ? typePredicateNode.parameterName.text : undefined, + parameterIndex: typePredicateNode.parameterName ? links.typePredicateParameterIndex : undefined, + type: links.typeFromTypePredicate + }; + } + else if (classType) { returnType = classType; } else if (declaration.type) { @@ -3248,8 +3266,8 @@ module ts { } } - links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, - minArgumentCount, hasRestParameter(declaration), hasStringLiterals); + links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, typePredicate, + minArgumentCount, hasRestParameters(declaration), hasStringLiterals); } return links.resolvedSignature; } @@ -3962,9 +3980,13 @@ module ts { freshTypeParameters = instantiateList(signature.typeParameters, mapper, instantiateTypeParameter); mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper); } + if (signature.typePredicate) { + signature.typePredicate.type = instantiateType(signature.typePredicate.type, mapper); + } let result = createSignature(signature.declaration, freshTypeParameters, instantiateList(signature.parameters, mapper, instantiateSymbol), signature.resolvedReturnType ? instantiateType(signature.resolvedReturnType, mapper) : undefined, + signature.typePredicate, signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals); result.target = signature; result.mapper = mapper; @@ -4632,6 +4654,43 @@ module ts { } result &= related; } + + if (source.typePredicate && target.typePredicate) { + if (source.typePredicate.parameterIndex !== target.typePredicate.parameterIndex || + source.typePredicate.type.symbol !== target.typePredicate.type.symbol) { + + if (reportErrors) { + let sourceParamText = source.typePredicate.parameterName; + let targetParamText = target.typePredicate.parameterName; + let sourceTypeText = typeToString(source.typePredicate.type); + let targetTypeText = typeToString(target.typePredicate.type); + + if (source.typePredicate.parameterIndex !== target.typePredicate.parameterIndex) { + reportError(Diagnostics.Parameter_index_from_0_does_not_match_the_parameter_index_from_1, + sourceParamText, + targetParamText); + } + if (source.typePredicate.type.symbol !== target.typePredicate.type.symbol) { + reportError(Diagnostics.Type_0_is_not_assignable_to_type_1, + sourceTypeText, + targetTypeText); + } + + reportError(Diagnostics.Type_guard_annotation_0_is_not_assignable_to_1, + `${sourceParamText} is ${sourceTypeText}`, + `${targetParamText} is ${targetTypeText}`); + } + + return Ternary.False; + } + } + else if (!source.typePredicate && target.typePredicate) { + if (reportErrors) { + reportError(Diagnostics.A_non_type_guard_function_is_not_assignable_to_a_type_guard_function); + } + return Ternary.False; + } + let t = getReturnTypeOfSignature(target); if (t === voidType) return result; let s = getReturnTypeOfSignature(source); @@ -5164,6 +5223,13 @@ module ts { function inferFromSignature(source: Signature, target: Signature) { forEachMatchingParameterType(source, target, inferFromTypes); + if (source.typePredicate && + target.typePredicate && + target.typePredicate.parameterIndex === source.typePredicate.parameterIndex) { + + inferFromTypes(source.typePredicate.type, target.typePredicate.type); + return; + } inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); } @@ -5545,7 +5611,7 @@ module ts { let targetType: Type; let prototypeProperty = getPropertyOfType(rightType, "prototype"); if (prototypeProperty) { - // Target type is type of the protoype property + // Target type is type of the prototype property let prototypePropertyType = getTypeOfSymbol(prototypeProperty); if (prototypePropertyType !== anyType) { targetType = prototypePropertyType; @@ -5561,7 +5627,6 @@ module ts { else if (rightType.flags & TypeFlags.Anonymous) { constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct); } - if (constructSignatures && constructSignatures.length) { targetType = getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature)))); } @@ -5581,10 +5646,38 @@ module ts { return type; } + function narrowTypeByTypePredicate(type: Type, expr: CallExpression, assumeTrue: boolean): Type { + if (type.flags & TypeFlags.Any) { + return type; + } + let signature = getResolvedSignature(expr); + if (!assumeTrue) { + if (type.flags & TypeFlags.Union && signature.typePredicate) { + return getUnionType(filter((type).types, t => !isTypeSubtypeOf(t, signature.typePredicate.type))); + } + return type; + } + if (signature.typePredicate) { + if (expr.arguments && expr.arguments[signature.typePredicate.parameterIndex]) { + if (getSymbolAtLocation(expr.arguments[signature.typePredicate.parameterIndex]) === symbol) { + if (isTypeSubtypeOf(signature.typePredicate.type, type)) { + return signature.typePredicate.type; + } + if (type.flags & TypeFlags.Union) { + return getUnionType(filter((type).types, t => isTypeSubtypeOf(t, signature.typePredicate.type))); + } + } + } + } + return type; + } + // Narrow the given type based on the given expression having the assumed boolean value. The returned type // will be a subtype or the same type as the argument. function narrowType(type: Type, expr: Expression, assumeTrue: boolean): Type { switch (expr.kind) { + case SyntaxKind.CallExpression: + return narrowTypeByTypePredicate(type, expr, assumeTrue); case SyntaxKind.ParenthesizedExpression: return narrowType(type, (expr).expression, assumeTrue); case SyntaxKind.BinaryExpression: @@ -8486,6 +8579,20 @@ module ts { node.kind === SyntaxKind.FunctionExpression; } + function getTypePredicateParameterIndex(parameterList: NodeArray, parameter: Identifier): number { + let index = -1; + if (parameterList) { + for (let i = 0; i < parameterList.length; i++) { + let param = parameterList[i]; + if (param.name.kind === SyntaxKind.Identifier && + (param.name).text === parameter.text) { + + return i; + } + } + } + } + function checkSignatureDeclaration(node: SignatureDeclaration) { // Grammar checking if (node.kind === SyntaxKind.IndexSignature) { @@ -8506,6 +8613,27 @@ module ts { checkSourceElement(node.type); } + if (node.typePredicate) { + let links = getNodeLinks(node.typePredicate); + if (links.typePredicateParameterIndex === undefined) { + links.typePredicateParameterIndex = getTypePredicateParameterIndex(node.parameters, node.typePredicate.parameterName); + } + if (!links.typeFromTypePredicate) { + links.typeFromTypePredicate = getTypeFromTypeNode(node.typePredicate.type); + } + if (links.typePredicateParameterIndex >= 0) { + checkTypeAssignableTo( + links.typeFromTypePredicate, + getTypeAtLocation(node.parameters[links.typePredicateParameterIndex]), + node.typePredicate.type); + } + else if(node.typePredicate.parameterName) { + error(node.typePredicate.parameterName, + Diagnostics.Cannot_find_parameter_0, + node.typePredicate.parameterName.text); + } + } + if (produceDiagnostics) { checkCollisionWithArgumentsInGeneratedCode(node); if (compilerOptions.noImplicitAny && !node.type) { @@ -10065,9 +10193,6 @@ module ts { if (node.expression) { let func = getContainingFunction(node); if (func) { - let returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func)); - let exprType = checkExpressionCached(node.expression); - if (func.asteriskToken) { // A generator does not need its return expressions checked against its return type. // Instead, the yield expressions are checked against the element type. @@ -10076,6 +10201,13 @@ module ts { return; } + let signature = getSignatureFromDeclaration(func); + let exprType = checkExpressionCached(node.expression); + if (signature.typePredicate && exprType !== booleanType) { + error(node.expression, Diagnostics.A_type_guard_function_can_only_return_a_boolean); + } + let returnType = getReturnTypeOfSignature(signature); + if (func.kind === SyntaxKind.SetAccessor) { error(node.expression, Diagnostics.Setters_cannot_return_a_value); } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 8ccc9d890e2..5a87f67ddd3 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -179,6 +179,11 @@ module ts { Generators_are_not_allowed_in_an_ambient_context: { code: 1221, category: DiagnosticCategory.Error, key: "Generators are not allowed in an ambient context." }, An_overload_signature_cannot_be_declared_as_a_generator: { code: 1222, category: DiagnosticCategory.Error, key: "An overload signature cannot be declared as a generator." }, _0_tag_already_specified: { code: 1223, category: DiagnosticCategory.Error, key: "'{0}' tag already specified." }, + A_non_type_guard_function_is_not_assignable_to_a_type_guard_function: { code: 1224, category: DiagnosticCategory.Error, key: "A non-type guard function is not assignable to a type guard function." }, + A_type_guard_function_can_only_return_a_boolean: { code: 1225, category: DiagnosticCategory.Error, key: "A type-guard function can only return a boolean." }, + Cannot_find_parameter_0: { code: 1226, category: DiagnosticCategory.Error, key: "Cannot find parameter '{0}'." }, + Type_guard_annotation_0_is_not_assignable_to_1: { code: 1227, category: DiagnosticCategory.Error, key: "Type-guard annotation '{0}' is not assignable to '{1}'." }, + Parameter_index_from_0_does_not_match_the_parameter_index_from_1: { code: 1228, category: DiagnosticCategory.Error, key: "Parameter index from '{0}' does not match the parameter index from '{1}'." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index fb246955f73..0053b071438 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -703,6 +703,27 @@ "category": "Error", "code": 1223 }, + "A non-type guard function is not assignable to a type guard function.": { + "category": "Error", + "code": 1224 + }, + "A type-guard function can only return a boolean.": { + "category": "Error", + "code": 1225 + }, + "Cannot find parameter '{0}'.": { + "category": "Error", + "code": 1226 + }, + "Type-guard annotation '{0}' is not assignable to '{1}'.": { + "category": "Error", + "code": 1227 + }, + "Parameter index from '{0}' does not match the parameter index from '{1}'.": { + "category": "Error", + "code": 1228 + }, + "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 80c70a250fb..ac4517a0b79 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -81,7 +81,8 @@ module ts { visitNodes(cbNodes, node.modifiers) || visitNodes(cbNodes, (node).typeParameters) || visitNodes(cbNodes, (node).parameters) || - visitNode(cbNode, (node).type); + visitNode(cbNode, (node).type) || + visitNode(cbNode, (node).typePredicate); case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: case SyntaxKind.Constructor: @@ -98,11 +99,15 @@ module ts { visitNodes(cbNodes, (node).typeParameters) || visitNodes(cbNodes, (node).parameters) || visitNode(cbNode, (node).type) || + visitNode(cbNode, (node).typePredicate) || visitNode(cbNode, (node).equalsGreaterThanToken) || visitNode(cbNode, (node).body); case SyntaxKind.TypeReference: return visitNode(cbNode, (node).typeName) || visitNodes(cbNodes, (node).typeArguments); + case SyntaxKind.TypePredicate: + return visitNode(cbNode, (node).parameterName) || + visitNode(cbNode, (node).type); case SyntaxKind.TypeQuery: return visitNode(cbNode, (node).exprName); case SyntaxKind.TypeLiteral: @@ -763,7 +768,7 @@ module ts { return (contextFlags & ParserContextFlags.Decorator) !== 0; } - function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): void { + function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any) { let start = scanner.getTokenPos(); let length = scanner.getTextPos() - start; @@ -2025,6 +2030,17 @@ module ts { else if (parseOptional(returnToken)) { signature.type = parseType(); } + if (token === SyntaxKind.IsKeyword) { + let node = createNode(SyntaxKind.TypePredicate); + node.pos = signature.type.pos; + node.parameterName = (signature.type).typeName; + + nextToken(); + + node.type = parseType(); + signature.type = undefined; + signature.typePredicate = finishNode(node); + } } // Note: after careful analysis of the grammar, it does not appear to be possible to diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 89ac837ab24..d7e65dff81c 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -72,6 +72,7 @@ module ts { "in": SyntaxKind.InKeyword, "instanceof": SyntaxKind.InstanceOfKeyword, "interface": SyntaxKind.InterfaceKeyword, + "is": SyntaxKind.IsKeyword, "let": SyntaxKind.LetKeyword, "module": SyntaxKind.ModuleKeyword, "namespace": SyntaxKind.NamespaceKeyword, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0fcf0e1f67a..acf71db16c7 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -137,6 +137,7 @@ module ts { ConstructorKeyword, DeclareKeyword, GetKeyword, + IsKeyword, ModuleKeyword, NamespaceKeyword, RequireKeyword, @@ -169,6 +170,7 @@ module ts { ConstructSignature, IndexSignature, // Type + TypePredicate, TypeReference, FunctionType, ConstructorType, @@ -462,6 +464,7 @@ module ts { typeParameters?: NodeArray; parameters: NodeArray; type?: TypeNode; + typePredicate?: TypePredicateNode; } // SyntaxKind.VariableDeclaration @@ -605,6 +608,11 @@ module ts { typeName: EntityName; typeArguments?: NodeArray; } + + export interface TypePredicateNode extends TypeNode { + parameterName?: Identifier; + type: TypeNode; + } export interface TypeQueryNode extends TypeNode { exprName: EntityName; @@ -1376,6 +1384,12 @@ module ts { NotAccessible, CannotBeNamed } + + export interface TypePredicate { + parameterName: string; + parameterIndex?: number; + type: Type; + } /* @internal */ export type AnyImportSyntax = ImportDeclaration | ImportEqualsDeclaration; @@ -1563,6 +1577,8 @@ module ts { assignmentChecks?: Map; // Cache of assignment checks hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context importOnRightSide?: Symbol; // for import declarations - import that appear on the right side + typePredicateParameterIndex?: number; // Index of type predicate parameter + typeFromTypePredicate?: Type; // Type from TypePredicate } export const enum TypeFlags { @@ -1588,7 +1604,7 @@ module ts { /* @internal */ ContainsUndefinedOrNull = 0x00040000, // Type is or contains Undefined or Null type /* @internal */ - ContainsObjectLiteral = 0x00080000, // Type is or contains object literal type + ContainsObjectLiteral = 0x00080000, // Type is or contains object literal type ESSymbol = 0x00100000, // Type of symbol primitive introduced in ES6 /* @internal */ @@ -1703,6 +1719,7 @@ module ts { declaration: SignatureDeclaration; // Originating declaration typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic) parameters: Symbol[]; // Parameters + typePredicate?: TypePredicate; // Type predicate /* @internal */ resolvedReturnType: Type; // Resolved return type /* @internal */ From 284b9db268ebc85445e3e2131e98ce68f7e6e4dc Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Tue, 2 Jun 2015 12:49:23 +0800 Subject: [PATCH 120/194] Fixes old tests --- tests/baselines/reference/APISample_linter.js | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/baselines/reference/APISample_linter.js b/tests/baselines/reference/APISample_linter.js index cd2df23ffbf..9b2675535f2 100644 --- a/tests/baselines/reference/APISample_linter.js +++ b/tests/baselines/reference/APISample_linter.js @@ -75,26 +75,26 @@ function delint(sourceFile) { delintNode(sourceFile); function delintNode(node) { switch (node.kind) { - case 187 /* ForStatement */: - case 188 /* ForInStatement */: - case 186 /* WhileStatement */: - case 185 /* DoStatement */: - if (node.statement.kind !== 180 /* Block */) { + case 189 /* ForStatement */: + case 190 /* ForInStatement */: + case 188 /* WhileStatement */: + case 187 /* DoStatement */: + if (node.statement.kind !== 182 /* Block */) { report(node, "A looping statement's contents should be wrapped in a block body."); } break; - case 184 /* IfStatement */: + case 186 /* IfStatement */: var ifStatement = node; - if (ifStatement.thenStatement.kind !== 180 /* Block */) { + if (ifStatement.thenStatement.kind !== 182 /* Block */) { report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body."); } if (ifStatement.elseStatement && - ifStatement.elseStatement.kind !== 180 /* Block */ && - ifStatement.elseStatement.kind !== 184 /* IfStatement */) { + ifStatement.elseStatement.kind !== 182 /* Block */ && + ifStatement.elseStatement.kind !== 186 /* IfStatement */) { report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body."); } break; - case 170 /* BinaryExpression */: + case 172 /* BinaryExpression */: var op = node.operatorToken.kind; if (op === 28 /* EqualsEqualsToken */ || op == 29 /* ExclamationEqualsToken */) { report(node, "Use '===' and '!=='."); From f8e2b99b6c0cb94add93d3ac5948130d0e5959fa Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Tue, 2 Jun 2015 12:49:36 +0800 Subject: [PATCH 121/194] Adds tests --- .../baselines/reference/typeGuardFunction.js | 105 ++++++++++ .../reference/typeGuardFunction.symbols | 144 ++++++++++++++ .../reference/typeGuardFunction.types | 159 +++++++++++++++ .../typeGuardFunctionErrors.errors.txt | 174 ++++++++++++++++ .../reference/typeGuardFunctionErrors.js | 173 ++++++++++++++++ .../reference/typeGuardFunctionGenerics.js | 69 +++++++ .../typeGuardFunctionGenerics.symbols | 125 ++++++++++++ .../reference/typeGuardFunctionGenerics.types | 138 +++++++++++++ .../reference/typeGuardOfFormIsType.js | 85 ++++++++ .../reference/typeGuardOfFormIsType.symbols | 128 ++++++++++++ .../reference/typeGuardOfFormIsType.types | 157 +++++++++++++++ .../typeGuardOfFormIsTypeOnInterfaces.js | 74 +++++++ .../typeGuardOfFormIsTypeOnInterfaces.symbols | 159 +++++++++++++++ .../typeGuardOfFormIsTypeOnInterfaces.types | 188 ++++++++++++++++++ .../typeGuards/typeGuardFunction.ts | 56 ++++++ .../typeGuards/typeGuardFunctionErrors.ts | 92 +++++++++ .../typeGuards/typeGuardFunctionGenerics.ts | 33 +++ .../typeGuards/typeGuardOfFormIsType.ts | 37 ++++ .../typeGuardOfFormIsTypeOnInterfaces.ts | 46 +++++ 19 files changed, 2142 insertions(+) create mode 100644 tests/baselines/reference/typeGuardFunction.js create mode 100644 tests/baselines/reference/typeGuardFunction.symbols create mode 100644 tests/baselines/reference/typeGuardFunction.types create mode 100644 tests/baselines/reference/typeGuardFunctionErrors.errors.txt create mode 100644 tests/baselines/reference/typeGuardFunctionErrors.js create mode 100644 tests/baselines/reference/typeGuardFunctionGenerics.js create mode 100644 tests/baselines/reference/typeGuardFunctionGenerics.symbols create mode 100644 tests/baselines/reference/typeGuardFunctionGenerics.types create mode 100644 tests/baselines/reference/typeGuardOfFormIsType.js create mode 100644 tests/baselines/reference/typeGuardOfFormIsType.symbols create mode 100644 tests/baselines/reference/typeGuardOfFormIsType.types create mode 100644 tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.js create mode 100644 tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.symbols create mode 100644 tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types create mode 100644 tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts create mode 100644 tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts create mode 100644 tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts create mode 100644 tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts create mode 100644 tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts diff --git a/tests/baselines/reference/typeGuardFunction.js b/tests/baselines/reference/typeGuardFunction.js new file mode 100644 index 00000000000..d6b64c09d4d --- /dev/null +++ b/tests/baselines/reference/typeGuardFunction.js @@ -0,0 +1,105 @@ +//// [typeGuardFunction.ts] + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +declare function isA(p1: any): p1 is A; +declare function isB(p1: any): p1 is B; +declare function isC(p1: any): p1 is C; + +declare function retC(): C; + +var a: A; +var b: B; + +// Basic. +if (isC(a)) { + a.propC; +} + +// Sub type. +var subType: C; +if(isA(subType)) { + subType.propC; +} + +// Union type. +var union: A | B; +if(isA(union)) { + union.propA; +} + +// The parameter index and argument index for the type guard target is matching. +// The type predicate type is assignable to the parameter type. +declare function isC_multipleParams(p1, p2): p1 is C; +if (isC_multipleParams(a, 0)) { + a.propC; +} + +// Evaluations are asssignable to boolean. +declare function acceptingBoolean(a: boolean); +acceptingBoolean(isA(a)); + +// Type predicates with different parameter name. +declare function acceptingTypeGuardFunction(p1: (item) => item is A); +acceptingTypeGuardFunction(isA); + +let union2: C | B; +let union3: boolean | B = isA(union2) || union2; + +//// [typeGuardFunction.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var A = (function () { + function A() { + } + return A; +})(); +var B = (function () { + function B() { + } + return B; +})(); +var C = (function (_super) { + __extends(C, _super); + function C() { + _super.apply(this, arguments); + } + return C; +})(A); +var a; +var b; +// Basic. +if (isC(a)) { + a.propC; +} +// Sub type. +var subType; +if (isA(subType)) { + subType.propC; +} +// Union type. +var union; +if (isA(union)) { + union.propA; +} +if (isC_multipleParams(a, 0)) { + a.propC; +} +acceptingBoolean(isA(a)); +acceptingTypeGuardFunction(isA); +var union2; +var union3 = isA(union2) || union2; diff --git a/tests/baselines/reference/typeGuardFunction.symbols b/tests/baselines/reference/typeGuardFunction.symbols new file mode 100644 index 00000000000..f9180d56b0b --- /dev/null +++ b/tests/baselines/reference/typeGuardFunction.symbols @@ -0,0 +1,144 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts === + +class A { +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) + + propA: number; +>propA : Symbol(propA, Decl(typeGuardFunction.ts, 1, 9)) +} + +class B { +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) + + propB: number; +>propB : Symbol(propB, Decl(typeGuardFunction.ts, 5, 9)) +} + +class C extends A { +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) + + propC: number; +>propC : Symbol(propC, Decl(typeGuardFunction.ts, 9, 19)) +} + +declare function isA(p1: any): p1 is A; +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 13, 21)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) + +declare function isB(p1: any): p1 is B; +>isB : Symbol(isB, Decl(typeGuardFunction.ts, 13, 39)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 14, 21)) +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) + +declare function isC(p1: any): p1 is C; +>isC : Symbol(isC, Decl(typeGuardFunction.ts, 14, 39)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 15, 21)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + +declare function retC(): C; +>retC : Symbol(retC, Decl(typeGuardFunction.ts, 15, 39)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + +var a: A; +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) + +var b: B; +>b : Symbol(b, Decl(typeGuardFunction.ts, 20, 3)) +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) + +// Basic. +if (isC(a)) { +>isC : Symbol(isC, Decl(typeGuardFunction.ts, 14, 39)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) + + a.propC; +>a.propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) +>propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +} + +// Sub type. +var subType: C; +>subType : Symbol(subType, Decl(typeGuardFunction.ts, 28, 3)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + +if(isA(subType)) { +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) +>subType : Symbol(subType, Decl(typeGuardFunction.ts, 28, 3)) + + subType.propC; +>subType.propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +>subType : Symbol(subType, Decl(typeGuardFunction.ts, 28, 3)) +>propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +} + +// Union type. +var union: A | B; +>union : Symbol(union, Decl(typeGuardFunction.ts, 34, 3)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) + +if(isA(union)) { +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) +>union : Symbol(union, Decl(typeGuardFunction.ts, 34, 3)) + + union.propA; +>union.propA : Symbol(A.propA, Decl(typeGuardFunction.ts, 1, 9)) +>union : Symbol(union, Decl(typeGuardFunction.ts, 34, 3)) +>propA : Symbol(A.propA, Decl(typeGuardFunction.ts, 1, 9)) +} + +// The parameter index and argument index for the type guard target is matching. +// The type predicate type is assignable to the parameter type. +declare function isC_multipleParams(p1, p2): p1 is C; +>isC_multipleParams : Symbol(isC_multipleParams, Decl(typeGuardFunction.ts, 37, 1)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 41, 36)) +>p2 : Symbol(p2, Decl(typeGuardFunction.ts, 41, 39)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + +if (isC_multipleParams(a, 0)) { +>isC_multipleParams : Symbol(isC_multipleParams, Decl(typeGuardFunction.ts, 37, 1)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) + + a.propC; +>a.propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) +>propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +} + +// Evaluations are asssignable to boolean. +declare function acceptingBoolean(a: boolean); +>acceptingBoolean : Symbol(acceptingBoolean, Decl(typeGuardFunction.ts, 44, 1)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 47, 34)) + +acceptingBoolean(isA(a)); +>acceptingBoolean : Symbol(acceptingBoolean, Decl(typeGuardFunction.ts, 44, 1)) +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) + +// Type predicates with different parameter name. +declare function acceptingTypeGuardFunction(p1: (item) => item is A); +>acceptingTypeGuardFunction : Symbol(acceptingTypeGuardFunction, Decl(typeGuardFunction.ts, 48, 25)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 51, 44)) +>item : Symbol(item, Decl(typeGuardFunction.ts, 51, 49)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) + +acceptingTypeGuardFunction(isA); +>acceptingTypeGuardFunction : Symbol(acceptingTypeGuardFunction, Decl(typeGuardFunction.ts, 48, 25)) +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) + +let union2: C | B; +>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 54, 3)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) + +let union3: boolean | B = isA(union2) || union2; +>union3 : Symbol(union3, Decl(typeGuardFunction.ts, 55, 3)) +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) +>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 54, 3)) +>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 54, 3)) + diff --git a/tests/baselines/reference/typeGuardFunction.types b/tests/baselines/reference/typeGuardFunction.types new file mode 100644 index 00000000000..2b3d1c40c8e --- /dev/null +++ b/tests/baselines/reference/typeGuardFunction.types @@ -0,0 +1,159 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts === + +class A { +>A : A + + propA: number; +>propA : number +} + +class B { +>B : B + + propB: number; +>propB : number +} + +class C extends A { +>C : C +>A : A + + propC: number; +>propC : number +} + +declare function isA(p1: any): p1 is A; +>isA : (p1: any) => boolean +>p1 : any +>p1 : any +>A : A + +declare function isB(p1: any): p1 is B; +>isB : (p1: any) => boolean +>p1 : any +>p1 : any +>B : B + +declare function isC(p1: any): p1 is C; +>isC : (p1: any) => boolean +>p1 : any +>p1 : any +>C : C + +declare function retC(): C; +>retC : () => C +>C : C + +var a: A; +>a : A +>A : A + +var b: B; +>b : B +>B : B + +// Basic. +if (isC(a)) { +>isC(a) : boolean +>isC : (p1: any) => boolean +>a : A + + a.propC; +>a.propC : number +>a : C +>propC : number +} + +// Sub type. +var subType: C; +>subType : C +>C : C + +if(isA(subType)) { +>isA(subType) : boolean +>isA : (p1: any) => boolean +>subType : C + + subType.propC; +>subType.propC : number +>subType : C +>propC : number +} + +// Union type. +var union: A | B; +>union : A | B +>A : A +>B : B + +if(isA(union)) { +>isA(union) : boolean +>isA : (p1: any) => boolean +>union : A | B + + union.propA; +>union.propA : number +>union : A +>propA : number +} + +// The parameter index and argument index for the type guard target is matching. +// The type predicate type is assignable to the parameter type. +declare function isC_multipleParams(p1, p2): p1 is C; +>isC_multipleParams : (p1: any, p2: any) => boolean +>p1 : any +>p2 : any +>p1 : any +>C : C + +if (isC_multipleParams(a, 0)) { +>isC_multipleParams(a, 0) : boolean +>isC_multipleParams : (p1: any, p2: any) => boolean +>a : A +>0 : number + + a.propC; +>a.propC : number +>a : C +>propC : number +} + +// Evaluations are asssignable to boolean. +declare function acceptingBoolean(a: boolean); +>acceptingBoolean : (a: boolean) => any +>a : boolean + +acceptingBoolean(isA(a)); +>acceptingBoolean(isA(a)) : any +>acceptingBoolean : (a: boolean) => any +>isA(a) : boolean +>isA : (p1: any) => boolean +>a : A + +// Type predicates with different parameter name. +declare function acceptingTypeGuardFunction(p1: (item) => item is A); +>acceptingTypeGuardFunction : (p1: (item: any) => boolean) => any +>p1 : (item: any) => boolean +>item : any +>item : any +>A : A + +acceptingTypeGuardFunction(isA); +>acceptingTypeGuardFunction(isA) : any +>acceptingTypeGuardFunction : (p1: (item: any) => boolean) => any +>isA : (p1: any) => boolean + +let union2: C | B; +>union2 : B | C +>C : C +>B : B + +let union3: boolean | B = isA(union2) || union2; +>union3 : boolean | B +>B : B +>isA(union2) || union2 : boolean | B +>isA(union2) : boolean +>isA : (p1: any) => boolean +>union2 : B | C +>union2 : B + diff --git a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt new file mode 100644 index 00000000000..8b5ed551dff --- /dev/null +++ b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt @@ -0,0 +1,174 @@ +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(15,12): error TS1225: A type-guard function can only return a boolean. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,55): error TS2304: Cannot find name 'x'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,57): error TS1144: '{' or ';' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,57): error TS2304: Cannot find name 'is'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,60): error TS1005: ';' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,62): error TS1005: ';' expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(22,33): error TS2304: Cannot find name 'x'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(26,10): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(27,5): error TS1131: Property or signature expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(28,1): error TS1128: Declaration or statement expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(30,38): error TS1226: Cannot find parameter 'x'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(34,51): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'propA' is missing in type 'B'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(38,56): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(42,56): error TS2322: Type 'T[]' is not assignable to type 'string'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(56,7): error TS2339: Property 'propB' does not exist on type 'A'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(61,7): error TS2339: Property 'propB' does not exist on type 'A'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(66,7): error TS2339: Property 'propB' does not exist on type 'A'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(71,46): error TS2345: Argument of type '(p1: any) => boolean' is not assignable to parameter of type '(p1: any) => boolean'. + Type-guard annotation 'p1 is C' is not assignable to 'p1 is B'. + Type 'C' is not assignable to type 'B'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(75,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. + A non-type guard function is not assignable to a type guard function. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(81,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. + Type-guard annotation 'p2 is A' is not assignable to 'p1 is A'. + Parameter index from 'p2' does not match the parameter index from 'p1'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(87,1): error TS2322: Type '(p1: any, p2: any, p3: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(92,56): error TS1226: Cannot find parameter 'p1'. + + +==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (22 errors) ==== + + class A { + propA: number; + } + + class B { + propB: number; + } + + class C extends A { + propC: number; + } + + function hasANonBooleanReturnStatement(x): x is A { + return ''; + ~~ +!!! error TS1225: A type-guard function can only return a boolean. + } + + function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { + ~ +!!! error TS2304: Cannot find name 'x'. + ~~ +!!! error TS1144: '{' or ';' expected. + ~~ +!!! error TS2304: Cannot find name 'is'. + ~ +!!! error TS1005: ';' expected. + ~ +!!! error TS1005: ';' expected. + return true; + } + + function hasMissingIsKeyword(): x { + ~ +!!! error TS2304: Cannot find name 'x'. + return true; + } + + function hasMissingTypeInTypeGuardType(x): x is { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + return true; + ~~~~~~ +!!! error TS1131: Property or signature expected. + } + ~ +!!! error TS1128: Declaration or statement expected. + + function hasNonMatchingParameter(y): x is A { + ~ +!!! error TS1226: Cannot find parameter 'x'. + return true; + } + + function hasNonMatchingParameterType1(x: A): x is B { + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'propA' is missing in type 'B'. + return true; + } + + function hasNonMatchingParameterType2(x: string): x is number { + ~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + return true; + } + + function hasNonMathcingGenericType(a: string): a is T[] { + ~~~ +!!! error TS2322: Type 'T[]' is not assignable to type 'string'. + return true; + } + + let a: A; + let b: B; + + declare function isB(p1): p1 is B; + declare function isC(p1): p1 is C; + declare function funA(p1: any, p2: any): p1 is B; + declare function hasNoTypeGuard(x); + + // Passed argument is not the same as the one being guarded. + if (isB(b)) { + a.propB; + ~~~~~ +!!! error TS2339: Property 'propB' does not exist on type 'A'. + } + + // Parameter index and argument index for the type guard target is not matching. + if (funA(0, a)) { + a.propB; // Error + ~~~~~ +!!! error TS2339: Property 'propB' does not exist on type 'A'. + } + + // No type guard in if statement + if (hasNoTypeGuard(a)) { + a.propB; + ~~~~~ +!!! error TS2339: Property 'propB' does not exist on type 'A'. + } + + // Type predicate type is not assignable + declare function acceptingDifferentSignatureTypeGuardFunction(p1: (p1) => p1 is B); + acceptingDifferentSignatureTypeGuardFunction(isC); + ~~~ +!!! error TS2345: Argument of type '(p1: any) => boolean' is not assignable to parameter of type '(p1: any) => boolean'. +!!! error TS2345: Type-guard annotation 'p1 is C' is not assignable to 'p1 is B'. +!!! error TS2345: Type 'C' is not assignable to type 'B'. + + // Boolean not assignable to type guard + var assign1: (p1, p2) => p1 is A; + assign1 = function(p1, p2): boolean { + ~~~~~~~ +!!! error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. +!!! error TS2322: A non-type guard function is not assignable to a type guard function. + return true; + }; + + // Must have matching parameter index + var assign2: (p1, p2) => p1 is A; + assign2 = function(p1, p2): p2 is A { + ~~~~~~~ +!!! error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. +!!! error TS2322: Type-guard annotation 'p2 is A' is not assignable to 'p1 is A'. +!!! error TS2322: Parameter index from 'p2' does not match the parameter index from 'p1'. + return true; + }; + + // No matching signature + var assign3: (p1, p2) => p1 is A; + assign3 = function(p1, p2, p3): p1 is A { + ~~~~~~~ +!!! error TS2322: Type '(p1: any, p2: any, p3: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. + return true; + }; + + // Type guard paramater referring to a binding pattern + declare function destructureParameter({ p1, p2, p3 }): p1 is A; + ~~ +!!! error TS1226: Cannot find parameter 'p1'. + \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardFunctionErrors.js b/tests/baselines/reference/typeGuardFunctionErrors.js new file mode 100644 index 00000000000..cc65fc00cba --- /dev/null +++ b/tests/baselines/reference/typeGuardFunctionErrors.js @@ -0,0 +1,173 @@ +//// [typeGuardFunctionErrors.ts] + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +function hasANonBooleanReturnStatement(x): x is A { + return ''; +} + +function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { + return true; +} + +function hasMissingIsKeyword(): x { + return true; +} + +function hasMissingTypeInTypeGuardType(x): x is { + return true; +} + +function hasNonMatchingParameter(y): x is A { + return true; +} + +function hasNonMatchingParameterType1(x: A): x is B { + return true; +} + +function hasNonMatchingParameterType2(x: string): x is number { + return true; +} + +function hasNonMathcingGenericType(a: string): a is T[] { + return true; +} + +let a: A; +let b: B; + +declare function isB(p1): p1 is B; +declare function isC(p1): p1 is C; +declare function funA(p1: any, p2: any): p1 is B; +declare function hasNoTypeGuard(x); + +// Passed argument is not the same as the one being guarded. +if (isB(b)) { + a.propB; +} + +// Parameter index and argument index for the type guard target is not matching. +if (funA(0, a)) { + a.propB; // Error +} + +// No type guard in if statement +if (hasNoTypeGuard(a)) { + a.propB; +} + +// Type predicate type is not assignable +declare function acceptingDifferentSignatureTypeGuardFunction(p1: (p1) => p1 is B); +acceptingDifferentSignatureTypeGuardFunction(isC); + +// Boolean not assignable to type guard +var assign1: (p1, p2) => p1 is A; +assign1 = function(p1, p2): boolean { + return true; +}; + +// Must have matching parameter index +var assign2: (p1, p2) => p1 is A; +assign2 = function(p1, p2): p2 is A { + return true; +}; + +// No matching signature +var assign3: (p1, p2) => p1 is A; +assign3 = function(p1, p2, p3): p1 is A { + return true; +}; + +// Type guard paramater referring to a binding pattern +declare function destructureParameter({ p1, p2, p3 }): p1 is A; + + +//// [typeGuardFunctionErrors.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var A = (function () { + function A() { + } + return A; +})(); +var B = (function () { + function B() { + } + return B; +})(); +var C = (function (_super) { + __extends(C, _super); + function C() { + _super.apply(this, arguments); + } + return C; +})(A); +function hasANonBooleanReturnStatement(x) { + return ''; +} +is; +A; +{ + return true; +} +function hasMissingIsKeyword() { + return true; +} +return true; +function hasNonMatchingParameter(y) { + return true; +} +function hasNonMatchingParameterType1(x) { + return true; +} +function hasNonMatchingParameterType2(x) { + return true; +} +function hasNonMathcingGenericType(a) { + return true; +} +var a; +var b; +// Passed argument is not the same as the one being guarded. +if (isB(b)) { + a.propB; +} +// Parameter index and argument index for the type guard target is not matching. +if (funA(0, a)) { + a.propB; // Error +} +// No type guard in if statement +if (hasNoTypeGuard(a)) { + a.propB; +} +acceptingDifferentSignatureTypeGuardFunction(isC); +// Boolean not assignable to type guard +var assign1; +assign1 = function (p1, p2) { + return true; +}; +// Must have matching parameter index +var assign2; +assign2 = function (p1, p2) { + return true; +}; +// No matching signature +var assign3; +assign3 = function (p1, p2, p3) { + return true; +}; diff --git a/tests/baselines/reference/typeGuardFunctionGenerics.js b/tests/baselines/reference/typeGuardFunctionGenerics.js new file mode 100644 index 00000000000..6704225a0d0 --- /dev/null +++ b/tests/baselines/reference/typeGuardFunctionGenerics.js @@ -0,0 +1,69 @@ +//// [typeGuardFunctionGenerics.ts] + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +declare function isB(p1): p1 is B; +declare function isC(p1): p1 is C; +declare function retC(x): C; + +declare function funA(p1: (p1) => T): T; +declare function funB(p1: (p1) => T, p2: any): p2 is T; +declare function funC(p1: (p1) => p1 is T): T; +declare function funD(p1: (p1) => p1 is T, p2: any): p2 is T; +declare function funE(p1: (p1) => p1 is T, p2: U): T; + +let a: A; +let test1: boolean = funA(isB); +if (funB(retC, a)) { + a.propC; +} +let test2: B = funC(isB); +if (funD(isC, a)) { + a.propC; +} +let test3: B = funE(isB, 1); + +//// [typeGuardFunctionGenerics.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var A = (function () { + function A() { + } + return A; +})(); +var B = (function () { + function B() { + } + return B; +})(); +var C = (function (_super) { + __extends(C, _super); + function C() { + _super.apply(this, arguments); + } + return C; +})(A); +var a; +var test1 = funA(isB); +if (funB(retC, a)) { + a.propC; +} +var test2 = funC(isB); +if (funD(isC, a)) { + a.propC; +} +var test3 = funE(isB, 1); diff --git a/tests/baselines/reference/typeGuardFunctionGenerics.symbols b/tests/baselines/reference/typeGuardFunctionGenerics.symbols new file mode 100644 index 00000000000..0ad8fab2fdb --- /dev/null +++ b/tests/baselines/reference/typeGuardFunctionGenerics.symbols @@ -0,0 +1,125 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts === + +class A { +>A : Symbol(A, Decl(typeGuardFunctionGenerics.ts, 0, 0)) + + propA: number; +>propA : Symbol(propA, Decl(typeGuardFunctionGenerics.ts, 1, 9)) +} + +class B { +>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1)) + + propB: number; +>propB : Symbol(propB, Decl(typeGuardFunctionGenerics.ts, 5, 9)) +} + +class C extends A { +>C : Symbol(C, Decl(typeGuardFunctionGenerics.ts, 7, 1)) +>A : Symbol(A, Decl(typeGuardFunctionGenerics.ts, 0, 0)) + + propC: number; +>propC : Symbol(propC, Decl(typeGuardFunctionGenerics.ts, 9, 19)) +} + +declare function isB(p1): p1 is B; +>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 13, 21)) +>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1)) + +declare function isC(p1): p1 is C; +>isC : Symbol(isC, Decl(typeGuardFunctionGenerics.ts, 13, 34)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 14, 21)) +>C : Symbol(C, Decl(typeGuardFunctionGenerics.ts, 7, 1)) + +declare function retC(x): C; +>retC : Symbol(retC, Decl(typeGuardFunctionGenerics.ts, 14, 34)) +>x : Symbol(x, Decl(typeGuardFunctionGenerics.ts, 15, 22)) +>C : Symbol(C, Decl(typeGuardFunctionGenerics.ts, 7, 1)) + +declare function funA(p1: (p1) => T): T; +>funA : Symbol(funA, Decl(typeGuardFunctionGenerics.ts, 15, 28)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 17, 22)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 17, 25)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 17, 30)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 17, 22)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 17, 22)) + +declare function funB(p1: (p1) => T, p2: any): p2 is T; +>funB : Symbol(funB, Decl(typeGuardFunctionGenerics.ts, 17, 43)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 18, 22)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 18, 25)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 18, 30)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 18, 22)) +>p2 : Symbol(p2, Decl(typeGuardFunctionGenerics.ts, 18, 39)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 18, 22)) + +declare function funC(p1: (p1) => p1 is T): T; +>funC : Symbol(funC, Decl(typeGuardFunctionGenerics.ts, 18, 58)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 19, 22)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 19, 25)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 19, 30)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 19, 22)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 19, 22)) + +declare function funD(p1: (p1) => p1 is T, p2: any): p2 is T; +>funD : Symbol(funD, Decl(typeGuardFunctionGenerics.ts, 19, 49)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 20, 22)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 20, 25)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 20, 30)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 20, 22)) +>p2 : Symbol(p2, Decl(typeGuardFunctionGenerics.ts, 20, 45)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 20, 22)) + +declare function funE(p1: (p1) => p1 is T, p2: U): T; +>funE : Symbol(funE, Decl(typeGuardFunctionGenerics.ts, 20, 64)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 21, 22)) +>U : Symbol(U, Decl(typeGuardFunctionGenerics.ts, 21, 24)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 21, 28)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 21, 33)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 21, 22)) +>p2 : Symbol(p2, Decl(typeGuardFunctionGenerics.ts, 21, 48)) +>U : Symbol(U, Decl(typeGuardFunctionGenerics.ts, 21, 24)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 21, 22)) + +let a: A; +>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3)) +>A : Symbol(A, Decl(typeGuardFunctionGenerics.ts, 0, 0)) + +let test1: boolean = funA(isB); +>test1 : Symbol(test1, Decl(typeGuardFunctionGenerics.ts, 24, 3)) +>funA : Symbol(funA, Decl(typeGuardFunctionGenerics.ts, 15, 28)) +>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1)) + +if (funB(retC, a)) { +>funB : Symbol(funB, Decl(typeGuardFunctionGenerics.ts, 17, 43)) +>retC : Symbol(retC, Decl(typeGuardFunctionGenerics.ts, 14, 34)) +>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3)) + + a.propC; +>a.propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19)) +>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3)) +>propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19)) +} +let test2: B = funC(isB); +>test2 : Symbol(test2, Decl(typeGuardFunctionGenerics.ts, 28, 3)) +>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1)) +>funC : Symbol(funC, Decl(typeGuardFunctionGenerics.ts, 18, 58)) +>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1)) + +if (funD(isC, a)) { +>funD : Symbol(funD, Decl(typeGuardFunctionGenerics.ts, 19, 49)) +>isC : Symbol(isC, Decl(typeGuardFunctionGenerics.ts, 13, 34)) +>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3)) + + a.propC; +>a.propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19)) +>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3)) +>propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19)) +} +let test3: B = funE(isB, 1); +>test3 : Symbol(test3, Decl(typeGuardFunctionGenerics.ts, 32, 3)) +>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1)) +>funE : Symbol(funE, Decl(typeGuardFunctionGenerics.ts, 20, 64)) +>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1)) + diff --git a/tests/baselines/reference/typeGuardFunctionGenerics.types b/tests/baselines/reference/typeGuardFunctionGenerics.types new file mode 100644 index 00000000000..77162e55a40 --- /dev/null +++ b/tests/baselines/reference/typeGuardFunctionGenerics.types @@ -0,0 +1,138 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts === + +class A { +>A : A + + propA: number; +>propA : number +} + +class B { +>B : B + + propB: number; +>propB : number +} + +class C extends A { +>C : C +>A : A + + propC: number; +>propC : number +} + +declare function isB(p1): p1 is B; +>isB : (p1: any) => boolean +>p1 : any +>p1 : any +>B : B + +declare function isC(p1): p1 is C; +>isC : (p1: any) => boolean +>p1 : any +>p1 : any +>C : C + +declare function retC(x): C; +>retC : (x: any) => C +>x : any +>C : C + +declare function funA(p1: (p1) => T): T; +>funA : (p1: (p1: any) => T) => T +>T : T +>p1 : (p1: any) => T +>p1 : any +>T : T +>T : T + +declare function funB(p1: (p1) => T, p2: any): p2 is T; +>funB : (p1: (p1: any) => T, p2: any) => boolean +>T : T +>p1 : (p1: any) => T +>p1 : any +>T : T +>p2 : any +>p2 : any +>T : T + +declare function funC(p1: (p1) => p1 is T): T; +>funC : (p1: (p1: any) => boolean) => T +>T : T +>p1 : (p1: any) => boolean +>p1 : any +>p1 : any +>T : T +>T : T + +declare function funD(p1: (p1) => p1 is T, p2: any): p2 is T; +>funD : (p1: (p1: any) => boolean, p2: any) => boolean +>T : T +>p1 : (p1: any) => boolean +>p1 : any +>p1 : any +>T : T +>p2 : any +>p2 : any +>T : T + +declare function funE(p1: (p1) => p1 is T, p2: U): T; +>funE : (p1: (p1: any) => boolean, p2: U) => T +>T : T +>U : U +>p1 : (p1: any) => boolean +>p1 : any +>p1 : any +>T : T +>p2 : U +>U : U +>T : T + +let a: A; +>a : A +>A : A + +let test1: boolean = funA(isB); +>test1 : boolean +>funA(isB) : boolean +>funA : (p1: (p1: any) => T) => T +>isB : (p1: any) => boolean + +if (funB(retC, a)) { +>funB(retC, a) : boolean +>funB : (p1: (p1: any) => T, p2: any) => boolean +>retC : (x: any) => C +>a : A + + a.propC; +>a.propC : number +>a : C +>propC : number +} +let test2: B = funC(isB); +>test2 : B +>B : B +>funC(isB) : B +>funC : (p1: (p1: any) => boolean) => T +>isB : (p1: any) => boolean + +if (funD(isC, a)) { +>funD(isC, a) : boolean +>funD : (p1: (p1: any) => boolean, p2: any) => boolean +>isC : (p1: any) => boolean +>a : A + + a.propC; +>a.propC : number +>a : C +>propC : number +} +let test3: B = funE(isB, 1); +>test3 : B +>B : B +>funE(isB, 1) : B +>funE : (p1: (p1: any) => boolean, p2: U) => T +>isB : (p1: any) => boolean +>1 : number + diff --git a/tests/baselines/reference/typeGuardOfFormIsType.js b/tests/baselines/reference/typeGuardOfFormIsType.js new file mode 100644 index 00000000000..65d99319d1e --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsType.js @@ -0,0 +1,85 @@ +//// [typeGuardOfFormIsType.ts] + +class C1 { + p1: string; +} +class C2 { + p2: number; +} +class D1 extends C1 { + p3: number; +} +var str: string; +var num: number; +var strOrNum: string | number; + +function isC1(x: any): x is C1 { + return true; +} + +function isC2(x: any): x is C2 { + return true; +} + +function isD1(x: any): x is D1 { + return true; +} + +var c1Orc2: C1 | C2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 + +var c2Ord1: C2 | D1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 + +//// [typeGuardOfFormIsType.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var C1 = (function () { + function C1() { + } + return C1; +})(); +var C2 = (function () { + function C2() { + } + return C2; +})(); +var D1 = (function (_super) { + __extends(D1, _super); + function D1() { + _super.apply(this, arguments); + } + return D1; +})(C1); +var str; +var num; +var strOrNum; +function isC1(x) { + return true; +} +function isC2(x) { + return true; +} +function isD1(x) { + return true; +} +var c1Orc2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +var c2Ord1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2 = isC1(c2Ord1) && c2Ord1; // C2 | D1 diff --git a/tests/baselines/reference/typeGuardOfFormIsType.symbols b/tests/baselines/reference/typeGuardOfFormIsType.symbols new file mode 100644 index 00000000000..a7bd0f4c165 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsType.symbols @@ -0,0 +1,128 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts === + +class C1 { +>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0)) + + p1: string; +>p1 : Symbol(p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) +} +class C2 { +>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1)) + + p2: number; +>p2 : Symbol(p2, Decl(typeGuardOfFormIsType.ts, 4, 10)) +} +class D1 extends C1 { +>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0)) + + p3: number; +>p3 : Symbol(p3, Decl(typeGuardOfFormIsType.ts, 7, 21)) +} +var str: string; +>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3)) + +var num: number; +>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3)) + +var strOrNum: string | number; +>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormIsType.ts, 12, 3)) + +function isC1(x: any): x is C1 { +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsType.ts, 12, 30)) +>x : Symbol(x, Decl(typeGuardOfFormIsType.ts, 14, 14)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0)) + + return true; +} + +function isC2(x: any): x is C2 { +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsType.ts, 16, 1)) +>x : Symbol(x, Decl(typeGuardOfFormIsType.ts, 18, 14)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1)) + + return true; +} + +function isD1(x: any): x is D1 { +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1)) +>x : Symbol(x, Decl(typeGuardOfFormIsType.ts, 22, 14)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1)) + + return true; +} + +var c1Orc2: C1 | C2; +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1)) + +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3)) +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsType.ts, 12, 30)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) + +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3)) +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsType.ts, 16, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>c1Orc2.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10)) + +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) + +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>c1Orc2.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21)) + +var c2Ord1: C2 | D1; +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1)) + +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3)) +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsType.ts, 16, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>c2Ord1.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10)) + +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>c2Ord1.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21)) + +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>c2Ord1.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) + +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 +>r2 : Symbol(r2, Decl(typeGuardOfFormIsType.ts, 36, 3)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1)) +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsType.ts, 12, 30)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) + diff --git a/tests/baselines/reference/typeGuardOfFormIsType.types b/tests/baselines/reference/typeGuardOfFormIsType.types new file mode 100644 index 00000000000..b14e5e22910 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsType.types @@ -0,0 +1,157 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts === + +class C1 { +>C1 : C1 + + p1: string; +>p1 : string +} +class C2 { +>C2 : C2 + + p2: number; +>p2 : number +} +class D1 extends C1 { +>D1 : D1 +>C1 : C1 + + p3: number; +>p3 : number +} +var str: string; +>str : string + +var num: number; +>num : number + +var strOrNum: string | number; +>strOrNum : string | number + +function isC1(x: any): x is C1 { +>isC1 : (x: any) => boolean +>x : any +>x : any +>C1 : C1 + + return true; +>true : boolean +} + +function isC2(x: any): x is C2 { +>isC2 : (x: any) => boolean +>x : any +>x : any +>C2 : C2 + + return true; +>true : boolean +} + +function isD1(x: any): x is D1 { +>isD1 : (x: any) => boolean +>x : any +>x : any +>D1 : D1 + + return true; +>true : boolean +} + +var c1Orc2: C1 | C2; +>c1Orc2 : C1 | C2 +>C1 : C1 +>C2 : C2 + +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +>str = isC1(c1Orc2) && c1Orc2.p1 : string +>str : string +>isC1(c1Orc2) && c1Orc2.p1 : string +>isC1(c1Orc2) : boolean +>isC1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p1 : string +>c1Orc2 : C1 +>p1 : string + +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +>num = isC2(c1Orc2) && c1Orc2.p2 : number +>num : number +>isC2(c1Orc2) && c1Orc2.p2 : number +>isC2(c1Orc2) : boolean +>isC2 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p2 : number +>c1Orc2 : C2 +>p2 : number + +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +>str = isD1(c1Orc2) && c1Orc2.p1 : string +>str : string +>isD1(c1Orc2) && c1Orc2.p1 : string +>isD1(c1Orc2) : boolean +>isD1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p1 : string +>c1Orc2 : D1 +>p1 : string + +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +>num = isD1(c1Orc2) && c1Orc2.p3 : number +>num : number +>isD1(c1Orc2) && c1Orc2.p3 : number +>isD1(c1Orc2) : boolean +>isD1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p3 : number +>c1Orc2 : D1 +>p3 : number + +var c2Ord1: C2 | D1; +>c2Ord1 : C2 | D1 +>C2 : C2 +>D1 : D1 + +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +>num = isC2(c2Ord1) && c2Ord1.p2 : number +>num : number +>isC2(c2Ord1) && c2Ord1.p2 : number +>isC2(c2Ord1) : boolean +>isC2 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p2 : number +>c2Ord1 : C2 +>p2 : number + +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +>num = isD1(c2Ord1) && c2Ord1.p3 : number +>num : number +>isD1(c2Ord1) && c2Ord1.p3 : number +>isD1(c2Ord1) : boolean +>isD1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p3 : number +>c2Ord1 : D1 +>p3 : number + +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +>str = isD1(c2Ord1) && c2Ord1.p1 : string +>str : string +>isD1(c2Ord1) && c2Ord1.p1 : string +>isD1(c2Ord1) : boolean +>isD1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p1 : string +>c2Ord1 : D1 +>p1 : string + +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 +>r2 : C2 | D1 +>C2 : C2 +>D1 : D1 +>isC1(c2Ord1) && c2Ord1 : D1 +>isC1(c2Ord1) : boolean +>isC1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1 : D1 + diff --git a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.js b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.js new file mode 100644 index 00000000000..d5faee96e8b --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.js @@ -0,0 +1,74 @@ +//// [typeGuardOfFormIsTypeOnInterfaces.ts] + +interface C1 { + (): C1; + prototype: C1; + p1: string; +} +interface C2 { + (): C2; + prototype: C2; + p2: number; +} +interface D1 extends C1 { + prototype: D1; + p3: number; +} +var str: string; +var num: number; +var strOrNum: string | number; + + +function isC1(x: any): x is C1 { + return true; +} + +function isC2(x: any): x is C2 { + return true; +} + +function isD1(x: any): x is D1 { + return true; +} + +var c1: C1; +var c2: C2; +var d1: D1; +var c1Orc2: C1 | C2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 + +var c2Ord1: C2 | D1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 + +//// [typeGuardOfFormIsTypeOnInterfaces.js] +var str; +var num; +var strOrNum; +function isC1(x) { + return true; +} +function isC2(x) { + return true; +} +function isD1(x) { + return true; +} +var c1; +var c2; +var d1; +var c1Orc2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +var c2Ord1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2 = isC1(c2Ord1) && c2Ord1; // C2 | D1 diff --git a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.symbols b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.symbols new file mode 100644 index 00000000000..37249ef7659 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.symbols @@ -0,0 +1,159 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts === + +interface C1 { +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + + (): C1; +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + + prototype: C1; +>prototype : Symbol(prototype, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 2, 11)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + + p1: string; +>p1 : Symbol(p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) +} +interface C2 { +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + + (): C2; +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + + prototype: C2; +>prototype : Symbol(prototype, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 7, 11)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + + p2: number; +>p2 : Symbol(p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18)) +} +interface D1 extends C1 { +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + + prototype: D1; +>prototype : Symbol(prototype, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 11, 25)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) + + p3: number; +>p3 : Symbol(p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18)) +} +var str: string; +>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3)) + +var num: number; +>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3)) + +var strOrNum: string | number; +>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 3)) + + +function isC1(x: any): x is C1 { +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 30)) +>x : Symbol(x, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 20, 14)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + + return true; +} + +function isC2(x: any): x is C2 { +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 22, 1)) +>x : Symbol(x, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 24, 14)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + + return true; +} + +function isD1(x: any): x is D1 { +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1)) +>x : Symbol(x, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 28, 14)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) + + return true; +} + +var c1: C1; +>c1 : Symbol(c1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 32, 3)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + +var c2: C2; +>c2 : Symbol(c2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 33, 3)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + +var d1: D1; +>d1 : Symbol(d1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 34, 3)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) + +var c1Orc2: C1 | C2; +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3)) +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 30)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) + +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3)) +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 22, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>c1Orc2.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18)) + +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) + +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>c1Orc2.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18)) + +var c2Ord1: C2 | D1; +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) + +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3)) +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 22, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>c2Ord1.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18)) + +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>c2Ord1.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18)) + +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>c2Ord1.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) + +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 +>r2 : Symbol(r2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 45, 3)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 30)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) + diff --git a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types new file mode 100644 index 00000000000..3a659d71163 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types @@ -0,0 +1,188 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts === + +interface C1 { +>C1 : C1 + + (): C1; +>C1 : C1 + + prototype: C1; +>prototype : C1 +>C1 : C1 + + p1: string; +>p1 : string +} +interface C2 { +>C2 : C2 + + (): C2; +>C2 : C2 + + prototype: C2; +>prototype : C2 +>C2 : C2 + + p2: number; +>p2 : number +} +interface D1 extends C1 { +>D1 : D1 +>C1 : C1 + + prototype: D1; +>prototype : D1 +>D1 : D1 + + p3: number; +>p3 : number +} +var str: string; +>str : string + +var num: number; +>num : number + +var strOrNum: string | number; +>strOrNum : string | number + + +function isC1(x: any): x is C1 { +>isC1 : (x: any) => boolean +>x : any +>x : any +>C1 : C1 + + return true; +>true : boolean +} + +function isC2(x: any): x is C2 { +>isC2 : (x: any) => boolean +>x : any +>x : any +>C2 : C2 + + return true; +>true : boolean +} + +function isD1(x: any): x is D1 { +>isD1 : (x: any) => boolean +>x : any +>x : any +>D1 : D1 + + return true; +>true : boolean +} + +var c1: C1; +>c1 : C1 +>C1 : C1 + +var c2: C2; +>c2 : C2 +>C2 : C2 + +var d1: D1; +>d1 : D1 +>D1 : D1 + +var c1Orc2: C1 | C2; +>c1Orc2 : C1 | C2 +>C1 : C1 +>C2 : C2 + +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +>str = isC1(c1Orc2) && c1Orc2.p1 : string +>str : string +>isC1(c1Orc2) && c1Orc2.p1 : string +>isC1(c1Orc2) : boolean +>isC1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p1 : string +>c1Orc2 : C1 +>p1 : string + +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +>num = isC2(c1Orc2) && c1Orc2.p2 : number +>num : number +>isC2(c1Orc2) && c1Orc2.p2 : number +>isC2(c1Orc2) : boolean +>isC2 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p2 : number +>c1Orc2 : C2 +>p2 : number + +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +>str = isD1(c1Orc2) && c1Orc2.p1 : string +>str : string +>isD1(c1Orc2) && c1Orc2.p1 : string +>isD1(c1Orc2) : boolean +>isD1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p1 : string +>c1Orc2 : D1 +>p1 : string + +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +>num = isD1(c1Orc2) && c1Orc2.p3 : number +>num : number +>isD1(c1Orc2) && c1Orc2.p3 : number +>isD1(c1Orc2) : boolean +>isD1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p3 : number +>c1Orc2 : D1 +>p3 : number + +var c2Ord1: C2 | D1; +>c2Ord1 : C2 | D1 +>C2 : C2 +>D1 : D1 + +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +>num = isC2(c2Ord1) && c2Ord1.p2 : number +>num : number +>isC2(c2Ord1) && c2Ord1.p2 : number +>isC2(c2Ord1) : boolean +>isC2 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p2 : number +>c2Ord1 : C2 +>p2 : number + +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +>num = isD1(c2Ord1) && c2Ord1.p3 : number +>num : number +>isD1(c2Ord1) && c2Ord1.p3 : number +>isD1(c2Ord1) : boolean +>isD1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p3 : number +>c2Ord1 : D1 +>p3 : number + +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +>str = isD1(c2Ord1) && c2Ord1.p1 : string +>str : string +>isD1(c2Ord1) && c2Ord1.p1 : string +>isD1(c2Ord1) : boolean +>isD1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p1 : string +>c2Ord1 : D1 +>p1 : string + +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 +>r2 : C2 | D1 +>C2 : C2 +>D1 : D1 +>isC1(c2Ord1) && c2Ord1 : D1 +>isC1(c2Ord1) : boolean +>isC1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1 : D1 + diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts new file mode 100644 index 00000000000..93cfd90ceb5 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts @@ -0,0 +1,56 @@ + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +declare function isA(p1: any): p1 is A; +declare function isB(p1: any): p1 is B; +declare function isC(p1: any): p1 is C; + +declare function retC(): C; + +var a: A; +var b: B; + +// Basic. +if (isC(a)) { + a.propC; +} + +// Sub type. +var subType: C; +if(isA(subType)) { + subType.propC; +} + +// Union type. +var union: A | B; +if(isA(union)) { + union.propA; +} + +// The parameter index and argument index for the type guard target is matching. +// The type predicate type is assignable to the parameter type. +declare function isC_multipleParams(p1, p2): p1 is C; +if (isC_multipleParams(a, 0)) { + a.propC; +} + +// Evaluations are asssignable to boolean. +declare function acceptingBoolean(a: boolean); +acceptingBoolean(isA(a)); + +// Type predicates with different parameter name. +declare function acceptingTypeGuardFunction(p1: (item) => item is A); +acceptingTypeGuardFunction(isA); + +let union2: C | B; +let union3: boolean | B = isA(union2) || union2; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts new file mode 100644 index 00000000000..28a512aca6d --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts @@ -0,0 +1,92 @@ + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +function hasANonBooleanReturnStatement(x): x is A { + return ''; +} + +function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { + return true; +} + +function hasMissingIsKeyword(): x { + return true; +} + +function hasMissingTypeInTypeGuardType(x): x is { + return true; +} + +function hasNonMatchingParameter(y): x is A { + return true; +} + +function hasNonMatchingParameterType1(x: A): x is B { + return true; +} + +function hasNonMatchingParameterType2(x: string): x is number { + return true; +} + +function hasNonMathcingGenericType(a: string): a is T[] { + return true; +} + +let a: A; +let b: B; + +declare function isB(p1): p1 is B; +declare function isC(p1): p1 is C; +declare function funA(p1: any, p2: any): p1 is B; +declare function hasNoTypeGuard(x); + +// Passed argument is not the same as the one being guarded. +if (isB(b)) { + a.propB; +} + +// Parameter index and argument index for the type guard target is not matching. +if (funA(0, a)) { + a.propB; // Error +} + +// No type guard in if statement +if (hasNoTypeGuard(a)) { + a.propB; +} + +// Type predicate type is not assignable +declare function acceptingDifferentSignatureTypeGuardFunction(p1: (p1) => p1 is B); +acceptingDifferentSignatureTypeGuardFunction(isC); + +// Boolean not assignable to type guard +var assign1: (p1, p2) => p1 is A; +assign1 = function(p1, p2): boolean { + return true; +}; + +// Must have matching parameter index +var assign2: (p1, p2) => p1 is A; +assign2 = function(p1, p2): p2 is A { + return true; +}; + +// No matching signature +var assign3: (p1, p2) => p1 is A; +assign3 = function(p1, p2, p3): p1 is A { + return true; +}; + +// Type guard paramater referring to a binding pattern +declare function destructureParameter({ p1, p2, p3 }): p1 is A; diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts new file mode 100644 index 00000000000..d0e108b5735 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts @@ -0,0 +1,33 @@ + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +declare function isB(p1): p1 is B; +declare function isC(p1): p1 is C; +declare function retC(x): C; + +declare function funA(p1: (p1) => T): T; +declare function funB(p1: (p1) => T, p2: any): p2 is T; +declare function funC(p1: (p1) => p1 is T): T; +declare function funD(p1: (p1) => p1 is T, p2: any): p2 is T; +declare function funE(p1: (p1) => p1 is T, p2: U): T; + +let a: A; +let test1: boolean = funA(isB); +if (funB(retC, a)) { + a.propC; +} +let test2: B = funC(isB); +if (funD(isC, a)) { + a.propC; +} +let test3: B = funE(isB, 1); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts new file mode 100644 index 00000000000..9f5ca611ee9 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts @@ -0,0 +1,37 @@ + +class C1 { + p1: string; +} +class C2 { + p2: number; +} +class D1 extends C1 { + p3: number; +} +var str: string; +var num: number; +var strOrNum: string | number; + +function isC1(x: any): x is C1 { + return true; +} + +function isC2(x: any): x is C2 { + return true; +} + +function isD1(x: any): x is D1 { + return true; +} + +var c1Orc2: C1 | C2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 + +var c2Ord1: C2 | D1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts new file mode 100644 index 00000000000..a199aeb1e68 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts @@ -0,0 +1,46 @@ + +interface C1 { + (): C1; + prototype: C1; + p1: string; +} +interface C2 { + (): C2; + prototype: C2; + p2: number; +} +interface D1 extends C1 { + prototype: D1; + p3: number; +} +var str: string; +var num: number; +var strOrNum: string | number; + + +function isC1(x: any): x is C1 { + return true; +} + +function isC2(x: any): x is C2 { + return true; +} + +function isD1(x: any): x is D1 { + return true; +} + +var c1: C1; +var c2: C2; +var d1: D1; +var c1Orc2: C1 | C2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 + +var c2Ord1: C2 | D1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 \ No newline at end of file From b7d1df68fb21703e529a2600bf42ad0ce3f6b9be Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Tue, 2 Jun 2015 23:25:21 +0800 Subject: [PATCH 122/194] Adds type guard methods --- src/compiler/checker.ts | 48 ++++-- .../diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 + src/compiler/parser.ts | 42 ++++-- .../reference/typeGuardMethods.errors.txt | 73 +++++++++ tests/baselines/reference/typeGuardMethods.js | 141 ++++++++++++++++++ .../typeGuards/typeGuardMethods.ts | 64 ++++++++ 7 files changed, 350 insertions(+), 23 deletions(-) create mode 100644 tests/baselines/reference/typeGuardMethods.errors.txt create mode 100644 tests/baselines/reference/typeGuardMethods.js create mode 100644 tests/cases/conformance/expressions/typeGuards/typeGuardMethods.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a09a2736aac..5a33748fb0b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5646,6 +5646,24 @@ module ts { return type; } + function shouldNarrowTypeByTypePredicate(signature: Signature, expr: CallExpression): boolean { + if (!signature.typePredicate) { + return false; + } + if (expr.arguments && + expr.arguments[signature.typePredicate.parameterIndex] && + getSymbolAtLocation(expr.arguments[signature.typePredicate.parameterIndex]) === symbol) { + + return true; + } + if (expr.expression.kind === SyntaxKind.PropertyAccessExpression && + getSymbolAtLocation((expr.expression).expression) === symbol) { + + return true; + } + return false; + } + function narrowTypeByTypePredicate(type: Type, expr: CallExpression, assumeTrue: boolean): Type { if (type.flags & TypeFlags.Any) { return type; @@ -5657,16 +5675,12 @@ module ts { } return type; } - if (signature.typePredicate) { - if (expr.arguments && expr.arguments[signature.typePredicate.parameterIndex]) { - if (getSymbolAtLocation(expr.arguments[signature.typePredicate.parameterIndex]) === symbol) { - if (isTypeSubtypeOf(signature.typePredicate.type, type)) { - return signature.typePredicate.type; - } - if (type.flags & TypeFlags.Union) { - return getUnionType(filter((type).types, t => isTypeSubtypeOf(t, signature.typePredicate.type))); - } - } + if (shouldNarrowTypeByTypePredicate(signature, expr)) { + if (isTypeSubtypeOf(signature.typePredicate.type, type)) { + return signature.typePredicate.type; + } + if (type.flags & TypeFlags.Union) { + return getUnionType(filter((type).types, t => isTypeSubtypeOf(t, signature.typePredicate.type))); } } return type; @@ -8622,8 +8636,7 @@ module ts { links.typeFromTypePredicate = getTypeFromTypeNode(node.typePredicate.type); } if (links.typePredicateParameterIndex >= 0) { - checkTypeAssignableTo( - links.typeFromTypePredicate, + checkTypeAssignableTo(links.typeFromTypePredicate, getTypeAtLocation(node.parameters[links.typePredicateParameterIndex]), node.typePredicate.type); } @@ -8632,6 +8645,17 @@ module ts { Diagnostics.Cannot_find_parameter_0, node.typePredicate.parameterName.text); } + else { + let typeOfClass = getTypeAtLocation(node.parent); + if (!isTypeSubtypeOf(links.typeFromTypePredicate, typeOfClass) && + !isTypeSubtypeOf(typeOfClass, links.typeFromTypePredicate)) { + + error(node.typePredicate, + Diagnostics.Type_0_and_type_1_are_disjoint_types, + typeToString(links.typeFromTypePredicate), + typeToString(typeOfClass)); + } + } } if (produceDiagnostics) { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 5a87f67ddd3..aba138b9a1b 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -184,6 +184,7 @@ module ts { Cannot_find_parameter_0: { code: 1226, category: DiagnosticCategory.Error, key: "Cannot find parameter '{0}'." }, Type_guard_annotation_0_is_not_assignable_to_1: { code: 1227, category: DiagnosticCategory.Error, key: "Type-guard annotation '{0}' is not assignable to '{1}'." }, Parameter_index_from_0_does_not_match_the_parameter_index_from_1: { code: 1228, category: DiagnosticCategory.Error, key: "Parameter index from '{0}' does not match the parameter index from '{1}'." }, + Type_0_and_type_1_are_disjoint_types: { code: 1229, category: DiagnosticCategory.Error, key: "Type '{0}' and type '{1}' are disjoint types." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0053b071438..a94839fba7d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -723,6 +723,10 @@ "category": "Error", "code": 1228 }, + "Type '{0}' and type '{1}' are disjoint types.": { + "category": "Error", + "code": 1229 + }, "Duplicate identifier '{0}'.": { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ac4517a0b79..0f84ec20383 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2014,6 +2014,34 @@ module ts { return parseInitializer(/*inParameter*/ true); } + function parseTypePredicate(signature: SignatureDeclaration) { + let node = createNode(SyntaxKind.TypePredicate); + if (token !== SyntaxKind.ThisKeyword) { + node.pos = signature.type.pos; + node.parameterName = (signature.type).typeName; + signature.type = undefined; + } + else { + // Swallow `this` + nextToken(); + } + + // Swallow `is` + nextToken(); + + node.type = parseType(); + signature.typePredicate = finishNode(node); + } + + function parseTypePredicateOrReturnType(signature: SignatureDeclaration) { + if (token === SyntaxKind.ThisKeyword) { + parseTypePredicate(signature); + } + else { + signature.type = parseType(); + } + } + function fillSignature( returnToken: SyntaxKind, yieldAndGeneratorParameterContext: boolean, @@ -2025,21 +2053,13 @@ module ts { if (returnTokenRequired) { parseExpected(returnToken); - signature.type = parseType(); + parseTypePredicateOrReturnType(signature); } else if (parseOptional(returnToken)) { - signature.type = parseType(); + parseTypePredicateOrReturnType(signature); } if (token === SyntaxKind.IsKeyword) { - let node = createNode(SyntaxKind.TypePredicate); - node.pos = signature.type.pos; - node.parameterName = (signature.type).typeName; - - nextToken(); - - node.type = parseType(); - signature.type = undefined; - signature.typePredicate = finishNode(node); + parseTypePredicate(signature); } } diff --git a/tests/baselines/reference/typeGuardMethods.errors.txt b/tests/baselines/reference/typeGuardMethods.errors.txt new file mode 100644 index 00000000000..246f84ccc09 --- /dev/null +++ b/tests/baselines/reference/typeGuardMethods.errors.txt @@ -0,0 +1,73 @@ +tests/cases/conformance/expressions/typeGuards/typeGuardMethods.ts(14,12): error TS1229: Type 'A' and type 'B' are disjoint types. +tests/cases/conformance/expressions/typeGuards/typeGuardMethods.ts(17,12): error TS1229: Type 'C' and type 'B' are disjoint types. + + +==== tests/cases/conformance/expressions/typeGuards/typeGuardMethods.ts (2 errors) ==== + + class A { + propA: number; + isA(): this is A { + return true; + } + isC(): this is C { + return false; + } + } + + class B { + propB: number; + isA(): this is A { + ~~~~~~~~~ +!!! error TS1229: Type 'A' and type 'B' are disjoint types. + return false; + } + isC(): this is C { + ~~~~~~~~~ +!!! error TS1229: Type 'C' and type 'B' are disjoint types. + return false; + } + } + + class C extends A { + propC: number; + isA(): this is A { + return false; + } + isC(): this is C { + return true; + } + } + + class D extends C { + isA(): this is A { + return false; + } + isString(x: any): x is string { // with parameter declaration + return true; + } + } + + var a: A; + + // Basic. + if (a.isC()) { + a.propC; + } + + // Sub type. + var subType: C; + if(subType.isA()) { + subType.propC; + } + + // Union type. + var union: A | B; + if(union.isA()) { + union.propA; + } + + var b: any; + var d = new D; + if(d.isString(b)) { + b.length; + } \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardMethods.js b/tests/baselines/reference/typeGuardMethods.js new file mode 100644 index 00000000000..dcc7eca43c9 --- /dev/null +++ b/tests/baselines/reference/typeGuardMethods.js @@ -0,0 +1,141 @@ +//// [typeGuardMethods.ts] + +class A { + propA: number; + isA(): this is A { + return true; + } + isC(): this is C { + return false; + } +} + +class B { + propB: number; + isA(): this is A { + return false; + } + isC(): this is C { + return false; + } +} + +class C extends A { + propC: number; + isA(): this is A { + return false; + } + isC(): this is C { + return true; + } +} + +class D extends C { + isA(): this is A { + return false; + } + isString(x: any): x is string { // with parameter declaration + return true; + } +} + +var a: A; + +// Basic. +if (a.isC()) { + a.propC; +} + +// Sub type. +var subType: C; +if(subType.isA()) { + subType.propC; +} + +// Union type. +var union: A | B; +if(union.isA()) { + union.propA; +} + +var b: any; +var d = new D; +if(d.isString(b)) { + b.length; +} + +//// [typeGuardMethods.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var A = (function () { + function A() { + } + A.prototype.isA = function () { + return true; + }; + A.prototype.isC = function () { + return false; + }; + return A; +})(); +var B = (function () { + function B() { + } + B.prototype.isA = function () { + return false; + }; + B.prototype.isC = function () { + return false; + }; + return B; +})(); +var C = (function (_super) { + __extends(C, _super); + function C() { + _super.apply(this, arguments); + } + C.prototype.isA = function () { + return false; + }; + C.prototype.isC = function () { + return true; + }; + return C; +})(A); +var D = (function (_super) { + __extends(D, _super); + function D() { + _super.apply(this, arguments); + } + D.prototype.isA = function () { + return false; + }; + D.prototype.isString = function (x) { + return true; + }; + return D; +})(C); +var a; +// Basic. +if (a.isC()) { + a.propC; +} +// Sub type. +var subType; +if (subType.isA()) { + subType.propC; +} +// Union type. +var union; +if (union.isA()) { + union.propA; +} +var b; +var d = new D; +if (d.isString(b)) { + b.length; +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardMethods.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardMethods.ts new file mode 100644 index 00000000000..80ae65a7ddb --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardMethods.ts @@ -0,0 +1,64 @@ + +class A { + propA: number; + isA(): this is A { + return true; + } + isC(): this is C { + return false; + } +} + +class B { + propB: number; + isA(): this is A { + return false; + } + isC(): this is C { + return false; + } +} + +class C extends A { + propC: number; + isA(): this is A { + return false; + } + isC(): this is C { + return true; + } +} + +class D extends C { + isA(): this is A { + return false; + } + isString(x: any): x is string { // with parameter declaration + return true; + } +} + +var a: A; + +// Basic. +if (a.isC()) { + a.propC; +} + +// Sub type. +var subType: C; +if(subType.isA()) { + subType.propC; +} + +// Union type. +var union: A | B; +if(union.isA()) { + union.propA; +} + +var b: any; +var d = new D; +if(d.isString(b)) { + b.length; +} \ No newline at end of file From b0542342c38749367530d7b6d400b7824795286c Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Wed, 3 Jun 2015 15:29:06 +0800 Subject: [PATCH 123/194] Addresses PR feedback --- src/compiler/checker.ts | 100 ++++++++++-------- .../diagnosticInformationMap.generated.ts | 4 +- src/compiler/diagnosticMessages.json | 4 +- .../typeGuardFunctionErrors.errors.txt | 16 +-- 4 files changed, 66 insertions(+), 58 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5a33748fb0b..80477ea1841 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3231,7 +3231,10 @@ module ts { let returnType: Type; let typePredicate: TypePredicate; - if (declaration.typePredicate) { + if (classType) { + returnType = classType; + } + else if (declaration.typePredicate) { returnType = booleanType; let typePredicateNode = declaration.typePredicate; let links = getNodeLinks(typePredicateNode); @@ -3242,14 +3245,11 @@ module ts { links.typeFromTypePredicate = getTypeFromTypeNode(declaration.typePredicate.type); } typePredicate = { - parameterName: typePredicateNode.parameterName ? typePredicateNode.parameterName.text : undefined, - parameterIndex: typePredicateNode.parameterName ? links.typePredicateParameterIndex : undefined, - type: links.typeFromTypePredicate + parameterName: typePredicateNode.parameterName ? typePredicateNode.parameterName.text : undefined, + parameterIndex: typePredicateNode.parameterName ? links.typePredicateParameterIndex : undefined, + type: links.typeFromTypePredicate }; } - else if (classType) { - returnType = classType; - } else if (declaration.type) { returnType = getTypeFromTypeNode(declaration.type); } @@ -3976,17 +3976,22 @@ module ts { function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature { let freshTypeParameters: TypeParameter[]; + let freshTypePredicate: TypePredicate; if (signature.typeParameters && !eraseTypeParameters) { freshTypeParameters = instantiateList(signature.typeParameters, mapper, instantiateTypeParameter); mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper); } if (signature.typePredicate) { - signature.typePredicate.type = instantiateType(signature.typePredicate.type, mapper); + freshTypePredicate = { + parameterName: signature.typePredicate.parameterName, + parameterIndex: signature.typePredicate.parameterIndex, + type: instantiateType(signature.typePredicate.type, mapper) + } } let result = createSignature(signature.declaration, freshTypeParameters, instantiateList(signature.parameters, mapper, instantiateSymbol), signature.resolvedReturnType ? instantiateType(signature.resolvedReturnType, mapper) : undefined, - signature.typePredicate, + freshTypePredicate, signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals); result.target = signature; result.mapper = mapper; @@ -4656,33 +4661,33 @@ module ts { } if (source.typePredicate && target.typePredicate) { - if (source.typePredicate.parameterIndex !== target.typePredicate.parameterIndex || - source.typePredicate.type.symbol !== target.typePredicate.type.symbol) { - + let hasDifferentParamaterIndex = source.typePredicate.parameterIndex !== target.typePredicate.parameterIndex; + let hasDifferentTypes = !isTypeIdenticalTo(source.typePredicate.type, target.typePredicate.type); + if (hasDifferentParamaterIndex || hasDifferentTypes) { if (reportErrors) { let sourceParamText = source.typePredicate.parameterName; let targetParamText = target.typePredicate.parameterName; let sourceTypeText = typeToString(source.typePredicate.type); let targetTypeText = typeToString(target.typePredicate.type); - if (source.typePredicate.parameterIndex !== target.typePredicate.parameterIndex) { - reportError(Diagnostics.Parameter_index_from_0_does_not_match_the_parameter_index_from_1, + if (hasDifferentParamaterIndex) { + reportError(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourceParamText, targetParamText); } - if (source.typePredicate.type.symbol !== target.typePredicate.type.symbol) { + if (hasDifferentTypes) { reportError(Diagnostics.Type_0_is_not_assignable_to_type_1, sourceTypeText, targetTypeText); } - reportError(Diagnostics.Type_guard_annotation_0_is_not_assignable_to_1, + reportError(Diagnostics.Type_predicate_0_is_not_assignable_to_1, `${sourceParamText} is ${sourceTypeText}`, `${targetParamText} is ${targetTypeText}`); } - return Ternary.False; } + return Ternary.True; } else if (!source.typePredicate && target.typePredicate) { if (reportErrors) { @@ -5223,12 +5228,15 @@ module ts { function inferFromSignature(source: Signature, target: Signature) { forEachMatchingParameterType(source, target, inferFromTypes); - if (source.typePredicate && - target.typePredicate && - target.typePredicate.parameterIndex === source.typePredicate.parameterIndex) { - - inferFromTypes(source.typePredicate.type, target.typePredicate.type); - return; + if (source.typePredicate && target.typePredicate) { + if (target.typePredicate.parameterIndex === source.typePredicate.parameterIndex) { + // Return types from type predicates are treated as booleans. In order to infer types + // from type predicates we would need infer from the type from type predicates. Since + // we can't infer any type information from the return types. We can just add a return + // statement after the below infer statement. + inferFromTypes(source.typePredicate.type, target.typePredicate.type); + return; + } } inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); } @@ -5633,19 +5641,24 @@ module ts { } if (targetType) { - // Narrow to the target type if it's a subtype of the current type - if (isTypeSubtypeOf(targetType, type)) { - return targetType; - } - // If the current type is a union type, remove all constituents that aren't subtypes of the target. - if (type.flags & TypeFlags.Union) { - return getUnionType(filter((type).types, t => isTypeSubtypeOf(t, targetType))); - } + return getOptionalNarrowedType(type, targetType); } return type; } + function getOptionalNarrowedType(originalType: Type, narrowedTypeCandidate: Type) { + // Narrow to the target type if it's a subtype of the current type + if (isTypeSubtypeOf(narrowedTypeCandidate, originalType)) { + return narrowedTypeCandidate; + } + // If the current type is a union type, remove all constituents that aren't subtypes of the target. + if (originalType.flags & TypeFlags.Union) { + return getUnionType(filter((originalType).types, t => isTypeSubtypeOf(t, narrowedTypeCandidate))); + } + return originalType; + } + function shouldNarrowTypeByTypePredicate(signature: Signature, expr: CallExpression): boolean { if (!signature.typePredicate) { return false; @@ -5670,18 +5683,16 @@ module ts { } let signature = getResolvedSignature(expr); if (!assumeTrue) { - if (type.flags & TypeFlags.Union && signature.typePredicate) { + if (type.flags & TypeFlags.Union && + signature.typePredicate && + getSymbolAtLocation(expr.arguments[signature.typePredicate.parameterIndex]) === symbol) { + return getUnionType(filter((type).types, t => !isTypeSubtypeOf(t, signature.typePredicate.type))); } return type; } if (shouldNarrowTypeByTypePredicate(signature, expr)) { - if (isTypeSubtypeOf(signature.typePredicate.type, type)) { - return signature.typePredicate.type; - } - if (type.flags & TypeFlags.Union) { - return getUnionType(filter((type).types, t => isTypeSubtypeOf(t, signature.typePredicate.type))); - } + return getOptionalNarrowedType(type, signature.typePredicate.type); } return type; } @@ -8640,7 +8651,7 @@ module ts { getTypeAtLocation(node.parameters[links.typePredicateParameterIndex]), node.typePredicate.type); } - else if(node.typePredicate.parameterName) { + else if (node.typePredicate.parameterName) { error(node.typePredicate.parameterName, Diagnostics.Cannot_find_parameter_0, node.typePredicate.parameterName.text); @@ -10217,6 +10228,9 @@ module ts { if (node.expression) { let func = getContainingFunction(node); if (func) { + let signature = getSignatureFromDeclaration(func); + let exprType = checkExpressionCached(node.expression); + if (func.asteriskToken) { // A generator does not need its return expressions checked against its return type. // Instead, the yield expressions are checked against the element type. @@ -10225,13 +10239,7 @@ module ts { return; } - let signature = getSignatureFromDeclaration(func); - let exprType = checkExpressionCached(node.expression); - if (signature.typePredicate && exprType !== booleanType) { - error(node.expression, Diagnostics.A_type_guard_function_can_only_return_a_boolean); - } let returnType = getReturnTypeOfSignature(signature); - if (func.kind === SyntaxKind.SetAccessor) { error(node.expression, Diagnostics.Setters_cannot_return_a_value); } @@ -10240,7 +10248,7 @@ module ts { error(node.expression, Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } - else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) { + else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func) || signature.typePredicate) { checkTypeAssignableTo(exprType, returnType, node.expression, /*headMessage*/ undefined); } } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index aba138b9a1b..46c1cd37b3f 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -182,8 +182,8 @@ module ts { A_non_type_guard_function_is_not_assignable_to_a_type_guard_function: { code: 1224, category: DiagnosticCategory.Error, key: "A non-type guard function is not assignable to a type guard function." }, A_type_guard_function_can_only_return_a_boolean: { code: 1225, category: DiagnosticCategory.Error, key: "A type-guard function can only return a boolean." }, Cannot_find_parameter_0: { code: 1226, category: DiagnosticCategory.Error, key: "Cannot find parameter '{0}'." }, - Type_guard_annotation_0_is_not_assignable_to_1: { code: 1227, category: DiagnosticCategory.Error, key: "Type-guard annotation '{0}' is not assignable to '{1}'." }, - Parameter_index_from_0_does_not_match_the_parameter_index_from_1: { code: 1228, category: DiagnosticCategory.Error, key: "Parameter index from '{0}' does not match the parameter index from '{1}'." }, + Type_predicate_0_is_not_assignable_to_1: { code: 1227, category: DiagnosticCategory.Error, key: "Type predicate '{0}' is not assignable to '{1}'." }, + Parameter_0_is_not_in_the_same_position_as_parameter_1: { code: 1228, category: DiagnosticCategory.Error, key: "Parameter '{0}' is not in the same position as parameter '{1}'." }, Type_0_and_type_1_are_disjoint_types: { code: 1229, category: DiagnosticCategory.Error, key: "Type '{0}' and type '{1}' are disjoint types." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index a94839fba7d..ebcba6386ff 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -715,11 +715,11 @@ "category": "Error", "code": 1226 }, - "Type-guard annotation '{0}' is not assignable to '{1}'.": { + "Type predicate '{0}' is not assignable to '{1}'.": { "category": "Error", "code": 1227 }, - "Parameter index from '{0}' does not match the parameter index from '{1}'.": { + "Parameter '{0}' is not in the same position as parameter '{1}'.": { "category": "Error", "code": 1228 }, diff --git a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt index 8b5ed551dff..001fe8a14ae 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt +++ b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(15,12): error TS1225: A type-guard function can only return a boolean. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(15,12): error TS2322: Type 'string' is not assignable to type 'boolean'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,55): error TS2304: Cannot find name 'x'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,57): error TS1144: '{' or ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(18,57): error TS2304: Cannot find name 'is'. @@ -17,13 +17,13 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(56,7): tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(61,7): error TS2339: Property 'propB' does not exist on type 'A'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(66,7): error TS2339: Property 'propB' does not exist on type 'A'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(71,46): error TS2345: Argument of type '(p1: any) => boolean' is not assignable to parameter of type '(p1: any) => boolean'. - Type-guard annotation 'p1 is C' is not assignable to 'p1 is B'. + Type predicate 'p1 is C' is not assignable to 'p1 is B'. Type 'C' is not assignable to type 'B'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(75,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. A non-type guard function is not assignable to a type guard function. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(81,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. - Type-guard annotation 'p2 is A' is not assignable to 'p1 is A'. - Parameter index from 'p2' does not match the parameter index from 'p1'. + Type predicate 'p2 is A' is not assignable to 'p1 is A'. + Parameter 'p2' is not in the same position as parameter 'p1'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(87,1): error TS2322: Type '(p1: any, p2: any, p3: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(92,56): error TS1226: Cannot find parameter 'p1'. @@ -45,7 +45,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(92,56) function hasANonBooleanReturnStatement(x): x is A { return ''; ~~ -!!! error TS1225: A type-guard function can only return a boolean. +!!! error TS2322: Type 'string' is not assignable to type 'boolean'. } function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { @@ -137,7 +137,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(92,56) acceptingDifferentSignatureTypeGuardFunction(isC); ~~~ !!! error TS2345: Argument of type '(p1: any) => boolean' is not assignable to parameter of type '(p1: any) => boolean'. -!!! error TS2345: Type-guard annotation 'p1 is C' is not assignable to 'p1 is B'. +!!! error TS2345: Type predicate 'p1 is C' is not assignable to 'p1 is B'. !!! error TS2345: Type 'C' is not assignable to type 'B'. // Boolean not assignable to type guard @@ -154,8 +154,8 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(92,56) assign2 = function(p1, p2): p2 is A { ~~~~~~~ !!! error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. -!!! error TS2322: Type-guard annotation 'p2 is A' is not assignable to 'p1 is A'. -!!! error TS2322: Parameter index from 'p2' does not match the parameter index from 'p1'. +!!! error TS2322: Type predicate 'p2 is A' is not assignable to 'p1 is A'. +!!! error TS2322: Parameter 'p2' is not in the same position as parameter 'p1'. return true; }; From 3aa0839d1ba9a510dccd8ea7cf65501aae18dd43 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Wed, 3 Jun 2015 17:11:11 +0800 Subject: [PATCH 124/194] Fixes rebase issues --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 80477ea1841..c75ba19df2f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3267,7 +3267,7 @@ module ts { } links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, typePredicate, - minArgumentCount, hasRestParameters(declaration), hasStringLiterals); + minArgumentCount, hasRestParameter(declaration), hasStringLiterals); } return links.resolvedSignature; } From e6ced33c1389633de8a335183f6057476f1f2e7c Mon Sep 17 00:00:00 2001 From: jbondc Date: Wed, 3 Jun 2015 11:56:30 -0400 Subject: [PATCH 125/194] Make index types optional in ResolvedType --- src/compiler/types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0fcf0e1f67a..296e75c4b76 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1588,7 +1588,7 @@ module ts { /* @internal */ ContainsUndefinedOrNull = 0x00040000, // Type is or contains Undefined or Null type /* @internal */ - ContainsObjectLiteral = 0x00080000, // Type is or contains object literal type + ContainsObjectLiteral = 0x00080000, // Type is or contains object literal type ESSymbol = 0x00100000, // Type of symbol primitive introduced in ES6 /* @internal */ @@ -1674,8 +1674,8 @@ module ts { properties: Symbol[]; // Properties callSignatures: Signature[]; // Call signatures of type constructSignatures: Signature[]; // Construct signatures of type - stringIndexType: Type; // String index type - numberIndexType: Type; // Numeric index type + stringIndexType?: Type; // String index type + numberIndexType?: Type; // Numeric index type } // Just a place to cache element types of iterables and iterators From 86d9398a929de9c5816e664a271ff392687107d2 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 1 Jun 2015 16:08:58 -0700 Subject: [PATCH 126/194] clean hostCache to avoid extending lifetime of script snapshots --- src/services/services.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/services/services.ts b/src/services/services.ts index 58155f2a691..6a497c87307 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2487,6 +2487,10 @@ module ts { } } + // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point. + // It needs to be cleared to allow all collected snapshots to be released + hostCache = undefined; + program = newProgram; // Make sure all the nodes in the program are both bound, and have their parent @@ -2495,6 +2499,7 @@ module ts { return; function getOrCreateSourceFile(fileName: string): SourceFile { + Debug.assert(hostCache !== undefined); // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. From 3cac56af1ab7bb7c51a192a4f8ff8d4e9dbc06e6 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 3 Jun 2015 12:05:12 -0700 Subject: [PATCH 127/194] Fixed case for the 'declare' keyword. --- src/compiler/parser.ts | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4a46e375f87..72cd3bb620d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1818,7 +1818,7 @@ module ts { if (matchesPattern) { // Report that we need an identifier. However, report it right after the dot, // and not on the next token. This is because the next token might actually - // be an identifier and the error woudl be quite confusing. + // be an identifier and the error would be quite confusing. return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentToken*/ true, Diagnostics.Identifier_expected); } } @@ -3981,19 +3981,31 @@ module ts { return parseDebuggerStatement(); case SyntaxKind.AtToken: return parseDeclaration(); - case SyntaxKind.ConstKeyword: case SyntaxKind.DeclareKeyword: + if (lookAhead(isFollowedByIdentifierOrKeywordOnSameLine) && getDeclarationFlags() & flags) { + return parseDeclaration(); + } + break; + case SyntaxKind.ModuleKeyword: + if (lookAhead(isFollowedByIdentifierOrStringOnSameLine) && getDeclarationFlags() & flags) { + return parseDeclaration(); + } + break; + case SyntaxKind.NamespaceKeyword: + case SyntaxKind.TypeKeyword: + if (lookAhead(isFollowedByIdentifierOnSameLine) && getDeclarationFlags() & flags) { + return parseDeclaration(); + } + break; + case SyntaxKind.ConstKeyword: case SyntaxKind.EnumKeyword: case SyntaxKind.ExportKeyword: case SyntaxKind.ImportKeyword: case SyntaxKind.InterfaceKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: case SyntaxKind.PrivateKeyword: case SyntaxKind.ProtectedKeyword: case SyntaxKind.PublicKeyword: case SyntaxKind.StaticKeyword: - case SyntaxKind.TypeKeyword: if (getDeclarationFlags() & flags) { return parseDeclaration(); } @@ -4044,6 +4056,21 @@ module ts { } } + function isFollowedByIdentifierOrKeywordOnSameLine() { + nextToken(); + return !scanner.hasPrecedingLineBreak() && isIdentifierOrKeyword(); + } + + function isFollowedByIdentifierOrStringOnSameLine() { + nextToken(); + return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === SyntaxKind.StringLiteral); + } + + function isFollowedByIdentifierOnSameLine() { + nextToken(); + return !scanner.hasPrecedingLineBreak() && isIdentifier(); + } + function parseFunctionBlockOrSemicolon(isGenerator: boolean, diagnosticMessage?: DiagnosticMessage): Block { if (token !== SyntaxKind.OpenBraceToken && canParseSemicolon()) { parseSemicolon(); From 3cd480ddb6e5aae35d7504de9de5fb8ee4ea8b1d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 3 Jun 2015 12:05:53 -0700 Subject: [PATCH 128/194] Accepted baselines. --- ...reventsParsingAsAmbientExternalModule01.js | 4 ++++ ...tsParsingAsAmbientExternalModule01.symbols | 4 ++++ ...entsParsingAsAmbientExternalModule01.types | 6 +++++ ...arsingAsAmbientExternalModule02.errors.txt | 16 -------------- ...reventsParsingAsAmbientExternalModule02.js | 7 ++++++ ...tsParsingAsAmbientExternalModule02.symbols | 20 +++++++++++++++++ ...entsParsingAsAmbientExternalModule02.types | 22 +++++++++++++++++++ .../asiPreventsParsingAsNamespace01.js | 3 +++ .../asiPreventsParsingAsNamespace01.symbols | 6 +++-- .../asiPreventsParsingAsNamespace01.types | 2 ++ .../asiPreventsParsingAsNamespace02.js | 3 +++ .../asiPreventsParsingAsNamespace02.symbols | 6 +++-- .../asiPreventsParsingAsNamespace02.types | 2 ++ .../asiPreventsParsingAsNamespace03.js | 6 +++++ .../asiPreventsParsingAsNamespace03.symbols | 4 +++- .../asiPreventsParsingAsNamespace03.types | 6 +++-- ...asiPreventsParsingAsNamespace04.errors.txt | 9 -------- .../asiPreventsParsingAsNamespace04.js | 2 +- .../asiPreventsParsingAsNamespace04.symbols | 8 +++++++ .../asiPreventsParsingAsNamespace04.types | 11 ++++++++++ .../asiPreventsParsingAsNamespace05.js | 14 ++++++++++++ .../asiPreventsParsingAsNamespace05.symbols | 20 +++++++++++++---- .../asiPreventsParsingAsNamespace05.types | 19 +++++++++++++--- .../asiPreventsParsingAsTypeAlias01.js | 2 ++ .../asiPreventsParsingAsTypeAlias01.symbols | 7 ++++-- .../asiPreventsParsingAsTypeAlias01.types | 6 ++++- .../asiPreventsParsingAsTypeAlias02.js | 5 +++++ .../asiPreventsParsingAsTypeAlias02.symbols | 5 ++++- .../asiPreventsParsingAsTypeAlias02.types | 8 +++++-- .../reservedNamesInAliases.errors.txt | 13 ++++++----- .../reference/reservedNamesInAliases.js | 2 ++ .../reference/reservedWords2.errors.txt | 10 ++++----- tests/baselines/reference/reservedWords2.js | 1 + 33 files changed, 203 insertions(+), 56 deletions(-) delete mode 100644 tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.errors.txt create mode 100644 tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.symbols create mode 100644 tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.types delete mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace04.errors.txt create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace04.symbols create mode 100644 tests/baselines/reference/asiPreventsParsingAsNamespace04.types diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.js b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.js index efd82f27d1f..caf90acae5f 100644 --- a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.js +++ b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.js @@ -11,3 +11,7 @@ module // this is the identifier 'module' //// [asiPreventsParsingAsAmbientExternalModule01.js] var declare; var module; +declare; // this is the identifier 'declare' +module; // this is the identifier 'module' +"my external module"; // this is just a string +{ } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.symbols b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.symbols index 87eb8daf7e2..c35432b7ece 100644 --- a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.symbols +++ b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.symbols @@ -7,6 +7,10 @@ var module: string; >module : Symbol(module, Decl(asiPreventsParsingAsAmbientExternalModule01.ts, 2, 3)) declare // this is the identifier 'declare' +>declare : Symbol(declare, Decl(asiPreventsParsingAsAmbientExternalModule01.ts, 1, 3)) + module // this is the identifier 'module' +>module : Symbol(module, Decl(asiPreventsParsingAsAmbientExternalModule01.ts, 2, 3)) + "my external module" // this is just a string { } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.types b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.types index 94a2cc8d6a1..3e6aade9a21 100644 --- a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.types +++ b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule01.types @@ -7,6 +7,12 @@ var module: string; >module : string declare // this is the identifier 'declare' +>declare : number + module // this is the identifier 'module' +>module : string + "my external module" // this is just a string +>"my external module" : string + { } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.errors.txt b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.errors.txt deleted file mode 100644 index 3064b137a19..00000000000 --- a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.errors.txt +++ /dev/null @@ -1,16 +0,0 @@ -tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule02.ts(8,5): error TS2435: Ambient modules cannot be nested in other modules. - - -==== tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule02.ts (1 errors) ==== - - var declare: number; - var module: string; - - module container { - declare // this is the identifier 'declare' - module // this is the identifier 'module' - "my external module" // this is just a string - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2435: Ambient modules cannot be nested in other modules. - { } // this is a block body - } \ No newline at end of file diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.js b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.js index 444b4b392c9..20e2693ba7f 100644 --- a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.js +++ b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.js @@ -13,3 +13,10 @@ module container { //// [asiPreventsParsingAsAmbientExternalModule02.js] var declare; var module; +var container; +(function (container) { + declare; // this is the identifier 'declare' + module; // this is the identifier 'module' + "my external module"; // this is just a string + { } // this is a block body +})(container || (container = {})); diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.symbols b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.symbols new file mode 100644 index 00000000000..ed97f39fc11 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.symbols @@ -0,0 +1,20 @@ +=== tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule02.ts === + +var declare: number; +>declare : Symbol(declare, Decl(asiPreventsParsingAsAmbientExternalModule02.ts, 1, 3)) + +var module: string; +>module : Symbol(module, Decl(asiPreventsParsingAsAmbientExternalModule02.ts, 2, 3)) + +module container { +>container : Symbol(container, Decl(asiPreventsParsingAsAmbientExternalModule02.ts, 2, 19)) + + declare // this is the identifier 'declare' +>declare : Symbol(declare, Decl(asiPreventsParsingAsAmbientExternalModule02.ts, 1, 3)) + + module // this is the identifier 'module' +>module : Symbol(module, Decl(asiPreventsParsingAsAmbientExternalModule02.ts, 2, 3)) + + "my external module" // this is just a string + { } // this is a block body +} diff --git a/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.types b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.types new file mode 100644 index 00000000000..67671853993 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsAmbientExternalModule02.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/externalModules/asiPreventsParsingAsAmbientExternalModule02.ts === + +var declare: number; +>declare : number + +var module: string; +>module : string + +module container { +>container : typeof container + + declare // this is the identifier 'declare' +>declare : number + + module // this is the identifier 'module' +>module : string + + "my external module" // this is just a string +>"my external module" : string + + { } // this is a block body +} diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace01.js b/tests/baselines/reference/asiPreventsParsingAsNamespace01.js index eed9769da69..282d9dd1c7c 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace01.js +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace01.js @@ -10,3 +10,6 @@ n // this is the identifier 'n' //// [asiPreventsParsingAsNamespace01.js] var namespace; var n; +namespace; // this is the identifier 'namespace' +n; // this is the identifier 'n' +{ } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace01.symbols b/tests/baselines/reference/asiPreventsParsingAsNamespace01.symbols index a2494904bed..b196d733352 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace01.symbols +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace01.symbols @@ -4,10 +4,12 @@ var namespace: number; >namespace : Symbol(namespace, Decl(asiPreventsParsingAsNamespace01.ts, 1, 3)) var n: string; ->n : Symbol(n, Decl(asiPreventsParsingAsNamespace01.ts, 2, 3), Decl(asiPreventsParsingAsNamespace01.ts, 2, 14)) +>n : Symbol(n, Decl(asiPreventsParsingAsNamespace01.ts, 2, 3)) namespace // this is the identifier 'namespace' +>namespace : Symbol(namespace, Decl(asiPreventsParsingAsNamespace01.ts, 1, 3)) + n // this is the identifier 'n' ->n : Symbol(n, Decl(asiPreventsParsingAsNamespace01.ts, 2, 3), Decl(asiPreventsParsingAsNamespace01.ts, 2, 14)) +>n : Symbol(n, Decl(asiPreventsParsingAsNamespace01.ts, 2, 3)) { } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace01.types b/tests/baselines/reference/asiPreventsParsingAsNamespace01.types index 87044c58066..417a96dbed4 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace01.types +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace01.types @@ -7,6 +7,8 @@ var n: string; >n : string namespace // this is the identifier 'namespace' +>namespace : number + n // this is the identifier 'n' >n : string diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace02.js b/tests/baselines/reference/asiPreventsParsingAsNamespace02.js index de2bdfa8a9e..514a026dc78 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace02.js +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace02.js @@ -10,3 +10,6 @@ m // this is the identifier 'm' //// [asiPreventsParsingAsNamespace02.js] var module; var m; +module; // this is the identifier 'namespace' +m; // this is the identifier 'm' +{ } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace02.symbols b/tests/baselines/reference/asiPreventsParsingAsNamespace02.symbols index 70024a8de62..a3bb37c73bc 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace02.symbols +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace02.symbols @@ -4,10 +4,12 @@ var module: number; >module : Symbol(module, Decl(asiPreventsParsingAsNamespace02.ts, 1, 3)) var m: string; ->m : Symbol(m, Decl(asiPreventsParsingAsNamespace02.ts, 2, 3), Decl(asiPreventsParsingAsNamespace02.ts, 2, 14)) +>m : Symbol(m, Decl(asiPreventsParsingAsNamespace02.ts, 2, 3)) module // this is the identifier 'namespace' +>module : Symbol(module, Decl(asiPreventsParsingAsNamespace02.ts, 1, 3)) + m // this is the identifier 'm' ->m : Symbol(m, Decl(asiPreventsParsingAsNamespace02.ts, 2, 3), Decl(asiPreventsParsingAsNamespace02.ts, 2, 14)) +>m : Symbol(m, Decl(asiPreventsParsingAsNamespace02.ts, 2, 3)) { } // this is a block body diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace02.types b/tests/baselines/reference/asiPreventsParsingAsNamespace02.types index 8f6dec87a00..e9e1433be7a 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace02.types +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace02.types @@ -7,6 +7,8 @@ var m: string; >m : string module // this is the identifier 'namespace' +>module : number + m // this is the identifier 'm' >m : string diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace03.js b/tests/baselines/reference/asiPreventsParsingAsNamespace03.js index 6d8b8970977..3c27694f5ce 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace03.js +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace03.js @@ -12,3 +12,9 @@ namespace container { //// [asiPreventsParsingAsNamespace03.js] var namespace; var n; +var container; +(function (container) { + namespace; // this is the identifier 'namespace' + n; // this is the identifier 'n' + { } // this is a block body +})(container || (container = {})); diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace03.symbols b/tests/baselines/reference/asiPreventsParsingAsNamespace03.symbols index 8dfa30c17a4..e77d012a1bf 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace03.symbols +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace03.symbols @@ -10,8 +10,10 @@ namespace container { >container : Symbol(container, Decl(asiPreventsParsingAsNamespace03.ts, 2, 14)) namespace // this is the identifier 'namespace' +>namespace : Symbol(namespace, Decl(asiPreventsParsingAsNamespace03.ts, 1, 3)) + n // this is the identifier 'n' ->n : Symbol(n, Decl(asiPreventsParsingAsNamespace03.ts, 4, 21)) +>n : Symbol(n, Decl(asiPreventsParsingAsNamespace03.ts, 2, 3)) { } // this is a block body } diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace03.types b/tests/baselines/reference/asiPreventsParsingAsNamespace03.types index 37423757159..f119a789e11 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace03.types +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace03.types @@ -7,11 +7,13 @@ var n: string; >n : string namespace container { ->container : any +>container : typeof container namespace // this is the identifier 'namespace' +>namespace : number + n // this is the identifier 'n' ->n : any +>n : string { } // this is a block body } diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace04.errors.txt b/tests/baselines/reference/asiPreventsParsingAsNamespace04.errors.txt deleted file mode 100644 index d0a6be446aa..00000000000 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace04.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace04.ts(3,8): error TS1003: Identifier expected. - - -==== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace04.ts (1 errors) ==== - - let module = 10; - module in {} - ~~ -!!! error TS1003: Identifier expected. \ No newline at end of file diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace04.js b/tests/baselines/reference/asiPreventsParsingAsNamespace04.js index bcd8975d46d..704c8893e76 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace04.js +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace04.js @@ -5,4 +5,4 @@ module in {} //// [asiPreventsParsingAsNamespace04.js] var module = 10; - in {}; +module in {}; diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace04.symbols b/tests/baselines/reference/asiPreventsParsingAsNamespace04.symbols new file mode 100644 index 00000000000..60d1f8fcc48 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace04.symbols @@ -0,0 +1,8 @@ +=== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace04.ts === + +let module = 10; +>module : Symbol(module, Decl(asiPreventsParsingAsNamespace04.ts, 1, 3)) + +module in {} +>module : Symbol(module, Decl(asiPreventsParsingAsNamespace04.ts, 1, 3)) + diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace04.types b/tests/baselines/reference/asiPreventsParsingAsNamespace04.types new file mode 100644 index 00000000000..3fa2a448cf9 --- /dev/null +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace04.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/internalModules/moduleDeclarations/asiPreventsParsingAsNamespace04.ts === + +let module = 10; +>module : number +>10 : number + +module in {} +>module in {} : boolean +>module : number +>{} : {} + diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace05.js b/tests/baselines/reference/asiPreventsParsingAsNamespace05.js index 0a525179d2d..35f557328c0 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace05.js +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace05.js @@ -1,6 +1,9 @@ //// [asiPreventsParsingAsNamespace05.ts] let namespace = 10; +namespace a.b { + export let c = 20; +} namespace a.b.c @@ -9,3 +12,14 @@ a.b.c //// [asiPreventsParsingAsNamespace05.js] var namespace = 10; +var a; +(function (a) { + var b; + (function (b) { + b.c = 20; + })(b = a.b || (a.b = {})); +})(a || (a = {})); +namespace; +a.b.c; +{ +} diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace05.symbols b/tests/baselines/reference/asiPreventsParsingAsNamespace05.symbols index 65125806b61..47f05862b0a 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace05.symbols +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace05.symbols @@ -3,10 +3,22 @@ let namespace = 10; >namespace : Symbol(namespace, Decl(asiPreventsParsingAsNamespace05.ts, 1, 3)) -namespace -a.b.c +namespace a.b { >a : Symbol(a, Decl(asiPreventsParsingAsNamespace05.ts, 1, 19)) ->b : Symbol(b, Decl(asiPreventsParsingAsNamespace05.ts, 4, 2)) ->c : Symbol(c, Decl(asiPreventsParsingAsNamespace05.ts, 4, 4)) +>b : Symbol(b, Decl(asiPreventsParsingAsNamespace05.ts, 2, 12)) + + export let c = 20; +>c : Symbol(c, Decl(asiPreventsParsingAsNamespace05.ts, 3, 14)) +} + +namespace +>namespace : Symbol(namespace, Decl(asiPreventsParsingAsNamespace05.ts, 1, 3)) + +a.b.c +>a.b.c : Symbol(a.b.c, Decl(asiPreventsParsingAsNamespace05.ts, 3, 14)) +>a.b : Symbol(a.b, Decl(asiPreventsParsingAsNamespace05.ts, 2, 12)) +>a : Symbol(a, Decl(asiPreventsParsingAsNamespace05.ts, 1, 19)) +>b : Symbol(a.b, Decl(asiPreventsParsingAsNamespace05.ts, 2, 12)) +>c : Symbol(a.b.c, Decl(asiPreventsParsingAsNamespace05.ts, 3, 14)) { } diff --git a/tests/baselines/reference/asiPreventsParsingAsNamespace05.types b/tests/baselines/reference/asiPreventsParsingAsNamespace05.types index f17ad1f2a1e..515147c1096 100644 --- a/tests/baselines/reference/asiPreventsParsingAsNamespace05.types +++ b/tests/baselines/reference/asiPreventsParsingAsNamespace05.types @@ -4,10 +4,23 @@ let namespace = 10; >namespace : number >10 : number +namespace a.b { +>a : typeof a +>b : typeof b + + export let c = 20; +>c : number +>20 : number +} + namespace +>namespace : number + a.b.c ->a : any ->b : any ->c : any +>a.b.c : number +>a.b : typeof a.b +>a : typeof a +>b : typeof a.b +>c : number { } diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.js b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.js index 33e3895fab4..b05988290cb 100644 --- a/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.js +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.js @@ -11,3 +11,5 @@ Foo = string; var type; var string; var Foo; +type; +Foo = string; diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.symbols b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.symbols index d11c9ff5c13..fa82d53ac70 100644 --- a/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.symbols +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.symbols @@ -7,9 +7,12 @@ var string; >string : Symbol(string, Decl(asiPreventsParsingAsTypeAlias01.ts, 2, 3)) var Foo; ->Foo : Symbol(Foo, Decl(asiPreventsParsingAsTypeAlias01.ts, 3, 3), Decl(asiPreventsParsingAsTypeAlias01.ts, 3, 8)) +>Foo : Symbol(Foo, Decl(asiPreventsParsingAsTypeAlias01.ts, 3, 3)) type +>type : Symbol(type, Decl(asiPreventsParsingAsTypeAlias01.ts, 1, 3)) + Foo = string; ->Foo : Symbol(Foo, Decl(asiPreventsParsingAsTypeAlias01.ts, 3, 3), Decl(asiPreventsParsingAsTypeAlias01.ts, 3, 8)) +>Foo : Symbol(Foo, Decl(asiPreventsParsingAsTypeAlias01.ts, 3, 3)) +>string : Symbol(string, Decl(asiPreventsParsingAsTypeAlias01.ts, 2, 3)) diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types index d112022afa4..7492a698e3a 100644 --- a/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias01.types @@ -10,6 +10,10 @@ var Foo; >Foo : any type +>type : any + Foo = string; ->Foo : string +>Foo = string : any +>Foo : any +>string : any diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.js b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.js index 4a8298b2bdf..eae9898c8d4 100644 --- a/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.js +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.js @@ -13,3 +13,8 @@ namespace container { var type; var string; var Foo; +var container; +(function (container) { + type; + Foo = string; +})(container || (container = {})); diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.symbols b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.symbols index 0da88560109..4b83dba4c5d 100644 --- a/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.symbols +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.symbols @@ -13,6 +13,9 @@ namespace container { >container : Symbol(container, Decl(asiPreventsParsingAsTypeAlias02.ts, 3, 8)) type +>type : Symbol(type, Decl(asiPreventsParsingAsTypeAlias02.ts, 1, 3)) + Foo = string; ->Foo : Symbol(Foo, Decl(asiPreventsParsingAsTypeAlias02.ts, 5, 21)) +>Foo : Symbol(Foo, Decl(asiPreventsParsingAsTypeAlias02.ts, 3, 3)) +>string : Symbol(string, Decl(asiPreventsParsingAsTypeAlias02.ts, 2, 3)) } diff --git a/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.types b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.types index 4af0721ec24..1e6c7a8caf1 100644 --- a/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.types +++ b/tests/baselines/reference/asiPreventsParsingAsTypeAlias02.types @@ -10,9 +10,13 @@ var Foo; >Foo : any namespace container { ->container : any +>container : typeof container type +>type : any + Foo = string; ->Foo : string +>Foo = string : any +>Foo : any +>string : any } diff --git a/tests/baselines/reference/reservedNamesInAliases.errors.txt b/tests/baselines/reference/reservedNamesInAliases.errors.txt index 277e06111c4..5c17158053e 100644 --- a/tests/baselines/reference/reservedNamesInAliases.errors.txt +++ b/tests/baselines/reference/reservedNamesInAliases.errors.txt @@ -2,12 +2,13 @@ tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(2,6): error tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(3,6): error TS2457: Type alias name cannot be 'number' tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(4,6): error TS2457: Type alias name cannot be 'boolean' tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(5,6): error TS2457: Type alias name cannot be 'string' -tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,6): error TS1003: Identifier expected. -tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,11): error TS1005: ';' expected. +tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,1): error TS2304: Cannot find name 'type'. +tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,6): error TS1005: ';' expected. +tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,11): error TS1109: Expression expected. tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,13): error TS2304: Cannot find name 'I'. -==== tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts (7 errors) ==== +==== tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts (8 errors) ==== interface I {} type any = I; ~~~ @@ -22,9 +23,11 @@ tests/cases/conformance/types/typeAliases/reservedNamesInAliases.ts(6,13): error ~~~~~~ !!! error TS2457: Type alias name cannot be 'string' type void = I; + ~~~~ +!!! error TS2304: Cannot find name 'type'. ~~~~ -!!! error TS1003: Identifier expected. - ~ !!! error TS1005: ';' expected. + ~ +!!! error TS1109: Expression expected. ~ !!! error TS2304: Cannot find name 'I'. \ No newline at end of file diff --git a/tests/baselines/reference/reservedNamesInAliases.js b/tests/baselines/reference/reservedNamesInAliases.js index 773cc3ca84a..4ebc3bdb95f 100644 --- a/tests/baselines/reference/reservedNamesInAliases.js +++ b/tests/baselines/reference/reservedNamesInAliases.js @@ -7,4 +7,6 @@ type string = I; type void = I; //// [reservedNamesInAliases.js] +type; +void ; I; diff --git a/tests/baselines/reference/reservedWords2.errors.txt b/tests/baselines/reference/reservedWords2.errors.txt index 471eef4710a..090b2d0d43e 100644 --- a/tests/baselines/reference/reservedWords2.errors.txt +++ b/tests/baselines/reference/reservedWords2.errors.txt @@ -13,8 +13,8 @@ tests/cases/compiler/reservedWords2.ts(4,12): error TS1109: Expression expected. tests/cases/compiler/reservedWords2.ts(5,9): error TS2300: Duplicate identifier '(Missing)'. tests/cases/compiler/reservedWords2.ts(5,10): error TS1003: Identifier expected. tests/cases/compiler/reservedWords2.ts(5,18): error TS1005: '=>' expected. -tests/cases/compiler/reservedWords2.ts(6,7): error TS2300: Duplicate identifier '(Missing)'. -tests/cases/compiler/reservedWords2.ts(6,8): error TS1003: Identifier expected. +tests/cases/compiler/reservedWords2.ts(6,1): error TS2304: Cannot find name 'module'. +tests/cases/compiler/reservedWords2.ts(6,8): error TS1005: ';' expected. tests/cases/compiler/reservedWords2.ts(7,11): error TS2300: Duplicate identifier '(Missing)'. tests/cases/compiler/reservedWords2.ts(7,11): error TS1005: ':' expected. tests/cases/compiler/reservedWords2.ts(7,19): error TS2300: Duplicate identifier '(Missing)'. @@ -68,10 +68,10 @@ tests/cases/compiler/reservedWords2.ts(10,6): error TS1003: Identifier expected. ~ !!! error TS1005: '=>' expected. module void {} - -!!! error TS2300: Duplicate identifier '(Missing)'. + ~~~~~~ +!!! error TS2304: Cannot find name 'module'. ~~~~ -!!! error TS1003: Identifier expected. +!!! error TS1005: ';' expected. var {while, return} = { while: 1, return: 2 }; !!! error TS2300: Duplicate identifier '(Missing)'. diff --git a/tests/baselines/reference/reservedWords2.js b/tests/baselines/reference/reservedWords2.js index 6d5a5f530c5..fb90a718ec3 100644 --- a/tests/baselines/reference/reservedWords2.js +++ b/tests/baselines/reference/reservedWords2.js @@ -23,6 +23,7 @@ var ; typeof ; 10; throw function () { }; +module; void {}; var _a = { while: 1, return: 2 }, = _a.while, = _a.return; var _b = { this: 1, switch: { continue: 2 } }, = _b.this, = _b.switch.continue; From 46da6678ad082b53de4698740fa751bba7c8c29a Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 2 Jun 2015 17:33:57 -0700 Subject: [PATCH 129/194] Return expressions always need to be type checked --- src/compiler/checker.ts | 4 ++++ ...ltiLinePropertyAccessAndArrowFunctionIndent1.errors.txt | 5 ++++- .../reference/typeCheckReturnExpression.errors.txt | 7 +++++++ tests/baselines/reference/typeCheckReturnExpression.js | 5 +++++ tests/cases/compiler/typeCheckReturnExpression.ts | 2 ++ 5 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/typeCheckReturnExpression.errors.txt create mode 100644 tests/baselines/reference/typeCheckReturnExpression.js create mode 100644 tests/cases/compiler/typeCheckReturnExpression.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ab5d8e4207f..aa3b69d9b34 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7454,6 +7454,10 @@ module ts { } if (node.body) { + if (!node.type) { + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } + if (node.body.kind === SyntaxKind.Block) { checkSourceElement(node.body); } diff --git a/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt b/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt index 14b7769d22f..abf11dc9dba 100644 --- a/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt +++ b/tests/baselines/reference/multiLinePropertyAccessAndArrowFunctionIndent1.errors.txt @@ -1,12 +1,15 @@ tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(1,1): error TS1108: A 'return' statement can only be used within a function body. +tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(1,18): error TS2304: Cannot find name 'role'. tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(2,18): error TS2304: Cannot find name 'Role'. tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts(4,26): error TS2503: Cannot find namespace 'ng'. -==== tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts (3 errors) ==== +==== tests/cases/compiler/multiLinePropertyAccessAndArrowFunctionIndent1.ts (4 errors) ==== return this.edit(role) ~~~~~~ !!! error TS1108: A 'return' statement can only be used within a function body. + ~~~~ +!!! error TS2304: Cannot find name 'role'. .then((role: Role) => ~~~~ !!! error TS2304: Cannot find name 'Role'. diff --git a/tests/baselines/reference/typeCheckReturnExpression.errors.txt b/tests/baselines/reference/typeCheckReturnExpression.errors.txt new file mode 100644 index 00000000000..c648c57799d --- /dev/null +++ b/tests/baselines/reference/typeCheckReturnExpression.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/typeCheckReturnExpression.ts(1,11): error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type. + + +==== tests/cases/compiler/typeCheckReturnExpression.ts (1 errors) ==== + var foo = () => undefined; + ~~~~~~~~~~~~~~~ +!!! error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type. \ No newline at end of file diff --git a/tests/baselines/reference/typeCheckReturnExpression.js b/tests/baselines/reference/typeCheckReturnExpression.js new file mode 100644 index 00000000000..ba71780b48d --- /dev/null +++ b/tests/baselines/reference/typeCheckReturnExpression.js @@ -0,0 +1,5 @@ +//// [typeCheckReturnExpression.ts] +var foo = () => undefined; + +//// [typeCheckReturnExpression.js] +var foo = function () { return undefined; }; diff --git a/tests/cases/compiler/typeCheckReturnExpression.ts b/tests/cases/compiler/typeCheckReturnExpression.ts new file mode 100644 index 00000000000..00f75912bd1 --- /dev/null +++ b/tests/cases/compiler/typeCheckReturnExpression.ts @@ -0,0 +1,2 @@ +//@noImplicitAny: true +var foo = () => undefined; \ No newline at end of file From 22cc3a7d848fa3adfbbeb58ec359dc5a201221c8 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 2 Jun 2015 17:54:08 -0700 Subject: [PATCH 130/194] Add hopefully helpful comment --- src/compiler/checker.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index aa3b69d9b34..8ee39ab18f3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7455,6 +7455,11 @@ module ts { if (node.body) { if (!node.type) { + // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors + // we need. An example is the noImplicitAny errors resulting from widening the return expression + // of a function. Because checking of function expression bodies is deferred, there was never an + // appropriate time to do this during the main walk of the file (see the comment at the top of + // checkFunctionExpressionBodies). So it must be done now. getReturnTypeOfSignature(getSignatureFromDeclaration(node)); } From 9394c5ca04231ec17626ea4867042dcfd61b0443 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 2 Jun 2015 18:06:05 -0700 Subject: [PATCH 131/194] Add test for object literal methods --- .../typeCheckReturnExpressionMethodBody.errors.txt | 7 +++++++ .../reference/typeCheckReturnExpressionMethodBody.js | 5 +++++ .../cases/compiler/typeCheckReturnExpressionMethodBody.ts | 2 ++ 3 files changed, 14 insertions(+) create mode 100644 tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt create mode 100644 tests/baselines/reference/typeCheckReturnExpressionMethodBody.js create mode 100644 tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts diff --git a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt b/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt new file mode 100644 index 00000000000..a32f6548c9f --- /dev/null +++ b/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts(1,13): error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. + + +==== tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts (1 errors) ==== + var foo = { bar() { return undefined } }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. \ No newline at end of file diff --git a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.js b/tests/baselines/reference/typeCheckReturnExpressionMethodBody.js new file mode 100644 index 00000000000..3050b05268f --- /dev/null +++ b/tests/baselines/reference/typeCheckReturnExpressionMethodBody.js @@ -0,0 +1,5 @@ +//// [typeCheckReturnExpressionMethodBody.ts] +var foo = { bar() { return undefined } }; + +//// [typeCheckReturnExpressionMethodBody.js] +var foo = { bar: function () { return undefined; } }; diff --git a/tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts b/tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts new file mode 100644 index 00000000000..316572466df --- /dev/null +++ b/tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts @@ -0,0 +1,2 @@ +//@noImplicitAny: true +var foo = { bar() { return undefined } }; \ No newline at end of file From 34a5514fef25125b56dfff49fb0357aee2d1bb90 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Tue, 2 Jun 2015 18:21:39 -0700 Subject: [PATCH 132/194] Rename new test --- .../reference/typeCheckObjectLiteralMethodBody.errors.txt | 7 +++++++ ...onMethodBody.js => typeCheckObjectLiteralMethodBody.js} | 4 ++-- .../typeCheckReturnExpressionMethodBody.errors.txt | 7 ------- ...onMethodBody.ts => typeCheckObjectLiteralMethodBody.ts} | 0 4 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/typeCheckObjectLiteralMethodBody.errors.txt rename tests/baselines/reference/{typeCheckReturnExpressionMethodBody.js => typeCheckObjectLiteralMethodBody.js} (50%) delete mode 100644 tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt rename tests/cases/compiler/{typeCheckReturnExpressionMethodBody.ts => typeCheckObjectLiteralMethodBody.ts} (100%) diff --git a/tests/baselines/reference/typeCheckObjectLiteralMethodBody.errors.txt b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.errors.txt new file mode 100644 index 00000000000..7db4c2506cc --- /dev/null +++ b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.errors.txt @@ -0,0 +1,7 @@ +tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts(1,13): error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. + + +==== tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts (1 errors) ==== + var foo = { bar() { return undefined } }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. \ No newline at end of file diff --git a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.js b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.js similarity index 50% rename from tests/baselines/reference/typeCheckReturnExpressionMethodBody.js rename to tests/baselines/reference/typeCheckObjectLiteralMethodBody.js index 3050b05268f..1339315e93c 100644 --- a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.js +++ b/tests/baselines/reference/typeCheckObjectLiteralMethodBody.js @@ -1,5 +1,5 @@ -//// [typeCheckReturnExpressionMethodBody.ts] +//// [typeCheckObjectLiteralMethodBody.ts] var foo = { bar() { return undefined } }; -//// [typeCheckReturnExpressionMethodBody.js] +//// [typeCheckObjectLiteralMethodBody.js] var foo = { bar: function () { return undefined; } }; diff --git a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt b/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt deleted file mode 100644 index a32f6548c9f..00000000000 --- a/tests/baselines/reference/typeCheckReturnExpressionMethodBody.errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts(1,13): error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. - - -==== tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts (1 errors) ==== - var foo = { bar() { return undefined } }; - ~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type. \ No newline at end of file diff --git a/tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts b/tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts similarity index 100% rename from tests/cases/compiler/typeCheckReturnExpressionMethodBody.ts rename to tests/cases/compiler/typeCheckObjectLiteralMethodBody.ts From 1bb46e3f332c41612b166fc12608b34f02809c92 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Wed, 3 Jun 2015 13:39:25 -0700 Subject: [PATCH 133/194] Update LKG after commit 34a5514fef25125b56dfff49fb0357aee2d1bb90 --- bin/tsc.js | 30 ++++++++++++++++++---- bin/tsserver.js | 39 +++++++++++++++++++++++------ bin/typescript.js | 52 +++++++++++++++++++++++++++++++++------ bin/typescriptServices.js | 52 +++++++++++++++++++++++++++++++++------ 4 files changed, 147 insertions(+), 26 deletions(-) diff --git a/bin/tsc.js b/bin/tsc.js index 01d312f2083..a6d28976046 100644 --- a/bin/tsc.js +++ b/bin/tsc.js @@ -4688,6 +4688,21 @@ var ts; return result; } ts.convertToBase64 = convertToBase64; + var carriageReturnLineFeed = "\r\n"; + var lineFeed = "\n"; + function getNewLineCharacter(options) { + if (options.newLine === 0) { + return carriageReturnLineFeed; + } + else if (options.newLine === 1) { + return lineFeed; + } + else if (ts.sys) { + return ts.sys.newLine; + } + return carriageReturnLineFeed; + } + ts.getNewLineCharacter = getNewLineCharacter; })(ts || (ts = {})); var ts; (function (ts) { @@ -14454,6 +14469,9 @@ var ts; checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } if (node.body) { + if (!node.type) { + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } if (node.body.kind === 180) { checkSourceElement(node.body); } @@ -25062,8 +25080,6 @@ var ts; ts.ioReadTime = 0; ts.ioWriteTime = 0; ts.version = "1.5.3"; - var carriageReturnLineFeed = "\r\n"; - var lineFeed = "\n"; function findConfigFile(searchPath) { var fileName = "tsconfig.json"; while (true) { @@ -25134,9 +25150,7 @@ var ts; } } } - var newLine = options.newLine === 0 ? carriageReturnLineFeed : - options.newLine === 1 ? lineFeed : - ts.sys.newLine; + var newLine = ts.getNewLineCharacter(options); return { getSourceFile: getSourceFile, getDefaultLibFileName: function (options) { return ts.combinePaths(ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath())), ts.getDefaultLibFileName(options)); }, @@ -25204,6 +25218,7 @@ var ts; getGlobalDiagnostics: getGlobalDiagnostics, getSemanticDiagnostics: getSemanticDiagnostics, getDeclarationDiagnostics: getDeclarationDiagnostics, + getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics, getTypeChecker: getTypeChecker, getDiagnosticsProducingTypeChecker: getDiagnosticsProducingTypeChecker, getCommonSourceDirectory: function () { return commonSourceDirectory; }, @@ -25284,6 +25299,11 @@ var ts; return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile); } } + function getCompilerOptionsDiagnostics() { + var allDiagnostics = []; + ts.addRange(allDiagnostics, diagnostics.getGlobalDiagnostics()); + return ts.sortAndDeduplicateDiagnostics(allDiagnostics); + } function getGlobalDiagnostics() { var typeChecker = getDiagnosticsProducingTypeChecker(); var allDiagnostics = []; diff --git a/bin/tsserver.js b/bin/tsserver.js index 6cdb8f9560c..194f0768196 100644 --- a/bin/tsserver.js +++ b/bin/tsserver.js @@ -4565,6 +4565,21 @@ var ts; return result; } ts.convertToBase64 = convertToBase64; + var carriageReturnLineFeed = "\r\n"; + var lineFeed = "\n"; + function getNewLineCharacter(options) { + if (options.newLine === 0) { + return carriageReturnLineFeed; + } + else if (options.newLine === 1) { + return lineFeed; + } + else if (ts.sys) { + return ts.sys.newLine; + } + return carriageReturnLineFeed; + } + ts.getNewLineCharacter = getNewLineCharacter; })(ts || (ts = {})); var ts; (function (ts) { @@ -14844,6 +14859,9 @@ var ts; checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } if (node.body) { + if (!node.type) { + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } if (node.body.kind === 180) { checkSourceElement(node.body); } @@ -25452,8 +25470,6 @@ var ts; ts.ioReadTime = 0; ts.ioWriteTime = 0; ts.version = "1.5.3"; - var carriageReturnLineFeed = "\r\n"; - var lineFeed = "\n"; function findConfigFile(searchPath) { var fileName = "tsconfig.json"; while (true) { @@ -25524,9 +25540,7 @@ var ts; } } } - var newLine = options.newLine === 0 ? carriageReturnLineFeed : - options.newLine === 1 ? lineFeed : - ts.sys.newLine; + var newLine = ts.getNewLineCharacter(options); return { getSourceFile: getSourceFile, getDefaultLibFileName: function (options) { return ts.combinePaths(ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath())), ts.getDefaultLibFileName(options)); }, @@ -25594,6 +25608,7 @@ var ts; getGlobalDiagnostics: getGlobalDiagnostics, getSemanticDiagnostics: getSemanticDiagnostics, getDeclarationDiagnostics: getDeclarationDiagnostics, + getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics, getTypeChecker: getTypeChecker, getDiagnosticsProducingTypeChecker: getDiagnosticsProducingTypeChecker, getCommonSourceDirectory: function () { return commonSourceDirectory; }, @@ -25674,6 +25689,11 @@ var ts; return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile); } } + function getCompilerOptionsDiagnostics() { + var allDiagnostics = []; + ts.addRange(allDiagnostics, diagnostics.getGlobalDiagnostics()); + return ts.sortAndDeduplicateDiagnostics(allDiagnostics); + } function getGlobalDiagnostics() { var typeChecker = getDiagnosticsProducingTypeChecker(); var allDiagnostics = []; @@ -31379,11 +31399,14 @@ var ts; var options = compilerOptions ? ts.clone(compilerOptions) : getDefaultCompilerOptions(); options.isolatedModules = true; options.allowNonTsExtensions = true; + options.noLib = true; + options.noResolve = true; var inputFileName = fileName || "module.ts"; var sourceFile = ts.createSourceFile(inputFileName, input, options.target); if (diagnostics && sourceFile.parseDiagnostics) { diagnostics.push.apply(diagnostics, sourceFile.parseDiagnostics); } + var newLine = ts.getNewLineCharacter(options); var outputText; var compilerHost = { getSourceFile: function (fileName, target) { return fileName === inputFileName ? sourceFile : undefined; }, @@ -31395,11 +31418,11 @@ var ts; useCaseSensitiveFileNames: function () { return false; }, getCanonicalFileName: function (fileName) { return fileName; }, getCurrentDirectory: function () { return ""; }, - getNewLine: function () { return (ts.sys && ts.sys.newLine) || "\r\n"; } + getNewLine: function () { return newLine; } }; var program = ts.createProgram([inputFileName], options, compilerHost); if (diagnostics) { - diagnostics.push.apply(diagnostics, program.getGlobalDiagnostics()); + diagnostics.push.apply(diagnostics, program.getCompilerOptionsDiagnostics()); } program.emit(); ts.Debug.assert(outputText !== undefined, "Output generation failed"); @@ -31914,10 +31937,12 @@ var ts; } } } + hostCache = undefined; program = newProgram; program.getTypeChecker(); return; function getOrCreateSourceFile(fileName) { + ts.Debug.assert(hostCache !== undefined); var hostFileInformation = hostCache.getOrCreateEntry(fileName); if (!hostFileInformation) { return undefined; diff --git a/bin/typescript.js b/bin/typescript.js index dbede84a76e..dac610e2504 100644 --- a/bin/typescript.js +++ b/bin/typescript.js @@ -5793,6 +5793,21 @@ var ts; return result; } ts.convertToBase64 = convertToBase64; + var carriageReturnLineFeed = "\r\n"; + var lineFeed = "\n"; + function getNewLineCharacter(options) { + if (options.newLine === 0 /* CarriageReturnLineFeed */) { + return carriageReturnLineFeed; + } + else if (options.newLine === 1 /* LineFeed */) { + return lineFeed; + } + else if (ts.sys) { + return ts.sys.newLine; + } + return carriageReturnLineFeed; + } + ts.getNewLineCharacter = getNewLineCharacter; })(ts || (ts = {})); var ts; (function (ts) { @@ -17596,6 +17611,14 @@ var ts; checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } if (node.body) { + if (!node.type) { + // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors + // we need. An example is the noImplicitAny errors resulting from widening the return expression + // of a function. Because checking of function expression bodies is deferred, there was never an + // appropriate time to do this during the main walk of the file (see the comment at the top of + // checkFunctionExpressionBodies). So it must be done now. + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } if (node.body.kind === 180 /* Block */) { checkSourceElement(node.body); } @@ -29658,8 +29681,6 @@ var ts; /* @internal */ ts.ioWriteTime = 0; /** The version of the TypeScript compiler release */ ts.version = "1.5.3"; - var carriageReturnLineFeed = "\r\n"; - var lineFeed = "\n"; function findConfigFile(searchPath) { var fileName = "tsconfig.json"; while (true) { @@ -29733,9 +29754,7 @@ var ts; } } } - var newLine = options.newLine === 0 /* CarriageReturnLineFeed */ ? carriageReturnLineFeed : - options.newLine === 1 /* LineFeed */ ? lineFeed : - ts.sys.newLine; + var newLine = ts.getNewLineCharacter(options); return { getSourceFile: getSourceFile, getDefaultLibFileName: function (options) { return ts.combinePaths(ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath())), ts.getDefaultLibFileName(options)); }, @@ -29803,6 +29822,7 @@ var ts; getGlobalDiagnostics: getGlobalDiagnostics, getSemanticDiagnostics: getSemanticDiagnostics, getDeclarationDiagnostics: getDeclarationDiagnostics, + getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics, getTypeChecker: getTypeChecker, getDiagnosticsProducingTypeChecker: getDiagnosticsProducingTypeChecker, getCommonSourceDirectory: function () { return commonSourceDirectory; }, @@ -29894,6 +29914,11 @@ var ts; return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile); } } + function getCompilerOptionsDiagnostics() { + var allDiagnostics = []; + ts.addRange(allDiagnostics, diagnostics.getGlobalDiagnostics()); + return ts.sortAndDeduplicateDiagnostics(allDiagnostics); + } function getGlobalDiagnostics() { var typeChecker = getDiagnosticsProducingTypeChecker(); var allDiagnostics = []; @@ -36695,12 +36720,20 @@ var ts; * Extra compiler options that will unconditionally be used bu this function are: * - isolatedModules = true * - allowNonTsExtensions = true + * - noLib = true + * - noResolve = true */ function transpile(input, compilerOptions, fileName, diagnostics) { var options = compilerOptions ? ts.clone(compilerOptions) : getDefaultCompilerOptions(); options.isolatedModules = true; // Filename can be non-ts file. options.allowNonTsExtensions = true; + // We are not returning a sourceFile for lib file when asked by the program, + // so pass --noLib to avoid reporting a file not found error. + options.noLib = true; + // We are not doing a full typecheck, we are not resolving the whole context, + // so pass --noResolve to avoid reporting missing file errors. + options.noResolve = true; // Parse var inputFileName = fileName || "module.ts"; var sourceFile = ts.createSourceFile(inputFileName, input, options.target); @@ -36708,6 +36741,7 @@ var ts; if (diagnostics && sourceFile.parseDiagnostics) { diagnostics.push.apply(diagnostics, sourceFile.parseDiagnostics); } + var newLine = ts.getNewLineCharacter(options); // Output var outputText; // Create a compilerHost object to allow the compiler to read and write files @@ -36721,11 +36755,11 @@ var ts; useCaseSensitiveFileNames: function () { return false; }, getCanonicalFileName: function (fileName) { return fileName; }, getCurrentDirectory: function () { return ""; }, - getNewLine: function () { return (ts.sys && ts.sys.newLine) || "\r\n"; } + getNewLine: function () { return newLine; } }; var program = ts.createProgram([inputFileName], options, compilerHost); if (diagnostics) { - diagnostics.push.apply(diagnostics, program.getGlobalDiagnostics()); + diagnostics.push.apply(diagnostics, program.getCompilerOptionsDiagnostics()); } // Emit program.emit(); @@ -37328,12 +37362,16 @@ var ts; } } } + // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point. + // It needs to be cleared to allow all collected snapshots to be released + hostCache = undefined; program = newProgram; // Make sure all the nodes in the program are both bound, and have their parent // pointers set property. program.getTypeChecker(); return; function getOrCreateSourceFile(fileName) { + ts.Debug.assert(hostCache !== undefined); // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. diff --git a/bin/typescriptServices.js b/bin/typescriptServices.js index dbede84a76e..dac610e2504 100644 --- a/bin/typescriptServices.js +++ b/bin/typescriptServices.js @@ -5793,6 +5793,21 @@ var ts; return result; } ts.convertToBase64 = convertToBase64; + var carriageReturnLineFeed = "\r\n"; + var lineFeed = "\n"; + function getNewLineCharacter(options) { + if (options.newLine === 0 /* CarriageReturnLineFeed */) { + return carriageReturnLineFeed; + } + else if (options.newLine === 1 /* LineFeed */) { + return lineFeed; + } + else if (ts.sys) { + return ts.sys.newLine; + } + return carriageReturnLineFeed; + } + ts.getNewLineCharacter = getNewLineCharacter; })(ts || (ts = {})); var ts; (function (ts) { @@ -17596,6 +17611,14 @@ var ts; checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); } if (node.body) { + if (!node.type) { + // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors + // we need. An example is the noImplicitAny errors resulting from widening the return expression + // of a function. Because checking of function expression bodies is deferred, there was never an + // appropriate time to do this during the main walk of the file (see the comment at the top of + // checkFunctionExpressionBodies). So it must be done now. + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } if (node.body.kind === 180 /* Block */) { checkSourceElement(node.body); } @@ -29658,8 +29681,6 @@ var ts; /* @internal */ ts.ioWriteTime = 0; /** The version of the TypeScript compiler release */ ts.version = "1.5.3"; - var carriageReturnLineFeed = "\r\n"; - var lineFeed = "\n"; function findConfigFile(searchPath) { var fileName = "tsconfig.json"; while (true) { @@ -29733,9 +29754,7 @@ var ts; } } } - var newLine = options.newLine === 0 /* CarriageReturnLineFeed */ ? carriageReturnLineFeed : - options.newLine === 1 /* LineFeed */ ? lineFeed : - ts.sys.newLine; + var newLine = ts.getNewLineCharacter(options); return { getSourceFile: getSourceFile, getDefaultLibFileName: function (options) { return ts.combinePaths(ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath())), ts.getDefaultLibFileName(options)); }, @@ -29803,6 +29822,7 @@ var ts; getGlobalDiagnostics: getGlobalDiagnostics, getSemanticDiagnostics: getSemanticDiagnostics, getDeclarationDiagnostics: getDeclarationDiagnostics, + getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics, getTypeChecker: getTypeChecker, getDiagnosticsProducingTypeChecker: getDiagnosticsProducingTypeChecker, getCommonSourceDirectory: function () { return commonSourceDirectory; }, @@ -29894,6 +29914,11 @@ var ts; return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile); } } + function getCompilerOptionsDiagnostics() { + var allDiagnostics = []; + ts.addRange(allDiagnostics, diagnostics.getGlobalDiagnostics()); + return ts.sortAndDeduplicateDiagnostics(allDiagnostics); + } function getGlobalDiagnostics() { var typeChecker = getDiagnosticsProducingTypeChecker(); var allDiagnostics = []; @@ -36695,12 +36720,20 @@ var ts; * Extra compiler options that will unconditionally be used bu this function are: * - isolatedModules = true * - allowNonTsExtensions = true + * - noLib = true + * - noResolve = true */ function transpile(input, compilerOptions, fileName, diagnostics) { var options = compilerOptions ? ts.clone(compilerOptions) : getDefaultCompilerOptions(); options.isolatedModules = true; // Filename can be non-ts file. options.allowNonTsExtensions = true; + // We are not returning a sourceFile for lib file when asked by the program, + // so pass --noLib to avoid reporting a file not found error. + options.noLib = true; + // We are not doing a full typecheck, we are not resolving the whole context, + // so pass --noResolve to avoid reporting missing file errors. + options.noResolve = true; // Parse var inputFileName = fileName || "module.ts"; var sourceFile = ts.createSourceFile(inputFileName, input, options.target); @@ -36708,6 +36741,7 @@ var ts; if (diagnostics && sourceFile.parseDiagnostics) { diagnostics.push.apply(diagnostics, sourceFile.parseDiagnostics); } + var newLine = ts.getNewLineCharacter(options); // Output var outputText; // Create a compilerHost object to allow the compiler to read and write files @@ -36721,11 +36755,11 @@ var ts; useCaseSensitiveFileNames: function () { return false; }, getCanonicalFileName: function (fileName) { return fileName; }, getCurrentDirectory: function () { return ""; }, - getNewLine: function () { return (ts.sys && ts.sys.newLine) || "\r\n"; } + getNewLine: function () { return newLine; } }; var program = ts.createProgram([inputFileName], options, compilerHost); if (diagnostics) { - diagnostics.push.apply(diagnostics, program.getGlobalDiagnostics()); + diagnostics.push.apply(diagnostics, program.getCompilerOptionsDiagnostics()); } // Emit program.emit(); @@ -37328,12 +37362,16 @@ var ts; } } } + // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point. + // It needs to be cleared to allow all collected snapshots to be released + hostCache = undefined; program = newProgram; // Make sure all the nodes in the program are both bound, and have their parent // pointers set property. program.getTypeChecker(); return; function getOrCreateSourceFile(fileName) { + ts.Debug.assert(hostCache !== undefined); // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. From c7b2fe016d06fd4c9da9b4b44a61ea1288fd5b07 Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Wed, 3 Jun 2015 13:40:36 -0700 Subject: [PATCH 134/194] Remove the DocumentEvent itself from createEvent overload. --- src/lib/dom.generated.d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index d9daefa1aeb..31bf794d8fd 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -12340,7 +12340,6 @@ interface DocumentEvent { createEvent(eventInterface:"CustomEvent"): CustomEvent; createEvent(eventInterface:"DeviceMotionEvent"): DeviceMotionEvent; createEvent(eventInterface:"DeviceOrientationEvent"): DeviceOrientationEvent; - createEvent(eventInterface:"DocumentEvent"): DocumentEvent; createEvent(eventInterface:"DragEvent"): DragEvent; createEvent(eventInterface:"ErrorEvent"): ErrorEvent; createEvent(eventInterface:"Event"): Event; From 3fe308d2a6b642704942cb4b1ee8fe8438d22e3f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 3 Jun 2015 13:46:13 -0700 Subject: [PATCH 135/194] Added an explanation for the lookahead. --- src/compiler/parser.ts | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 72cd3bb620d..914952d5169 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3973,7 +3973,7 @@ module ts { case SyntaxKind.ThrowKeyword: return parseThrowStatement(); case SyntaxKind.TryKeyword: - // Include the next two for error recovery. + // Include 'catch' and 'finally' for error recovery. case SyntaxKind.CatchKeyword: case SyntaxKind.FinallyKeyword: return parseTryStatement(); @@ -3981,6 +3981,33 @@ module ts { return parseDebuggerStatement(); case SyntaxKind.AtToken: return parseDeclaration(); + + case SyntaxKind.ConstKeyword: + case SyntaxKind.EnumKeyword: + case SyntaxKind.ExportKeyword: + case SyntaxKind.ImportKeyword: + case SyntaxKind.InterfaceKeyword: + case SyntaxKind.PrivateKeyword: + case SyntaxKind.ProtectedKeyword: + case SyntaxKind.PublicKeyword: + case SyntaxKind.StaticKeyword: + if (getDeclarationFlags() & flags) { + return parseDeclaration(); + } + break; + + // 'declare', 'module', 'namespace', and 'type' are all legal JavaScript identifiers when ASI + // takes effect. In such cases, we cannot parse out the "expected" declarations. For instance, while + // + // namespace n + // + // can be none other than the beginning of a namespace declaration, JavaScript sees + // + // namespace + // n + // + // as the identifier 'namespace' on one line followed by the identifier 'n' on another. + // We need to look one token ahead to see if it permissible to try parsing a declaration. case SyntaxKind.DeclareKeyword: if (lookAhead(isFollowedByIdentifierOrKeywordOnSameLine) && getDeclarationFlags() & flags) { return parseDeclaration(); @@ -3997,19 +4024,6 @@ module ts { return parseDeclaration(); } break; - case SyntaxKind.ConstKeyword: - case SyntaxKind.EnumKeyword: - case SyntaxKind.ExportKeyword: - case SyntaxKind.ImportKeyword: - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.PublicKeyword: - case SyntaxKind.StaticKeyword: - if (getDeclarationFlags() & flags) { - return parseDeclaration(); - } - break; } return parseExpressionOrLabeledStatement(); } From 269ae3ab995847d0e0db00d546486cfbfbf24ff7 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 3 Jun 2015 13:48:34 -0700 Subject: [PATCH 136/194] introduce FileMap to store mappings with filenames as keys --- src/compiler/core.ts | 32 +++++++++++++++++++++++ src/compiler/program.ts | 17 ++++++------ src/services/services.ts | 56 +++++++++++++++++++++------------------- src/services/shims.ts | 10 ++++++- 4 files changed, 80 insertions(+), 35 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 281bfa36ece..b798bd8771d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -15,6 +15,38 @@ module ts { True = -1 } + export class FileMap { + private files: Map = {}; + + constructor(private getCanonicalFileName: (fileName: string) => string) { + } + + public set(fileName: string, value: T) { + this.files[this.normalizeKey(fileName)] = value; + } + + public get(fileName: string) { + return this.files[this.normalizeKey(fileName)]; + } + + public contains(fileName: string) { + return hasProperty(this.files, this.normalizeKey(fileName)); + } + + public delete(fileName: string) { + let key = this.normalizeKey(fileName); + delete this.files[key]; + } + + public forEachValue(f: (value: T) => void) { + forEachValue(this.files, f); + } + + private normalizeKey(key: string) { + return this.getCanonicalFileName(normalizeSlashes(key)); + } + } + export const enum Comparison { LessThan = -1, EqualTo = 0, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 955e24fd1de..dd693b55907 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -149,7 +149,6 @@ module ts { export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost): Program { let program: Program; let files: SourceFile[] = []; - let filesByName: Map = {}; let diagnostics = createDiagnosticCollection(); let seenNoDefaultLib = options.noLib; let commonSourceDirectory: string; @@ -159,6 +158,8 @@ module ts { let start = new Date().getTime(); host = host || createCompilerHost(options); + let filesByName: FileMap = new FileMap(host.getCanonicalFileName); + forEach(rootNames, name => processRootFile(name, false)); if (!seenNoDefaultLib) { processRootFile(host.getDefaultLibFileName(options), true); @@ -238,8 +239,7 @@ module ts { } function getSourceFile(fileName: string) { - fileName = host.getCanonicalFileName(normalizeSlashes(fileName)); - return hasProperty(filesByName, fileName) ? filesByName[fileName] : undefined; + return filesByName.get(fileName); } function getDiagnosticsHelper(sourceFile: SourceFile, getDiagnostics: (sourceFile: SourceFile) => Diagnostic[]): Diagnostic[] { @@ -358,19 +358,19 @@ module ts { // Get source file from normalized fileName function findSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refStart?: number, refLength?: number): SourceFile { let canonicalName = host.getCanonicalFileName(normalizeSlashes(fileName)); - if (hasProperty(filesByName, canonicalName)) { + if (filesByName.contains(canonicalName)) { // We've already looked for this file, use cached result return getSourceFileFromCache(fileName, canonicalName, /*useAbsolutePath*/ false); } else { let normalizedAbsolutePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory()); let canonicalAbsolutePath = host.getCanonicalFileName(normalizedAbsolutePath); - if (hasProperty(filesByName, canonicalAbsolutePath)) { + if (filesByName.contains(canonicalAbsolutePath)) { return getSourceFileFromCache(normalizedAbsolutePath, canonicalAbsolutePath, /*useAbsolutePath*/ true); } // We haven't looked for this file, do so now and cache result - let file = filesByName[canonicalName] = host.getSourceFile(fileName, options.target, hostErrorMessage => { + let file = host.getSourceFile(fileName, options.target, hostErrorMessage => { if (refFile) { diagnostics.add(createFileDiagnostic(refFile, refStart, refLength, Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); @@ -379,11 +379,12 @@ module ts { diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); } }); + filesByName.set(canonicalName, file); if (file) { seenNoDefaultLib = seenNoDefaultLib || file.hasNoDefaultLib; // Set the source file for normalized absolute path - filesByName[canonicalAbsolutePath] = file; + filesByName.set(canonicalAbsolutePath, file); if (!options.noResolve) { let basePath = getDirectoryPath(fileName); @@ -402,7 +403,7 @@ module ts { } function getSourceFileFromCache(fileName: string, canonicalName: string, useAbsolutePath: boolean): SourceFile { - let file = filesByName[canonicalName]; + let file = filesByName.get(canonicalName); if (file && host.useCaseSensitiveFileNames()) { let sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory()) : file.fileName; if (canonicalName !== sourceFileName) { diff --git a/src/services/services.ts b/src/services/services.ts index 400bf754a00..908d9efbaca 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -960,6 +960,7 @@ module ts { log? (s: string): void; trace? (s: string): void; error? (s: string): void; + useCaseSensitiveFileNames? (): boolean; } // @@ -1632,12 +1633,12 @@ module ts { // at each language service public entry point, since we don't know when // set of scripts handled by the host changes. class HostCache { - private fileNameToEntry: Map; + private fileNameToEntry: FileMap; private _compilationSettings: CompilerOptions; - constructor(private host: LanguageServiceHost, private getCanonicalFileName: (fileName: string) => string) { + constructor(private host: LanguageServiceHost, getCanonicalFileName: (fileName: string) => string) { // script id => script index - this.fileNameToEntry = {}; + this.fileNameToEntry = new FileMap(getCanonicalFileName); // Initialize the list with the root file names let rootFileNames = host.getScriptFileNames(); @@ -1653,10 +1654,6 @@ module ts { return this._compilationSettings; } - private normalizeFileName(fileName: string): string { - return this.getCanonicalFileName(normalizeSlashes(fileName)); - } - private createEntry(fileName: string) { let entry: HostFileInformation; let scriptSnapshot = this.host.getScriptSnapshot(fileName); @@ -1668,15 +1665,16 @@ module ts { }; } - return this.fileNameToEntry[this.normalizeFileName(fileName)] = entry; + this.fileNameToEntry.set(fileName, entry); + return entry; } private getEntry(fileName: string): HostFileInformation { - return lookUp(this.fileNameToEntry, this.normalizeFileName(fileName)); + return this.fileNameToEntry.get(fileName); } private contains(fileName: string): boolean { - return hasProperty(this.fileNameToEntry, this.normalizeFileName(fileName)); + return this.fileNameToEntry.contains(fileName); } public getOrCreateEntry(fileName: string): HostFileInformation { @@ -1690,10 +1688,9 @@ module ts { public getRootFileNames(): string[] { let fileNames: string[] = []; - forEachKey(this.fileNameToEntry, key => { - let entry = this.getEntry(key); - if (entry) { - fileNames.push(entry.hostFileName); + this.fileNameToEntry.forEachValue(value => { + if (value) { + fileNames.push(value.hostFileName); } }); @@ -1873,20 +1870,28 @@ module ts { return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents:*/ true); } - export function createDocumentRegistry(): DocumentRegistry { + function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string { + return useCaseSensitivefileNames + ? ((fileName) => fileName) + : ((fileName) => fileName.toLowerCase()); + } + + + export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean): DocumentRegistry { // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have // for those settings. - let buckets: Map> = {}; + let buckets: Map> = {}; + let getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames || false); function getKeyFromCompilationSettings(settings: CompilerOptions): string { return "_" + settings.target; // + "|" + settings.propagateEnumConstantoString() } - function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): Map { + function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): FileMap { let key = getKeyFromCompilationSettings(settings); let bucket = lookUp(buckets, key); if (!bucket && createIfMissing) { - buckets[key] = bucket = {}; + buckets[key] = bucket = new FileMap(getCanonicalFileName); } return bucket; } @@ -1896,7 +1901,7 @@ module ts { let entries = lookUp(buckets, name); let sourceFiles: { name: string; refCount: number; references: string[]; }[] = []; for (let i in entries) { - let entry = entries[i]; + let entry = entries.get(i); sourceFiles.push({ name: i, refCount: entry.languageServiceRefCount, @@ -1928,18 +1933,19 @@ module ts { acquiring: boolean): SourceFile { let bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true); - let entry = lookUp(bucket, fileName); + let entry = bucket.get(fileName); if (!entry) { Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?"); // Have never seen this file with these settings. Create a new source file for it. let sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents:*/ false); - bucket[fileName] = entry = { + entry = { sourceFile: sourceFile, languageServiceRefCount: 0, owners: [] }; + bucket.set(fileName, entry); } else { // We have an entry for this file. However, it may be for a different version of @@ -1967,12 +1973,12 @@ module ts { let bucket = getBucketForCompilationSettings(compilationSettings, false); Debug.assert(bucket !== undefined); - let entry = lookUp(bucket, fileName); + let entry = bucket.get(fileName); entry.languageServiceRefCount--; Debug.assert(entry.languageServiceRefCount >= 0); if (entry.languageServiceRefCount === 0) { - delete bucket[fileName]; + bucket.delete(fileName); } } @@ -2400,9 +2406,7 @@ module ts { } } - function getCanonicalFileName(fileName: string) { - return useCaseSensitivefileNames ? fileName : fileName.toLowerCase(); - } + let getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames); function getValidSourceFile(fileName: string): SourceFile { fileName = normalizeSlashes(fileName); diff --git a/src/services/shims.ts b/src/services/shims.ts index d3f59737538..4dfab444cde 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -56,6 +56,7 @@ module ts { getDefaultLibFileName(options: string): string; getNewLine?(): string; getProjectVersion?(): string; + useCaseSensitiveFileNames?(): boolean; } /** Public interface of the the of a config service shim instance.*/ @@ -270,6 +271,10 @@ module ts { return this.shimHost.getProjectVersion(); } + public useCaseSensitiveFileNames(): boolean { + return this.shimHost.useCaseSensitiveFileNames && this.useCaseSensitiveFileNames(); + } + public getCompilationSettings(): CompilerOptions { var settingsJson = this.shimHost.getCompilationSettings(); if (settingsJson == null || settingsJson == "") { @@ -909,7 +914,7 @@ module ts { export class TypeScriptServicesFactory implements ShimFactory { private _shims: Shim[] = []; - private documentRegistry: DocumentRegistry = createDocumentRegistry(); + private documentRegistry: DocumentRegistry; /* * Returns script API version. @@ -920,6 +925,9 @@ module ts { public createLanguageServiceShim(host: LanguageServiceShimHost): LanguageServiceShim { try { + if (this.documentRegistry === undefined) { + this.documentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); + } var hostAdapter = new LanguageServiceShimHostAdapter(host); var languageService = createLanguageService(hostAdapter, this.documentRegistry); return new LanguageServiceShimObject(this, host, languageService); From 64a31e2e51e7911db411a6f22fa46896f23d7121 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 3 Jun 2015 13:51:53 -0700 Subject: [PATCH 137/194] Renamed functions, removed the duplicates found from renaming. --- src/compiler/parser.ts | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 914952d5169..b430a27e2b4 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2688,7 +2688,7 @@ module ts { function nextTokenIsIdentifierOnSameLine() { nextToken(); - return !scanner.hasPrecedingLineBreak() && isIdentifier() + return !scanner.hasPrecedingLineBreak() && isIdentifier(); } function parseYieldExpression(): YieldExpression { @@ -4009,18 +4009,18 @@ module ts { // as the identifier 'namespace' on one line followed by the identifier 'n' on another. // We need to look one token ahead to see if it permissible to try parsing a declaration. case SyntaxKind.DeclareKeyword: - if (lookAhead(isFollowedByIdentifierOrKeywordOnSameLine) && getDeclarationFlags() & flags) { + if (lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) && getDeclarationFlags() & flags) { return parseDeclaration(); } break; case SyntaxKind.ModuleKeyword: - if (lookAhead(isFollowedByIdentifierOrStringOnSameLine) && getDeclarationFlags() & flags) { + if (lookAhead(nextTokenIsIdentifierOrStringLiteralOnSameLine) && getDeclarationFlags() & flags) { return parseDeclaration(); } break; case SyntaxKind.NamespaceKeyword: case SyntaxKind.TypeKeyword: - if (lookAhead(isFollowedByIdentifierOnSameLine) && getDeclarationFlags() & flags) { + if (lookAhead(nextTokenIsIdentifierOnSameLine) && getDeclarationFlags() & flags) { return parseDeclaration(); } break; @@ -4070,21 +4070,11 @@ module ts { } } - function isFollowedByIdentifierOrKeywordOnSameLine() { - nextToken(); - return !scanner.hasPrecedingLineBreak() && isIdentifierOrKeyword(); - } - - function isFollowedByIdentifierOrStringOnSameLine() { + function nextTokenIsIdentifierOrStringLiteralOnSameLine() { nextToken(); return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === SyntaxKind.StringLiteral); } - function isFollowedByIdentifierOnSameLine() { - nextToken(); - return !scanner.hasPrecedingLineBreak() && isIdentifier(); - } - function parseFunctionBlockOrSemicolon(isGenerator: boolean, diagnosticMessage?: DiagnosticMessage): Block { if (token !== SyntaxKind.OpenBraceToken && canParseSemicolon()) { parseSemicolon(); From cdb6d5bca5cafb37bc5efc0ab24e018d200d1c97 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jun 2015 13:56:55 -0700 Subject: [PATCH 138/194] Don't access the anyType directly. Encapsulate all access to it behind a helper. --- src/compiler/checker.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index aa2207d5431..903d5964a44 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2131,6 +2131,10 @@ module ts { return prop ? getTypeOfSymbol(prop) : undefined; } + function isTheAnyType(type: Type) { + return type === anyType; + } + // Return the inferred type for a binding element function getTypeForBindingElement(declaration: BindingElement): Type { let pattern = declaration.parent; @@ -2142,7 +2146,7 @@ module ts { // If no type was specified or inferred for parent, or if the specified or inferred type is any, // infer from the initializer of the binding element if one is present. Otherwise, go with the // undefined or any type of the parent. - if (!parentType || parentType === anyType) { + if (!parentType || isTheAnyType(parentType)) { if (declaration.initializer) { return checkExpressionCached(declaration.initializer); } @@ -5547,7 +5551,7 @@ module ts { if (prototypeProperty) { // Target type is type of the protoype property let prototypePropertyType = getTypeOfSymbol(prototypeProperty); - if (prototypePropertyType !== anyType) { + if (!isTheAnyType(prototypePropertyType)) { targetType = prototypePropertyType; } } @@ -6496,7 +6500,7 @@ module ts { function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) { let type = checkExpressionOrQualifiedName(left); if (type === unknownType) return type; - if (type !== anyType) { + if (!isTheAnyType(type)) { let apparentType = getApparentType(getWidenedType(type)); if (apparentType === unknownType) { // handle cases when type is Type parameter with invalid constraint @@ -6536,7 +6540,7 @@ module ts { : (node).left; let type = checkExpressionOrQualifiedName(left); - if (type !== unknownType && type !== anyType) { + if (type !== unknownType && !isTheAnyType(type)) { let prop = getPropertyOfType(getWidenedType(type), propertyName); if (prop && prop.parent && prop.parent.flags & SymbolFlags.Class) { if (left.kind === SyntaxKind.SuperKeyword && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) { @@ -6626,7 +6630,7 @@ module ts { } // Fall back to any. - if (compilerOptions.noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && objectType !== anyType) { + if (compilerOptions.noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !isTheAnyType(objectType)) { error(node, Diagnostics.Index_signature_of_object_type_implicitly_has_an_any_type); } @@ -7276,7 +7280,7 @@ module ts { // types are provided for the argument expressions, and the result is always of type Any. // We exclude union types because we may have a union of function types that happen to have // no common signatures. - if (funcType === anyType || (!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) { + if (isTheAnyType(funcType) || (!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) { if (node.typeArguments) { error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); } @@ -7309,7 +7313,7 @@ module ts { // TS 1.0 spec: 4.11 // If ConstructExpr is of type Any, Args can be any argument // list and the result of the operation is of type Any. - if (expressionType === anyType) { + if (isTheAnyType(expressionType)) { if (node.typeArguments) { error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); } @@ -7364,7 +7368,7 @@ module ts { let callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call); - if (tagType === anyType || (!callSignatures.length && !(tagType.flags & TypeFlags.Union) && isTypeAssignableTo(tagType, globalFunctionType))) { + if (isTheAnyType(tagType) || (!callSignatures.length && !(tagType.flags & TypeFlags.Union) && isTypeAssignableTo(tagType, globalFunctionType))) { return resolveUntypedCall(node); } @@ -7576,7 +7580,7 @@ module ts { } // Functions that return 'void' or 'any' don't need any return expressions. - if (returnType === voidType || returnType === anyType) { + if (returnType === voidType || isTheAnyType(returnType)) { return; } From dd8f3c41ad9eb06ddfd40b5d76a2cd4d2155b1db Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 3 Jun 2015 14:08:37 -0700 Subject: [PATCH 139/194] Addressing CR feedback --- src/compiler/checker.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c180d8425f2..45a40135be8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4306,6 +4306,7 @@ module ts { // Effectively, we will generate a false positive when two types are structurally equal to at least 10 levels, but unequal at // some level beyond that. function isDeeplyNestedGeneric(type: ObjectType, stack: ObjectType[]): boolean { + // We track type references (created by createTypeReference) and instantiated types (created by instantiateType) if (type.flags & (TypeFlags.Reference | TypeFlags.Instantiated) && depth >= 10) { let symbol = type.symbol; let count = 0; From 7e3a3f45e15cc8cd9f13106f8c3140cb5a63eaf9 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 3 Jun 2015 14:55:42 -0700 Subject: [PATCH 140/194] emit module name for system modules, add moduleName argument to 'transpile' function --- src/compiler/emitter.ts | 10 +++++++--- src/compiler/parser.ts | 2 +- src/compiler/types.ts | 2 +- src/services/services.ts | 7 +++++-- .../baselines/reference/systemModule12.errors.txt | 10 ++++++++++ tests/baselines/reference/systemModule12.js | 14 ++++++++++++++ tests/cases/compiler/systemModule12.ts | 5 +++++ 7 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 tests/baselines/reference/systemModule12.errors.txt create mode 100644 tests/baselines/reference/systemModule12.js create mode 100644 tests/cases/compiler/systemModule12.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index d0d65aec2fb..794d0d59382 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -5527,7 +5527,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { Debug.assert(!exportFunctionForFile); // make sure that name of 'exports' function does not conflict with existing identifiers exportFunctionForFile = makeUniqueName("exports"); - write("System.register(["); + write("System.register("); + if (node.moduleName) { + write(`"${node.moduleName}", `); + } + write("[") for (let i = 0; i < externalImports.length; ++i) { let text = getExternalModuleNameText(externalImports[i]); if (i !== 0) { @@ -5613,8 +5617,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { writeLine(); write("define("); - if (node.amdModuleName) { - write("\"" + node.amdModuleName + "\", "); + if (node.moduleName) { + write("\"" + node.moduleName + "\", "); } emitAMDDependencies(node, /*includeNonAmdDependencies*/ true); write(") {"); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 80c70a250fb..9129a606f89 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4895,7 +4895,7 @@ module ts { sourceFile.referencedFiles = referencedFiles; sourceFile.amdDependencies = amdDependencies; - sourceFile.amdModuleName = amdModuleName; + sourceFile.moduleName = amdModuleName; } function setExternalModuleIndicator(sourceFile: SourceFile) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0fcf0e1f67a..a10c1c52c37 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1134,7 +1134,7 @@ module ts { text: string; amdDependencies: {path: string; name: string}[]; - amdModuleName: string; + moduleName: string; referencedFiles: FileReference[]; hasNoDefaultLib: boolean; diff --git a/src/services/services.ts b/src/services/services.ts index 400bf754a00..f56a41178a4 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -735,7 +735,7 @@ module ts { public endOfFileToken: Node; public amdDependencies: { name: string; path: string }[]; - public amdModuleName: string; + public moduleName: string; public referencedFiles: FileReference[]; public syntacticDiagnostics: Diagnostic[]; @@ -1766,7 +1766,7 @@ module ts { * - isolatedModules = true * - allowNonTsExtensions = true */ - export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[]): string { + export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string { let options = compilerOptions ? clone(compilerOptions) : getDefaultCompilerOptions(); options.isolatedModules = true; @@ -1777,6 +1777,9 @@ module ts { // Parse var inputFileName = fileName || "module.ts"; var sourceFile = createSourceFile(inputFileName, input, options.target); + if (moduleName) { + sourceFile.moduleName = moduleName; + } // Store syntactic diagnostics if (diagnostics && sourceFile.parseDiagnostics) { diff --git a/tests/baselines/reference/systemModule12.errors.txt b/tests/baselines/reference/systemModule12.errors.txt new file mode 100644 index 00000000000..5c89e2e65d6 --- /dev/null +++ b/tests/baselines/reference/systemModule12.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/systemModule12.ts(3,15): error TS2307: Cannot find module 'file1'. + + +==== tests/cases/compiler/systemModule12.ts (1 errors) ==== + + /// + import n from 'file1' + ~~~~~~~ +!!! error TS2307: Cannot find module 'file1'. + \ No newline at end of file diff --git a/tests/baselines/reference/systemModule12.js b/tests/baselines/reference/systemModule12.js new file mode 100644 index 00000000000..0b5f5a3e850 --- /dev/null +++ b/tests/baselines/reference/systemModule12.js @@ -0,0 +1,14 @@ +//// [systemModule12.ts] + +/// +import n from 'file1' + + +//// [systemModule12.js] +System.register("NamedModule", [], function(exports_1) { + return { + setters:[], + execute: function() { + } + } +}); diff --git a/tests/cases/compiler/systemModule12.ts b/tests/cases/compiler/systemModule12.ts new file mode 100644 index 00000000000..690fabc0a28 --- /dev/null +++ b/tests/cases/compiler/systemModule12.ts @@ -0,0 +1,5 @@ +// @module: system +// @isolatedModules: true + +/// +import n from 'file1' From 7ca13ee945ddf019bed048ab8cd81687e4746d74 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jun 2015 15:06:58 -0700 Subject: [PATCH 141/194] Check for 'any' only by using the flag, not by checking for instance equality. --- src/compiler/checker.ts | 158 +++++++++--------- .../reference/ArrowFunction3.errors.txt | 5 +- ...rsiveImplicitConstructorErrors3.errors.txt | 5 +- .../parserGenericsInTypeContexts1.errors.txt | 5 +- .../parserGenericsInTypeContexts2.errors.txt | 5 +- .../parserX_ArrowFunction3.errors.txt | 5 +- ...rUsedAsTypeParameterConstraint4.errors.txt | 14 +- .../reference/unknownSymbols1.errors.txt | 5 +- 8 files changed, 89 insertions(+), 113 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 903d5964a44..03a029d4b84 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1493,8 +1493,9 @@ module ts { // Write undefined/null type as any if (type.flags & TypeFlags.Intrinsic) { // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving - writer.writeKeyword(!(globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike) && - (type.flags & TypeFlags.Any) ? "any" : (type).intrinsicName); + writer.writeKeyword(!(globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike) && isTypeAny(type) + ? "any" + : (type).intrinsicName); } else if (type.flags & TypeFlags.Reference) { writeTypeReference(type, flags); @@ -2131,8 +2132,8 @@ module ts { return prop ? getTypeOfSymbol(prop) : undefined; } - function isTheAnyType(type: Type) { - return type === anyType; + function isTypeAny(type: Type) { + return type && type.flags & TypeFlags.Any; } // Return the inferred type for a binding element @@ -2146,7 +2147,7 @@ module ts { // If no type was specified or inferred for parent, or if the specified or inferred type is any, // infer from the initializer of the binding element if one is present. Otherwise, go with the // undefined or any type of the parent. - if (!parentType || isTheAnyType(parentType)) { + if (!parentType || isTypeAny(parentType)) { if (declaration.initializer) { return checkExpressionCached(declaration.initializer); } @@ -2173,7 +2174,7 @@ module ts { // fact an iterable or array (depending on target language). let elementType = checkIteratedTypeOrElementType(parentType, pattern, /*allowStringInput*/ false); if (!declaration.dotDotDotToken) { - if (elementType.flags & TypeFlags.Any) { + if (isTypeAny(elementType)) { return elementType; } @@ -3720,9 +3721,9 @@ module ts { } } - function containsAnyType(types: Type[]) { + function containsTypeAny(types: Type[]) { for (let type of types) { - if (type.flags & TypeFlags.Any) { + if (isTypeAny(type)) { return true; } } @@ -3750,7 +3751,7 @@ module ts { let sortedTypes: Type[] = []; addTypesToSortedSet(sortedTypes, types); if (noSubtypeReduction) { - if (containsAnyType(sortedTypes)) { + if (containsTypeAny(sortedTypes)) { return anyType; } removeAllButLast(sortedTypes, undefinedType); @@ -4186,13 +4187,13 @@ module ts { // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases if (source === target) return Ternary.True; if (relation !== identityRelation) { - if (target.flags & TypeFlags.Any) return Ternary.True; + if (isTypeAny(target)) return Ternary.True; if (source === undefinedType) return Ternary.True; if (source === nullType && target !== undefinedType) return Ternary.True; if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True; if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True; if (relation === assignableRelation) { - if (source.flags & TypeFlags.Any) return Ternary.True; + if (isTypeAny(source)) return Ternary.True; if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True; } } @@ -5537,7 +5538,7 @@ module ts { function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { // Check that type is not any, assumed result is true, and we have variable symbol on the left - if (type.flags & TypeFlags.Any || !assumeTrue || expr.left.kind !== SyntaxKind.Identifier || getResolvedSymbol(expr.left) !== symbol) { + if (isTypeAny(type) || !assumeTrue || expr.left.kind !== SyntaxKind.Identifier || getResolvedSymbol(expr.left) !== symbol) { return type; } // Check that right operand is a function type with a prototype property @@ -5551,7 +5552,7 @@ module ts { if (prototypeProperty) { // Target type is type of the protoype property let prototypePropertyType = getTypeOfSymbol(prototypeProperty); - if (!isTheAnyType(prototypePropertyType)) { + if (!isTypeAny(prototypePropertyType)) { targetType = prototypePropertyType; } } @@ -6499,39 +6500,39 @@ module ts { function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) { let type = checkExpressionOrQualifiedName(left); - if (type === unknownType) return type; - if (!isTheAnyType(type)) { - let apparentType = getApparentType(getWidenedType(type)); - if (apparentType === unknownType) { - // handle cases when type is Type parameter with invalid constraint - return unknownType; - } - let prop = getPropertyOfType(apparentType, right.text); - if (!prop) { - if (right.text) { - error(right, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(right), typeToString(type)); - } - return unknownType; - } - getNodeLinks(node).resolvedSymbol = prop; - if (prop.parent && prop.parent.flags & SymbolFlags.Class) { - // TS 1.0 spec (April 2014): 4.8.2 - // - In a constructor, instance member function, instance member accessor, or - // instance member variable initializer where this references a derived class instance, - // a super property access is permitted and must specify a public instance member function of the base class. - // - In a static member function or static member accessor - // where this references the constructor function object of a derived class, - // a super property access is permitted and must specify a public static member function of the base class. - if (left.kind === SyntaxKind.SuperKeyword && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) { - error(right, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword); - } - else { - checkClassPropertyAccess(node, left, type, prop); - } - } - return getTypeOfSymbol(prop); + if (isTypeAny(type)) { + return type; } - return anyType; + + let apparentType = getApparentType(getWidenedType(type)); + if (apparentType === unknownType) { + // handle cases when type is Type parameter with invalid constraint + return unknownType; + } + let prop = getPropertyOfType(apparentType, right.text); + if (!prop) { + if (right.text) { + error(right, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(right), typeToString(type)); + } + return unknownType; + } + getNodeLinks(node).resolvedSymbol = prop; + if (prop.parent && prop.parent.flags & SymbolFlags.Class) { + // TS 1.0 spec (April 2014): 4.8.2 + // - In a constructor, instance member function, instance member accessor, or + // instance member variable initializer where this references a derived class instance, + // a super property access is permitted and must specify a public instance member function of the base class. + // - In a static member function or static member accessor + // where this references the constructor function object of a derived class, + // a super property access is permitted and must specify a public static member function of the base class. + if (left.kind === SyntaxKind.SuperKeyword && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) { + error(right, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword); + } + else { + checkClassPropertyAccess(node, left, type, prop); + } + } + return getTypeOfSymbol(prop); } function isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean { @@ -6540,7 +6541,7 @@ module ts { : (node).left; let type = checkExpressionOrQualifiedName(left); - if (type !== unknownType && !isTheAnyType(type)) { + if (type !== unknownType && !isTypeAny(type)) { let prop = getPropertyOfType(getWidenedType(type), propertyName); if (prop && prop.parent && prop.parent.flags & SymbolFlags.Class) { if (left.kind === SyntaxKind.SuperKeyword && getDeclarationKindFromSymbol(prop) !== SyntaxKind.MethodDeclaration) { @@ -6630,7 +6631,7 @@ module ts { } // Fall back to any. - if (compilerOptions.noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !isTheAnyType(objectType)) { + if (compilerOptions.noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !isTypeAny(objectType)) { error(node, Diagnostics.Index_signature_of_object_type_implicitly_has_an_any_type); } @@ -7280,8 +7281,10 @@ module ts { // types are provided for the argument expressions, and the result is always of type Any. // We exclude union types because we may have a union of function types that happen to have // no common signatures. - if (isTheAnyType(funcType) || (!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) { - if (node.typeArguments) { + if (isTypeAny(funcType) || (!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) { + // The unknownType indicates that an error already occured (and was reported). No + // need to report another error in this case. + if (funcType !== unknownType && node.typeArguments) { error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); } return resolveUntypedCall(node); @@ -7310,15 +7313,6 @@ module ts { } let expressionType = checkExpression(node.expression); - // TS 1.0 spec: 4.11 - // If ConstructExpr is of type Any, Args can be any argument - // list and the result of the operation is of type Any. - if (isTheAnyType(expressionType)) { - if (node.typeArguments) { - error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); - } - return resolveUntypedCall(node); - } // If ConstructExpr's apparent type(section 3.8.1) is an object type with one or // more construct signatures, the expression is processed in the same manner as a @@ -7331,6 +7325,16 @@ module ts { return resolveErrorCall(node); } + // TS 1.0 spec: 4.11 + // If ConstructExpr is of type Any, Args can be any argument + // list and the result of the operation is of type Any. + if (isTypeAny(expressionType)) { + if (node.typeArguments) { + error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); + } + return resolveUntypedCall(node); + } + // Technically, this signatures list may be incomplete. We are taking the apparent type, // but we are not including construct signatures that may have been added to the Object or // Function interface, since they have none by default. This is a bit of a leap of faith @@ -7368,7 +7372,7 @@ module ts { let callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call); - if (isTheAnyType(tagType) || (!callSignatures.length && !(tagType.flags & TypeFlags.Union) && isTypeAssignableTo(tagType, globalFunctionType))) { + if (isTypeAny(tagType) || (!callSignatures.length && !(tagType.flags & TypeFlags.Union) && isTypeAssignableTo(tagType, globalFunctionType))) { return resolveUntypedCall(node); } @@ -7580,7 +7584,7 @@ module ts { } // Functions that return 'void' or 'any' don't need any return expressions. - if (returnType === voidType || isTheAnyType(returnType)) { + if (returnType === voidType || isTypeAny(returnType)) { return; } @@ -7896,7 +7900,7 @@ module ts { error(node.left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } // NOTE: do not raise error if right is unknown as related error was already reported - if (!(rightType.flags & TypeFlags.Any || isTypeSubtypeOf(rightType, globalFunctionType))) { + if (!(isTypeAny(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) { error(node.right, Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type); } return booleanType; @@ -7922,10 +7926,11 @@ module ts { if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) { // TODO(andersh): Computed property support let name = (p).name; - let type = sourceType.flags & TypeFlags.Any ? sourceType : - getTypeOfPropertyOfType(sourceType, name.text) || - isNumericLiteralName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) || - getIndexTypeOfType(sourceType, IndexKind.String); + let type = isTypeAny(sourceType) + ? sourceType + : getTypeOfPropertyOfType(sourceType, name.text) || + isNumericLiteralName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) || + getIndexTypeOfType(sourceType, IndexKind.String); if (type) { checkDestructuringAssignment((p).initializer || name, type); } @@ -7951,8 +7956,9 @@ module ts { if (e.kind !== SyntaxKind.OmittedExpression) { if (e.kind !== SyntaxKind.SpreadElementExpression) { let propName = "" + i; - let type = sourceType.flags & TypeFlags.Any ? sourceType : - isTupleLikeType(sourceType) + let type = isTypeAny(sourceType) + ? sourceType + : isTupleLikeType(sourceType) ? getTypeOfPropertyOfType(sourceType, propName) : elementType; if (type) { @@ -8091,10 +8097,10 @@ module ts { // If one or both operands are of the String primitive type, the result is of the String primitive type. resultType = stringType; } - else if (leftType.flags & TypeFlags.Any || rightType.flags & TypeFlags.Any) { + else if (isTypeAny(leftType) || isTypeAny(rightType)) { // Otherwise, the result is of type Any. // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we. - resultType = anyType; + resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; } // Symbols are not allowed at all in arithmetic expressions @@ -9824,7 +9830,7 @@ module ts { } function checkIteratedTypeOrElementType(inputType: Type, errorNode: Node, allowStringInput: boolean): Type { - if (inputType.flags & TypeFlags.Any) { + if (isTypeAny(inputType)) { return inputType; } @@ -9883,7 +9889,7 @@ module ts { * whole pattern and that T (above) is 'any'. */ function getElementTypeOfIterable(type: Type, errorNode: Node): Type { - if (type.flags & TypeFlags.Any) { + if (isTypeAny(type)) { return undefined; } @@ -9896,7 +9902,7 @@ module ts { } else { let iteratorFunction = getTypeOfPropertyOfType(type, getPropertyNameForKnownSymbolName("iterator")); - if (iteratorFunction && iteratorFunction.flags & TypeFlags.Any) { + if (isTypeAny(iteratorFunction)) { return undefined; } @@ -9929,7 +9935,7 @@ module ts { * */ function getElementTypeOfIterator(type: Type, errorNode: Node): Type { - if (type.flags & TypeFlags.Any) { + if (isTypeAny(type)) { return undefined; } @@ -9942,7 +9948,7 @@ module ts { } else { let iteratorNextFunction = getTypeOfPropertyOfType(type, "next"); - if (iteratorNextFunction && iteratorNextFunction.flags & TypeFlags.Any) { + if (isTypeAny(iteratorNextFunction)) { return undefined; } @@ -9955,7 +9961,7 @@ module ts { } let iteratorNextResult = getUnionType(map(iteratorNextFunctionSignatures, getReturnTypeOfSignature)); - if (iteratorNextResult.flags & TypeFlags.Any) { + if (isTypeAny(iteratorNextResult)) { return undefined; } @@ -9975,7 +9981,7 @@ module ts { } function getElementTypeOfIterableIterator(type: Type): Type { - if (type.flags & TypeFlags.Any) { + if (isTypeAny(type)) { return undefined; } diff --git a/tests/baselines/reference/ArrowFunction3.errors.txt b/tests/baselines/reference/ArrowFunction3.errors.txt index b931fcb1cd8..aa5d1bfb725 100644 --- a/tests/baselines/reference/ArrowFunction3.errors.txt +++ b/tests/baselines/reference/ArrowFunction3.errors.txt @@ -1,11 +1,8 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction3.ts(1,13): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction3.ts(1,14): error TS1110: Type expected. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction3.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction3.ts (1 errors) ==== var v = (a): => { - -!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~~ !!! error TS1110: Type expected. diff --git a/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt b/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt index 760d1561113..1a04e356296 100644 --- a/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt +++ b/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt @@ -1,5 +1,4 @@ tests/cases/compiler/genericRecursiveImplicitConstructorErrors3.ts(3,66): error TS2314: Generic type 'MemberName' requires 3 type argument(s). -tests/cases/compiler/genericRecursiveImplicitConstructorErrors3.ts(3,66): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. tests/cases/compiler/genericRecursiveImplicitConstructorErrors3.ts(10,22): error TS2314: Generic type 'PullTypeSymbol' requires 3 type argument(s). tests/cases/compiler/genericRecursiveImplicitConstructorErrors3.ts(12,48): error TS2314: Generic type 'PullSymbol' requires 3 type argument(s). tests/cases/compiler/genericRecursiveImplicitConstructorErrors3.ts(13,31): error TS2314: Generic type 'PullTypeSymbol' requires 3 type argument(s). @@ -8,14 +7,12 @@ tests/cases/compiler/genericRecursiveImplicitConstructorErrors3.ts(18,53): error tests/cases/compiler/genericRecursiveImplicitConstructorErrors3.ts(19,22): error TS2339: Property 'isArray' does not exist on type 'PullTypeSymbol'. -==== tests/cases/compiler/genericRecursiveImplicitConstructorErrors3.ts (8 errors) ==== +==== tests/cases/compiler/genericRecursiveImplicitConstructorErrors3.ts (7 errors) ==== module TypeScript { export class MemberName { static create(arg1: any, arg2?: any, arg3?: any): MemberName { ~~~~~~~~~~ !!! error TS2314: Generic type 'MemberName' requires 3 type argument(s). - ~~~~~~~~~~ -!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. } } } diff --git a/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt b/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt index 75652c829ee..477cc3edcdc 100644 --- a/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt +++ b/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt @@ -7,10 +7,9 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts1.ts(8,9): error TS2304: Cannot find name 'K'. tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts1.ts(11,16): error TS2304: Cannot find name 'E'. tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts1.ts(14,16): error TS2304: Cannot find name 'F'. -tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts1.ts(14,16): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. -==== tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts1.ts (10 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts1.ts (9 errors) ==== class C extends A implements B { ~ !!! error TS2304: Cannot find name 'A'. @@ -43,8 +42,6 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts function f2(): F { ~ !!! error TS2304: Cannot find name 'F'. - ~~~~ -!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt b/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt index c365f461b7c..f686b56bf89 100644 --- a/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt +++ b/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt @@ -7,10 +7,9 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts2.ts(8,9): error TS2304: Cannot find name 'K'. tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts2.ts(11,16): error TS2304: Cannot find name 'E'. tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts2.ts(14,16): error TS2304: Cannot find name 'F'. -tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts2.ts(14,16): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. -==== tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts2.ts (10 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts2.ts (9 errors) ==== class C extends A, Y>> implements B, Y>> { ~ !!! error TS2304: Cannot find name 'A'. @@ -43,8 +42,6 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts function f2(): F, Y>> { ~ !!! error TS2304: Cannot find name 'F'. - ~~~~~~~~~~~~~~~~ -!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserX_ArrowFunction3.errors.txt b/tests/baselines/reference/parserX_ArrowFunction3.errors.txt index 4ef812dc797..aa4a4c55a9f 100644 --- a/tests/baselines/reference/parserX_ArrowFunction3.errors.txt +++ b/tests/baselines/reference/parserX_ArrowFunction3.errors.txt @@ -1,11 +1,8 @@ -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction3.ts(1,13): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction3.ts(1,14): error TS1110: Type expected. -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction3.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction3.ts (1 errors) ==== var v = (a): => { - -!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~~ !!! error TS1110: Type expected. diff --git a/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt b/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt index 983f2798554..d86b63d2ce3 100644 --- a/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt +++ b/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt @@ -7,16 +7,12 @@ tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsed tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(15,8): error TS2304: Cannot find name 'W'. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(19,17): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(19,43): error TS2304: Cannot find name 'V'. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(19,43): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(20,47): error TS2304: Cannot find name 'X'. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(20,47): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(22,13): error TS2322: Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(23,20): error TS2322: Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(28,15): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(28,44): error TS2304: Cannot find name 'W'. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(28,44): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(29,47): error TS2304: Cannot find name 'Y'. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(29,47): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(31,13): error TS2322: Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(32,20): error TS2322: Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(37,14): error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. @@ -29,7 +25,7 @@ tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsed tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts(46,36): error TS2304: Cannot find name 'X'. -==== tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts (29 errors) ==== +==== tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts (25 errors) ==== // Type parameters are in scope in their own and other type parameter lists // Some negative cases @@ -67,13 +63,9 @@ tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsed !!! error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~ !!! error TS2304: Cannot find name 'V'. - ~ -!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function bar(): X { // error ~ !!! error TS2304: Cannot find name 'X'. - ~ -!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function baz(a: X, b: Y): T { x = y; ~ @@ -90,13 +82,9 @@ tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsed !!! error TS2313: Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~ !!! error TS2304: Cannot find name 'W'. - ~ -!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function bar(): Y { // error ~ !!! error TS2304: Cannot find name 'Y'. - ~ -!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function baz(a: X, b: Y): T { x = y; ~ diff --git a/tests/baselines/reference/unknownSymbols1.errors.txt b/tests/baselines/reference/unknownSymbols1.errors.txt index dcf6894f324..a757ab9613b 100644 --- a/tests/baselines/reference/unknownSymbols1.errors.txt +++ b/tests/baselines/reference/unknownSymbols1.errors.txt @@ -2,7 +2,6 @@ tests/cases/compiler/unknownSymbols1.ts(1,9): error TS2304: Cannot find name 'as tests/cases/compiler/unknownSymbols1.ts(2,8): error TS2304: Cannot find name 'asdf'. tests/cases/compiler/unknownSymbols1.ts(4,17): error TS2304: Cannot find name 'asdf'. tests/cases/compiler/unknownSymbols1.ts(4,35): error TS2304: Cannot find name 'asdf'. -tests/cases/compiler/unknownSymbols1.ts(4,35): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. tests/cases/compiler/unknownSymbols1.ts(6,12): error TS2304: Cannot find name 'asdf'. tests/cases/compiler/unknownSymbols1.ts(9,10): error TS2304: Cannot find name 'asdf'. tests/cases/compiler/unknownSymbols1.ts(12,10): error TS2304: Cannot find name 'asdf'. @@ -14,7 +13,7 @@ tests/cases/compiler/unknownSymbols1.ts(30,14): error TS2339: Property 'asdf' do tests/cases/compiler/unknownSymbols1.ts(30,21): error TS2304: Cannot find name 'asdf'. -==== tests/cases/compiler/unknownSymbols1.ts (14 errors) ==== +==== tests/cases/compiler/unknownSymbols1.ts (13 errors) ==== var x = asdf; ~~~~ !!! error TS2304: Cannot find name 'asdf'. @@ -27,8 +26,6 @@ tests/cases/compiler/unknownSymbols1.ts(30,21): error TS2304: Cannot find name ' !!! error TS2304: Cannot find name 'asdf'. ~~~~ !!! error TS2304: Cannot find name 'asdf'. - ~~~~ -!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function foo2() { return asdf; ~~~~ From 7b17f6ec8c2a1a6a2a0bc1144318d714d814de9b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jun 2015 15:16:16 -0700 Subject: [PATCH 142/194] Don't check if *all* constituent types are 'any'. Instead check if *any* of hte constituent types are 'any', or if *all* if the constituent types have some other flag. --- src/compiler/checker.ts | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 03a029d4b84..389881f1b5e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2133,7 +2133,7 @@ module ts { } function isTypeAny(type: Type) { - return type && type.flags & TypeFlags.Any; + return type && (type.flags & TypeFlags.Any) !== 0; } // Return the inferred type for a binding element @@ -6313,7 +6313,11 @@ module ts { function isNumericComputedName(name: ComputedPropertyName): boolean { // It seems odd to consider an expression of type Any to result in a numeric name, // but this behavior is consistent with checkIndexedAccess - return allConstituentTypesHaveKind(checkComputedPropertyName(name), TypeFlags.Any | TypeFlags.NumberLike); + return isTypeAnyOrAllConstituentTypesHaveKind(checkComputedPropertyName(name), TypeFlags.NumberLike); + } + + function isTypeAnyOrAllConstituentTypesHaveKind(type: Type, kind: TypeFlags): boolean { + return isTypeAny(type) || allConstituentTypesHaveKind(type, kind); } function isNumericLiteralName(name: string) { @@ -6348,7 +6352,7 @@ module ts { // This will allow types number, string, symbol or any. It will also allow enums, the unknown // type, and any union of these types (like string | number). - if (!allConstituentTypesHaveKind(links.resolvedType, TypeFlags.Any | TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol)) { + if (!isTypeAnyOrAllConstituentTypesHaveKind(links.resolvedType, TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.ESSymbol)) { error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any); } else { @@ -6614,10 +6618,10 @@ module ts { } // Check for compatible indexer types. - if (allConstituentTypesHaveKind(indexType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) { + if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) { // Try to use a number indexer. - if (allConstituentTypesHaveKind(indexType, TypeFlags.Any | TypeFlags.NumberLike)) { + if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike)) { let numberIndexType = getIndexTypeOfType(objectType, IndexKind.Number); if (numberIndexType) { return numberIndexType; @@ -7688,7 +7692,7 @@ module ts { } function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean { - if (!allConstituentTypesHaveKind(type, TypeFlags.Any | TypeFlags.NumberLike)) { + if (!isTypeAnyOrAllConstituentTypesHaveKind(type, TypeFlags.NumberLike)) { error(operand, diagnostic); return false; } @@ -7911,10 +7915,10 @@ module ts { // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type, // and the right operand to be of type Any, an object type, or a type parameter type. // The result is always of the Boolean primitive type. - if (!allConstituentTypesHaveKind(leftType, TypeFlags.Any | TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) { + if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) { error(node.left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol); } - if (!allConstituentTypesHaveKind(rightType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) { + if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.ObjectType | TypeFlags.TypeParameter)) { error(node.right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } return booleanType; @@ -9796,7 +9800,7 @@ module ts { if (varExpr.kind === SyntaxKind.ArrayLiteralExpression || varExpr.kind === SyntaxKind.ObjectLiteralExpression) { error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern); } - else if (!allConstituentTypesHaveKind(leftType, TypeFlags.Any | TypeFlags.StringLike)) { + else if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike)) { error(varExpr, Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any); } else { @@ -9808,7 +9812,7 @@ module ts { let rightType = checkExpression(node.expression); // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved // in this case error about missing name is already reported - do not report extra one - if (!allConstituentTypesHaveKind(rightType, TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.TypeParameter)) { + if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.ObjectType | TypeFlags.TypeParameter)) { error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter); } From ef54047a65c963201d972bccec5d5e08d53f6091 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 3 Jun 2015 15:22:17 -0700 Subject: [PATCH 143/194] address PR feedback --- src/compiler/core.ts | 38 +++++++++++++++++++++----------------- src/compiler/program.ts | 2 +- src/compiler/types.ts | 8 ++++++++ src/services/services.ts | 6 +++--- src/services/shims.ts | 2 +- 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index b798bd8771d..ed9647970c0 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -15,35 +15,39 @@ module ts { True = -1 } - export class FileMap { - private files: Map = {}; - - constructor(private getCanonicalFileName: (fileName: string) => string) { + export function createFileMap(getCanonicalFileName: (fileName: string) => string): FileMap { + let files: Map = {}; + return { + get, + set, + contains, + delete: deleteItem, + forEachValue: forEachValueInMap } - public set(fileName: string, value: T) { - this.files[this.normalizeKey(fileName)] = value; + function set(fileName: string, value: T) { + files[normalizeKey(fileName)] = value; } - public get(fileName: string) { - return this.files[this.normalizeKey(fileName)]; + function get(fileName: string) { + return files[normalizeKey(fileName)]; } - public contains(fileName: string) { - return hasProperty(this.files, this.normalizeKey(fileName)); + function contains(fileName: string) { + return hasProperty(files, normalizeKey(fileName)); } - public delete(fileName: string) { - let key = this.normalizeKey(fileName); - delete this.files[key]; + function deleteItem (fileName: string) { + let key = normalizeKey(fileName); + delete files[key]; } - public forEachValue(f: (value: T) => void) { - forEachValue(this.files, f); + function forEachValueInMap(f: (value: T) => void) { + forEachValue(files, f); } - private normalizeKey(key: string) { - return this.getCanonicalFileName(normalizeSlashes(key)); + function normalizeKey(key: string) { + return getCanonicalFileName(normalizeSlashes(key)); } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index dd693b55907..74c0ac7fefb 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -158,7 +158,7 @@ module ts { let start = new Date().getTime(); host = host || createCompilerHost(options); - let filesByName: FileMap = new FileMap(host.getCanonicalFileName); + let filesByName = createFileMap(host.getCanonicalFileName); forEach(rootNames, name => processRootFile(name, false)); if (!seenNoDefaultLib) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0fcf0e1f67a..638dd0b79ec 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3,6 +3,14 @@ module ts { [index: string]: T; } + export interface FileMap { + get(fileName: string): T; + set(fileName: string, value: T): void; + contains(fileName: string): boolean; + delete(fileName: string): void; + forEachValue(f: (v: T) => void): void; + } + export interface TextRange { pos: number; end: number; diff --git a/src/services/services.ts b/src/services/services.ts index 908d9efbaca..f2aa6dfee7f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1638,7 +1638,7 @@ module ts { constructor(private host: LanguageServiceHost, getCanonicalFileName: (fileName: string) => string) { // script id => script index - this.fileNameToEntry = new FileMap(getCanonicalFileName); + this.fileNameToEntry = createFileMap(getCanonicalFileName); // Initialize the list with the root file names let rootFileNames = host.getScriptFileNames(); @@ -1881,7 +1881,7 @@ module ts { // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have // for those settings. let buckets: Map> = {}; - let getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames || false); + let getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames); function getKeyFromCompilationSettings(settings: CompilerOptions): string { return "_" + settings.target; // + "|" + settings.propagateEnumConstantoString() @@ -1891,7 +1891,7 @@ module ts { let key = getKeyFromCompilationSettings(settings); let bucket = lookUp(buckets, key); if (!bucket && createIfMissing) { - buckets[key] = bucket = new FileMap(getCanonicalFileName); + buckets[key] = bucket = createFileMap(getCanonicalFileName); } return bucket; } diff --git a/src/services/shims.ts b/src/services/shims.ts index 4dfab444cde..004393fb3b5 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -272,7 +272,7 @@ module ts { } public useCaseSensitiveFileNames(): boolean { - return this.shimHost.useCaseSensitiveFileNames && this.useCaseSensitiveFileNames(); + return this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false; } public getCompilationSettings(): CompilerOptions { From 12bea33fe37652b570ec9f245b7a019f88003370 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jun 2015 15:37:09 -0700 Subject: [PATCH 144/194] Remove last read reference of TypeFlags.Any --- src/compiler/checker.ts | 87 +++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 389881f1b5e..82c70861101 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5417,55 +5417,58 @@ module ts { function getNarrowedTypeOfSymbol(symbol: Symbol, node: Node) { let type = getTypeOfSymbol(symbol); // Only narrow when symbol is variable of type any or an object, union, or type parameter type - if (node && symbol.flags & SymbolFlags.Variable && type.flags & (TypeFlags.Any | TypeFlags.ObjectType | TypeFlags.Union | TypeFlags.TypeParameter)) { - loop: while (node.parent) { - let child = node; - node = node.parent; - let narrowedType = type; - switch (node.kind) { - case SyntaxKind.IfStatement: - // In a branch of an if statement, narrow based on controlling expression - if (child !== (node).expression) { - narrowedType = narrowType(type, (node).expression, /*assumeTrue*/ child === (node).thenStatement); - } - break; - case SyntaxKind.ConditionalExpression: - // In a branch of a conditional expression, narrow based on controlling condition - if (child !== (node).condition) { - narrowedType = narrowType(type, (node).condition, /*assumeTrue*/ child === (node).whenTrue); - } - break; - case SyntaxKind.BinaryExpression: - // In the right operand of an && or ||, narrow based on left operand - if (child === (node).right) { - if ((node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) { - narrowedType = narrowType(type, (node).left, /*assumeTrue*/ true); + if (node && symbol.flags & SymbolFlags.Variable) { + if (isTypeAny(type) || type.flags & (TypeFlags.ObjectType | TypeFlags.Union | TypeFlags.TypeParameter)) { + loop: while (node.parent) { + let child = node; + node = node.parent; + let narrowedType = type; + switch (node.kind) { + case SyntaxKind.IfStatement: + // In a branch of an if statement, narrow based on controlling expression + if (child !== (node).expression) { + narrowedType = narrowType(type, (node).expression, /*assumeTrue*/ child === (node).thenStatement); } - else if ((node).operatorToken.kind === SyntaxKind.BarBarToken) { - narrowedType = narrowType(type, (node).left, /*assumeTrue*/ false); + break; + case SyntaxKind.ConditionalExpression: + // In a branch of a conditional expression, narrow based on controlling condition + if (child !== (node).condition) { + narrowedType = narrowType(type, (node).condition, /*assumeTrue*/ child === (node).whenTrue); } + break; + case SyntaxKind.BinaryExpression: + // In the right operand of an && or ||, narrow based on left operand + if (child === (node).right) { + if ((node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) { + narrowedType = narrowType(type, (node).left, /*assumeTrue*/ true); + } + else if ((node).operatorToken.kind === SyntaxKind.BarBarToken) { + narrowedType = narrowType(type, (node).left, /*assumeTrue*/ false); + } + } + break; + case SyntaxKind.SourceFile: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.Constructor: + // Stop at the first containing function or module declaration + break loop; + } + // Use narrowed type if construct contains no assignments to variable + if (narrowedType !== type) { + if (isVariableAssignedWithin(symbol, node)) { + break; } - break; - case SyntaxKind.SourceFile: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.Constructor: - // Stop at the first containing function or module declaration - break loop; - } - // Use narrowed type if construct contains no assignments to variable - if (narrowedType !== type) { - if (isVariableAssignedWithin(symbol, node)) { - break; + type = narrowedType; } - type = narrowedType; } } } + return type; function narrowTypeByEquality(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { From b5077bf3729c8d65c9f559c813860298899d82a2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 3 Jun 2015 16:28:14 -0700 Subject: [PATCH 145/194] Remove HarnessDiagnostics. Just use the normal ts Diagnostic instead. --- src/harness/harness.ts | 99 +++++-------------- src/harness/projectsRunner.ts | 3 +- .../reference/contextualTyping.errors.txt | 10 +- .../reference/inlineSourceMap2.errors.txt | 8 +- .../reference/noDefaultLib.errors.txt | 4 +- .../reference/parser509698.errors.txt | 28 +++--- .../amd/invalidRootFile.errors.txt | 6 +- .../node/invalidRootFile.errors.txt | 6 +- ...SourceRootWithNoSourceMapOption.errors.txt | 4 +- ...SourceRootWithNoSourceMapOption.errors.txt | 4 +- .../noDefaultLib/amd/noDefaultLib.errors.txt | 28 +++--- .../noDefaultLib/node/noDefaultLib.errors.txt | 28 +++--- .../typeCheckTypeArgument.errors.txt | 20 ++-- tests/cases/compiler/contextualTyping.ts | 1 - 14 files changed, 103 insertions(+), 146 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index b3791283a63..86cc255b063 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -899,7 +899,7 @@ module Harness { private compileOptions: ts.CompilerOptions; private settings: Harness.TestCaseParser.CompilerSetting[] = []; - private lastErrors: HarnessDiagnostic[]; + private lastErrors: ts.Diagnostic[]; public reset() { this.inputFiles = []; @@ -1078,10 +1078,6 @@ module Harness { } break; - case 'normalizenewline': - newLine = setting.value; - break; - case 'comments': options.removeComments = setting.value === 'false'; break; @@ -1144,11 +1140,7 @@ module Harness { var emitResult = program.emit(); - var errors: HarnessDiagnostic[] = []; - ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics).forEach(err => { - // TODO: new compiler formats errors after this point to add . and newlines so we'll just do it manually for now - errors.push(getMinimalDiagnostic(err)); - }); + var errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); this.lastErrors = errors; var result = new CompilerResult(fileOutputs, errors, program, ts.sys.getCurrentDirectory(), emitResult.sourceMaps); @@ -1235,70 +1227,50 @@ module Harness { return normalized; } - export function getMinimalDiagnostic(err: ts.Diagnostic): HarnessDiagnostic { - var errorLineInfo = err.file ? err.file.getLineAndCharacterOfPosition(err.start) : { line: -1, character: -1 }; - return { - fileName: err.file && err.file.fileName, - start: err.start, - end: err.start + err.length, - line: errorLineInfo.line + 1, - character: errorLineInfo.character + 1, - message: ts.flattenDiagnosticMessageText(err.messageText, ts.sys.newLine), - category: ts.DiagnosticCategory[err.category].toLowerCase(), - code: err.code - }; - } - - export function minimalDiagnosticsToString(diagnostics: HarnessDiagnostic[]) { + export function minimalDiagnosticsToString(diagnostics: ts.Diagnostic[]) { // This is basically copied from tsc.ts's reportError to replicate what tsc does var errorOutput = ""; - ts.forEach(diagnostics, diagnotic => { - if (diagnotic.fileName) { - errorOutput += diagnotic.fileName + "(" + diagnotic.line + "," + diagnotic.character + "): "; + ts.forEach(diagnostics, diagnostic => { + if (diagnostic.file) { + var lineAndCharacter = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); + errorOutput += diagnostic.file.fileName + "(" + (lineAndCharacter.line + 1) + "," + (lineAndCharacter.character + 1) + "): "; } - errorOutput += diagnotic.category + " TS" + diagnotic.code + ": " + diagnotic.message + ts.sys.newLine; + errorOutput += ts.DiagnosticCategory[diagnostic.category].toLowerCase() + " TS" + diagnostic.code + ": " + ts.flattenDiagnosticMessageText(diagnostic.messageText, ts.sys.newLine) + ts.sys.newLine; }); return errorOutput; } - function compareDiagnostics(d1: HarnessDiagnostic, d2: HarnessDiagnostic) { - return ts.compareValues(d1.fileName, d2.fileName) || - ts.compareValues(d1.start, d2.start) || - ts.compareValues(d1.end, d2.end) || - ts.compareValues(d1.code, d2.code) || - ts.compareValues(d1.message, d2.message) || - 0; - } - - export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: HarnessDiagnostic[]) { - diagnostics.sort(compareDiagnostics); + export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: ts.Diagnostic[]) { + diagnostics.sort(ts.compareDiagnostics); var outputLines: string[] = []; // Count up all the errors we find so we don't miss any var totalErrorsReported = 0; - function outputErrorText(error: Harness.Compiler.HarnessDiagnostic) { - var errLines = RunnerBase.removeFullPaths(error.message) + function outputErrorText(error: ts.Diagnostic) { + var message = ts.flattenDiagnosticMessageText(error.messageText, ts.sys.newLine); + + var errLines = RunnerBase.removeFullPaths(message) .split('\n') .map(s => s.length > 0 && s.charAt(s.length - 1) === '\r' ? s.substr(0, s.length - 1) : s) .filter(s => s.length > 0) - .map(s => '!!! ' + error.category + " TS" + error.code + ": " + s); + .map(s => '!!! ' + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s); errLines.forEach(e => outputLines.push(e)); totalErrorsReported++; } // Report global errors - var globalErrors = diagnostics.filter(err => !err.fileName); + var globalErrors = diagnostics.filter(err => !err.file); globalErrors.forEach(outputErrorText); // 'merge' the lines of each input file with any errors associated with it inputFiles.filter(f => f.content !== undefined).forEach(inputFile => { // Filter down to the errors in the file var fileErrors = diagnostics.filter(e => { - var errFn = e.fileName; - return errFn && errFn === inputFile.unitName; + var errFn = e.file; + return errFn && errFn.fileName === inputFile.unitName; }); @@ -1334,18 +1306,19 @@ module Harness { outputLines.push(' ' + line); fileErrors.forEach(err => { // Does any error start or continue on to this line? Emit squiggles - if ((err.end >= thisLineStart) && ((err.start < nextLineStart) || (lineIndex === lines.length - 1))) { + let end = ts.textSpanEnd(err); + if ((end >= thisLineStart) && ((err.start < nextLineStart) || (lineIndex === lines.length - 1))) { // How many characters from the start of this line the error starts at (could be positive or negative) var relativeOffset = err.start - thisLineStart; // How many characters of the error are on this line (might be longer than this line in reality) - var length = (err.end - err.start) - Math.max(0, thisLineStart - err.start); + var length = (end - err.start) - Math.max(0, thisLineStart - err.start); // Calculate the start of the squiggle var squiggleStart = Math.max(0, relativeOffset); // TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another outputLines.push(' ' + line.substr(0, squiggleStart).replace(/[^\s]/g, ' ') + new Array(Math.min(length, line.length - squiggleStart) + 1).join('~')); // If the error ended here, or we're at the end of the file, emit its message - if ((lineIndex === lines.length - 1) || nextLineStart > err.end) { + if ((lineIndex === lines.length - 1) || nextLineStart > end) { // Just like above, we need to do a split on a string instead of on a regex // because the JS engine does regexes wrong @@ -1361,12 +1334,12 @@ module Harness { }); var numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => { - return diagnostic.fileName && (isLibraryFile(diagnostic.fileName) || isBuiltFile(diagnostic.fileName)); + return diagnostic.file && (isLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName)); }); var numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => { // Count an error generated from tests262-harness folder.This should only apply for test262 - return diagnostic.fileName && diagnostic.fileName.indexOf("test262-harness") >= 0; + return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0; }); // Verify we didn't miss any errors in total @@ -1419,17 +1392,6 @@ module Harness { //harnessCompiler.compileString(code, unitName, callback); } - export interface HarnessDiagnostic { - fileName: string; - start: number; - end: number; - line: number; - character: number; - message: string; - category: string; - code: number; - } - export interface GeneratedFile { fileName: string; code: string; @@ -1459,12 +1421,12 @@ module Harness { /** Contains the code and errors of a compilation and some helper methods to check its status. */ export class CompilerResult { public files: GeneratedFile[] = []; - public errors: HarnessDiagnostic[] = []; + public errors: ts.Diagnostic[] = []; public declFilesCode: GeneratedFile[] = []; public sourceMaps: GeneratedFile[] = []; /** @param fileResults an array of strings for the fileName and an ITextWriter with its code */ - constructor(fileResults: GeneratedFile[], errors: HarnessDiagnostic[], public program: ts.Program, + constructor(fileResults: GeneratedFile[], errors: ts.Diagnostic[], public program: ts.Program, public currentDirectoryForProgram: string, private sourceMapData: ts.SourceMapData[]) { fileResults.forEach(emittedFile => { @@ -1489,15 +1451,6 @@ module Harness { return Harness.SourceMapRecoder.getSourceMapRecord(this.sourceMapData, this.program, this.files); } } - - public isErrorAt(line: number, column: number, message: string) { - for (var i = 0; i < this.errors.length; i++) { - if ((this.errors[i].line + 1) === line && (this.errors[i].character + 1) === column && this.errors[i].message === message) - return true; - } - - return false; - } } } diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 39221d55b29..324524272e0 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -323,9 +323,8 @@ class ProjectRunner extends RunnerBase { sourceFile => { return { unitName: sourceFile.fileName, content: sourceFile.text }; }); - var diagnostics = ts.map(compilerResult.errors, error => Harness.Compiler.getMinimalDiagnostic(error)); - return Harness.Compiler.getErrorBaseline(inputFiles, diagnostics); + return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors); } var name = 'Compiling project for ' + testCase.scenario + ': testcase ' + testCaseFileName; diff --git a/tests/baselines/reference/contextualTyping.errors.txt b/tests/baselines/reference/contextualTyping.errors.txt index f6941b7b92d..2e050777bfd 100644 --- a/tests/baselines/reference/contextualTyping.errors.txt +++ b/tests/baselines/reference/contextualTyping.errors.txt @@ -1,5 +1,11 @@ -tests/cases/compiler/contextualTyping.ts(189,18): error TS2384: Overload signatures must all be ambient or non-ambient.\ntests/cases/compiler/contextualTyping.ts(197,15): error TS2300: Duplicate identifier 'Point'.\ntests/cases/compiler/contextualTyping.ts(207,10): error TS2300: Duplicate identifier 'Point'.\ntests/cases/compiler/contextualTyping.ts(230,5): error TS2322: Type '{}' is not assignable to type 'B'. - Property 'x' is missing in type '{}'.\n\n\n==== tests/cases/compiler/contextualTyping.ts (4 errors) ==== +tests/cases/compiler/contextualTyping.ts(189,18): error TS2384: Overload signatures must all be ambient or non-ambient. +tests/cases/compiler/contextualTyping.ts(197,15): error TS2300: Duplicate identifier 'Point'. +tests/cases/compiler/contextualTyping.ts(207,10): error TS2300: Duplicate identifier 'Point'. +tests/cases/compiler/contextualTyping.ts(230,5): error TS2322: Type '{}' is not assignable to type 'B'. + Property 'x' is missing in type '{}'. + + +==== tests/cases/compiler/contextualTyping.ts (4 errors) ==== // DEFAULT INTERFACES interface IFoo { n: number; diff --git a/tests/baselines/reference/inlineSourceMap2.errors.txt b/tests/baselines/reference/inlineSourceMap2.errors.txt index 75db5689c66..2d8bc4be0c1 100644 --- a/tests/baselines/reference/inlineSourceMap2.errors.txt +++ b/tests/baselines/reference/inlineSourceMap2.errors.txt @@ -1,12 +1,12 @@ -error TS5050: Option 'mapRoot' cannot be specified with option 'inlineSourceMap'. -error TS5049: Option 'sourceRoot' cannot be specified with option 'inlineSourceMap'. error TS5048: Option 'sourceMap' cannot be specified with option 'inlineSourceMap'. +error TS5049: Option 'sourceRoot' cannot be specified with option 'inlineSourceMap'. +error TS5050: Option 'mapRoot' cannot be specified with option 'inlineSourceMap'. tests/cases/compiler/inlineSourceMap2.ts(5,1): error TS2304: Cannot find name 'console'. -!!! error TS5050: Option 'mapRoot' cannot be specified with option 'inlineSourceMap'. -!!! error TS5049: Option 'sourceRoot' cannot be specified with option 'inlineSourceMap'. !!! error TS5048: Option 'sourceMap' cannot be specified with option 'inlineSourceMap'. +!!! error TS5049: Option 'sourceRoot' cannot be specified with option 'inlineSourceMap'. +!!! error TS5050: Option 'mapRoot' cannot be specified with option 'inlineSourceMap'. ==== tests/cases/compiler/inlineSourceMap2.ts (1 errors) ==== // configuration errors diff --git a/tests/baselines/reference/noDefaultLib.errors.txt b/tests/baselines/reference/noDefaultLib.errors.txt index b8f42ba7c33..02098950055 100644 --- a/tests/baselines/reference/noDefaultLib.errors.txt +++ b/tests/baselines/reference/noDefaultLib.errors.txt @@ -1,10 +1,10 @@ -error TS2318: Cannot find global type 'IArguments'. error TS2318: Cannot find global type 'Boolean'. +error TS2318: Cannot find global type 'IArguments'. tests/cases/compiler/noDefaultLib.ts(4,11): error TS2317: Global type 'Array' must have 1 type parameter(s). -!!! error TS2318: Cannot find global type 'IArguments'. !!! error TS2318: Cannot find global type 'Boolean'. +!!! error TS2318: Cannot find global type 'IArguments'. ==== tests/cases/compiler/noDefaultLib.ts (1 errors) ==== /// var x; diff --git a/tests/baselines/reference/parser509698.errors.txt b/tests/baselines/reference/parser509698.errors.txt index 85485dd6501..2aaaec18dc2 100644 --- a/tests/baselines/reference/parser509698.errors.txt +++ b/tests/baselines/reference/parser509698.errors.txt @@ -1,21 +1,21 @@ -error TS2318: Cannot find global type 'String'. -error TS2318: Cannot find global type 'RegExp'. -error TS2318: Cannot find global type 'Object'. -error TS2318: Cannot find global type 'Number'. -error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'Function'. -error TS2318: Cannot find global type 'Boolean'. error TS2318: Cannot find global type 'Array'. +error TS2318: Cannot find global type 'Boolean'. +error TS2318: Cannot find global type 'Function'. +error TS2318: Cannot find global type 'IArguments'. +error TS2318: Cannot find global type 'Number'. +error TS2318: Cannot find global type 'Object'. +error TS2318: Cannot find global type 'RegExp'. +error TS2318: Cannot find global type 'String'. -!!! error TS2318: Cannot find global type 'String'. -!!! error TS2318: Cannot find global type 'RegExp'. -!!! error TS2318: Cannot find global type 'Object'. -!!! error TS2318: Cannot find global type 'Number'. -!!! error TS2318: Cannot find global type 'IArguments'. -!!! error TS2318: Cannot find global type 'Function'. -!!! error TS2318: Cannot find global type 'Boolean'. !!! error TS2318: Cannot find global type 'Array'. +!!! error TS2318: Cannot find global type 'Boolean'. +!!! error TS2318: Cannot find global type 'Function'. +!!! error TS2318: Cannot find global type 'IArguments'. +!!! error TS2318: Cannot find global type 'Number'. +!!! error TS2318: Cannot find global type 'Object'. +!!! error TS2318: Cannot find global type 'RegExp'. +!!! error TS2318: Cannot find global type 'String'. ==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser509698.ts (0 errors) ==== ///