-
Notifications
You must be signed in to change notification settings - Fork 162
Expand file tree
/
Copy pathDocumentRenderer.ts
More file actions
115 lines (108 loc) · 5.16 KB
/
Copy pathDocumentRenderer.ts
File metadata and controls
115 lines (108 loc) · 5.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* eslint-disable @typescript-eslint/ban-ts-comment */
import { ExtensionContext, TextDocument, WorkspaceConfiguration, workspace } from "vscode";
import { CodeLensRenderer } from "./render/CodeLensRenderer";
import { DiagnosticRenderer } from "./render/DiagnosticRenderer";
import { GutterIconRenderer } from "./render/GutterIconRenderer";
import { RulerHighlightRenderer } from "./render/RulerHighlightRenderer";
import { InspectionRenderer } from "./render/InspectionRenderer";
import { sendInfo } from "vscode-extension-telemetry-wrapper";
import { isCodeLensDisabled, logger } from "../utils";
import { InspectActionCodeLensProvider } from "./InspectActionCodeLensProvider";
import { debounce } from "lodash";
import InspectionCache from "./InspectionCache";
/**
* `DocumentRenderer` is responsible for
* - managing `Rewrite with new Java syntax` code lenses renderer
* - managing inspection renderers based on settings
* - rendering inspections for a document
*/
export class DocumentRenderer {
private readonly availableRenderers: { [type: string]: InspectionRenderer } = {};
private readonly installedRenderers: InspectionRenderer[] = [];
private readonly inspectActionCodeLensProvider: InspectActionCodeLensProvider;
private readonly rerenderDebouncelyMap: { [key: string]: (document: TextDocument) => void } = {};
public constructor() {
this.inspectActionCodeLensProvider = new InspectActionCodeLensProvider();
this.availableRenderers['diagnostics'] = new DiagnosticRenderer();
this.availableRenderers['guttericons'] = new GutterIconRenderer();
this.availableRenderers['codelenses'] = new CodeLensRenderer();
this.availableRenderers['rulerhighlights'] = new RulerHighlightRenderer();
}
public install(context: ExtensionContext): DocumentRenderer {
if (this.installedRenderers.length > 0) {
logger.warn('DefaultRenderer is already installed');
return this;
}
this.inspectActionCodeLensProvider.install(context);
// watch for inspection renderers configuration changes
workspace.onDidChangeConfiguration(event => {
if (event.affectsConfiguration('java.copilot.inspection.renderer')) {
const settings = this.reloadInspectionRenderers(context);
sendInfo('java.copilot.inspection.renderer.changed', { 'settings': `${settings.join(',')}` });
}
});
this.reloadInspectionRenderers(context);
return this;
}
/**
* rerender all inspections for the given document
* @param document the document to rerender
* @param debounced whether to rerender debouncely
*/
public async rerender(document: TextDocument, debounced: boolean = false): Promise<void> {
if (document.languageId !== 'java') return;
if (!debounced) {
this.inspectActionCodeLensProvider.rerender(document);
this.rerenderInspections(document);
return;
}
// clear all rendered inspections first
this.installedRenderers.forEach(r => r.clear(document));
const key = document.uri.fsPath;
if (!this.rerenderDebouncelyMap[key]) {
this.rerenderDebouncelyMap[key] = debounce((document: TextDocument) => {
this.inspectActionCodeLensProvider.rerender(document);
this.rerenderInspections(document);
});
}
this.rerenderDebouncelyMap[key](document);
}
private async rerenderInspections(document: TextDocument): Promise<void> {
const inspections = await InspectionCache.getCachedInspectionsOfDoc(document);
this.installedRenderers.forEach(r => r.clear(document));
this.installedRenderers.forEach(r => {
r.renderInspections(document, inspections);
});
}
private reloadInspectionRenderers(context: ExtensionContext): string[] {
this.installedRenderers.splice(0, this.installedRenderers.length);
const settings = this.reloadInspectionRendererSettings();
Object.entries(this.availableRenderers).forEach(([type, renderer]) => {
if (settings.includes(type.toLowerCase())) { // if enabled
this.installedRenderers.push(renderer);
renderer.install(context);
} else {
renderer.uninstall();
}
});
return settings;
}
/**
* get the enabled inspection renderer names
*/
private reloadInspectionRendererSettings(): string[] {
const config: WorkspaceConfiguration = workspace.getConfiguration('java.copilot.inspection.renderer');
const types: string[] = Object.keys(this.availableRenderers);
const settings = types.map(type => config.get<boolean>(type) ? type.toLowerCase() : '').filter(t => t);
if (settings.length === 0) {
settings.push('diagnostics');
settings.push('rulerhighlights');
const disabled = isCodeLensDisabled();
if (disabled) {
logger.warn('CodeLens is disabled, fallback to GutterIcons');
}
settings.push(disabled ? 'guttericons' : 'codelenses');
}
return settings;
}
}