1
1
import type { LanguagePlugin } from '@volar/language-core' ;
2
2
import * as path from 'path-browserify' ;
3
- import { getDefaultVueLanguagePlugins } from './plugins' ;
3
+ import { getDefaultVueLanguagePlugins , createPluginContext } from './plugins' ;
4
4
import { VueFile } from './virtualFile/vueFile' ;
5
5
import { VueCompilerOptions , VueLanguagePlugin } from './types' ;
6
6
import type * as ts from 'typescript/lib/tsserverlibrary' ;
@@ -32,6 +32,25 @@ function getVueFileRegistry(key: string, plugins: VueLanguagePlugin[]) {
32
32
return fileRegistry ;
33
33
}
34
34
35
+ function getFileRegistryKey (
36
+ compilerOptions : ts . CompilerOptions ,
37
+ vueCompilerOptions : VueCompilerOptions ,
38
+ plugins : ReturnType < VueLanguagePlugin > [ ] ,
39
+ globalTypesHolder : string | undefined ,
40
+ ) {
41
+ const values = [
42
+ globalTypesHolder ,
43
+ ...Object . keys ( vueCompilerOptions )
44
+ . sort ( )
45
+ . filter ( key => key !== 'plugins' )
46
+ . map ( key => [ key , vueCompilerOptions [ key as keyof VueCompilerOptions ] ] ) ,
47
+ [ ...new Set ( plugins . map ( plugin => plugin . requiredCompilerOptions ?? [ ] ) . flat ( ) ) ]
48
+ . sort ( )
49
+ . map ( key => [ key , compilerOptions [ key as keyof ts . CompilerOptions ] ] ) ,
50
+ ] ;
51
+ return JSON . stringify ( values ) ;
52
+ }
53
+
35
54
export function createVueLanguage (
36
55
ts : typeof import ( 'typescript/lib/tsserverlibrary' ) ,
37
56
compilerOptions : ts . CompilerOptions = { } ,
@@ -42,6 +61,14 @@ export function createVueLanguage(
42
61
43
62
const vueCompilerOptions = resolveVueCompilerOptions ( _vueCompilerOptions ) ;
44
63
const allowLanguageIds = new Set ( [ 'vue' ] ) ;
64
+ const pluginContext = createPluginContext (
65
+ ts ,
66
+ compilerOptions ,
67
+ vueCompilerOptions ,
68
+ codegenStack ,
69
+ globalTypesHolder ,
70
+ ) ;
71
+ const plugins = getDefaultVueLanguagePlugins ( pluginContext ) ;
45
72
46
73
if ( vueCompilerOptions . extensions . includes ( '.md' ) ) {
47
74
allowLanguageIds . add ( 'markdown' ) ;
@@ -51,38 +78,19 @@ export function createVueLanguage(
51
78
}
52
79
53
80
let fileRegistry : Map < string , VueFile > | undefined ;
54
- let plugins : ReturnType < VueLanguagePlugin > [ ] = [ ] ;
55
81
56
82
return {
57
83
createVirtualFile ( fileName , languageId , snapshot ) {
58
84
if ( allowLanguageIds . has ( languageId ) ) {
59
85
60
86
if ( ! fileRegistry ) {
61
87
62
- globalTypesHolder ??= fileName ;
63
-
64
- const keys = [
65
- globalTypesHolder ,
66
- ...Object . keys ( vueCompilerOptions )
67
- . sort ( )
68
- . filter ( key => key !== 'plugins' )
69
- . map ( key => [ key , vueCompilerOptions [ key as keyof VueCompilerOptions ] ] ) ,
70
- [ ...new Set ( plugins . map ( plugin => plugin . requiredCompilerOptions ?? [ ] ) . flat ( ) ) ]
71
- . sort ( )
72
- . map ( key => [ key , compilerOptions [ key as keyof ts . CompilerOptions ] ] ) ,
73
- ] ;
88
+ pluginContext . globalTypesHolder ??= fileName ;
74
89
75
90
fileRegistry = getVueFileRegistry (
76
- JSON . stringify ( keys ) ,
91
+ getFileRegistryKey ( compilerOptions , vueCompilerOptions , plugins , pluginContext . globalTypesHolder ) ,
77
92
vueCompilerOptions . plugins ,
78
93
) ;
79
- plugins = getDefaultVueLanguagePlugins (
80
- ts ,
81
- compilerOptions ,
82
- vueCompilerOptions ,
83
- codegenStack ,
84
- globalTypesHolder ,
85
- ) ;
86
94
}
87
95
88
96
if ( fileRegistry . has ( fileName ) ) {
@@ -95,8 +103,35 @@ export function createVueLanguage(
95
103
return vueFile ;
96
104
}
97
105
} ,
98
- updateVirtualFile ( sourceFile , snapshot ) {
99
- sourceFile . update ( snapshot ) ;
106
+ updateVirtualFile ( vueFile , snapshot ) {
107
+ vueFile . update ( snapshot ) ;
108
+ } ,
109
+ disposeVirtualFile ( vueFile , files ) {
110
+ fileRegistry ?. delete ( vueFile . fileName ) ;
111
+ if ( vueFile . fileName === pluginContext . globalTypesHolder ) {
112
+ if ( fileRegistry ?. size ) {
113
+ for ( const [ fileName , file ] of fileRegistry ! ) {
114
+ pluginContext . globalTypesHolder = fileName ;
115
+
116
+ fileRegistry = getVueFileRegistry (
117
+ getFileRegistryKey ( compilerOptions , vueCompilerOptions , plugins , pluginContext . globalTypesHolder ) ,
118
+ vueCompilerOptions . plugins ,
119
+ ) ;
120
+
121
+ files . updateSourceFile (
122
+ file . fileName ,
123
+ file . languageId ,
124
+ // force dirty
125
+ { ...file . snapshot } ,
126
+ ) ;
127
+ break ;
128
+ }
129
+ }
130
+ else {
131
+ fileRegistry = undefined ;
132
+ pluginContext . globalTypesHolder = undefined ;
133
+ }
134
+ }
100
135
} ,
101
136
typescript : {
102
137
resolveSourceFileName ( tsFileName ) {
0 commit comments