From e9dc96598cd635265881104b08b4a4120b43f845 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 27 Aug 2015 14:03:19 -0700 Subject: [PATCH 1/2] Update LKG --- lib/lib.d.ts | 25 ++- lib/lib.dom.d.ts | 24 ++- lib/lib.es6.d.ts | 25 ++- lib/lib.webworker.d.ts | 21 ++- lib/tsc.js | 161 +++++++++++++++- lib/tsserver.js | 336 +++++++++++++++++++++++++++++---- lib/typescript.d.ts | 8 + lib/typescript.js | 357 ++++++++++++++++++++++++++++++++---- lib/typescriptServices.d.ts | 8 + lib/typescriptServices.js | 357 ++++++++++++++++++++++++++++++++---- 10 files changed, 1197 insertions(+), 125 deletions(-) diff --git a/lib/lib.d.ts b/lib/lib.d.ts index 7a411e002f..c55970d9ac 100644 --- a/lib/lib.d.ts +++ b/lib/lib.d.ts @@ -6929,6 +6929,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec webkitMatchesSelector(selectors: string): boolean; webkitRequestFullScreen(): void; webkitRequestFullscreen(): void; + getElementsByClassName(classNames: string): NodeListOf; addEventListener(type: "MSGestureChange", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureDoubleTap", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureEnd", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; @@ -7916,7 +7917,6 @@ interface HTMLElement extends Element { contains(child: HTMLElement): boolean; dragDrop(): boolean; focus(): void; - getElementsByClassName(classNames: string): NodeListOf; insertAdjacentElement(position: string, insertedElement: Element): Element; insertAdjacentHTML(where: string, html: string): void; insertAdjacentText(where: string, text: string): void; @@ -11719,7 +11719,7 @@ interface MessageEvent extends Event { declare var MessageEvent: { prototype: MessageEvent; - new(): MessageEvent; + new(type: string, eventInitDict?: MessageEventInit): MessageEvent; } interface MessagePort extends EventTarget { @@ -12461,7 +12461,7 @@ interface ProgressEvent extends Event { declare var ProgressEvent: { prototype: ProgressEvent; - new(): ProgressEvent; + new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } interface Range { @@ -16628,7 +16628,6 @@ interface NodeListOf extends NodeList { [index: number]: TNode; } - interface BlobPropertyBag { type?: string; endings?: string; @@ -16645,6 +16644,21 @@ interface EventListenerObject { declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; +interface MessageEventInit extends EventInit { + data?: any; + origin?: string; + lastEventId?: string; + channel?: string; + source?: any; + ports?: MessagePort[]; +} + +interface ProgressEventInit extends EventInit { + lengthComputable?: boolean; + loaded?: number; + total?: number; +} + interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void; } @@ -16974,8 +16988,7 @@ 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; - +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; ///////////////////////////// /// WorkerGlobalScope APIs ///////////////////////////// diff --git a/lib/lib.dom.d.ts b/lib/lib.dom.d.ts index 896db2d55e..54461afef4 100644 --- a/lib/lib.dom.d.ts +++ b/lib/lib.dom.d.ts @@ -3105,6 +3105,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec webkitMatchesSelector(selectors: string): boolean; webkitRequestFullScreen(): void; webkitRequestFullscreen(): void; + getElementsByClassName(classNames: string): NodeListOf; addEventListener(type: "MSGestureChange", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureDoubleTap", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureEnd", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; @@ -4092,7 +4093,6 @@ interface HTMLElement extends Element { contains(child: HTMLElement): boolean; dragDrop(): boolean; focus(): void; - getElementsByClassName(classNames: string): NodeListOf; insertAdjacentElement(position: string, insertedElement: Element): Element; insertAdjacentHTML(where: string, html: string): void; insertAdjacentText(where: string, text: string): void; @@ -7895,7 +7895,7 @@ interface MessageEvent extends Event { declare var MessageEvent: { prototype: MessageEvent; - new(): MessageEvent; + new(type: string, eventInitDict?: MessageEventInit): MessageEvent; } interface MessagePort extends EventTarget { @@ -8637,7 +8637,7 @@ interface ProgressEvent extends Event { declare var ProgressEvent: { prototype: ProgressEvent; - new(): ProgressEvent; + new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } interface Range { @@ -12804,7 +12804,6 @@ interface NodeListOf extends NodeList { [index: number]: TNode; } - interface BlobPropertyBag { type?: string; endings?: string; @@ -12821,6 +12820,21 @@ interface EventListenerObject { declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; +interface MessageEventInit extends EventInit { + data?: any; + origin?: string; + lastEventId?: string; + channel?: string; + source?: any; + ports?: MessagePort[]; +} + +interface ProgressEventInit extends EventInit { + lengthComputable?: boolean; + loaded?: number; + total?: number; +} + interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void; } @@ -13150,4 +13164,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; +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; \ No newline at end of file diff --git a/lib/lib.es6.d.ts b/lib/lib.es6.d.ts index 02b89b3a2b..de051a44ed 100644 --- a/lib/lib.es6.d.ts +++ b/lib/lib.es6.d.ts @@ -8217,6 +8217,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec webkitMatchesSelector(selectors: string): boolean; webkitRequestFullScreen(): void; webkitRequestFullscreen(): void; + getElementsByClassName(classNames: string): NodeListOf; addEventListener(type: "MSGestureChange", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureDoubleTap", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureEnd", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; @@ -9204,7 +9205,6 @@ interface HTMLElement extends Element { contains(child: HTMLElement): boolean; dragDrop(): boolean; focus(): void; - getElementsByClassName(classNames: string): NodeListOf; insertAdjacentElement(position: string, insertedElement: Element): Element; insertAdjacentHTML(where: string, html: string): void; insertAdjacentText(where: string, text: string): void; @@ -13007,7 +13007,7 @@ interface MessageEvent extends Event { declare var MessageEvent: { prototype: MessageEvent; - new(): MessageEvent; + new(type: string, eventInitDict?: MessageEventInit): MessageEvent; } interface MessagePort extends EventTarget { @@ -13749,7 +13749,7 @@ interface ProgressEvent extends Event { declare var ProgressEvent: { prototype: ProgressEvent; - new(): ProgressEvent; + new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } interface Range { @@ -17916,7 +17916,6 @@ interface NodeListOf extends NodeList { [index: number]: TNode; } - interface BlobPropertyBag { type?: string; endings?: string; @@ -17933,6 +17932,21 @@ interface EventListenerObject { declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; +interface MessageEventInit extends EventInit { + data?: any; + origin?: string; + lastEventId?: string; + channel?: string; + source?: any; + ports?: MessagePort[]; +} + +interface ProgressEventInit extends EventInit { + lengthComputable?: boolean; + loaded?: number; + total?: number; +} + interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void; } @@ -18262,8 +18276,7 @@ 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; -interface DOMTokenList { +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;interface DOMTokenList { [Symbol.iterator](): IterableIterator; } diff --git a/lib/lib.webworker.d.ts b/lib/lib.webworker.d.ts index ed9f18e8da..0f3e85da9f 100644 --- a/lib/lib.webworker.d.ts +++ b/lib/lib.webworker.d.ts @@ -776,7 +776,7 @@ interface MessageEvent extends Event { declare var MessageEvent: { prototype: MessageEvent; - new(): MessageEvent; + new(type: string, eventInitDict?: MessageEventInit): MessageEvent; } interface MessagePort extends EventTarget { @@ -829,7 +829,7 @@ interface ProgressEvent extends Event { declare var ProgressEvent: { prototype: ProgressEvent; - new(): ProgressEvent; + new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent; } interface WebSocket extends EventTarget { @@ -1100,6 +1100,21 @@ interface EventListenerObject { declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; +interface MessageEventInit extends EventInit { + data?: any; + origin?: string; + lastEventId?: string; + channel?: string; + source?: any; + ports?: MessagePort[]; +} + +interface ProgressEventInit extends EventInit { + lengthComputable?: boolean; + loaded?: number; + total?: number; +} + interface ErrorEventHandler { (message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void; } @@ -1156,4 +1171,4 @@ declare function postMessage(data: any): void; declare var console: Console; declare function addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void; declare function addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void; -declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; +declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; \ No newline at end of file diff --git a/lib/tsc.js b/lib/tsc.js index eb2a963b82..f9ce3ad902 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -1569,6 +1569,7 @@ var ts; 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." }, Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, + Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, 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." }, @@ -4482,6 +4483,7 @@ var ts; case 134: return node === parent_2.expression; case 137: + case 238: return true; case 186: return parent_2.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent_2); @@ -9823,7 +9825,6 @@ var ts; } if (!name) { parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); - return undefined; } var preName, postName; if (typeExpression) { @@ -11681,7 +11682,7 @@ var ts; } function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & 32 || targetSymbol.flags & 64) { + if (targetSymbol.flags & 32 || targetSymbol.flags & 64 || targetSymbol.flags & 524288) { buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaraiton, flags); } } @@ -18860,9 +18861,13 @@ var ts; function checkTypeNodeAsExpression(node) { if (node && node.kind === 149) { var root = getFirstIdentifier(node.typeName); - var rootSymbol = resolveName(root, root.text, 107455, undefined, undefined); - if (rootSymbol && rootSymbol.flags & 8388608 && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { - markAliasSymbolAsReferenced(rootSymbol); + var meaning = root.parent.kind === 149 ? 793056 : 1536; + var rootSymbol = resolveName(root, root.text, meaning | 8388608, undefined, undefined); + if (rootSymbol && rootSymbol.flags & 8388608) { + var aliasTarget = resolveAlias(rootSymbol); + if (aliasTarget.flags & 107455 && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { + markAliasSymbolAsReferenced(rootSymbol); + } } } } @@ -21147,6 +21152,9 @@ var ts; return ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; } var typeSymbol = resolveEntityName(typeName, 793056, true); + if (!typeSymbol) { + return ts.TypeReferenceSerializationKind.ObjectType; + } var type = getDeclaredTypeOfSymbol(typeSymbol); if (type === unknownType) { return ts.TypeReferenceSerializationKind.Unknown; @@ -23011,6 +23019,9 @@ var ts; if (ts.isSupportedExpressionWithTypeArguments(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } + else if (!isImplementsList && node.expression.kind === 91) { + write("null"); + } function getHeritageClauseVisibilityError(symbolAccesibilityResult) { var diagnosticMessage; if (node.parent.parent.kind === 212) { @@ -24708,7 +24719,12 @@ var ts; return; } } - writeTextOfNode(currentSourceFile, node); + if (ts.nodeIsSynthesized(node)) { + write(node.text); + } + else { + writeTextOfNode(currentSourceFile, node); + } } function isNameOfNestedRedeclaration(node) { if (languageVersion < 2) { @@ -24733,6 +24749,9 @@ var ts; else if (isNameOfNestedRedeclaration(node)) { write(getGeneratedNameForNode(node)); } + else if (ts.nodeIsSynthesized(node)) { + write(node.text); + } else { writeTextOfNode(currentSourceFile, node); } @@ -28558,7 +28577,7 @@ var ts; } function trimReactWhitespaceAndApplyEntities(node) { var result = undefined; - var text = ts.getTextOfNode(node); + var text = ts.getTextOfNode(node, true); var firstNonWhitespace = 0; var lastNonWhitespace = -1; for (var i = 0; i < text.length; i++) { @@ -29362,10 +29381,124 @@ var ts; } ts.resolveTripleslashReference = resolveTripleslashReference; function resolveModuleName(moduleName, containingFile, compilerOptions, host) { - return legacyNameResolver(moduleName, containingFile, compilerOptions, host); + var moduleResolution = compilerOptions.moduleResolution !== undefined + ? compilerOptions.moduleResolution + : compilerOptions.module === 1 ? 2 : 1; + switch (moduleResolution) { + case 2: return nodeModuleNameResolver(moduleName, containingFile, host); + case 1: return classicNameResolver(moduleName, containingFile, compilerOptions, host); + } } ts.resolveModuleName = resolveModuleName; - function legacyNameResolver(moduleName, containingFile, compilerOptions, host) { + function nodeModuleNameResolver(moduleName, containingFile, host) { + var containingDirectory = ts.getDirectoryPath(containingFile); + if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) { + var failedLookupLocations = []; + var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); + var resolvedFileName = loadNodeModuleFromFile(candidate, false, failedLookupLocations, host); + if (resolvedFileName) { + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + resolvedFileName = loadNodeModuleFromDirectory(candidate, false, failedLookupLocations, host); + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + else { + return loadModuleFromNodeModules(moduleName, containingDirectory, host); + } + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function loadNodeModuleFromFile(candidate, loadOnlyDts, failedLookupLocation, host) { + if (loadOnlyDts) { + return tryLoad(".d.ts"); + } + else { + return ts.forEach(ts.supportedExtensions, tryLoad); + } + function tryLoad(ext) { + var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; + if (host.fileExists(fileName)) { + return fileName; + } + else { + failedLookupLocation.push(fileName); + return undefined; + } + } + } + function loadNodeModuleFromDirectory(candidate, loadOnlyDts, failedLookupLocation, host) { + var packageJsonPath = ts.combinePaths(candidate, "package.json"); + if (host.fileExists(packageJsonPath)) { + var jsonContent; + try { + var jsonText = host.readFile(packageJsonPath); + jsonContent = jsonText ? JSON.parse(jsonText) : { typings: undefined }; + } + catch (e) { + jsonContent = { typings: undefined }; + } + if (jsonContent.typings) { + var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), loadOnlyDts, failedLookupLocation, host); + if (result) { + return result; + } + } + } + else { + failedLookupLocation.push(packageJsonPath); + } + return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), loadOnlyDts, failedLookupLocation, host); + } + function loadModuleFromNodeModules(moduleName, directory, host) { + var failedLookupLocations = []; + directory = ts.normalizeSlashes(directory); + while (true) { + var baseName = ts.getBaseFileName(directory); + if (baseName !== "node_modules") { + var nodeModulesFolder = ts.combinePaths(directory, "node_modules"); + var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); + var result = loadNodeModuleFromFile(candidate, true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + result = loadNodeModuleFromDirectory(candidate, true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + } + var parentPath = ts.getDirectoryPath(directory); + if (parentPath === directory) { + break; + } + directory = parentPath; + } + return { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + } + function baseUrlModuleNameResolver(moduleName, containingFile, baseUrl, host) { + ts.Debug.assert(baseUrl !== undefined); + var normalizedModuleName = ts.normalizeSlashes(moduleName); + var basePart = useBaseUrl(moduleName) ? baseUrl : ts.getDirectoryPath(containingFile); + var candidate = ts.normalizePath(ts.combinePaths(basePart, moduleName)); + var failedLookupLocations = []; + return ts.forEach(ts.supportedExtensions, function (ext) { return tryLoadFile(candidate + ext); }) || { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + function tryLoadFile(location) { + if (host.fileExists(location)) { + return { resolvedFileName: location, failedLookupLocations: failedLookupLocations }; + } + else { + failedLookupLocations.push(location); + return undefined; + } + } + } + ts.baseUrlModuleNameResolver = baseUrlModuleNameResolver; + function nameStartsWithDotSlashOrDotDotSlash(name) { + var i = name.lastIndexOf("./", 1); + return i === 0 || (i === 1 && name.charCodeAt(0) === 46); + } + function useBaseUrl(moduleName) { + return ts.getRootLength(moduleName) === 0 && !nameStartsWithDotSlashOrDotDotSlash(moduleName); + } + function classicNameResolver(moduleName, containingFile, compilerOptions, host) { if (moduleName.indexOf('!') != -1) { return { resolvedFileName: undefined, failedLookupLocations: [] }; } @@ -29398,6 +29531,7 @@ var ts; } return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } + ts.classicNameResolver = classicNameResolver; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -30262,6 +30396,15 @@ var ts; type: "boolean", experimental: true, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators + }, + { + name: "moduleResolution", + type: { + "node": 2, + "classic": 1 + }, + experimental: true, + description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; function parseCommandLine(commandLine) { diff --git a/lib/tsserver.js b/lib/tsserver.js index 6fdd0b20f3..e01d4f0527 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -1569,6 +1569,7 @@ var ts; 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." }, Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, + Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, 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." }, @@ -3200,6 +3201,15 @@ var ts; type: "boolean", experimental: true, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators + }, + { + name: "moduleResolution", + type: { + "node": 2, + "classic": 1 + }, + experimental: true, + description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; function parseCommandLine(commandLine) { @@ -4203,6 +4213,7 @@ var ts; case 134: return node === parent_2.expression; case 137: + case 238: return true; case 186: return parent_2.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent_2); @@ -9544,7 +9555,6 @@ var ts; } if (!name) { parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); - return undefined; } var preName, postName; if (typeExpression) { @@ -12113,7 +12123,7 @@ var ts; } function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & 32 || targetSymbol.flags & 64) { + if (targetSymbol.flags & 32 || targetSymbol.flags & 64 || targetSymbol.flags & 524288) { buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaraiton, flags); } } @@ -19292,9 +19302,13 @@ var ts; function checkTypeNodeAsExpression(node) { if (node && node.kind === 149) { var root = getFirstIdentifier(node.typeName); - var rootSymbol = resolveName(root, root.text, 107455, undefined, undefined); - if (rootSymbol && rootSymbol.flags & 8388608 && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { - markAliasSymbolAsReferenced(rootSymbol); + var meaning = root.parent.kind === 149 ? 793056 : 1536; + var rootSymbol = resolveName(root, root.text, meaning | 8388608, undefined, undefined); + if (rootSymbol && rootSymbol.flags & 8388608) { + var aliasTarget = resolveAlias(rootSymbol); + if (aliasTarget.flags & 107455 && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { + markAliasSymbolAsReferenced(rootSymbol); + } } } } @@ -21579,6 +21593,9 @@ var ts; return ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; } var typeSymbol = resolveEntityName(typeName, 793056, true); + if (!typeSymbol) { + return ts.TypeReferenceSerializationKind.ObjectType; + } var type = getDeclaredTypeOfSymbol(typeSymbol); if (type === unknownType) { return ts.TypeReferenceSerializationKind.Unknown; @@ -23443,6 +23460,9 @@ var ts; if (ts.isSupportedExpressionWithTypeArguments(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } + else if (!isImplementsList && node.expression.kind === 91) { + write("null"); + } function getHeritageClauseVisibilityError(symbolAccesibilityResult) { var diagnosticMessage; if (node.parent.parent.kind === 212) { @@ -25140,7 +25160,12 @@ var ts; return; } } - writeTextOfNode(currentSourceFile, node); + if (ts.nodeIsSynthesized(node)) { + write(node.text); + } + else { + writeTextOfNode(currentSourceFile, node); + } } function isNameOfNestedRedeclaration(node) { if (languageVersion < 2) { @@ -25165,6 +25190,9 @@ var ts; else if (isNameOfNestedRedeclaration(node)) { write(getGeneratedNameForNode(node)); } + else if (ts.nodeIsSynthesized(node)) { + write(node.text); + } else { writeTextOfNode(currentSourceFile, node); } @@ -28990,7 +29018,7 @@ var ts; } function trimReactWhitespaceAndApplyEntities(node) { var result = undefined; - var text = ts.getTextOfNode(node); + var text = ts.getTextOfNode(node, true); var firstNonWhitespace = 0; var lastNonWhitespace = -1; for (var i = 0; i < text.length; i++) { @@ -29794,10 +29822,124 @@ var ts; } ts.resolveTripleslashReference = resolveTripleslashReference; function resolveModuleName(moduleName, containingFile, compilerOptions, host) { - return legacyNameResolver(moduleName, containingFile, compilerOptions, host); + var moduleResolution = compilerOptions.moduleResolution !== undefined + ? compilerOptions.moduleResolution + : compilerOptions.module === 1 ? 2 : 1; + switch (moduleResolution) { + case 2: return nodeModuleNameResolver(moduleName, containingFile, host); + case 1: return classicNameResolver(moduleName, containingFile, compilerOptions, host); + } } ts.resolveModuleName = resolveModuleName; - function legacyNameResolver(moduleName, containingFile, compilerOptions, host) { + function nodeModuleNameResolver(moduleName, containingFile, host) { + var containingDirectory = ts.getDirectoryPath(containingFile); + if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) { + var failedLookupLocations = []; + var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); + var resolvedFileName = loadNodeModuleFromFile(candidate, false, failedLookupLocations, host); + if (resolvedFileName) { + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + resolvedFileName = loadNodeModuleFromDirectory(candidate, false, failedLookupLocations, host); + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + else { + return loadModuleFromNodeModules(moduleName, containingDirectory, host); + } + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function loadNodeModuleFromFile(candidate, loadOnlyDts, failedLookupLocation, host) { + if (loadOnlyDts) { + return tryLoad(".d.ts"); + } + else { + return ts.forEach(ts.supportedExtensions, tryLoad); + } + function tryLoad(ext) { + var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; + if (host.fileExists(fileName)) { + return fileName; + } + else { + failedLookupLocation.push(fileName); + return undefined; + } + } + } + function loadNodeModuleFromDirectory(candidate, loadOnlyDts, failedLookupLocation, host) { + var packageJsonPath = ts.combinePaths(candidate, "package.json"); + if (host.fileExists(packageJsonPath)) { + var jsonContent; + try { + var jsonText = host.readFile(packageJsonPath); + jsonContent = jsonText ? JSON.parse(jsonText) : { typings: undefined }; + } + catch (e) { + jsonContent = { typings: undefined }; + } + if (jsonContent.typings) { + var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), loadOnlyDts, failedLookupLocation, host); + if (result) { + return result; + } + } + } + else { + failedLookupLocation.push(packageJsonPath); + } + return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), loadOnlyDts, failedLookupLocation, host); + } + function loadModuleFromNodeModules(moduleName, directory, host) { + var failedLookupLocations = []; + directory = ts.normalizeSlashes(directory); + while (true) { + var baseName = ts.getBaseFileName(directory); + if (baseName !== "node_modules") { + var nodeModulesFolder = ts.combinePaths(directory, "node_modules"); + var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); + var result = loadNodeModuleFromFile(candidate, true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + result = loadNodeModuleFromDirectory(candidate, true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + } + var parentPath = ts.getDirectoryPath(directory); + if (parentPath === directory) { + break; + } + directory = parentPath; + } + return { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + } + function baseUrlModuleNameResolver(moduleName, containingFile, baseUrl, host) { + ts.Debug.assert(baseUrl !== undefined); + var normalizedModuleName = ts.normalizeSlashes(moduleName); + var basePart = useBaseUrl(moduleName) ? baseUrl : ts.getDirectoryPath(containingFile); + var candidate = ts.normalizePath(ts.combinePaths(basePart, moduleName)); + var failedLookupLocations = []; + return ts.forEach(ts.supportedExtensions, function (ext) { return tryLoadFile(candidate + ext); }) || { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + function tryLoadFile(location) { + if (host.fileExists(location)) { + return { resolvedFileName: location, failedLookupLocations: failedLookupLocations }; + } + else { + failedLookupLocations.push(location); + return undefined; + } + } + } + ts.baseUrlModuleNameResolver = baseUrlModuleNameResolver; + function nameStartsWithDotSlashOrDotDotSlash(name) { + var i = name.lastIndexOf("./", 1); + return i === 0 || (i === 1 && name.charCodeAt(0) === 46); + } + function useBaseUrl(moduleName) { + return ts.getRootLength(moduleName) === 0 && !nameStartsWithDotSlashOrDotDotSlash(moduleName); + } + function classicNameResolver(moduleName, containingFile, compilerOptions, host) { if (moduleName.indexOf('!') != -1) { return { resolvedFileName: undefined, failedLookupLocations: [] }; } @@ -29830,6 +29972,7 @@ var ts; } return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } + ts.classicNameResolver = classicNameResolver; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -32608,6 +32751,34 @@ var ts; } } ts.hasDocComment = hasDocComment; + function getJsDocTagAtPosition(sourceFile, position) { + var node = ts.getTokenAtPosition(sourceFile, position); + if (isToken(node)) { + switch (node.kind) { + case 100: + case 106: + case 72: + node = node.parent === undefined ? undefined : node.parent.parent; + break; + default: + node = node.parent; + break; + } + } + if (node) { + var jsDocComment = node.jsDocComment; + if (jsDocComment) { + for (var _i = 0, _a = jsDocComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.pos <= position && position <= tag.end) { + return tag; + } + } + } + } + return undefined; + } + ts.getJsDocTagAtPosition = getJsDocTagAtPosition; function nodeHasTokens(n) { return n.getWidth() !== 0; } @@ -35172,6 +35343,45 @@ var ts; })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {})); var scanner = ts.createScanner(2, true); var emptyArray = []; + var jsDocTagNames = [ + "augments", + "author", + "argument", + "borrows", + "class", + "constant", + "constructor", + "constructs", + "default", + "deprecated", + "description", + "event", + "example", + "extends", + "field", + "fileOverview", + "function", + "ignore", + "inner", + "lends", + "link", + "memberOf", + "name", + "namespace", + "param", + "private", + "property", + "public", + "requires", + "returns", + "see", + "since", + "static", + "throws", + "type", + "version" + ]; + var jsDocCompletionEntries; function createNode(kind, pos, end, flags, parent) { var node = new (ts.getNodeConstructor(kind))(); node.pos = pos; @@ -36883,6 +37093,7 @@ var ts; var syntacticStart = new Date().getTime(); var sourceFile = getValidSourceFile(fileName); var isJavaScriptFile = ts.isJavaScript(fileName); + var isJsDocTagName = false; var start = new Date().getTime(); var currentToken = ts.getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); @@ -36890,8 +37101,33 @@ var ts; var insideComment = isInsideComment(sourceFile, currentToken, position); log("getCompletionData: Is inside comment: " + (new Date().getTime() - start)); if (insideComment) { - log("Returning an empty list because completion was inside a comment."); - return undefined; + if (ts.hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === 64) { + isJsDocTagName = true; + } + var insideJsDocTagExpression = false; + var tag = ts.getJsDocTagAtPosition(sourceFile, position); + if (tag) { + if (tag.tagName.pos <= position && position <= tag.tagName.end) { + isJsDocTagName = true; + } + switch (tag.kind) { + case 267: + case 265: + case 266: + var tagWithExpression = tag; + if (tagWithExpression.typeExpression) { + insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end; + } + break; + } + } + if (isJsDocTagName) { + return { symbols: undefined, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName: isJsDocTagName }; + } + if (!insideJsDocTagExpression) { + log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment."); + return undefined; + } } start = new Date().getTime(); var previousToken = ts.findPrecedingToken(position, sourceFile); @@ -36954,7 +37190,7 @@ var ts; } } log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart)); - return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag) }; + return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName: isJsDocTagName }; function getTypeScriptMemberSymbols() { isMemberCompletion = true; isNewIdentifierLocation = false; @@ -37247,9 +37483,10 @@ var ts; containingNodeKind === 215 || isFunction(containingNodeKind) || containingNodeKind === 212 || - containingNodeKind === 211 || + containingNodeKind === 184 || containingNodeKind === 213 || - containingNodeKind === 160; + containingNodeKind === 160 || + containingNodeKind === 214; case 21: return containingNodeKind === 160; case 53: @@ -37270,8 +37507,9 @@ var ts; contextToken.parent.parent.kind === 153); case 25: return containingNodeKind === 212 || - containingNodeKind === 211 || + containingNodeKind === 184 || containingNodeKind === 213 || + containingNodeKind === 214 || isFunction(containingNodeKind); case 111: return containingNodeKind === 139; @@ -37383,8 +37621,11 @@ var ts; if (!completionData) { return undefined; } - var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot; + var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot, isJsDocTagName = completionData.isJsDocTagName; var entries; + if (isJsDocTagName) { + return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() }; + } if (isRightOfDot && ts.isJavaScript(fileName)) { entries = getCompletionEntriesFromSymbols(symbols); ts.addRange(entries, getJavaScriptCompletionEntries()); @@ -37395,7 +37636,7 @@ var ts; } entries = getCompletionEntriesFromSymbols(symbols); } - if (!isMemberCompletion) { + if (!isMemberCompletion && !isJsDocTagName) { ts.addRange(entries, keywordCompletions); } return { isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries }; @@ -37424,6 +37665,16 @@ var ts; } return entries; } + function getAllJsDocCompletionEntries() { + return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, function (tagName) { + return { + name: tagName, + kind: ScriptElementKind.keyword, + kindModifiers: "", + sortText: "0" + }; + })); + } function createCompletionEntry(symbol, location) { var displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, true, location); if (!displayName) { @@ -37698,6 +37949,7 @@ var ts; displayParts.push(ts.keywordPart(130)); displayParts.push(ts.spacePart()); addFullSymbolName(symbol); + writeTypeParametersOfSymbol(symbol, sourceFile); displayParts.push(ts.spacePart()); displayParts.push(ts.operatorPart(55)); displayParts.push(ts.spacePart()); @@ -37736,16 +37988,26 @@ var ts; writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration); } else { - var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135).parent; - var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); - if (signatureDeclaration.kind === 146) { - displayParts.push(ts.keywordPart(90)); + var container = ts.getContainingFunction(location); + if (container) { + var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135).parent; + var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); + if (signatureDeclaration.kind === 146) { + displayParts.push(ts.keywordPart(90)); + displayParts.push(ts.spacePart()); + } + else if (signatureDeclaration.kind !== 145 && signatureDeclaration.name) { + addFullSymbolName(signatureDeclaration.symbol); + } + ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32)); + } + else { + var declaration = ts.getDeclarationOfKind(symbol, 135).parent; + displayParts.push(ts.keywordPart(130)); displayParts.push(ts.spacePart()); + addFullSymbolName(declaration.symbol); + writeTypeParametersOfSymbol(declaration.symbol, sourceFile); } - else if (signatureDeclaration.kind !== 145 && signatureDeclaration.name) { - addFullSymbolName(signatureDeclaration.symbol); - } - ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32)); } } if (symbolFlags & 8) { @@ -37951,9 +38213,13 @@ var ts; function tryAddConstructSignature(symbol, location, symbolKind, symbolName, containerName, result) { if (isNewExpressionTarget(location) || location.kind === 119) { if (symbol.flags & 32) { - var classDeclaration = symbol.getDeclarations()[0]; - ts.Debug.assert(classDeclaration && classDeclaration.kind === 212); - return tryAddSignature(classDeclaration.members, true, symbolKind, symbolName, containerName, result); + for (var _i = 0, _a = symbol.getDeclarations(); _i < _a.length; _i++) { + var declaration = _a[_i]; + if (ts.isClassLike(declaration)) { + return tryAddSignature(declaration.members, true, symbolKind, symbolName, containerName, result); + } + } + ts.Debug.fail("Expected declaration to have at least one class-like declaration"); } } return false; @@ -42229,13 +42495,15 @@ var ts; info = this.openFile(fileName, false); } else { - if (this.openFileRoots.indexOf(info) >= 0) { - this.openFileRoots = copyListRemovingItem(info, this.openFileRoots); + if (info.isOpen) { + if (this.openFileRoots.indexOf(info) >= 0) { + this.openFileRoots = copyListRemovingItem(info, this.openFileRoots); + } + if (this.openFilesReferenced.indexOf(info) >= 0) { + this.openFilesReferenced = copyListRemovingItem(info, this.openFilesReferenced); + } + this.openFileRootsConfigured.push(info); } - if (this.openFilesReferenced.indexOf(info) >= 0) { - this.openFilesReferenced = copyListRemovingItem(info, this.openFilesReferenced); - } - this.openFileRootsConfigured.push(info); } project.addRoot(info); } diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index edeb166cf8..604bdbf373 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -1293,6 +1293,10 @@ declare module "typescript" { Error = 1, Message = 2, } + const enum ModuleResolutionKind { + Classic = 1, + NodeJs = 2, + } interface CompilerOptions { allowNonTsExtensions?: boolean; charset?: string; @@ -1332,6 +1336,7 @@ declare module "typescript" { experimentalDecorators?: boolean; experimentalAsyncFunctions?: boolean; emitDecoratorMetadata?: boolean; + moduleResolution?: ModuleResolutionKind; [option: string]: string | number | boolean; } const enum ModuleKind { @@ -1509,6 +1514,9 @@ declare module "typescript" { function findConfigFile(searchPath: string): string; function resolveTripleslashReference(moduleName: string, containingFile: string): string; function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule; + function nodeModuleNameResolver(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModule; + function baseUrlModuleNameResolver(moduleName: string, containingFile: string, baseUrl: string, host: ModuleResolutionHost): ResolvedModule; + function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule; function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string; diff --git a/lib/typescript.js b/lib/typescript.js index 9507f25db6..bcb172085b 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -644,6 +644,11 @@ var ts; DiagnosticCategory[DiagnosticCategory["Message"] = 2] = "Message"; })(ts.DiagnosticCategory || (ts.DiagnosticCategory = {})); var DiagnosticCategory = ts.DiagnosticCategory; + (function (ModuleResolutionKind) { + ModuleResolutionKind[ModuleResolutionKind["Classic"] = 1] = "Classic"; + ModuleResolutionKind[ModuleResolutionKind["NodeJs"] = 2] = "NodeJs"; + })(ts.ModuleResolutionKind || (ts.ModuleResolutionKind = {})); + var ModuleResolutionKind = ts.ModuleResolutionKind; (function (ModuleKind) { ModuleKind[ModuleKind["None"] = 0] = "None"; ModuleKind[ModuleKind["CommonJS"] = 1] = "CommonJS"; @@ -2433,6 +2438,7 @@ var ts; 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." }, Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, + Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, 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." }, @@ -5832,6 +5838,7 @@ var ts; case 134 /* ComputedPropertyName */: return node === parent_2.expression; case 137 /* Decorator */: + case 238 /* JsxExpression */: return true; case 186 /* ExpressionWithTypeArguments */: return parent_2.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent_2); @@ -12258,7 +12265,6 @@ var ts; } if (!name) { parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); - return undefined; } var preName, postName; if (typeExpression) { @@ -14561,7 +14567,7 @@ var ts; } function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */) { + if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */ || targetSymbol.flags & 524288 /* TypeAlias */) { buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaraiton, flags); } } @@ -23164,9 +23170,16 @@ var ts; // serialize the type metadata. if (node && node.kind === 149 /* TypeReference */) { var root = getFirstIdentifier(node.typeName); - var rootSymbol = resolveName(root, root.text, 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); - if (rootSymbol && rootSymbol.flags & 8388608 /* Alias */ && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { - markAliasSymbolAsReferenced(rootSymbol); + var meaning = root.parent.kind === 149 /* TypeReference */ ? 793056 /* Type */ : 1536 /* Namespace */; + // Resolve type so we know which symbol is referenced + var rootSymbol = resolveName(root, root.text, meaning | 8388608 /* Alias */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); + // Resolved symbol is alias + if (rootSymbol && rootSymbol.flags & 8388608 /* Alias */) { + var aliasTarget = resolveAlias(rootSymbol); + // If alias has value symbol - mark alias as referenced + if (aliasTarget.flags & 107455 /* Value */ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { + markAliasSymbolAsReferenced(rootSymbol); + } } } } @@ -25835,6 +25848,10 @@ var ts; } // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. var typeSymbol = resolveEntityName(typeName, 793056 /* Type */, /*ignoreErrors*/ true); + // We might not be able to resolve type symbol so use unknown type in that case (eg error case) + if (!typeSymbol) { + return ts.TypeReferenceSerializationKind.ObjectType; + } var type = getDeclaredTypeOfSymbol(typeSymbol); if (type === unknownType) { return ts.TypeReferenceSerializationKind.Unknown; @@ -27820,6 +27837,9 @@ var ts; if (ts.isSupportedExpressionWithTypeArguments(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } + else if (!isImplementsList && node.expression.kind === 91 /* NullKeyword */) { + write("null"); + } function getHeritageClauseVisibilityError(symbolAccesibilityResult) { var diagnosticMessage; // Heritage clause is written by user so it can always be named @@ -29775,7 +29795,12 @@ var ts; return; } } - writeTextOfNode(currentSourceFile, node); + if (ts.nodeIsSynthesized(node)) { + write(node.text); + } + else { + writeTextOfNode(currentSourceFile, node); + } } function isNameOfNestedRedeclaration(node) { if (languageVersion < 2 /* ES6 */) { @@ -29800,6 +29825,9 @@ var ts; else if (isNameOfNestedRedeclaration(node)) { write(getGeneratedNameForNode(node)); } + else if (ts.nodeIsSynthesized(node)) { + write(node.text); + } else { writeTextOfNode(currentSourceFile, node); } @@ -34261,7 +34289,7 @@ var ts; } function trimReactWhitespaceAndApplyEntities(node) { var result = undefined; - var text = ts.getTextOfNode(node); + var text = ts.getTextOfNode(node, /*includeTrivia*/ true); var firstNonWhitespace = 0; var lastNonWhitespace = -1; // JSX trims whitespace at the end and beginning of lines, except that the @@ -34312,7 +34340,7 @@ var ts; } case 1 /* Preserve */: default: - return ts.getTextOfNode(node, true); + return ts.getTextOfNode(node, /*includeTrivia*/ true); } } function emitJsxText(node) { @@ -34324,7 +34352,7 @@ var ts; break; case 1 /* Preserve */: default: - writer.writeLiteral(ts.getTextOfNode(node, true)); + writer.writeLiteral(ts.getTextOfNode(node, /*includeTrivia*/ true)); break; } } @@ -35124,11 +35152,128 @@ var ts; } ts.resolveTripleslashReference = resolveTripleslashReference; function resolveModuleName(moduleName, containingFile, compilerOptions, host) { - // TODO: use different resolution strategy based on compiler options - return legacyNameResolver(moduleName, containingFile, compilerOptions, host); + var moduleResolution = compilerOptions.moduleResolution !== undefined + ? compilerOptions.moduleResolution + : compilerOptions.module === 1 /* CommonJS */ ? 2 /* NodeJs */ : 1 /* Classic */; + switch (moduleResolution) { + case 2 /* NodeJs */: return nodeModuleNameResolver(moduleName, containingFile, host); + case 1 /* Classic */: return classicNameResolver(moduleName, containingFile, compilerOptions, host); + } } ts.resolveModuleName = resolveModuleName; - function legacyNameResolver(moduleName, containingFile, compilerOptions, host) { + function nodeModuleNameResolver(moduleName, containingFile, host) { + var containingDirectory = ts.getDirectoryPath(containingFile); + if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) { + var failedLookupLocations = []; + var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); + var resolvedFileName = loadNodeModuleFromFile(candidate, /* loadOnlyDts */ false, failedLookupLocations, host); + if (resolvedFileName) { + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + resolvedFileName = loadNodeModuleFromDirectory(candidate, /* loadOnlyDts */ false, failedLookupLocations, host); + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + else { + return loadModuleFromNodeModules(moduleName, containingDirectory, host); + } + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function loadNodeModuleFromFile(candidate, loadOnlyDts, failedLookupLocation, host) { + if (loadOnlyDts) { + return tryLoad(".d.ts"); + } + else { + return ts.forEach(ts.supportedExtensions, tryLoad); + } + function tryLoad(ext) { + var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; + if (host.fileExists(fileName)) { + return fileName; + } + else { + failedLookupLocation.push(fileName); + return undefined; + } + } + } + function loadNodeModuleFromDirectory(candidate, loadOnlyDts, failedLookupLocation, host) { + var packageJsonPath = ts.combinePaths(candidate, "package.json"); + if (host.fileExists(packageJsonPath)) { + var jsonContent; + try { + var jsonText = host.readFile(packageJsonPath); + jsonContent = jsonText ? JSON.parse(jsonText) : { typings: undefined }; + } + catch (e) { + // gracefully handle if readFile fails or returns not JSON + jsonContent = { typings: undefined }; + } + if (jsonContent.typings) { + var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), loadOnlyDts, failedLookupLocation, host); + if (result) { + return result; + } + } + } + else { + // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results + failedLookupLocation.push(packageJsonPath); + } + return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), loadOnlyDts, failedLookupLocation, host); + } + function loadModuleFromNodeModules(moduleName, directory, host) { + var failedLookupLocations = []; + directory = ts.normalizeSlashes(directory); + while (true) { + var baseName = ts.getBaseFileName(directory); + if (baseName !== "node_modules") { + var nodeModulesFolder = ts.combinePaths(directory, "node_modules"); + var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); + var result = loadNodeModuleFromFile(candidate, /* loadOnlyDts */ true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + result = loadNodeModuleFromDirectory(candidate, /* loadOnlyDts */ true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + } + var parentPath = ts.getDirectoryPath(directory); + if (parentPath === directory) { + break; + } + directory = parentPath; + } + return { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + } + function baseUrlModuleNameResolver(moduleName, containingFile, baseUrl, host) { + ts.Debug.assert(baseUrl !== undefined); + var normalizedModuleName = ts.normalizeSlashes(moduleName); + var basePart = useBaseUrl(moduleName) ? baseUrl : ts.getDirectoryPath(containingFile); + var candidate = ts.normalizePath(ts.combinePaths(basePart, moduleName)); + var failedLookupLocations = []; + return ts.forEach(ts.supportedExtensions, function (ext) { return tryLoadFile(candidate + ext); }) || { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + function tryLoadFile(location) { + if (host.fileExists(location)) { + return { resolvedFileName: location, failedLookupLocations: failedLookupLocations }; + } + else { + failedLookupLocations.push(location); + return undefined; + } + } + } + ts.baseUrlModuleNameResolver = baseUrlModuleNameResolver; + function nameStartsWithDotSlashOrDotDotSlash(name) { + var i = name.lastIndexOf("./", 1); + return i === 0 || (i === 1 && name.charCodeAt(0) === 46 /* dot */); + } + function useBaseUrl(moduleName) { + // path is not rooted + // module name does not start with './' or '../' + return ts.getRootLength(moduleName) === 0 && !nameStartsWithDotSlashOrDotDotSlash(moduleName); + } + function classicNameResolver(moduleName, containingFile, compilerOptions, host) { // module names that contain '!' are used to reference resources and are not resolved to actual files on disk if (moduleName.indexOf('!') != -1) { return { resolvedFileName: undefined, failedLookupLocations: [] }; @@ -35164,6 +35309,7 @@ var ts; } return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } + ts.classicNameResolver = classicNameResolver; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -36103,6 +36249,15 @@ var ts; type: "boolean", experimental: true, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators + }, + { + name: "moduleResolution", + type: { + "node": 2 /* NodeJs */, + "classic": 1 /* Classic */ + }, + experimental: true, + description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; function parseCommandLine(commandLine) { @@ -38656,6 +38811,38 @@ var ts; } } ts.hasDocComment = hasDocComment; + /** + * Get the corresponding JSDocTag node if the position is in a jsDoc comment + */ + function getJsDocTagAtPosition(sourceFile, position) { + var node = ts.getTokenAtPosition(sourceFile, position); + if (isToken(node)) { + switch (node.kind) { + case 100 /* VarKeyword */: + case 106 /* LetKeyword */: + case 72 /* ConstKeyword */: + // if the current token is var, let or const, skip the VariableDeclarationList + node = node.parent === undefined ? undefined : node.parent.parent; + break; + default: + node = node.parent; + break; + } + } + if (node) { + var jsDocComment = node.jsDocComment; + if (jsDocComment) { + for (var _i = 0, _a = jsDocComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.pos <= position && position <= tag.end) { + return tag; + } + } + } + } + return undefined; + } + ts.getJsDocTagAtPosition = getJsDocTagAtPosition; function nodeHasTokens(n) { // If we have a token or node that has a non-zero width, it must have tokens. // Note, that getWidth() does not take trivia into account. @@ -41591,6 +41778,45 @@ var ts; })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {})); var scanner = ts.createScanner(2 /* Latest */, /*skipTrivia*/ true); var emptyArray = []; + var jsDocTagNames = [ + "augments", + "author", + "argument", + "borrows", + "class", + "constant", + "constructor", + "constructs", + "default", + "deprecated", + "description", + "event", + "example", + "extends", + "field", + "fileOverview", + "function", + "ignore", + "inner", + "lends", + "link", + "memberOf", + "name", + "namespace", + "param", + "private", + "property", + "public", + "requires", + "returns", + "see", + "since", + "static", + "throws", + "type", + "version" + ]; + var jsDocCompletionEntries; function createNode(kind, pos, end, flags, parent) { var node = new (ts.getNodeConstructor(kind))(); node.pos = pos; @@ -43614,6 +43840,7 @@ var ts; var syntacticStart = new Date().getTime(); var sourceFile = getValidSourceFile(fileName); var isJavaScriptFile = ts.isJavaScript(fileName); + var isJsDocTagName = false; var start = new Date().getTime(); var currentToken = ts.getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); @@ -43622,8 +43849,40 @@ var ts; var insideComment = isInsideComment(sourceFile, currentToken, position); log("getCompletionData: Is inside comment: " + (new Date().getTime() - start)); if (insideComment) { - log("Returning an empty list because completion was inside a comment."); - return undefined; + // The current position is next to the '@' sign, when no tag name being provided yet. + // Provide a full list of tag names + if (ts.hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === 64 /* at */) { + isJsDocTagName = true; + } + // Completion should work inside certain JsDoc tags. For example: + // /** @type {number | string} */ + // Completion should work in the brackets + var insideJsDocTagExpression = false; + var tag = ts.getJsDocTagAtPosition(sourceFile, position); + if (tag) { + if (tag.tagName.pos <= position && position <= tag.tagName.end) { + isJsDocTagName = true; + } + switch (tag.kind) { + case 267 /* JSDocTypeTag */: + case 265 /* JSDocParameterTag */: + case 266 /* JSDocReturnTag */: + var tagWithExpression = tag; + if (tagWithExpression.typeExpression) { + insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end; + } + break; + } + } + if (isJsDocTagName) { + return { symbols: undefined, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName: isJsDocTagName }; + } + if (!insideJsDocTagExpression) { + // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal + // comment or the plain text part of a jsDoc comment, so no completion should be available + log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment."); + return undefined; + } } start = new Date().getTime(); var previousToken = ts.findPrecedingToken(position, sourceFile); @@ -43699,7 +43958,7 @@ var ts; } } log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart)); - return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag) }; + return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName: isJsDocTagName }; function getTypeScriptMemberSymbols() { // Right of dot member completion list isMemberCompletion = true; @@ -44083,9 +44342,10 @@ var ts; containingNodeKind === 215 /* EnumDeclaration */ || isFunction(containingNodeKind) || containingNodeKind === 212 /* ClassDeclaration */ || - containingNodeKind === 211 /* FunctionDeclaration */ || + containingNodeKind === 184 /* ClassExpression */ || containingNodeKind === 213 /* InterfaceDeclaration */ || - containingNodeKind === 160 /* ArrayBindingPattern */; // var [x, y| + containingNodeKind === 160 /* ArrayBindingPattern */ || + containingNodeKind === 214 /* TypeAliasDeclaration */; // type Map, K, | case 21 /* DotToken */: return containingNodeKind === 160 /* ArrayBindingPattern */; // var [.| case 53 /* ColonToken */: @@ -44106,8 +44366,9 @@ var ts; contextToken.parent.parent.kind === 153 /* TypeLiteral */); // let x : { a; | case 25 /* LessThanToken */: return containingNodeKind === 212 /* ClassDeclaration */ || - containingNodeKind === 211 /* FunctionDeclaration */ || + containingNodeKind === 184 /* ClassExpression */ || containingNodeKind === 213 /* InterfaceDeclaration */ || + containingNodeKind === 214 /* TypeAliasDeclaration */ || isFunction(containingNodeKind); case 111 /* StaticKeyword */: return containingNodeKind === 139 /* PropertyDeclaration */; @@ -44248,8 +44509,12 @@ var ts; if (!completionData) { return undefined; } - var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot; + var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot, isJsDocTagName = completionData.isJsDocTagName; var entries; + if (isJsDocTagName) { + // If the current position is a jsDoc tag name, only tag names should be provided for completion + return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() }; + } if (isRightOfDot && ts.isJavaScript(fileName)) { entries = getCompletionEntriesFromSymbols(symbols); ts.addRange(entries, getJavaScriptCompletionEntries()); @@ -44261,7 +44526,7 @@ var ts; entries = getCompletionEntriesFromSymbols(symbols); } // Add keywords if this is not a member completion list - if (!isMemberCompletion) { + if (!isMemberCompletion && !isJsDocTagName) { ts.addRange(entries, keywordCompletions); } return { isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries }; @@ -44290,6 +44555,16 @@ var ts; } return entries; } + function getAllJsDocCompletionEntries() { + return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, function (tagName) { + return { + name: tagName, + kind: ScriptElementKind.keyword, + kindModifiers: "", + sortText: "0" + }; + })); + } function createCompletionEntry(symbol, location) { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can @@ -44601,6 +44876,7 @@ var ts; displayParts.push(ts.keywordPart(130 /* TypeKeyword */)); displayParts.push(ts.spacePart()); addFullSymbolName(symbol); + writeTypeParametersOfSymbol(symbol, sourceFile); displayParts.push(ts.spacePart()); displayParts.push(ts.operatorPart(55 /* EqualsToken */)); displayParts.push(ts.spacePart()); @@ -44641,16 +44917,29 @@ var ts; } else { // Method/function type parameter - var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; - var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); - if (signatureDeclaration.kind === 146 /* ConstructSignature */) { - displayParts.push(ts.keywordPart(90 /* NewKeyword */)); + var container = ts.getContainingFunction(location); + if (container) { + var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; + var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); + if (signatureDeclaration.kind === 146 /* ConstructSignature */) { + displayParts.push(ts.keywordPart(90 /* NewKeyword */)); + displayParts.push(ts.spacePart()); + } + else if (signatureDeclaration.kind !== 145 /* CallSignature */ && signatureDeclaration.name) { + addFullSymbolName(signatureDeclaration.symbol); + } + ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */)); + } + else { + // Type aliash type parameter + // For example + // type list = T[]; // Both T will go through same code path + var declaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; + displayParts.push(ts.keywordPart(130 /* TypeKeyword */)); displayParts.push(ts.spacePart()); + addFullSymbolName(declaration.symbol); + writeTypeParametersOfSymbol(declaration.symbol, sourceFile); } - else if (signatureDeclaration.kind !== 145 /* CallSignature */ && signatureDeclaration.name) { - addFullSymbolName(signatureDeclaration.symbol); - } - ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */)); } } if (symbolFlags & 8 /* EnumMember */) { @@ -44863,9 +45152,15 @@ var ts; // and in either case the symbol has a construct signature definition, i.e. class if (isNewExpressionTarget(location) || location.kind === 119 /* ConstructorKeyword */) { if (symbol.flags & 32 /* Class */) { - var classDeclaration = symbol.getDeclarations()[0]; - ts.Debug.assert(classDeclaration && classDeclaration.kind === 212 /* ClassDeclaration */); - return tryAddSignature(classDeclaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); + // Find the first class-like declaration and try to get the construct signature. + for (var _i = 0, _a = symbol.getDeclarations(); _i < _a.length; _i++) { + var declaration = _a[_i]; + if (ts.isClassLike(declaration)) { + return tryAddSignature(declaration.members, + /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); + } + } + ts.Debug.fail("Expected declaration to have at least one class-like declaration"); } } return false; diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index 890c77e5ae..7ea3324afe 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -1293,6 +1293,10 @@ declare namespace ts { Error = 1, Message = 2, } + const enum ModuleResolutionKind { + Classic = 1, + NodeJs = 2, + } interface CompilerOptions { allowNonTsExtensions?: boolean; charset?: string; @@ -1332,6 +1336,7 @@ declare namespace ts { experimentalDecorators?: boolean; experimentalAsyncFunctions?: boolean; emitDecoratorMetadata?: boolean; + moduleResolution?: ModuleResolutionKind; [option: string]: string | number | boolean; } const enum ModuleKind { @@ -1509,6 +1514,9 @@ declare namespace ts { function findConfigFile(searchPath: string): string; function resolveTripleslashReference(moduleName: string, containingFile: string): string; function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule; + function nodeModuleNameResolver(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModule; + function baseUrlModuleNameResolver(moduleName: string, containingFile: string, baseUrl: string, host: ModuleResolutionHost): ResolvedModule; + function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule; function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string; diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 9507f25db6..bcb172085b 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -644,6 +644,11 @@ var ts; DiagnosticCategory[DiagnosticCategory["Message"] = 2] = "Message"; })(ts.DiagnosticCategory || (ts.DiagnosticCategory = {})); var DiagnosticCategory = ts.DiagnosticCategory; + (function (ModuleResolutionKind) { + ModuleResolutionKind[ModuleResolutionKind["Classic"] = 1] = "Classic"; + ModuleResolutionKind[ModuleResolutionKind["NodeJs"] = 2] = "NodeJs"; + })(ts.ModuleResolutionKind || (ts.ModuleResolutionKind = {})); + var ModuleResolutionKind = ts.ModuleResolutionKind; (function (ModuleKind) { ModuleKind[ModuleKind["None"] = 0] = "None"; ModuleKind[ModuleKind["CommonJS"] = 1] = "CommonJS"; @@ -2433,6 +2438,7 @@ var ts; 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." }, Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: ts.DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." }, Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: ts.DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." }, + Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6: { code: 6069, category: ts.DiagnosticCategory.Message, key: "Specifies module resolution strategy: 'node' (Node) or 'classic' (TypeScript pre 1.6) ." }, 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." }, @@ -5832,6 +5838,7 @@ var ts; case 134 /* ComputedPropertyName */: return node === parent_2.expression; case 137 /* Decorator */: + case 238 /* JsxExpression */: return true; case 186 /* ExpressionWithTypeArguments */: return parent_2.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent_2); @@ -12258,7 +12265,6 @@ var ts; } if (!name) { parseErrorAtPosition(pos, 0, ts.Diagnostics.Identifier_expected); - return undefined; } var preName, postName; if (typeExpression) { @@ -14561,7 +14567,7 @@ var ts; } function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) { var targetSymbol = getTargetSymbol(symbol); - if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */) { + if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */ || targetSymbol.flags & 524288 /* TypeAlias */) { buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaraiton, flags); } } @@ -23164,9 +23170,16 @@ var ts; // serialize the type metadata. if (node && node.kind === 149 /* TypeReference */) { var root = getFirstIdentifier(node.typeName); - var rootSymbol = resolveName(root, root.text, 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); - if (rootSymbol && rootSymbol.flags & 8388608 /* Alias */ && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { - markAliasSymbolAsReferenced(rootSymbol); + var meaning = root.parent.kind === 149 /* TypeReference */ ? 793056 /* Type */ : 1536 /* Namespace */; + // Resolve type so we know which symbol is referenced + var rootSymbol = resolveName(root, root.text, meaning | 8388608 /* Alias */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); + // Resolved symbol is alias + if (rootSymbol && rootSymbol.flags & 8388608 /* Alias */) { + var aliasTarget = resolveAlias(rootSymbol); + // If alias has value symbol - mark alias as referenced + if (aliasTarget.flags & 107455 /* Value */ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { + markAliasSymbolAsReferenced(rootSymbol); + } } } } @@ -25835,6 +25848,10 @@ var ts; } // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. var typeSymbol = resolveEntityName(typeName, 793056 /* Type */, /*ignoreErrors*/ true); + // We might not be able to resolve type symbol so use unknown type in that case (eg error case) + if (!typeSymbol) { + return ts.TypeReferenceSerializationKind.ObjectType; + } var type = getDeclaredTypeOfSymbol(typeSymbol); if (type === unknownType) { return ts.TypeReferenceSerializationKind.Unknown; @@ -27820,6 +27837,9 @@ var ts; if (ts.isSupportedExpressionWithTypeArguments(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } + else if (!isImplementsList && node.expression.kind === 91 /* NullKeyword */) { + write("null"); + } function getHeritageClauseVisibilityError(symbolAccesibilityResult) { var diagnosticMessage; // Heritage clause is written by user so it can always be named @@ -29775,7 +29795,12 @@ var ts; return; } } - writeTextOfNode(currentSourceFile, node); + if (ts.nodeIsSynthesized(node)) { + write(node.text); + } + else { + writeTextOfNode(currentSourceFile, node); + } } function isNameOfNestedRedeclaration(node) { if (languageVersion < 2 /* ES6 */) { @@ -29800,6 +29825,9 @@ var ts; else if (isNameOfNestedRedeclaration(node)) { write(getGeneratedNameForNode(node)); } + else if (ts.nodeIsSynthesized(node)) { + write(node.text); + } else { writeTextOfNode(currentSourceFile, node); } @@ -34261,7 +34289,7 @@ var ts; } function trimReactWhitespaceAndApplyEntities(node) { var result = undefined; - var text = ts.getTextOfNode(node); + var text = ts.getTextOfNode(node, /*includeTrivia*/ true); var firstNonWhitespace = 0; var lastNonWhitespace = -1; // JSX trims whitespace at the end and beginning of lines, except that the @@ -34312,7 +34340,7 @@ var ts; } case 1 /* Preserve */: default: - return ts.getTextOfNode(node, true); + return ts.getTextOfNode(node, /*includeTrivia*/ true); } } function emitJsxText(node) { @@ -34324,7 +34352,7 @@ var ts; break; case 1 /* Preserve */: default: - writer.writeLiteral(ts.getTextOfNode(node, true)); + writer.writeLiteral(ts.getTextOfNode(node, /*includeTrivia*/ true)); break; } } @@ -35124,11 +35152,128 @@ var ts; } ts.resolveTripleslashReference = resolveTripleslashReference; function resolveModuleName(moduleName, containingFile, compilerOptions, host) { - // TODO: use different resolution strategy based on compiler options - return legacyNameResolver(moduleName, containingFile, compilerOptions, host); + var moduleResolution = compilerOptions.moduleResolution !== undefined + ? compilerOptions.moduleResolution + : compilerOptions.module === 1 /* CommonJS */ ? 2 /* NodeJs */ : 1 /* Classic */; + switch (moduleResolution) { + case 2 /* NodeJs */: return nodeModuleNameResolver(moduleName, containingFile, host); + case 1 /* Classic */: return classicNameResolver(moduleName, containingFile, compilerOptions, host); + } } ts.resolveModuleName = resolveModuleName; - function legacyNameResolver(moduleName, containingFile, compilerOptions, host) { + function nodeModuleNameResolver(moduleName, containingFile, host) { + var containingDirectory = ts.getDirectoryPath(containingFile); + if (ts.getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) { + var failedLookupLocations = []; + var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); + var resolvedFileName = loadNodeModuleFromFile(candidate, /* loadOnlyDts */ false, failedLookupLocations, host); + if (resolvedFileName) { + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + resolvedFileName = loadNodeModuleFromDirectory(candidate, /* loadOnlyDts */ false, failedLookupLocations, host); + return { resolvedFileName: resolvedFileName, failedLookupLocations: failedLookupLocations }; + } + else { + return loadModuleFromNodeModules(moduleName, containingDirectory, host); + } + } + ts.nodeModuleNameResolver = nodeModuleNameResolver; + function loadNodeModuleFromFile(candidate, loadOnlyDts, failedLookupLocation, host) { + if (loadOnlyDts) { + return tryLoad(".d.ts"); + } + else { + return ts.forEach(ts.supportedExtensions, tryLoad); + } + function tryLoad(ext) { + var fileName = ts.fileExtensionIs(candidate, ext) ? candidate : candidate + ext; + if (host.fileExists(fileName)) { + return fileName; + } + else { + failedLookupLocation.push(fileName); + return undefined; + } + } + } + function loadNodeModuleFromDirectory(candidate, loadOnlyDts, failedLookupLocation, host) { + var packageJsonPath = ts.combinePaths(candidate, "package.json"); + if (host.fileExists(packageJsonPath)) { + var jsonContent; + try { + var jsonText = host.readFile(packageJsonPath); + jsonContent = jsonText ? JSON.parse(jsonText) : { typings: undefined }; + } + catch (e) { + // gracefully handle if readFile fails or returns not JSON + jsonContent = { typings: undefined }; + } + if (jsonContent.typings) { + var result = loadNodeModuleFromFile(ts.normalizePath(ts.combinePaths(candidate, jsonContent.typings)), loadOnlyDts, failedLookupLocation, host); + if (result) { + return result; + } + } + } + else { + // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results + failedLookupLocation.push(packageJsonPath); + } + return loadNodeModuleFromFile(ts.combinePaths(candidate, "index"), loadOnlyDts, failedLookupLocation, host); + } + function loadModuleFromNodeModules(moduleName, directory, host) { + var failedLookupLocations = []; + directory = ts.normalizeSlashes(directory); + while (true) { + var baseName = ts.getBaseFileName(directory); + if (baseName !== "node_modules") { + var nodeModulesFolder = ts.combinePaths(directory, "node_modules"); + var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); + var result = loadNodeModuleFromFile(candidate, /* loadOnlyDts */ true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + result = loadNodeModuleFromDirectory(candidate, /* loadOnlyDts */ true, failedLookupLocations, host); + if (result) { + return { resolvedFileName: result, failedLookupLocations: failedLookupLocations }; + } + } + var parentPath = ts.getDirectoryPath(directory); + if (parentPath === directory) { + break; + } + directory = parentPath; + } + return { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + } + function baseUrlModuleNameResolver(moduleName, containingFile, baseUrl, host) { + ts.Debug.assert(baseUrl !== undefined); + var normalizedModuleName = ts.normalizeSlashes(moduleName); + var basePart = useBaseUrl(moduleName) ? baseUrl : ts.getDirectoryPath(containingFile); + var candidate = ts.normalizePath(ts.combinePaths(basePart, moduleName)); + var failedLookupLocations = []; + return ts.forEach(ts.supportedExtensions, function (ext) { return tryLoadFile(candidate + ext); }) || { resolvedFileName: undefined, failedLookupLocations: failedLookupLocations }; + function tryLoadFile(location) { + if (host.fileExists(location)) { + return { resolvedFileName: location, failedLookupLocations: failedLookupLocations }; + } + else { + failedLookupLocations.push(location); + return undefined; + } + } + } + ts.baseUrlModuleNameResolver = baseUrlModuleNameResolver; + function nameStartsWithDotSlashOrDotDotSlash(name) { + var i = name.lastIndexOf("./", 1); + return i === 0 || (i === 1 && name.charCodeAt(0) === 46 /* dot */); + } + function useBaseUrl(moduleName) { + // path is not rooted + // module name does not start with './' or '../' + return ts.getRootLength(moduleName) === 0 && !nameStartsWithDotSlashOrDotDotSlash(moduleName); + } + function classicNameResolver(moduleName, containingFile, compilerOptions, host) { // module names that contain '!' are used to reference resources and are not resolved to actual files on disk if (moduleName.indexOf('!') != -1) { return { resolvedFileName: undefined, failedLookupLocations: [] }; @@ -35164,6 +35309,7 @@ var ts; } return { resolvedFileName: referencedSourceFile, failedLookupLocations: failedLookupLocations }; } + ts.classicNameResolver = classicNameResolver; function createCompilerHost(options, setParentNodes) { var currentDirectory; var existingDirectories = {}; @@ -36103,6 +36249,15 @@ var ts; type: "boolean", experimental: true, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators + }, + { + name: "moduleResolution", + type: { + "node": 2 /* NodeJs */, + "classic": 1 /* Classic */ + }, + experimental: true, + description: ts.Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_or_classic_TypeScript_pre_1_6 } ]; function parseCommandLine(commandLine) { @@ -38656,6 +38811,38 @@ var ts; } } ts.hasDocComment = hasDocComment; + /** + * Get the corresponding JSDocTag node if the position is in a jsDoc comment + */ + function getJsDocTagAtPosition(sourceFile, position) { + var node = ts.getTokenAtPosition(sourceFile, position); + if (isToken(node)) { + switch (node.kind) { + case 100 /* VarKeyword */: + case 106 /* LetKeyword */: + case 72 /* ConstKeyword */: + // if the current token is var, let or const, skip the VariableDeclarationList + node = node.parent === undefined ? undefined : node.parent.parent; + break; + default: + node = node.parent; + break; + } + } + if (node) { + var jsDocComment = node.jsDocComment; + if (jsDocComment) { + for (var _i = 0, _a = jsDocComment.tags; _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.pos <= position && position <= tag.end) { + return tag; + } + } + } + } + return undefined; + } + ts.getJsDocTagAtPosition = getJsDocTagAtPosition; function nodeHasTokens(n) { // If we have a token or node that has a non-zero width, it must have tokens. // Note, that getWidth() does not take trivia into account. @@ -41591,6 +41778,45 @@ var ts; })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {})); var scanner = ts.createScanner(2 /* Latest */, /*skipTrivia*/ true); var emptyArray = []; + var jsDocTagNames = [ + "augments", + "author", + "argument", + "borrows", + "class", + "constant", + "constructor", + "constructs", + "default", + "deprecated", + "description", + "event", + "example", + "extends", + "field", + "fileOverview", + "function", + "ignore", + "inner", + "lends", + "link", + "memberOf", + "name", + "namespace", + "param", + "private", + "property", + "public", + "requires", + "returns", + "see", + "since", + "static", + "throws", + "type", + "version" + ]; + var jsDocCompletionEntries; function createNode(kind, pos, end, flags, parent) { var node = new (ts.getNodeConstructor(kind))(); node.pos = pos; @@ -43614,6 +43840,7 @@ var ts; var syntacticStart = new Date().getTime(); var sourceFile = getValidSourceFile(fileName); var isJavaScriptFile = ts.isJavaScript(fileName); + var isJsDocTagName = false; var start = new Date().getTime(); var currentToken = ts.getTokenAtPosition(sourceFile, position); log("getCompletionData: Get current token: " + (new Date().getTime() - start)); @@ -43622,8 +43849,40 @@ var ts; var insideComment = isInsideComment(sourceFile, currentToken, position); log("getCompletionData: Is inside comment: " + (new Date().getTime() - start)); if (insideComment) { - log("Returning an empty list because completion was inside a comment."); - return undefined; + // The current position is next to the '@' sign, when no tag name being provided yet. + // Provide a full list of tag names + if (ts.hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === 64 /* at */) { + isJsDocTagName = true; + } + // Completion should work inside certain JsDoc tags. For example: + // /** @type {number | string} */ + // Completion should work in the brackets + var insideJsDocTagExpression = false; + var tag = ts.getJsDocTagAtPosition(sourceFile, position); + if (tag) { + if (tag.tagName.pos <= position && position <= tag.tagName.end) { + isJsDocTagName = true; + } + switch (tag.kind) { + case 267 /* JSDocTypeTag */: + case 265 /* JSDocParameterTag */: + case 266 /* JSDocReturnTag */: + var tagWithExpression = tag; + if (tagWithExpression.typeExpression) { + insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end; + } + break; + } + } + if (isJsDocTagName) { + return { symbols: undefined, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName: isJsDocTagName }; + } + if (!insideJsDocTagExpression) { + // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal + // comment or the plain text part of a jsDoc comment, so no completion should be available + log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment."); + return undefined; + } } start = new Date().getTime(); var previousToken = ts.findPrecedingToken(position, sourceFile); @@ -43699,7 +43958,7 @@ var ts; } } log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart)); - return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag) }; + return { symbols: symbols, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName: isJsDocTagName }; function getTypeScriptMemberSymbols() { // Right of dot member completion list isMemberCompletion = true; @@ -44083,9 +44342,10 @@ var ts; containingNodeKind === 215 /* EnumDeclaration */ || isFunction(containingNodeKind) || containingNodeKind === 212 /* ClassDeclaration */ || - containingNodeKind === 211 /* FunctionDeclaration */ || + containingNodeKind === 184 /* ClassExpression */ || containingNodeKind === 213 /* InterfaceDeclaration */ || - containingNodeKind === 160 /* ArrayBindingPattern */; // var [x, y| + containingNodeKind === 160 /* ArrayBindingPattern */ || + containingNodeKind === 214 /* TypeAliasDeclaration */; // type Map, K, | case 21 /* DotToken */: return containingNodeKind === 160 /* ArrayBindingPattern */; // var [.| case 53 /* ColonToken */: @@ -44106,8 +44366,9 @@ var ts; contextToken.parent.parent.kind === 153 /* TypeLiteral */); // let x : { a; | case 25 /* LessThanToken */: return containingNodeKind === 212 /* ClassDeclaration */ || - containingNodeKind === 211 /* FunctionDeclaration */ || + containingNodeKind === 184 /* ClassExpression */ || containingNodeKind === 213 /* InterfaceDeclaration */ || + containingNodeKind === 214 /* TypeAliasDeclaration */ || isFunction(containingNodeKind); case 111 /* StaticKeyword */: return containingNodeKind === 139 /* PropertyDeclaration */; @@ -44248,8 +44509,12 @@ var ts; if (!completionData) { return undefined; } - var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot; + var symbols = completionData.symbols, isMemberCompletion = completionData.isMemberCompletion, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, isRightOfDot = completionData.isRightOfDot, isJsDocTagName = completionData.isJsDocTagName; var entries; + if (isJsDocTagName) { + // If the current position is a jsDoc tag name, only tag names should be provided for completion + return { isMemberCompletion: false, isNewIdentifierLocation: false, entries: getAllJsDocCompletionEntries() }; + } if (isRightOfDot && ts.isJavaScript(fileName)) { entries = getCompletionEntriesFromSymbols(symbols); ts.addRange(entries, getJavaScriptCompletionEntries()); @@ -44261,7 +44526,7 @@ var ts; entries = getCompletionEntriesFromSymbols(symbols); } // Add keywords if this is not a member completion list - if (!isMemberCompletion) { + if (!isMemberCompletion && !isJsDocTagName) { ts.addRange(entries, keywordCompletions); } return { isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries }; @@ -44290,6 +44555,16 @@ var ts; } return entries; } + function getAllJsDocCompletionEntries() { + return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, function (tagName) { + return { + name: tagName, + kind: ScriptElementKind.keyword, + kindModifiers: "", + sortText: "0" + }; + })); + } function createCompletionEntry(symbol, location) { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can @@ -44601,6 +44876,7 @@ var ts; displayParts.push(ts.keywordPart(130 /* TypeKeyword */)); displayParts.push(ts.spacePart()); addFullSymbolName(symbol); + writeTypeParametersOfSymbol(symbol, sourceFile); displayParts.push(ts.spacePart()); displayParts.push(ts.operatorPart(55 /* EqualsToken */)); displayParts.push(ts.spacePart()); @@ -44641,16 +44917,29 @@ var ts; } else { // Method/function type parameter - var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; - var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); - if (signatureDeclaration.kind === 146 /* ConstructSignature */) { - displayParts.push(ts.keywordPart(90 /* NewKeyword */)); + var container = ts.getContainingFunction(location); + if (container) { + var signatureDeclaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; + var signature = typeChecker.getSignatureFromDeclaration(signatureDeclaration); + if (signatureDeclaration.kind === 146 /* ConstructSignature */) { + displayParts.push(ts.keywordPart(90 /* NewKeyword */)); + displayParts.push(ts.spacePart()); + } + else if (signatureDeclaration.kind !== 145 /* CallSignature */ && signatureDeclaration.name) { + addFullSymbolName(signatureDeclaration.symbol); + } + ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */)); + } + else { + // Type aliash type parameter + // For example + // type list = T[]; // Both T will go through same code path + var declaration = ts.getDeclarationOfKind(symbol, 135 /* TypeParameter */).parent; + displayParts.push(ts.keywordPart(130 /* TypeKeyword */)); displayParts.push(ts.spacePart()); + addFullSymbolName(declaration.symbol); + writeTypeParametersOfSymbol(declaration.symbol, sourceFile); } - else if (signatureDeclaration.kind !== 145 /* CallSignature */ && signatureDeclaration.name) { - addFullSymbolName(signatureDeclaration.symbol); - } - ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */)); } } if (symbolFlags & 8 /* EnumMember */) { @@ -44863,9 +45152,15 @@ var ts; // and in either case the symbol has a construct signature definition, i.e. class if (isNewExpressionTarget(location) || location.kind === 119 /* ConstructorKeyword */) { if (symbol.flags & 32 /* Class */) { - var classDeclaration = symbol.getDeclarations()[0]; - ts.Debug.assert(classDeclaration && classDeclaration.kind === 212 /* ClassDeclaration */); - return tryAddSignature(classDeclaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); + // Find the first class-like declaration and try to get the construct signature. + for (var _i = 0, _a = symbol.getDeclarations(); _i < _a.length; _i++) { + var declaration = _a[_i]; + if (ts.isClassLike(declaration)) { + return tryAddSignature(declaration.members, + /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); + } + } + ts.Debug.fail("Expected declaration to have at least one class-like declaration"); } } return false; From 175b9bf96f0a14270d5d8185790056a869f075c9 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 27 Aug 2015 14:06:06 -0700 Subject: [PATCH 2/2] Adds a "typings" property to package.json --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 166b73b4a9..abd81e12f4 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "url": "https://github.com/Microsoft/TypeScript.git" }, "main": "./lib/typescript.js", + "typings": "./lib/typescript.d.ts", "bin": { "tsc": "./bin/tsc", "tsserver": "./bin/tsserver"