From 78a79140b3a193af285416d4401b84c0180927d2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 6 Apr 2015 14:10:04 -0700 Subject: [PATCH] Get sighelp for arbitrary functions working in .js files. --- src/services/outliningElementsCollector.ts | 1 + src/services/services.ts | 4 -- src/services/signatureHelp.ts | 46 ++++++++++++++++++++++ src/services/utilities.ts | 4 ++ 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 4c9dcedc7a4..25e7671bbe4 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -35,6 +35,7 @@ module ts { return isFunctionBlock(node) && node.parent.kind !== SyntaxKind.ArrowFunction; } + let depth = 0; let maxDepth = 20; function walk(n: Node): void { diff --git a/src/services/services.ts b/src/services/services.ts index d23c5fa1dfb..25ecee61fdd 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2470,10 +2470,6 @@ module ts { return program.getSyntacticDiagnostics(getValidSourceFile(fileName)); } - function isJavaScript(fileName: string) { - return fileExtensionIs(fileName, ".js"); - } - /** * getSemanticDiagnostiscs return array of Diagnostics. If '-d' is not enabled, only report semantic errors * If '-d' enabled, report both semantic and emitter errors diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 93856912dce..07b963d2461 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -202,11 +202,57 @@ module ts.SignatureHelp { cancellationToken.throwIfCancellationRequested(); if (!candidates.length) { + // We didn't have any sig help items produced by the TS compiler. If this is a JS + // file, then see if we can figure out anything better. + if (isJavaScript(sourceFile.fileName)) { + return createJavaScriptSignatureHelpItems(argumentInfo); + } + return undefined; } return createSignatureHelpItems(candidates, resolvedSignature, argumentInfo); + function createJavaScriptSignatureHelpItems(argumentInfo: ArgumentListInfo): SignatureHelpItems { + if (argumentInfo.invocation.kind !== SyntaxKind.CallExpression) { + return undefined; + } + + // See if we can find some symbol with the call expression name that has call signatures. + let callExpression = argumentInfo.invocation; + let expression = callExpression.expression; + let name = expression.kind === SyntaxKind.Identifier + ? expression + : expression.kind === SyntaxKind.PropertyAccessExpression + ? (expression).name + : undefined; + + if (!name || !name.text) { + return undefined; + } + + let typeChecker = program.getTypeChecker(); + for (let sourceFile of program.getSourceFiles()) { + let nameToDeclarations = sourceFile.getNamedDeclarations(); + let declarations = getProperty(nameToDeclarations, name.text); + + if (declarations) { + for (let declaration of declarations) { + let symbol = declaration.symbol; + if (symbol) { + let type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration); + if (type) { + let callSignatures = type.getCallSignatures(); + if (callSignatures && callSignatures.length) { + return createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo); + } + } + } + } + } + } + } + /** * Returns relevant information for the argument list and the current argument if we are * in the argument of an invocation; returns undefined otherwise. diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 719aa658724..5ad392c5a6c 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -650,4 +650,8 @@ module ts { typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags); }); } + + export function isJavaScript(fileName: string) { + return fileExtensionIs(fileName, ".js"); + } } \ No newline at end of file