1
1
import { createProxyLanguageService , decorateLanguageServiceHost } from '@volar/typescript' ;
2
- import type { Language , SourceScript } from '@vue/language-core' ;
2
+ import type { Language } from '@vue/language-core' ;
3
3
import { createAnalyzer } from 'laplacenoma' ;
4
- import * as rulesVue from 'laplacenoma/rules/vue' ;
4
+ // @ts -expect-error
5
+ import rulesVue from 'laplacenoma/rules/vue' ;
5
6
import type * as ts from 'typescript' ;
6
7
7
- const analyzer = createAnalyzer ( {
8
- rules : rulesVue ,
9
- } ) ;
10
-
11
8
let currentVersion = - 1 ;
12
9
let currentFileName = '' ;
13
10
let currentSnapshot : ts . IScriptSnapshot | undefined ;
14
11
let languageService : ts . LanguageService | undefined ;
15
12
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 (
17
35
ts : typeof import ( 'typescript' ) ,
18
- language : Language < string > ,
19
- sourceScript : SourceScript < string > ,
36
+ session : ts . server . Session ,
37
+ fileName : string ,
20
38
position : number ,
21
- leadingOffset : number = 0 ,
22
39
) {
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
+
23
58
if ( currentSnapshot !== sourceScript . snapshot || currentFileName !== sourceScript . id ) {
24
59
currentSnapshot = sourceScript . snapshot ;
25
60
currentFileName = sourceScript . id ;
26
61
currentVersion ++ ;
27
62
}
28
63
if ( ! languageService ) {
29
- const compilerOptions : ts . CompilerOptions = { allowJs : true , allowNonTsExtensions : true } ;
30
64
const languageServiceHost : ts . LanguageServiceHost = {
31
65
getProjectVersion : ( ) => currentVersion . toString ( ) ,
32
66
getScriptVersion : ( ) => currentVersion . toString ( ) ,
33
67
getScriptFileNames : ( ) => [ currentFileName ] ,
34
68
getScriptSnapshot : fileName => fileName === currentFileName ? currentSnapshot : undefined ,
35
- getCompilationSettings : ( ) => compilerOptions ,
69
+ getCompilationSettings : ( ) => ( { allowJs : true , allowNonTsExtensions : true } ) ,
36
70
getCurrentDirectory : ( ) => '' ,
37
71
getDefaultLibFileName : ( ) => '' ,
38
72
readFile : ( ) => undefined ,
@@ -49,6 +83,7 @@ export function getReactiveReferences(
49
83
sourceScript . generated . root ,
50
84
) ;
51
85
const map = serviceScript ? language . maps . get ( serviceScript . code , sourceScript ) : undefined ;
86
+ const leadingOffset = sourceScript . generated ? sourceScript . snapshot . getLength ( ) : 0 ;
52
87
const toSourceRange = map
53
88
? ( pos : number , end : number ) => {
54
89
for ( const [ mappedStart , mappedEnd ] of map . toSourceRange ( pos - leadingOffset , end - leadingOffset , false ) ) {
0 commit comments