Skip to content

Commit 9066601

Browse files
refactor(typescript-plugin): move reactivity analysis logic to a seperate typescript plugin (#5672)
Co-authored-by: Johnson Chu <[email protected]>
1 parent 5fde5f8 commit 9066601

File tree

11 files changed

+75
-44
lines changed

11 files changed

+75
-44
lines changed

extensions/vscode/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ function patchTypeScriptExtension() {
240240
configNamespace: 'typescript',
241241
languages: config.server.includeLanguages,
242242
},
243+
{
244+
name: 'vue-reactivity-analysis-plugin-pack',
245+
enableForWorkspaceTypeScriptVersions: true,
246+
},
243247
];
244248

245249
fs.readFileSync = (...args: any[]) => {

extensions/vscode/lib/reactivityVisualization.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { getReactiveReferences } from '@vue/typescript-plugin/lib/requests/getReactiveReferences';
1+
import type { Analyzer } from 'laplacenoma';
22
import type * as ts from 'typescript';
33
import * as vscode from 'vscode';
44
import { config } from './config';
@@ -85,11 +85,11 @@ export function activate(
8585
try {
8686
const result = await vscode.commands.executeCommand<
8787
{
88-
body?: ReturnType<typeof getReactiveReferences>;
88+
body?: ReturnType<Analyzer['analyze']> | undefined;
8989
} | undefined
9090
>(
9191
'typescript.tsserverRequest',
92-
'_vue:getReactiveReferences',
92+
'_vue:getReactivityAnalysis',
9393
[
9494
document.uri.fsPath.replace(/\\/g, '/'),
9595
document.offsetAt(editor.selection.active),

extensions/vscode/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,11 +461,14 @@
461461
"@types/node": "^22.10.4",
462462
"@types/semver": "^7.5.3",
463463
"@types/vscode": "1.88.0",
464+
"@volar/typescript": "2.4.23",
464465
"@volar/vscode": "2.4.23",
465466
"@vscode/vsce": "^3.2.1",
466467
"@vue/compiler-sfc": "^3.5.0",
468+
"@vue/language-core": "3.0.8",
467469
"@vue/language-server": "3.0.8",
468470
"@vue/typescript-plugin": "3.0.8",
471+
"laplacenoma": "^0.0.3",
469472
"reactive-vscode": "^0.2.9",
470473
"rolldown": "1.0.0-beta.8",
471474
"semver": "^7.5.4",

packages/typescript-plugin/lib/requests/getReactiveReferences.ts renamed to extensions/vscode/reactivityAnalysis/plugin.ts

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,72 @@
11
import { createProxyLanguageService, decorateLanguageServiceHost } from '@volar/typescript';
2-
import type { Language, SourceScript } from '@vue/language-core';
2+
import type { Language } from '@vue/language-core';
33
import { createAnalyzer } from 'laplacenoma';
4-
import * as rulesVue from 'laplacenoma/rules/vue';
4+
// @ts-expect-error
5+
import rulesVue from 'laplacenoma/rules/vue';
56
import type * as ts from 'typescript';
67

7-
const analyzer = createAnalyzer({
8-
rules: rulesVue,
9-
});
10-
118
let currentVersion = -1;
129
let currentFileName = '';
1310
let currentSnapshot: ts.IScriptSnapshot | undefined;
1411
let languageService: ts.LanguageService | undefined;
1512

16-
export function getReactiveReferences(
13+
const analyzer = createAnalyzer({ rules: rulesVue });
14+
const plugin: ts.server.PluginModuleFactory = ({ typescript: ts }) => {
15+
return {
16+
create(info) {
17+
if (info.session && !(info.session as any).handlers.has('_vue:getReactivityAnalysis')) {
18+
info.session.addProtocolHandler('_vue:getReactivityAnalysis', request => {
19+
const [fileName, position]: [string, number] = request.arguments;
20+
return {
21+
response: getReactivityAnalysis(ts, info.session!, fileName, position),
22+
responseRequired: true,
23+
};
24+
});
25+
}
26+
27+
return info.languageService;
28+
},
29+
};
30+
};
31+
32+
export = plugin;
33+
34+
function getReactivityAnalysis(
1735
ts: typeof import('typescript'),
18-
language: Language<string>,
19-
sourceScript: SourceScript<string>,
36+
session: ts.server.Session,
37+
fileName: string,
2038
position: number,
21-
leadingOffset: number = 0,
2239
) {
40+
const { project } = session['getFileAndProject']({
41+
file: fileName,
42+
projectFileName: undefined,
43+
}) as {
44+
file: ts.server.NormalizedPath;
45+
project: ts.server.Project;
46+
};
47+
48+
const language: Language<string> | undefined = project['program']?.__vue__?.language;
49+
if (!language) {
50+
return;
51+
}
52+
53+
const sourceScript = language.scripts.get(fileName);
54+
if (!sourceScript) {
55+
return;
56+
}
57+
2358
if (currentSnapshot !== sourceScript.snapshot || currentFileName !== sourceScript.id) {
2459
currentSnapshot = sourceScript.snapshot;
2560
currentFileName = sourceScript.id;
2661
currentVersion++;
2762
}
2863
if (!languageService) {
29-
const compilerOptions: ts.CompilerOptions = { allowJs: true, allowNonTsExtensions: true };
3064
const languageServiceHost: ts.LanguageServiceHost = {
3165
getProjectVersion: () => currentVersion.toString(),
3266
getScriptVersion: () => currentVersion.toString(),
3367
getScriptFileNames: () => [currentFileName],
3468
getScriptSnapshot: fileName => fileName === currentFileName ? currentSnapshot : undefined,
35-
getCompilationSettings: () => compilerOptions,
69+
getCompilationSettings: () => ({ allowJs: true, allowNonTsExtensions: true }),
3670
getCurrentDirectory: () => '',
3771
getDefaultLibFileName: () => '',
3872
readFile: () => undefined,
@@ -49,6 +83,7 @@ export function getReactiveReferences(
4983
sourceScript.generated.root,
5084
);
5185
const map = serviceScript ? language.maps.get(serviceScript.code, sourceScript) : undefined;
86+
const leadingOffset = sourceScript.generated ? sourceScript.snapshot.getLength() : 0;
5287
const toSourceRange = map
5388
? (pos: number, end: number) => {
5489
for (const [mappedStart, mappedEnd] of map.toSourceRange(pos - leadingOffset, end - leadingOffset, false)) {

extensions/vscode/rolldown.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const resolve = (...paths: string[]) => path.resolve(__dirname, ...paths);
88
const config: RolldownOptions = {
99
input: {
1010
'extension': './index.ts',
11+
'reactivity-analysis': './reactivityAnalysis/plugin.ts',
1112
},
1213
output: {
1314
format: 'cjs',
@@ -33,6 +34,12 @@ const config: RolldownOptions = {
3334
`module.exports = require('../../dist/typescript-plugin.js');`,
3435
);
3536

37+
fs.mkdirSync(resolve('./node_modules/vue-reactivity-analysis-plugin-pack'), { recursive: true });
38+
fs.writeFileSync(
39+
resolve('./node_modules/vue-reactivity-analysis-plugin-pack/index.js'),
40+
`module.exports = require('../../dist/reactivity-analysis.js');`,
41+
);
42+
3643
if (isDev) {
3744
fs.mkdirSync(resolve('./dist'), { recursive: true });
3845
fs.writeFileSync(

extensions/vscode/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
"module": "CommonJS",
66
"moduleResolution": "Node"
77
},
8-
"include": ["*", "lib/**/*"]
8+
"include": ["*", "lib/**/*", "reactivityAnalysis/**/*"]
99
}

packages/language-server/index.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,6 @@ connection.onInitialize(params => {
122122
getImportPathForFile(...args) {
123123
return sendTsServerRequest('_vue:getImportPathForFile', args);
124124
},
125-
getReactiveReferences(...args) {
126-
return sendTsServerRequest('_vue:getReactiveReferences', args);
127-
},
128125
isRefAtPosition(...args) {
129126
return sendTsServerRequest('_vue:isRefAtPosition', args);
130127
},

packages/typescript-plugin/index.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { getComponentSlots } from './lib/requests/getComponentSlots';
1212
import { getElementAttrs } from './lib/requests/getElementAttrs';
1313
import { getElementNames } from './lib/requests/getElementNames';
1414
import { getImportPathForFile } from './lib/requests/getImportPathForFile';
15-
import { getReactiveReferences } from './lib/requests/getReactiveReferences';
1615
import { isRefAtPosition } from './lib/requests/isRefAtPosition';
1716

1817
const windowsPathReg = /\\/g;
@@ -187,20 +186,6 @@ export = createLanguageServicePlugin(
187186
const { languageService } = getLanguageService(fileName);
188187
return createResponse(getElementNames(ts, languageService.getProgram()!, fileName));
189188
});
190-
session.addProtocolHandler('_vue:getReactiveReferences', request => {
191-
const [fileName, position]: Parameters<Requests['getReactiveReferences']> = request.arguments;
192-
const { language } = getLanguageService(fileName);
193-
const sourceScript = language.scripts.get(fileName)!;
194-
return createResponse(
195-
getReactiveReferences(
196-
ts,
197-
language,
198-
sourceScript,
199-
position,
200-
sourceScript.generated ? sourceScript.snapshot.getLength() : 0,
201-
),
202-
);
203-
});
204189

205190
projectService.logger.info('Vue specific commands are successfully added.');
206191

@@ -229,8 +214,7 @@ export = createLanguageServicePlugin(
229214
}
230215

231216
function getLanguageService(fileName: string) {
232-
// @ts-expect-error
233-
const { project } = session.getFileAndProject({
217+
const { project } = session['getFileAndProject']({
234218
file: fileName,
235219
projectFileName: undefined,
236220
}) as {

packages/typescript-plugin/lib/requests/index.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@ export interface Requests {
4040
getElementNames(
4141
fileName: string,
4242
): Response<ReturnType<typeof import('./getElementNames.js')['getElementNames']>>;
43-
getReactiveReferences(
44-
fileName: string,
45-
position: number,
46-
): Response<ReturnType<typeof import('./getReactiveReferences.js')['getReactiveReferences']>>;
4743
getDocumentHighlights(
4844
fileName: string,
4945
position: number,

packages/typescript-plugin/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
"@volar/typescript": "2.4.23",
1717
"@vue/language-core": "3.0.8",
1818
"@vue/shared": "^3.5.0",
19-
"laplacenoma": "^0.0.3",
2019
"path-browserify": "^1.0.1"
2120
},
2221
"devDependencies": {

0 commit comments

Comments
 (0)