( compiler: NgCompiler, tsLS: ts.LanguageService, fileName: string, position: number, options: ts.SignatureHelpItemsOptions | undefined, )
| 19 | * Queries the TypeScript Language Service to get signature help for a template position. |
| 20 | */ |
| 21 | export function getSignatureHelp( |
| 22 | compiler: NgCompiler, |
| 23 | tsLS: ts.LanguageService, |
| 24 | fileName: string, |
| 25 | position: number, |
| 26 | options: ts.SignatureHelpItemsOptions | undefined, |
| 27 | ): ts.SignatureHelpItems | undefined { |
| 28 | const typeCheckInfo = getTypeCheckInfoAtPosition(fileName, position, compiler); |
| 29 | if (typeCheckInfo === undefined) { |
| 30 | return undefined; |
| 31 | } |
| 32 | |
| 33 | const targetInfo = getTargetAtPosition(typeCheckInfo.nodes, position); |
| 34 | if (targetInfo === null) { |
| 35 | return undefined; |
| 36 | } |
| 37 | |
| 38 | if ( |
| 39 | targetInfo.context.kind !== TargetNodeKind.RawExpression && |
| 40 | targetInfo.context.kind !== TargetNodeKind.CallExpressionInArgContext |
| 41 | ) { |
| 42 | // Signature completions are only available in expressions. |
| 43 | return undefined; |
| 44 | } |
| 45 | |
| 46 | const symbol = compiler |
| 47 | .getTemplateTypeChecker() |
| 48 | .getSymbolOfNode(targetInfo.context.node, typeCheckInfo.declaration); |
| 49 | if (symbol === null || symbol.kind !== SymbolKind.Expression) { |
| 50 | return undefined; |
| 51 | } |
| 52 | |
| 53 | // Determine a shim position to use in the request to the TypeScript Language Service. |
| 54 | // Additionally, extract the `Call` node for which signature help is being queried, as this |
| 55 | // is needed to construct the correct span for the results later. |
| 56 | let shimPosition: number; |
| 57 | let expr: Call | SafeCall; |
| 58 | switch (targetInfo.context.kind) { |
| 59 | case TargetNodeKind.RawExpression: |
| 60 | // For normal expressions, just use the primary TCB position of the expression. |
| 61 | shimPosition = symbol.tcbLocation.positionInFile; |
| 62 | |
| 63 | // Walk up the parents of this expression and try to find a |
| 64 | // `Call` for which signature information is being fetched. |
| 65 | let callExpr: Call | SafeCall | null = null; |
| 66 | const parents = targetInfo.context.parents; |
| 67 | for (let i = parents.length - 1; i >= 0; i--) { |
| 68 | const parent = parents[i]; |
| 69 | if (parent instanceof Call || parent instanceof SafeCall) { |
| 70 | callExpr = parent; |
| 71 | break; |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | // If no Call node could be found, then this query cannot be safely |
| 76 | // answered as a correct span for the results will not be obtainable. |
| 77 | if (callExpr === null) { |
| 78 | return undefined; |
no test coverage detected
searching dependent graphs…