about summary refs log tree commit diff
path: root/editors/code
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-04-22 11:05:18 +0000
committerGitHub <noreply@github.com>2020-04-22 11:05:18 +0000
commite7bb260fbb988341a2afcd7b2acdeffb301a49c1 (patch)
treec0741087514a84f6ff66974b8ce7ead6f1b6b402 /editors/code
parent3d7451e6e74dc6dbb2501954727f9c00ec068f5e (diff)
parentc12d0e0214ea3d7262eff4b9e21a033ee423ef99 (diff)
downloadrust-e7bb260fbb988341a2afcd7b2acdeffb301a49c1.tar.gz
rust-e7bb260fbb988341a2afcd7b2acdeffb301a49c1.zip
Merge #4081
4081: Work around crlf in syntax tree r=matklad a=Veetaha

Workarounds fixes #4067 

Co-authored-by: veetaha <veetaha2@gmail.com>
Diffstat (limited to 'editors/code')
-rw-r--r--editors/code/src/commands/syntax_tree.ts37
1 files changed, 35 insertions, 2 deletions
diff --git a/editors/code/src/commands/syntax_tree.ts b/editors/code/src/commands/syntax_tree.ts
index b7a397414eb..cfcf47b2fc5 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
         return new vscode.Hover(["```rust\n" + rustSourceCode + "\n```"], astFileRange);
     }
 
-    private findAstNodeRange(astLine: vscode.TextLine) {
+    private findAstNodeRange(astLine: vscode.TextLine): vscode.Range {
         const lineOffset = astLine.range.start;
         const begin = lineOffset.translate(undefined, astLine.firstNonWhitespaceCharacterIndex);
         const end = lineOffset.translate(undefined, astLine.text.trimEnd().length);
@@ -209,10 +209,43 @@ class AstInspector implements vscode.HoverProvider, vscode.DefinitionProvider, D
         const parsedRange = /\[(\d+); (\d+)\)/.exec(astLine);
         if (!parsedRange) return;
 
-        const [begin, end] = parsedRange.slice(1).map(off => doc.positionAt(+off));
+        const [begin, end] = parsedRange
+            .slice(1)
+            .map(off => this.positionAt(doc, +off));
 
         return new vscode.Range(begin, end);
     }
+
+    // Memoize the last value, otherwise the CPU is at 100% single core
+    // with quadratic lookups when we build rust2Ast cache
+    cache?: { doc: vscode.TextDocument; offset: number; line: number };
+
+    positionAt(doc: vscode.TextDocument, targetOffset: number): vscode.Position {
+        if (doc.eol === vscode.EndOfLine.LF) {
+            return doc.positionAt(targetOffset);
+        }
+
+        // Shitty workaround for crlf line endings
+        // We are still in this prehistoric era of carriage returns here...
+
+        let line = 0;
+        let offset = 0;
+
+        const cache = this.cache;
+        if (cache?.doc === doc && cache.offset <= targetOffset) {
+            ({ line, offset } = cache);
+        }
+
+        while (true) {
+            const lineLenWithLf = doc.lineAt(line).text.length + 1;
+            if (offset + lineLenWithLf > targetOffset) {
+                this.cache = { doc, offset, line };
+                return doc.positionAt(targetOffset + line);
+            }
+            offset += lineLenWithLf;
+            line += 1;
+        }
+    }
 }
 
 class Lazy<T> {