aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2019-08-05 20:31:12 +0100
committerKirill Bulatov <[email protected]>2019-08-05 21:11:16 +0100
commitc5598d9ade92e9ec4474a14229bb34a44a4edad5 (patch)
tree96b6a9f1b6b4c1b8c31cbba32a74eaaa26c8f9ea
parent777552b6a8e534ef3780ecf30a432df1a48fd25c (diff)
Avoid shared mutable state
-rw-r--r--editors/code/src/commands/inlay_hints.ts106
-rw-r--r--editors/code/src/extension.ts20
2 files changed, 55 insertions, 71 deletions
diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts
index d6d1f61f9..5393a2bc9 100644
--- a/editors/code/src/commands/inlay_hints.ts
+++ b/editors/code/src/commands/inlay_hints.ts
@@ -21,67 +21,57 @@ const typeHintDecorationType = vscode.window.createTextEditorDecorationType({
21 21
22export class HintsUpdater { 22export class HintsUpdater {
23 private displayHints = true; 23 private displayHints = true;
24 private decorationsSinceLastChange = new Map<
25 string,
26 vscode.DecorationOptions[]
27 >();
28
29 public async loadHints(editor?: vscode.TextEditor): Promise<void> {
30 if (this.displayHints) {
31 const documentUri = this.getEditorDocumentUri(editor);
32 if (documentUri !== null) {
33 const latestDecorations = this.decorationsSinceLastChange.get(
34 documentUri.toString()
35 );
36 if (latestDecorations === undefined) {
37 await this.updateDecorationsFromServer(
38 documentUri,
39 editor!
40 );
41 } else {
42 await editor!.setDecorations(
43 typeHintDecorationType,
44 latestDecorations
45 );
46 }
47 }
48 }
49 }
50 24
51 public async toggleHintsDisplay(displayHints: boolean): Promise<void> { 25 public async toggleHintsDisplay(displayHints: boolean): Promise<void> {
52 if (this.displayHints !== displayHints) { 26 if (this.displayHints !== displayHints) {
53 this.displayHints = displayHints; 27 this.displayHints = displayHints;
54 this.decorationsSinceLastChange.clear(); 28 return this.refreshVisibleEditorsHints(
55 29 displayHints ? undefined : []
56 if (displayHints) { 30 );
57 return this.updateHints();
58 } else {
59 const currentEditor = vscode.window.activeTextEditor;
60 if (this.getEditorDocumentUri(currentEditor) !== null) {
61 return currentEditor!.setDecorations(
62 typeHintDecorationType,
63 []
64 );
65 }
66 }
67 } 31 }
68 } 32 }
69 33
70 public async updateHints(cause?: TextDocumentChangeEvent): Promise<void> { 34 public async refreshHintsForVisibleEditors(
35 cause?: TextDocumentChangeEvent
36 ): Promise<void> {
71 if (!this.displayHints) { 37 if (!this.displayHints) {
72 return; 38 return;
73 } 39 }
74 const editor = vscode.window.activeTextEditor; 40 if (
75 if (editor === undefined) { 41 cause !== undefined &&
42 (cause.contentChanges.length === 0 ||
43 !this.isRustDocument(cause.document))
44 ) {
76 return; 45 return;
77 } 46 }
78 const document = cause === undefined ? editor.document : cause.document; 47 return this.refreshVisibleEditorsHints();
79 if (!this.isRustDocument(document)) { 48 }
80 return; 49
50 private async refreshVisibleEditorsHints(
51 newDecorations?: vscode.DecorationOptions[]
52 ) {
53 const promises: Array<Promise<void>> = [];
54
55 for (const rustEditor of vscode.window.visibleTextEditors.filter(
56 editor => this.isRustDocument(editor.document)
57 )) {
58 if (newDecorations !== undefined) {
59 promises.push(
60 Promise.resolve(
61 rustEditor.setDecorations(
62 typeHintDecorationType,
63 newDecorations
64 )
65 )
66 );
67 } else {
68 promises.push(this.updateDecorationsFromServer(rustEditor));
69 }
81 } 70 }
82 71
83 this.decorationsSinceLastChange.clear(); 72 for (const promise of promises) {
84 return await this.updateDecorationsFromServer(document.uri, editor); 73 await promise;
74 }
85 } 75 }
86 76
87 private isRustDocument(document: vscode.TextDocument): boolean { 77 private isRustDocument(document: vscode.TextDocument): boolean {
@@ -89,23 +79,14 @@ export class HintsUpdater {
89 } 79 }
90 80
91 private async updateDecorationsFromServer( 81 private async updateDecorationsFromServer(
92 documentUri: vscode.Uri,
93 editor: TextEditor 82 editor: TextEditor
94 ): Promise<void> { 83 ): Promise<void> {
95 const newHints = await this.queryHints(documentUri.toString()); 84 const newHints = await this.queryHints(editor.document.uri.toString());
96 if ( 85 if (newHints !== null) {
97 newHints !== null &&
98 this.getEditorDocumentUri(vscode.window.activeTextEditor) ===
99 documentUri
100 ) {
101 const newDecorations = newHints.map(hint => ({ 86 const newDecorations = newHints.map(hint => ({
102 range: hint.range, 87 range: hint.range,
103 renderOptions: { after: { contentText: `: ${hint.label}` } } 88 renderOptions: { after: { contentText: `: ${hint.label}` } }
104 })); 89 }));
105 this.decorationsSinceLastChange.set(
106 documentUri.toString(),
107 newDecorations
108 );
109 return editor.setDecorations( 90 return editor.setDecorations(
110 typeHintDecorationType, 91 typeHintDecorationType,
111 newDecorations 92 newDecorations
@@ -127,13 +108,4 @@ export class HintsUpdater {
127 ) 108 )
128 ); 109 );
129 } 110 }
130
131 private getEditorDocumentUri(
132 editor?: vscode.TextEditor
133 ): vscode.Uri | null {
134 if (editor && this.isRustDocument(editor.document)) {
135 return editor.document.uri;
136 }
137 return null;
138 }
139} 111}
diff --git a/editors/code/src/extension.ts b/editors/code/src/extension.ts
index c6efc2e7e..39fe6efd8 100644
--- a/editors/code/src/extension.ts
+++ b/editors/code/src/extension.ts
@@ -151,15 +151,27 @@ export function activate(context: vscode.ExtensionContext) {
151 151
152 if (Server.config.displayInlayHints) { 152 if (Server.config.displayInlayHints) {
153 const hintsUpdater = new HintsUpdater(); 153 const hintsUpdater = new HintsUpdater();
154 hintsUpdater.loadHints(vscode.window.activeTextEditor).then(() => { 154 hintsUpdater.refreshHintsForVisibleEditors().then(() => {
155 // vscode may ignore top level hintsUpdater.refreshHintsForVisibleEditors()
156 // so update the hints once when the focus changes to guarantee their presence
157 let editorChangeDisposable: vscode.Disposable | null = null;
158 editorChangeDisposable = vscode.window.onDidChangeActiveTextEditor(
159 _ => {
160 if (editorChangeDisposable !== null) {
161 editorChangeDisposable.dispose();
162 }
163 return hintsUpdater.refreshHintsForVisibleEditors();
164 }
165 );
166
155 disposeOnDeactivation( 167 disposeOnDeactivation(
156 vscode.window.onDidChangeActiveTextEditor(editor => 168 vscode.window.onDidChangeVisibleTextEditors(_ =>
157 hintsUpdater.loadHints(editor) 169 hintsUpdater.refreshHintsForVisibleEditors()
158 ) 170 )
159 ); 171 );
160 disposeOnDeactivation( 172 disposeOnDeactivation(
161 vscode.workspace.onDidChangeTextDocument(e => 173 vscode.workspace.onDidChangeTextDocument(e =>
162 hintsUpdater.updateHints(e) 174 hintsUpdater.refreshHintsForVisibleEditors(e)
163 ) 175 )
164 ); 176 );
165 disposeOnDeactivation( 177 disposeOnDeactivation(