diff options
-rw-r--r-- | editors/code/ra_syntax_tree.tmGrammar.json | 2 | ||||
-rw-r--r-- | editors/code/src/commands/syntax_tree.ts | 37 |
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 | ||
218 | class Lazy<T> { | 251 | class Lazy<T> { |