|
1 | 1 | import * as vscode from "vscode"; |
2 | 2 | import { Annotations } from "./annotationProvider"; |
3 | 3 | import { IFunctionCallObject } from "./functionCallObject"; |
| 4 | +import { grabPossibleParameters } from "./paramExtractor"; |
4 | 5 |
|
5 | 6 | export async function decorateFunctionCall(currentEditor: vscode.TextEditor, documentCache: any, decArray, errDecArray: vscode.DecorationOptions[], fc: IFunctionCallObject, diagnostics: vscode.Diagnostic[]): Promise<void> { |
6 | 7 | // Check for existence of functionCallObject and a defintion location |
7 | 8 | if (fc === undefined || fc.definitionLocation === undefined) { |
8 | 9 | return; |
9 | 10 | } |
10 | 11 |
|
11 | | - // config option to hide annotations if param and arg names match |
| 12 | + // configs for decorations |
12 | 13 | const hideIfEqual = vscode.workspace.getConfiguration("jsannotations").get("hideIfEqual"); |
| 14 | + const willShowDiagnostics = vscode.workspace.getConfiguration("jsannotations").get("hideDiagnostics") === false; |
| 15 | + const willShowErrorAnnotation = vscode.workspace.getConfiguration("jsannotations").get("hideInvalidAnnotation") === false; |
13 | 16 |
|
14 | 17 | const document = await loadDefinitionDocument(fc.definitionLocation.uri, documentCache); |
15 | 18 | const definitionLine = document.lineAt(fc.definitionLocation.range.start.line).text; |
@@ -49,12 +52,12 @@ export async function decorateFunctionCall(currentEditor: vscode.TextEditor, doc |
49 | 52 | decoration = Annotations.paramAnnotation(paramList[restParamIdx] + `[${idx - restParamIdx}]: `, currentArgRange); |
50 | 53 | } else { |
51 | 54 | if (idx >= paramList.length) { |
52 | | - if (currentEditor.document.languageId === "javascript" && vscode.workspace.getConfiguration("jsannotations").get("hideDiagnostics") === false) { |
| 55 | + if (currentEditor.document.languageId === "javascript" && willShowDiagnostics) { |
53 | 56 | const diag = new vscode.Diagnostic(currentArgRange, "[JS Param Annotations] Invalid parameter", vscode.DiagnosticSeverity.Error); |
54 | 57 | diagnostics.push(diag); |
55 | 58 | } |
56 | 59 |
|
57 | | - if (vscode.workspace.getConfiguration("jsannotations").get("hideInvalidAnnotation") === false) { |
| 60 | + if (willShowErrorAnnotation) { |
58 | 61 | const errorDecoration = Annotations.errorParamAnnotation(currentArgRange); |
59 | 62 | errDecArray.push(errorDecoration); |
60 | 63 | } |
@@ -89,113 +92,6 @@ async function loadDefinitionDocument(uri: vscode.Uri, documentCache: any) { |
89 | 92 | return document; |
90 | 93 | } |
91 | 94 |
|
92 | | -function grabPossibleParameters(fc: IFunctionCallObject, definitionLine: string): string[] { |
93 | | - let paramList: string[] = []; |
94 | | - |
95 | | - // Grab any params inside the definition line |
96 | | - const defintionParam = grabDefLineParams(definitionLine); |
97 | | - |
98 | | - if (defintionParam !== "") { |
99 | | - if (fc.functionRange === undefined) { |
100 | | - return; |
101 | | - } |
102 | | - |
103 | | - paramList = defintionParam.split(/\s*,\s*/); |
104 | | - |
105 | | - paramList = squishGenerics(paramList); |
106 | | - |
107 | | - paramList = paramList.map((param) => { |
108 | | - // Extract identifiers |
109 | | - |
110 | | - const words = param.trim().split(" "); |
111 | | - |
112 | | - // If there are multiple words and the first word doesn't end with a colon, use the 2nd word as the param |
113 | | - // this will make sure the param name is used and not the access modifier in TS functions |
114 | | - if (words.length > 1 && !words[0].endsWith(":")) { |
115 | | - param = words[1]; |
116 | | - } |
117 | | - |
118 | | - const identifiers = param.match(/([\.a-zA-Z0-9]+):?/); |
119 | | - |
120 | | - if (identifiers && identifiers.length > 1) { |
121 | | - return identifiers[1]; |
122 | | - } |
123 | | - return ""; |
124 | | - }).filter((param) => param !== ""); |
125 | | - } |
126 | | - |
127 | | - return paramList; |
128 | | -} |
129 | | - |
130 | | -// This function will cycle through all of the current strings split by a comma, and combine strings that were of generic types and split incorrectly |
131 | | -function squishGenerics(paramList: string[]): string[] { |
132 | | - const newParamList = []; |
133 | | - |
134 | | - let currentStr = ""; |
135 | | - let numToGet = 1; // Always grab 1 string at the beginning |
136 | | - |
137 | | - for (const item of paramList) { |
138 | | - currentStr += item; |
139 | | - numToGet--; |
140 | | - |
141 | | - // If numToGet is zero, check the difference between '<' and '>' characters |
142 | | - if (numToGet === 0) { |
143 | | - const numOfLeftBrackets = currentStr.split("<").length - 1; |
144 | | - const numOfRightBrackets = currentStr.split(">").length - 1; |
145 | | - const numOfEqualSigns = currentStr.split("=").length - 1; |
146 | | - |
147 | | - // Diff is |num of left brackets ('<') minus the num of solo right brackets (which is the number of '>' minus the num of '=' signs)| |
148 | | - const diff = Math.abs(numOfLeftBrackets - (numOfRightBrackets - numOfEqualSigns)); |
149 | | - |
150 | | - if ((numOfEqualSigns > 0) || diff === 0) { |
151 | | - // If the difference is zero, we have a full param, push it to the new params, and start over at the next string |
152 | | - // Also, do this if there is equal signs in the params which exist with arrow functions. |
153 | | - newParamList.push(currentStr); |
154 | | - currentStr = ""; |
155 | | - numToGet = 1; |
156 | | - } else { |
157 | | - // Otherwise, set the number of strings to grab to the diff |
158 | | - numToGet = diff; |
159 | | - } |
160 | | - } |
161 | | - } |
162 | | - |
163 | | - return newParamList; |
164 | | -} |
165 | | - |
166 | | -function grabDefLineParams(definitionLine: string): string { |
167 | | - let startIdx; |
168 | | - let endIdx; |
169 | | - |
170 | | - startIdx = definitionLine.indexOf("("); |
171 | | - |
172 | | - if (startIdx === -1) { |
173 | | - return ""; |
174 | | - } else { |
175 | | - startIdx++; |
176 | | - } |
177 | | - |
178 | | - let depth = 1; |
179 | | - |
180 | | - for (let i = startIdx; i < definitionLine.length; i++) { |
181 | | - if (definitionLine[i] === "(") { |
182 | | - depth++; |
183 | | - } else if (definitionLine[i] === ")") { |
184 | | - depth--; |
185 | | - if (depth === 0) { |
186 | | - endIdx = i; |
187 | | - break; |
188 | | - } |
189 | | - } |
190 | | - } |
191 | | - |
192 | | - if (endIdx === undefined) { |
193 | | - return ""; |
194 | | - } |
195 | | - |
196 | | - return definitionLine.substring(startIdx, endIdx); |
197 | | -} |
198 | | - |
199 | 95 | function shouldntBeDecorated(paramList: string[], functionCall: IFunctionCallObject, functionCallLine: string, definitionLine: string): boolean { |
200 | 96 | // If the functionName is one of the parameters, don't decorate it |
201 | 97 | if (paramList.some((param) => param === functionCall.functionName)) { |
|
0 commit comments