aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/code/ra_syntax_tree.tmGrammar.json2
-rw-r--r--editors/code/src/commands/syntax_tree.ts37
2 files changed, 36 insertions, 3 deletions
diff --git a/editors/code/ra_syntax_tree.tmGrammar.json b/editors/code/ra_syntax_tree.tmGrammar.json
index 0d72a3e36..431d414f6 100644
--- a/editors/code/ra_syntax_tree.tmGrammar.json
+++ b/editors/code/ra_syntax_tree.tmGrammar.json
@@ -9,7 +9,7 @@
9 ], 9 ],
10 "repository": { 10 "repository": {
11 "node_type": { 11 "node_type": {
12 "match": "^\\s*([A-Z_]+?)@", 12 "match": "^\\s*([A-Z_][A-Z_0-9]*?)@",
13 "captures": { 13 "captures": {
14 "1": { 14 "1": {
15 "name": "entity.name.class" 15 "name": "entity.name.class"
diff --git a/editors/code/src/commands/syntax_tree.ts b/editors/code/src/commands/syntax_tree.ts
index b7a397414..cfcf47b2f 100644
--- a/editors/code/src/commands/syntax_tree.ts
+++ b/editors/code/src/commands/syntax_tree.ts
@@ -198,7 +198,7 @@ class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, D
198 return new vscode.Hover(["```rust\n" + rustSourceCode + "\n```"], astFileRange); 198 return new vscode.Hover(["```rust\n" + rustSourceCode + "\n```"], astFileRange);
199 } 199 }
200 200
201 private findAstNodeRange(astLine: vscode.TextLine) { 201 private findAstNodeRange(astLine: vscode.TextLine): vscode.Range {
202 const lineOffset = astLine.range.start; 202 const lineOffset = astLine.range.start;
203 const begin = lineOffset.translate(undefined, astLine.firstNonWhitespaceCharacterIndex); 203 const begin = lineOffset.translate(undefined, astLine.firstNonWhitespaceCharacterIndex);
204 const end = lineOffset.translate(undefined, astLine.text.trimEnd().length); 204 const end = lineOffset.translate(undefined, astLine.text.trimEnd().length);
@@ -209,10 +209,43 @@ class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, D
209 const parsedRange = /\[(\d+); (\d+)\)/.exec(astLine); 209 const parsedRange = /\[(\d+); (\d+)\)/.exec(astLine);
210 if (!parsedRange) return; 210 if (!parsedRange) return;
211 211
212 const [begin, end] = parsedRange.slice(1).map(off => doc.positionAt(+off)); 212 const [begin, end] = parsedRange
213 .slice(1)
214 .map(off => this.positionAt(doc, +off));
213 215
214 return new vscode.Range(begin, end); 216 return new vscode.Range(begin, end);
215 } 217 }
218
219 // Memoize the last value, otherwise the CPU is at 100% single core
220 // with quadratic lookups when we build rust2Ast cache
221 cache?: { doc: vscode.TextDocument; offset: number; line: number };
222
223 positionAt(doc: vscode.TextDocument, targetOffset: number): vscode.Position {
224 if (doc.eol === vscode.EndOfLine.LF) {
225 return doc.positionAt(targetOffset);
226 }
227
228 // Shitty workaround for crlf line endings
229 // We are still in this prehistoric era of carriage returns here...
230
231 let line = 0;
232 let offset = 0;
233
234 const cache = this.cache;
235 if (cache?.doc === doc && cache.offset <= targetOffset) {
236 ({ line, offset } = cache);
237 }
238
239 while (true) {
240 const lineLenWithLf = doc.lineAt(line).text.length + 1;
241 if (offset + lineLenWithLf > targetOffset) {
242 this.cache = { doc, offset, line };
243 return doc.positionAt(targetOffset + line);
244 }
245 offset += lineLenWithLf;
246 line += 1;
247 }
248 }
216} 249}
217 250
218class Lazy<T> { 251class Lazy<T> {