-
-
Notifications
You must be signed in to change notification settings - Fork 43
/
index.ts
117 lines (115 loc) 路 3.71 KB
/
index.ts
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
116
117
import { FileMap, LanguagePlugin, VirtualCode, createLanguage, forEachEmbeddedCode, isDiagnosticsEnabled } from '@volar/language-core';
import type { Linter } from 'eslint';
import { TextDocument } from 'vscode-languageserver-textdocument';
const windowsPath = /\\/g;
export function createProcessor(
languagePlugins: LanguagePlugin[],
caseSensitive: boolean,
extensionsMap: Record<string, string> = {
'javascript': '.js',
'typescript': '.ts',
'javascriptreact': '.jsx',
'typescriptreact': '.tsx',
'css': '.css',
'less': '.less',
'scss': '.scss',
'sass': '.sass',
'postcss': '.pcss',
'stylus': '.styl',
'html': '.html',
'pug': '.pug',
'json': '.json',
'jsonc': '.json',
'yaml': '.yaml',
'markdown': '.md',
},
supportsAutofix = true,
): Linter.Processor {
const language = createLanguage(languagePlugins, caseSensitive, () => { });
const documents = new FileMap<{
sourceDocument: TextDocument;
embeddedDocuments: TextDocument[];
codes: VirtualCode[];
}>(caseSensitive);
return {
supportsAutofix,
preprocess(text, filename) {
filename = filename.replace(windowsPath, '/');
const files: Linter.ProcessorFile[] = [];
const sourceScript = language.scripts.set(filename, {
getLength() {
return text.length;
},
getText(start, end) {
return text.substring(start, end);
},
getChangeRange() {
return undefined;
},
});
if (sourceScript?.generated) {
const codes = [];
const embeddedDocuments = [];
for (const code of forEachEmbeddedCode(sourceScript.generated.root)) {
if (code.mappings.some(mapping => isDiagnosticsEnabled(mapping.data))) {
const ext = extensionsMap[code.languageId];
if (!ext) {
continue;
}
files.push({
filename: filename + ext,
text: code.snapshot.getText(0, code.snapshot.getLength()),
});
codes.push(code);
embeddedDocuments.push(TextDocument.create(filename + ext, code.languageId, 0, code.snapshot.getText(0, code.snapshot.getLength())));
}
}
documents.set(filename, {
sourceDocument: TextDocument.create(filename, sourceScript.languageId, 0, text),
embeddedDocuments,
codes,
});
}
return files;
},
postprocess(messagesArr, filename) {
filename = filename.replace(windowsPath, '/');
const docs = documents.get(filename);
if (docs) {
const { codes, sourceDocument, embeddedDocuments } = docs;
for (let i = 0; i < messagesArr.length; i++) {
const code = codes[i];
const map = language.maps.get(code);
if (!map) {
messagesArr[i].length = 0;
continue;
}
const embeddedDocument = embeddedDocuments[i];
messagesArr[i] = messagesArr[i].filter(message => {
const start = embeddedDocument.offsetAt({ line: message.line - 1, character: message.column - 1 });
const end = embeddedDocument.offsetAt({ line: (message.endLine ?? message.line) - 1, character: (message.endColumn ?? message.column) - 1 });
for (const [sourceStart, mapping] of map.getSourceOffsets(start)) {
if (isDiagnosticsEnabled(mapping.data)) {
for (const [sourceEnd, mapping] of map.getSourceOffsets(end)) {
if (isDiagnosticsEnabled(mapping.data)) {
const sourcePosition = sourceDocument.positionAt(sourceStart);
const sourceEndPosition = sourceDocument.positionAt(sourceEnd);
message.line = sourcePosition.line + 1;
message.column = sourcePosition.character + 1;
message.endLine = sourceEndPosition.line + 1;
message.endColumn = sourceEndPosition.character + 1;
return true;
}
}
break;
}
}
return false;
});
}
return messagesArr.flat();
}
return [];
},
};
}