@tslite/services 0.0.0-stage → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +55 -0
- package/NOTICE +13 -0
- package/dist/_namespaces/edit.d.ts +8 -0
- package/dist/_namespaces/edit.js +11 -0
- package/dist/_namespaces/ts.Completions.StringCompletions.d.ts +1 -0
- package/dist/_namespaces/ts.Completions.StringCompletions.js +2 -0
- package/dist/_namespaces/ts.Completions.d.ts +2 -0
- package/dist/_namespaces/ts.Completions.js +3 -0
- package/dist/_namespaces/ts.FindAllReferences.d.ts +2 -0
- package/dist/_namespaces/ts.FindAllReferences.js +3 -0
- package/dist/_namespaces/ts.GoToDefinition.d.ts +1 -0
- package/dist/_namespaces/ts.GoToDefinition.js +2 -0
- package/dist/_namespaces/ts.NavigationBar.d.ts +1 -0
- package/dist/_namespaces/ts.NavigationBar.js +2 -0
- package/dist/_namespaces/ts.OrganizeImports.d.ts +1 -0
- package/dist/_namespaces/ts.OrganizeImports.js +2 -0
- package/dist/_namespaces/ts.OutliningElementsCollector.d.ts +1 -0
- package/dist/_namespaces/ts.OutliningElementsCollector.js +2 -0
- package/dist/_namespaces/ts.Rename.d.ts +1 -0
- package/dist/_namespaces/ts.Rename.js +2 -0
- package/dist/_namespaces/ts.SignatureHelp.d.ts +1 -0
- package/dist/_namespaces/ts.SignatureHelp.js +2 -0
- package/dist/_namespaces/ts.SmartSelectionRange.d.ts +1 -0
- package/dist/_namespaces/ts.SmartSelectionRange.js +2 -0
- package/dist/_namespaces/ts.SymbolDisplay.d.ts +1 -0
- package/dist/_namespaces/ts.SymbolDisplay.js +2 -0
- package/dist/_namespaces/ts.codefix.d.ts +26 -0
- package/dist/_namespaces/ts.codefix.js +27 -0
- package/dist/_namespaces/ts.d.ts +17 -0
- package/dist/_namespaces/ts.formatting.d.ts +7 -0
- package/dist/_namespaces/ts.formatting.js +8 -0
- package/dist/_namespaces/ts.js +20 -0
- package/dist/_namespaces/ts.refactor.addOrRemoveBracesToArrowFunction.d.ts +1 -0
- package/dist/_namespaces/ts.refactor.addOrRemoveBracesToArrowFunction.js +2 -0
- package/dist/_namespaces/ts.refactor.convertParamsToDestructuredObject.d.ts +1 -0
- package/dist/_namespaces/ts.refactor.convertParamsToDestructuredObject.js +2 -0
- package/dist/_namespaces/ts.refactor.convertStringOrTemplateLiteral.d.ts +1 -0
- package/dist/_namespaces/ts.refactor.convertStringOrTemplateLiteral.js +2 -0
- package/dist/_namespaces/ts.refactor.d.ts +9 -0
- package/dist/_namespaces/ts.refactor.extractSymbol.d.ts +1 -0
- package/dist/_namespaces/ts.refactor.extractSymbol.js +2 -0
- package/dist/_namespaces/ts.refactor.js +10 -0
- package/dist/_namespaces/ts.textChanges.d.ts +1 -0
- package/dist/_namespaces/ts.textChanges.js +2 -0
- package/dist/classifier.d.ts +5 -0
- package/dist/classifier.js +439 -0
- package/dist/codeFixProvider.d.ts +13 -0
- package/dist/codeFixProvider.js +84 -0
- package/dist/codefixes/addConvertToUnknownForNonOverlappingTypes.d.ts +1 -0
- package/dist/codefixes/addConvertToUnknownForNonOverlappingTypes.js +21 -0
- package/dist/codefixes/addEmptyExportDeclaration.d.ts +1 -0
- package/dist/codefixes/addEmptyExportDeclaration.js +17 -0
- package/dist/codefixes/addMissingAsync.d.ts +1 -0
- package/dist/codefixes/addMissingAsync.js +75 -0
- package/dist/codefixes/addMissingAwait.d.ts +1 -0
- package/dist/codefixes/addMissingAwait.js +236 -0
- package/dist/codefixes/addMissingConst.d.ts +1 -0
- package/dist/codefixes/addMissingConst.js +91 -0
- package/dist/codefixes/addNameToNamelessParameter.d.ts +1 -0
- package/dist/codefixes/addNameToNamelessParameter.js +29 -0
- package/dist/codefixes/convertConstToLet.d.ts +1 -0
- package/dist/codefixes/convertConstToLet.js +30 -0
- package/dist/codefixes/convertToAsyncFunction.d.ts +1 -0
- package/dist/codefixes/convertToAsyncFunction.js +495 -0
- package/dist/codefixes/convertToMappedObjectType.d.ts +1 -0
- package/dist/codefixes/convertToMappedObjectType.js +48 -0
- package/dist/codefixes/correctQualifiedNameToIndexedAccessType.d.ts +1 -0
- package/dist/codefixes/correctQualifiedNameToIndexedAccessType.js +33 -0
- package/dist/codefixes/fixAddModuleReferTypeMissingTypeof.d.ts +1 -0
- package/dist/codefixes/fixAddModuleReferTypeMissingTypeof.js +27 -0
- package/dist/codefixes/fixAwaitInSyncFunction.d.ts +1 -0
- package/dist/codefixes/fixAwaitInSyncFunction.js +69 -0
- package/dist/codefixes/fixExpectedComma.d.ts +1 -0
- package/dist/codefixes/fixExpectedComma.js +35 -0
- package/dist/codefixes/fixInvalidJsxCharacters.d.ts +1 -0
- package/dist/codefixes/fixInvalidJsxCharacters.js +41 -0
- package/dist/codefixes/fixMissingCallParentheses.d.ts +1 -0
- package/dist/codefixes/fixMissingCallParentheses.js +42 -0
- package/dist/codefixes/fixSpelling.d.ts +1 -0
- package/dist/codefixes/fixSpelling.js +94 -0
- package/dist/codefixes/fixUnreachableCode.d.ts +1 -0
- package/dist/codefixes/fixUnreachableCode.js +65 -0
- package/dist/codefixes/fixUnusedIdentifier.d.ts +1 -0
- package/dist/codefixes/fixUnusedIdentifier.js +224 -0
- package/dist/codefixes/helpers.d.ts +8 -0
- package/dist/codefixes/helpers.js +53 -0
- package/dist/codefixes/importFixes.d.ts +14 -0
- package/dist/codefixes/importFixes.js +441 -0
- package/dist/codefixes/inferFromUsage.d.ts +1 -0
- package/dist/codefixes/inferFromUsage.js +742 -0
- package/dist/codefixes/removeUnnecessaryAwait.d.ts +1 -0
- package/dist/codefixes/removeUnnecessaryAwait.js +41 -0
- package/dist/codefixes/returnValueCorrect.d.ts +1 -0
- package/dist/codefixes/returnValueCorrect.js +132 -0
- package/dist/codefixes/splitTypeOnlyImport.d.ts +1 -0
- package/dist/codefixes/splitTypeOnlyImport.js +32 -0
- package/dist/codefixes/useBigintLiteral.d.ts +1 -0
- package/dist/codefixes/useBigintLiteral.js +29 -0
- package/dist/completions.d.ts +83 -0
- package/dist/completions.js +1720 -0
- package/dist/documentHighlights.d.ts +8 -0
- package/dist/documentHighlights.js +367 -0
- package/dist/documentRegistry.d.ts +36 -0
- package/dist/documentRegistry.js +63 -0
- package/dist/editingServices.d.ts +1 -0
- package/dist/editingServices.js +4 -0
- package/dist/findAllReferences.d.ts +113 -0
- package/dist/findAllReferences.js +1366 -0
- package/dist/formatting/formatting.d.ts +26 -0
- package/dist/formatting/formatting.js +1021 -0
- package/dist/formatting/formattingContext.d.ts +34 -0
- package/dist/formatting/formattingContext.js +78 -0
- package/dist/formatting/formattingScanner.d.ts +14 -0
- package/dist/formatting/formattingScanner.js +228 -0
- package/dist/formatting/rule.d.ts +31 -0
- package/dist/formatting/rule.js +22 -0
- package/dist/formatting/rules.d.ts +7 -0
- package/dist/formatting/rules.js +610 -0
- package/dist/formatting/rulesMap.d.ts +5 -0
- package/dist/formatting/rulesMap.js +127 -0
- package/dist/formatting/smartIndenter.d.ts +44 -0
- package/dist/formatting/smartIndenter.js +518 -0
- package/dist/getEditsForFileRename.d.ts +6 -0
- package/dist/getEditsForFileRename.js +86 -0
- package/dist/goToDefinition.d.ts +8 -0
- package/dist/goToDefinition.js +246 -0
- package/dist/importTracker.d.ts +50 -0
- package/dist/importTracker.js +422 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/navigationBar.d.ts +3 -0
- package/dist/navigationBar.js +549 -0
- package/dist/organizeImports.d.ts +18 -0
- package/dist/organizeImports.js +290 -0
- package/dist/outliningElementsCollector.d.ts +2 -0
- package/dist/outliningElementsCollector.js +261 -0
- package/dist/refactorProvider.d.ts +5 -0
- package/dist/refactorProvider.js +16 -0
- package/dist/refactors/addOrRemoveBracesToArrowFunction.d.ts +1 -0
- package/dist/refactors/addOrRemoveBracesToArrowFunction.js +86 -0
- package/dist/refactors/convertExport.d.ts +1 -0
- package/dist/refactors/convertExport.js +126 -0
- package/dist/refactors/convertImport.d.ts +1 -0
- package/dist/refactors/convertImport.js +116 -0
- package/dist/refactors/convertParamsToDestructuredObject.d.ts +1 -0
- package/dist/refactors/convertParamsToDestructuredObject.js +282 -0
- package/dist/refactors/convertStringOrTemplateLiteral.d.ts +1 -0
- package/dist/refactors/convertStringOrTemplateLiteral.js +148 -0
- package/dist/refactors/extractSymbol.d.ts +60 -0
- package/dist/refactors/extractSymbol.js +1281 -0
- package/dist/refactors/extractType.d.ts +1 -0
- package/dist/refactors/extractType.js +102 -0
- package/dist/refactors/moveToNewFile.d.ts +1 -0
- package/dist/refactors/moveToNewFile.js +477 -0
- package/dist/rename.d.ts +2 -0
- package/dist/rename.js +100 -0
- package/dist/services.d.ts +48 -0
- package/dist/services.js +1480 -0
- package/dist/signatureHelp.d.ts +8 -0
- package/dist/signatureHelp.js +414 -0
- package/dist/smartSelection.d.ts +2 -0
- package/dist/smartSelection.js +243 -0
- package/dist/stringCompletions.d.ts +4 -0
- package/dist/stringCompletions.js +220 -0
- package/dist/suggestionDiagnostics.d.ts +6 -0
- package/dist/suggestionDiagnostics.js +92 -0
- package/dist/symbolDisplay.d.ts +16 -0
- package/dist/symbolDisplay.js +400 -0
- package/dist/textChanges.d.ts +161 -0
- package/dist/textChanges.js +1163 -0
- package/dist/types.d.ts +908 -0
- package/dist/types.js +263 -0
- package/dist/utilities.d.ts +283 -0
- package/dist/utilities.js +1981 -0
- package/package.json +45 -3
- package/README.md +0 -3
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CallLikeExpression, CancellationToken, CheckResult, Node, SignatureHelpItems, SignatureHelpTriggerReason, SourceFile } from "./_namespaces/ts.js";
|
|
2
|
+
export declare function getSignatureHelpItems(program: CheckResult, sourceFile: SourceFile, position: number, triggerReason: SignatureHelpTriggerReason | undefined, cancellationToken: CancellationToken): SignatureHelpItems | undefined;
|
|
3
|
+
export interface ArgumentInfoForCompletions {
|
|
4
|
+
readonly invocation: CallLikeExpression;
|
|
5
|
+
readonly argumentIndex: number;
|
|
6
|
+
readonly argumentCount: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function getArgumentInfoForCompletions(node: Node, position: number, sourceFile: SourceFile): ArgumentInfoForCompletions | undefined;
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
// Modificado de microsoft/TypeScript v3.9.10, src/services/signatureHelp.ts: o namespace virou módulo ES, com os imports explícitos.
|
|
2
|
+
import { Debug, EmitHint, InternalSymbolName, ListFormat, NodeBuilderFlags, SyntaxKind, contains, countWhere, createNodeArray, createPrinter, createTextSpan, createTextSpanFromBounds, emptyArray, findContainingList, findPrecedingToken, findTokenOnLeftOfPosition, first, firstDefined, getInvokedExpression, getPossibleGenericSignatures, getPossibleTypeArgumentsInfo, isBlock, isCallExpression, isFunctionTypeNode, isIdentifier, isInComment, isInString, isJsxOpeningLikeElement, isSourceFile, last, mapToDisplayParts, punctuationPart, rangeContainsRange, skipTrivia, spacePart, symbolToDisplayParts, } from "./_namespaces/ts.js";
|
|
3
|
+
var InvocationKind;
|
|
4
|
+
(function (InvocationKind) {
|
|
5
|
+
InvocationKind[InvocationKind["Call"] = 0] = "Call";
|
|
6
|
+
InvocationKind[InvocationKind["TypeArgs"] = 1] = "TypeArgs";
|
|
7
|
+
InvocationKind[InvocationKind["Contextual"] = 2] = "Contextual";
|
|
8
|
+
})(InvocationKind || (InvocationKind = {}));
|
|
9
|
+
export function getSignatureHelpItems(program, sourceFile, position, triggerReason, cancellationToken) {
|
|
10
|
+
const typeChecker = program.getTypeChecker();
|
|
11
|
+
// Decide whether to show signature help
|
|
12
|
+
const startingToken = findTokenOnLeftOfPosition(sourceFile, position);
|
|
13
|
+
if (!startingToken) {
|
|
14
|
+
// We are at the beginning of the file
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
// Only need to be careful if the user typed a character and signature help wasn't showing.
|
|
18
|
+
const onlyUseSyntacticOwners = !!triggerReason && triggerReason.kind === "characterTyped";
|
|
19
|
+
// Bail out quickly in the middle of a string or comment, don't provide signature help unless the user explicitly requested it.
|
|
20
|
+
if (onlyUseSyntacticOwners && (isInString(sourceFile, position, startingToken) || isInComment(sourceFile, position))) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
const isManuallyInvoked = !!triggerReason && triggerReason.kind === "invoked";
|
|
24
|
+
const argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile, typeChecker, isManuallyInvoked);
|
|
25
|
+
if (!argumentInfo)
|
|
26
|
+
return undefined;
|
|
27
|
+
cancellationToken.throwIfCancellationRequested();
|
|
28
|
+
// Extra syntactic and semantic filtering of signature help
|
|
29
|
+
const candidateInfo = getCandidateOrTypeInfo(argumentInfo, typeChecker, sourceFile, startingToken, onlyUseSyntacticOwners);
|
|
30
|
+
cancellationToken.throwIfCancellationRequested();
|
|
31
|
+
// Na tag, num arquivo JavaScript sem resposta do checker, a assinatura de uma declaração de mesmo nome em qualquer
|
|
32
|
+
// arquivo (o `createJSSignatureHelpItems`, CK-03).
|
|
33
|
+
if (!candidateInfo) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => candidateInfo.kind === 0 /* CandidateOrTypeKind.Candidate */
|
|
37
|
+
? createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker)
|
|
38
|
+
: createTypeHelpItems(candidateInfo.symbol, argumentInfo, sourceFile, typeChecker));
|
|
39
|
+
}
|
|
40
|
+
var CandidateOrTypeKind;
|
|
41
|
+
(function (CandidateOrTypeKind) {
|
|
42
|
+
CandidateOrTypeKind[CandidateOrTypeKind["Candidate"] = 0] = "Candidate";
|
|
43
|
+
CandidateOrTypeKind[CandidateOrTypeKind["Type"] = 1] = "Type";
|
|
44
|
+
})(CandidateOrTypeKind || (CandidateOrTypeKind = {}));
|
|
45
|
+
function getCandidateOrTypeInfo({ invocation, argumentCount }, checker, sourceFile, startingToken, onlyUseSyntacticOwners) {
|
|
46
|
+
switch (invocation.kind) {
|
|
47
|
+
case 0 /* InvocationKind.Call */: {
|
|
48
|
+
if (onlyUseSyntacticOwners && !isSyntacticOwner(startingToken, invocation.node, sourceFile)) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const candidates = [];
|
|
52
|
+
const resolvedSignature = checker.getResolvedSignatureForSignatureHelp(invocation.node, candidates, argumentCount);
|
|
53
|
+
return candidates.length === 0 ? undefined : { kind: 0 /* CandidateOrTypeKind.Candidate */, candidates, resolvedSignature };
|
|
54
|
+
}
|
|
55
|
+
case 1 /* InvocationKind.TypeArgs */: {
|
|
56
|
+
const { called } = invocation;
|
|
57
|
+
if (onlyUseSyntacticOwners && !containsPrecedingToken(startingToken, sourceFile, isIdentifier(called) ? called.parent : called)) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const candidates = getPossibleGenericSignatures(called, argumentCount, checker);
|
|
61
|
+
if (candidates.length !== 0)
|
|
62
|
+
return { kind: 0 /* CandidateOrTypeKind.Candidate */, candidates, resolvedSignature: first(candidates) };
|
|
63
|
+
const symbol = checker.getSymbolAtLocation(called);
|
|
64
|
+
return symbol && { kind: 1 /* CandidateOrTypeKind.Type */, symbol };
|
|
65
|
+
}
|
|
66
|
+
case 2 /* InvocationKind.Contextual */:
|
|
67
|
+
return { kind: 0 /* CandidateOrTypeKind.Candidate */, candidates: [invocation.signature], resolvedSignature: invocation.signature };
|
|
68
|
+
default:
|
|
69
|
+
return Debug.assertNever(invocation);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Na tag, também o `new` (CK-02). */
|
|
73
|
+
function isSyntacticOwner(startingToken, node, sourceFile) {
|
|
74
|
+
if (!isCallExpression(node))
|
|
75
|
+
return false;
|
|
76
|
+
const invocationChildren = node.getChildren(sourceFile);
|
|
77
|
+
switch (startingToken.kind) {
|
|
78
|
+
case SyntaxKind.OpenParenToken:
|
|
79
|
+
return contains(invocationChildren, startingToken);
|
|
80
|
+
case SyntaxKind.CommaToken: {
|
|
81
|
+
const containingList = findContainingList(startingToken);
|
|
82
|
+
return !!containingList && contains(invocationChildren, containingList);
|
|
83
|
+
}
|
|
84
|
+
case SyntaxKind.LessThanToken:
|
|
85
|
+
return containsPrecedingToken(startingToken, sourceFile, node.expression);
|
|
86
|
+
default:
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function containsPrecedingToken(startingToken, sourceFile, container) {
|
|
91
|
+
const pos = startingToken.getFullStart();
|
|
92
|
+
// There’s a possibility that `startingToken.parent` contains only `startingToken` and
|
|
93
|
+
// missing nodes, none of which are valid to be returned by `findPrecedingToken`. In that
|
|
94
|
+
// case, the preceding token we want is actually higher up the tree—almost definitely the
|
|
95
|
+
// next parent, but theoretically the situation with missing nodes might be happening on
|
|
96
|
+
// multiple nested levels.
|
|
97
|
+
let currentParent = startingToken.parent;
|
|
98
|
+
while (currentParent) {
|
|
99
|
+
// Na tag, sem o token de um JSDoc (o `excludeJsdoc`, CK-03).
|
|
100
|
+
const precedingToken = findPrecedingToken(pos, sourceFile, currentParent);
|
|
101
|
+
if (precedingToken) {
|
|
102
|
+
return rangeContainsRange(container, precedingToken);
|
|
103
|
+
}
|
|
104
|
+
currentParent = currentParent.parent;
|
|
105
|
+
}
|
|
106
|
+
return Debug.fail("Could not find preceding token");
|
|
107
|
+
}
|
|
108
|
+
export function getArgumentInfoForCompletions(node, position, sourceFile) {
|
|
109
|
+
const info = getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
|
110
|
+
return !info || info.isTypeParameterList || info.invocation.kind !== 0 /* InvocationKind.Call */ ? undefined
|
|
111
|
+
: { invocation: info.invocation.node, argumentCount: info.argumentCount, argumentIndex: info.argumentIndex };
|
|
112
|
+
}
|
|
113
|
+
function getArgumentOrParameterListInfo(node, sourceFile) {
|
|
114
|
+
const info = getArgumentOrParameterListAndIndex(node, sourceFile);
|
|
115
|
+
if (!info)
|
|
116
|
+
return undefined;
|
|
117
|
+
const { list, argumentIndex } = info;
|
|
118
|
+
const argumentCount = getArgumentCount(list);
|
|
119
|
+
if (argumentIndex !== 0) {
|
|
120
|
+
Debug.assertLessThan(argumentIndex, argumentCount);
|
|
121
|
+
}
|
|
122
|
+
const argumentsSpan = getApplicableSpanForArguments(list, sourceFile);
|
|
123
|
+
return { list, argumentIndex, argumentCount, argumentsSpan };
|
|
124
|
+
}
|
|
125
|
+
function getArgumentOrParameterListAndIndex(node, sourceFile) {
|
|
126
|
+
if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) {
|
|
127
|
+
// Find the list that starts right *after* the < or ( token.
|
|
128
|
+
// If the user has just opened a list, consider this item 0.
|
|
129
|
+
return { list: getChildListThatStartsWithOpenerToken(node.parent, node, sourceFile), argumentIndex: 0 };
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// findListItemInfo can return undefined if we are not in parent's argument list
|
|
133
|
+
// or type argument list. This includes cases where the cursor is:
|
|
134
|
+
// - To the right of the closing parenthesis, non-substitution template, or template tail.
|
|
135
|
+
// - Between the type arguments and the arguments (greater than token)
|
|
136
|
+
// - On the target of the call (parent.func)
|
|
137
|
+
// - On the 'new' keyword in a 'new' expression
|
|
138
|
+
const list = findContainingList(node);
|
|
139
|
+
return list && { list, argumentIndex: getArgumentIndex(list, node) };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* A lista de argumentos e o argumento corrente, quando o nó está nos argumentos de uma chamada. A posição só servia, na
|
|
144
|
+
* tag, ao template marcado (CK-02).
|
|
145
|
+
*/
|
|
146
|
+
function getImmediatelyContainingArgumentInfo(node, _position, sourceFile) {
|
|
147
|
+
const { parent } = node;
|
|
148
|
+
// Na tag, também o `new` (CK-02).
|
|
149
|
+
if (isCallExpression(parent)) {
|
|
150
|
+
const invocation = parent;
|
|
151
|
+
// There are 3 cases to handle:
|
|
152
|
+
// 1. The token introduces a list, and should begin a signature help session
|
|
153
|
+
// 2. The token is either not associated with a list, or ends a list, so the session should end
|
|
154
|
+
// 3. The token is buried inside a list, and should give signature help
|
|
155
|
+
//
|
|
156
|
+
// The following are examples of each:
|
|
157
|
+
//
|
|
158
|
+
// Case 1:
|
|
159
|
+
// foo<#T, U>(#a, b) -> The token introduces a list, and should begin a signature help session
|
|
160
|
+
// Case 2:
|
|
161
|
+
// fo#o<T, U>#(a, b)# -> The token is either not associated with a list, or ends a list, so the session should end
|
|
162
|
+
// Case 3:
|
|
163
|
+
// foo<T#, U#>(a#, #b#) -> The token is buried inside a list, and should give signature help
|
|
164
|
+
// Find out if 'node' is an argument, a type argument, or neither
|
|
165
|
+
const info = getArgumentOrParameterListInfo(node, sourceFile);
|
|
166
|
+
if (!info)
|
|
167
|
+
return undefined;
|
|
168
|
+
const { list, argumentIndex, argumentCount, argumentsSpan } = info;
|
|
169
|
+
const isTypeParameterList = !!parent.typeArguments && parent.typeArguments.pos === list.pos;
|
|
170
|
+
return { isTypeParameterList, invocation: { kind: 0 /* InvocationKind.Call */, node: invocation }, argumentsSpan, argumentIndex, argumentCount };
|
|
171
|
+
}
|
|
172
|
+
// Na tag, os três ramos seguintes eram o do tagged template, que a Linguagem não tem (CK-02).
|
|
173
|
+
else if (isJsxOpeningLikeElement(parent)) {
|
|
174
|
+
// Provide a signature help for JSX opening element or JSX self-closing element.
|
|
175
|
+
// This is not guarantee that JSX tag-name is resolved into stateless function component. (that is done in "getSignatureHelpItems")
|
|
176
|
+
// i.e
|
|
177
|
+
// export function MainButton(props: ButtonProps, context: any): JSX.Element { ... }
|
|
178
|
+
// <MainButton /*signatureHelp*/
|
|
179
|
+
const attributeSpanStart = parent.attributes.pos;
|
|
180
|
+
const attributeSpanEnd = skipTrivia(sourceFile.text, parent.attributes.end, /*stopAfterLineBreak*/ false);
|
|
181
|
+
return {
|
|
182
|
+
isTypeParameterList: false,
|
|
183
|
+
invocation: { kind: 0 /* InvocationKind.Call */, node: parent },
|
|
184
|
+
argumentsSpan: createTextSpan(attributeSpanStart, attributeSpanEnd - attributeSpanStart),
|
|
185
|
+
argumentIndex: 0,
|
|
186
|
+
argumentCount: 1
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
const typeArgInfo = getPossibleTypeArgumentsInfo(node, sourceFile);
|
|
191
|
+
if (typeArgInfo) {
|
|
192
|
+
const { called, nTypeArguments } = typeArgInfo;
|
|
193
|
+
const invocation = { kind: 1 /* InvocationKind.TypeArgs */, called };
|
|
194
|
+
const argumentsSpan = createTextSpanFromBounds(called.getStart(sourceFile), node.end);
|
|
195
|
+
return { isTypeParameterList: true, invocation, argumentsSpan, argumentIndex: nTypeArguments, argumentCount: nTypeArguments + 1 };
|
|
196
|
+
}
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function getImmediatelyContainingArgumentOrContextualParameterInfo(node, position, sourceFile, checker) {
|
|
201
|
+
return tryGetParameterInfo(node, position, sourceFile, checker) || getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
|
202
|
+
}
|
|
203
|
+
function tryGetParameterInfo(startingToken, _position, sourceFile, checker) {
|
|
204
|
+
const info = getContextualSignatureLocationInfo(startingToken, sourceFile, checker);
|
|
205
|
+
if (!info)
|
|
206
|
+
return undefined;
|
|
207
|
+
const { contextualType, argumentIndex, argumentCount, argumentsSpan } = info;
|
|
208
|
+
const signatures = contextualType.getCallSignatures();
|
|
209
|
+
if (signatures.length !== 1)
|
|
210
|
+
return undefined;
|
|
211
|
+
const invocation = { kind: 2 /* InvocationKind.Contextual */, signature: first(signatures), node: startingToken, symbol: chooseBetterSymbol(contextualType.symbol) };
|
|
212
|
+
return { isTypeParameterList: false, invocation, argumentsSpan, argumentIndex, argumentCount };
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Os parâmetros de uma arrow que se escreve onde o tipo dela já é esperado. Na tag, também os do método de um object literal
|
|
216
|
+
* e os de uma function expression (CK-02), e a expressão de vírgula que a arrow ainda sem o `=>` era (`(a, b`): o parser da
|
|
217
|
+
* cópia não a produz, porque o operador vírgula saiu (CK-02).
|
|
218
|
+
*/
|
|
219
|
+
function getContextualSignatureLocationInfo(startingToken, sourceFile, checker) {
|
|
220
|
+
if (startingToken.kind !== SyntaxKind.OpenParenToken && startingToken.kind !== SyntaxKind.CommaToken)
|
|
221
|
+
return undefined;
|
|
222
|
+
const { parent } = startingToken;
|
|
223
|
+
switch (parent.kind) {
|
|
224
|
+
case SyntaxKind.ParenthesizedExpression:
|
|
225
|
+
case SyntaxKind.ArrowFunction:
|
|
226
|
+
const info = getArgumentOrParameterListInfo(startingToken, sourceFile);
|
|
227
|
+
if (!info)
|
|
228
|
+
return undefined;
|
|
229
|
+
const { argumentIndex, argumentCount, argumentsSpan } = info;
|
|
230
|
+
const contextualType = checker.getContextualType(parent);
|
|
231
|
+
return contextualType && { contextualType, argumentIndex, argumentCount, argumentsSpan };
|
|
232
|
+
default:
|
|
233
|
+
return undefined;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// The type of a function type node has a symbol at that node, but it's better to use the symbol for a parameter or type alias.
|
|
237
|
+
function chooseBetterSymbol(s) {
|
|
238
|
+
return s.name === InternalSymbolName.Type
|
|
239
|
+
? firstDefined(s.declarations, d => isFunctionTypeNode(d) ? d.parent.symbol : undefined) || s
|
|
240
|
+
: s;
|
|
241
|
+
}
|
|
242
|
+
function getArgumentIndex(argumentsList, node) {
|
|
243
|
+
// The list we got back can include commas. In the presence of errors it may
|
|
244
|
+
// also just have nodes without commas. For example "Foo(a b c)" will have 3
|
|
245
|
+
// args without commas. We want to find what index we're at. So we count
|
|
246
|
+
// forward until we hit ourselves, only incrementing the index if it isn't a
|
|
247
|
+
// comma.
|
|
248
|
+
//
|
|
249
|
+
// Note: the subtlety around trailing commas (in getArgumentCount) does not apply
|
|
250
|
+
// here. That's because we're only walking forward until we hit the node we're
|
|
251
|
+
// on. In that case, even if we're after the trailing comma, we'll still see
|
|
252
|
+
// that trailing comma in the list, and we'll have generated the appropriate
|
|
253
|
+
// arg index.
|
|
254
|
+
let argumentIndex = 0;
|
|
255
|
+
for (const child of argumentsList.getChildren()) {
|
|
256
|
+
if (child === node) {
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
if (child.kind !== SyntaxKind.CommaToken) {
|
|
260
|
+
argumentIndex++;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return argumentIndex;
|
|
264
|
+
}
|
|
265
|
+
function getArgumentCount(argumentsList) {
|
|
266
|
+
// The argument count for a list is normally the number of non-comma children it has.
|
|
267
|
+
// For example, if you have "Foo(a,b)" then there will be three children of the arg
|
|
268
|
+
// list 'a' '<comma>' 'b'. So, in this case the arg count will be 2. However, there
|
|
269
|
+
// is a small subtlety. If you have "Foo(a,)", then the child list will just have
|
|
270
|
+
// 'a' '<comma>'. So, in the case where the last child is a comma, we increase the
|
|
271
|
+
// arg count by one to compensate.
|
|
272
|
+
//
|
|
273
|
+
// Note: this subtlety only applies to the last comma. If you had "Foo(a,," then
|
|
274
|
+
// we'll have: 'a' '<comma>' '<missing>'
|
|
275
|
+
// That will give us 2 non-commas. We then add one for the last comma, giving us an
|
|
276
|
+
// arg count of 3.
|
|
277
|
+
const listChildren = argumentsList.getChildren();
|
|
278
|
+
let argumentCount = countWhere(listChildren, arg => arg.kind !== SyntaxKind.CommaToken);
|
|
279
|
+
if (listChildren.length > 0 && last(listChildren).kind === SyntaxKind.CommaToken) {
|
|
280
|
+
argumentCount++;
|
|
281
|
+
}
|
|
282
|
+
return argumentCount;
|
|
283
|
+
}
|
|
284
|
+
function getApplicableSpanForArguments(argumentsList, sourceFile) {
|
|
285
|
+
// We use full start and skip trivia on the end because we want to include trivia on
|
|
286
|
+
// both sides. For example,
|
|
287
|
+
//
|
|
288
|
+
// foo( /*comment */ a, b, c /*comment*/ )
|
|
289
|
+
// | |
|
|
290
|
+
//
|
|
291
|
+
// The applicable span is from the first bar to the second bar (inclusive,
|
|
292
|
+
// but not including parentheses)
|
|
293
|
+
const applicableSpanStart = argumentsList.getFullStart();
|
|
294
|
+
const applicableSpanEnd = skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false);
|
|
295
|
+
return createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
|
|
296
|
+
}
|
|
297
|
+
function getContainingArgumentInfo(node, position, sourceFile, checker, isManuallyInvoked) {
|
|
298
|
+
for (let n = node; !isSourceFile(n) && (isManuallyInvoked || !isBlock(n)); n = n.parent) {
|
|
299
|
+
// If the node is not a subspan of its parent, this is a big problem.
|
|
300
|
+
// There have been crashes that might be caused by this violation.
|
|
301
|
+
Debug.assert(rangeContainsRange(n.parent, n), "Not a subspan", () => `Child: ${Debug.formatSyntaxKind(n.kind)}, parent: ${Debug.formatSyntaxKind(n.parent.kind)}`);
|
|
302
|
+
const argumentInfo = getImmediatelyContainingArgumentOrContextualParameterInfo(n, position, sourceFile, checker);
|
|
303
|
+
if (argumentInfo) {
|
|
304
|
+
return argumentInfo;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return undefined;
|
|
308
|
+
}
|
|
309
|
+
function getChildListThatStartsWithOpenerToken(parent, openerToken, sourceFile) {
|
|
310
|
+
const children = parent.getChildren(sourceFile);
|
|
311
|
+
const indexOfOpenerToken = children.indexOf(openerToken);
|
|
312
|
+
Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1);
|
|
313
|
+
return children[indexOfOpenerToken + 1];
|
|
314
|
+
}
|
|
315
|
+
function getExpressionFromInvocation(invocation) {
|
|
316
|
+
return invocation.kind === 0 /* InvocationKind.Call */ ? getInvokedExpression(invocation.node) : invocation.called;
|
|
317
|
+
}
|
|
318
|
+
function getEnclosingDeclarationFromInvocation(invocation) {
|
|
319
|
+
return invocation.kind === 0 /* InvocationKind.Call */ ? invocation.node : invocation.kind === 1 /* InvocationKind.TypeArgs */ ? invocation.called : invocation.node;
|
|
320
|
+
}
|
|
321
|
+
const signatureHelpNodeBuilderFlags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope;
|
|
322
|
+
function createSignatureHelpItems(candidates, resolvedSignature, { isTypeParameterList, argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex }, sourceFile, typeChecker) {
|
|
323
|
+
const enclosingDeclaration = getEnclosingDeclarationFromInvocation(invocation);
|
|
324
|
+
const callTargetSymbol = invocation.kind === 2 /* InvocationKind.Contextual */ ? invocation.symbol : typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation));
|
|
325
|
+
const callTargetDisplayParts = callTargetSymbol ? symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : emptyArray;
|
|
326
|
+
const items = candidates.map(candidateSignature => getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, typeChecker, enclosingDeclaration, sourceFile));
|
|
327
|
+
if (argumentIndex !== 0) {
|
|
328
|
+
Debug.assertLessThan(argumentIndex, argumentCount);
|
|
329
|
+
}
|
|
330
|
+
const selectedItemIndex = candidates.indexOf(resolvedSignature);
|
|
331
|
+
Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function.
|
|
332
|
+
return { items, applicableSpan, selectedItemIndex, argumentIndex, argumentCount };
|
|
333
|
+
}
|
|
334
|
+
function createTypeHelpItems(symbol, { argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex }, sourceFile, checker) {
|
|
335
|
+
const typeParameters = checker.getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
|
|
336
|
+
if (!typeParameters)
|
|
337
|
+
return undefined;
|
|
338
|
+
const items = [getTypeHelpItem(symbol, typeParameters, checker, getEnclosingDeclarationFromInvocation(invocation), sourceFile)];
|
|
339
|
+
return { items, applicableSpan, selectedItemIndex: 0, argumentIndex, argumentCount };
|
|
340
|
+
}
|
|
341
|
+
function getTypeHelpItem(symbol, typeParameters, checker, enclosingDeclaration, sourceFile) {
|
|
342
|
+
const typeSymbolDisplay = symbolToDisplayParts(checker, symbol);
|
|
343
|
+
const printer = createPrinter({ removeComments: true });
|
|
344
|
+
const parameters = typeParameters.map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer));
|
|
345
|
+
// Na tag, a documentação e as tags do JSDoc do símbolo. Sem o JSDoc (CK-03), as duas saem vazias, como as de um símbolo
|
|
346
|
+
// sem comentário na tag.
|
|
347
|
+
const documentation = [];
|
|
348
|
+
const tags = [];
|
|
349
|
+
const prefixDisplayParts = [...typeSymbolDisplay, punctuationPart(SyntaxKind.LessThanToken)];
|
|
350
|
+
return { isVariadic: false, prefixDisplayParts, suffixDisplayParts: [punctuationPart(SyntaxKind.GreaterThanToken)], separatorDisplayParts, parameters, documentation, tags };
|
|
351
|
+
}
|
|
352
|
+
const separatorDisplayParts = [punctuationPart(SyntaxKind.CommaToken), spacePart()];
|
|
353
|
+
function getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, checker, enclosingDeclaration, sourceFile) {
|
|
354
|
+
const { isVariadic, parameters, prefix, suffix } = (isTypeParameterList ? itemInfoForTypeParameters : itemInfoForParameters)(candidateSignature, checker, enclosingDeclaration, sourceFile);
|
|
355
|
+
const prefixDisplayParts = [...callTargetDisplayParts, ...prefix];
|
|
356
|
+
const suffixDisplayParts = [...suffix, ...returnTypeToDisplayParts(candidateSignature, enclosingDeclaration, checker)];
|
|
357
|
+
// Na tag, a documentação e as tags do JSDoc da assinatura; sem o JSDoc (CK-03), vazias.
|
|
358
|
+
const documentation = [];
|
|
359
|
+
const tags = [];
|
|
360
|
+
return { isVariadic, prefixDisplayParts, suffixDisplayParts, separatorDisplayParts, parameters, documentation, tags };
|
|
361
|
+
}
|
|
362
|
+
function returnTypeToDisplayParts(candidateSignature, enclosingDeclaration, checker) {
|
|
363
|
+
return mapToDisplayParts(writer => {
|
|
364
|
+
writer.writePunctuation(":");
|
|
365
|
+
writer.writeSpace(" ");
|
|
366
|
+
const predicate = checker.getTypePredicateOfSignature(candidateSignature);
|
|
367
|
+
if (predicate) {
|
|
368
|
+
checker.writeTypePredicate(predicate, enclosingDeclaration, /*flags*/ undefined, writer);
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
checker.writeType(checker.getReturnTypeOfSignature(candidateSignature), enclosingDeclaration, /*flags*/ undefined, writer);
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
function itemInfoForTypeParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) {
|
|
376
|
+
const typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
|
|
377
|
+
const printer = createPrinter({ removeComments: true });
|
|
378
|
+
const parameters = (typeParameters || emptyArray).map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer));
|
|
379
|
+
const parameterParts = mapToDisplayParts(writer => {
|
|
380
|
+
// Na tag, também o parâmetro `this`, antes dos outros (CK-02).
|
|
381
|
+
const params = createNodeArray(checker.getExpandedParameters(candidateSignature).map(param => checker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)));
|
|
382
|
+
printer.writeList(ListFormat.CallExpressionArguments, params, sourceFile, writer);
|
|
383
|
+
});
|
|
384
|
+
return { isVariadic: false, parameters, prefix: [punctuationPart(SyntaxKind.LessThanToken)], suffix: [punctuationPart(SyntaxKind.GreaterThanToken), ...parameterParts] };
|
|
385
|
+
}
|
|
386
|
+
function itemInfoForParameters(candidateSignature, checker, enclosingDeclaration, sourceFile) {
|
|
387
|
+
const isVariadic = checker.hasEffectiveRestParameter(candidateSignature);
|
|
388
|
+
const printer = createPrinter({ removeComments: true });
|
|
389
|
+
const typeParameterParts = mapToDisplayParts(writer => {
|
|
390
|
+
if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
|
|
391
|
+
const args = createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags)));
|
|
392
|
+
printer.writeList(ListFormat.TypeParameters, args, sourceFile, writer);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
const parameters = checker.getExpandedParameters(candidateSignature).map(p => createSignatureHelpParameterForParameter(p, checker, enclosingDeclaration, sourceFile, printer));
|
|
396
|
+
return { isVariadic, parameters, prefix: [...typeParameterParts, punctuationPart(SyntaxKind.OpenParenToken)], suffix: [punctuationPart(SyntaxKind.CloseParenToken)] };
|
|
397
|
+
}
|
|
398
|
+
function createSignatureHelpParameterForParameter(parameter, checker, enclosingDeclaration, sourceFile, printer) {
|
|
399
|
+
const displayParts = mapToDisplayParts(writer => {
|
|
400
|
+
const param = checker.symbolToParameterDeclaration(parameter, enclosingDeclaration, signatureHelpNodeBuilderFlags);
|
|
401
|
+
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
|
|
402
|
+
});
|
|
403
|
+
const isOptional = checker.isOptionalParameter(parameter.valueDeclaration);
|
|
404
|
+
// Na tag, a documentação do JSDoc do parâmetro; sem o JSDoc (CK-03), vazia.
|
|
405
|
+
return { name: parameter.name, documentation: [], displayParts, isOptional };
|
|
406
|
+
}
|
|
407
|
+
function createSignatureHelpParameterForTypeParameter(typeParameter, checker, enclosingDeclaration, sourceFile, printer) {
|
|
408
|
+
const displayParts = mapToDisplayParts(writer => {
|
|
409
|
+
const param = checker.typeParameterToDeclaration(typeParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags);
|
|
410
|
+
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
|
|
411
|
+
});
|
|
412
|
+
// Na tag, a documentação do JSDoc do parâmetro de tipo; sem o JSDoc (CK-03), vazia.
|
|
413
|
+
return { name: typeParameter.symbol.name, documentation: [], displayParts, isOptional: false };
|
|
414
|
+
}
|