1
1
import { NEXT_TS_ERRORS } from '../constant'
2
2
import {
3
- getInfo ,
4
3
getSource ,
5
4
getTs ,
6
5
getTypeChecker ,
7
6
isPositionInsideNode ,
7
+ log ,
8
+ virtualTsEnv ,
8
9
} from '../utils'
9
10
10
11
import type tsModule from 'typescript/lib/tsserverlibrary'
@@ -49,101 +50,6 @@ function getMetadataExport(fileName: string, position: number) {
49
50
return metadataExport
50
51
}
51
52
52
- let cachedProxiedLanguageService : tsModule . LanguageService | undefined
53
- let cachedProxiedLanguageServiceHost : tsModule . LanguageServiceHost | undefined
54
- function getProxiedLanguageService ( ) {
55
- if ( cachedProxiedLanguageService )
56
- return {
57
- languageService : cachedProxiedLanguageService as tsModule . LanguageService ,
58
- languageServiceHost :
59
- cachedProxiedLanguageServiceHost as tsModule . LanguageServiceHost & {
60
- addFile : ( fileName : string , body : string ) => void
61
- } ,
62
- }
63
-
64
- const languageServiceHost = getInfo ( ) . languageServiceHost
65
-
66
- const ts = getTs ( )
67
- class ProxiedLanguageServiceHost implements tsModule . LanguageServiceHost {
68
- files : {
69
- [ fileName : string ] : { file : tsModule . IScriptSnapshot ; ver : number }
70
- } = { }
71
-
72
- log = ( ) => { }
73
- trace = ( ) => { }
74
- error = ( ) => { }
75
- getCompilationSettings = ( ) => languageServiceHost . getCompilationSettings ( )
76
- getScriptIsOpen = ( ) => true
77
- getCurrentDirectory = ( ) => languageServiceHost . getCurrentDirectory ( )
78
- getDefaultLibFileName = ( o : any ) =>
79
- languageServiceHost . getDefaultLibFileName ( o )
80
-
81
- getScriptVersion = ( fileName : string ) => {
82
- const file = this . files [ fileName ]
83
- if ( ! file ) return languageServiceHost . getScriptVersion ( fileName )
84
- return file . ver . toString ( )
85
- }
86
-
87
- getScriptSnapshot = ( fileName : string ) => {
88
- const file = this . files [ fileName ]
89
- if ( ! file ) return languageServiceHost . getScriptSnapshot ( fileName )
90
- return file . file
91
- }
92
-
93
- getScriptFileNames ( ) : string [ ] {
94
- const names : Set < string > = new Set ( )
95
- for ( var name in this . files ) {
96
- if ( this . files . hasOwnProperty ( name ) ) {
97
- names . add ( name )
98
- }
99
- }
100
- const files = languageServiceHost . getScriptFileNames ( )
101
- for ( const file of files ) {
102
- names . add ( file )
103
- }
104
- return [ ...names ]
105
- }
106
-
107
- addFile ( fileName : string , body : string ) {
108
- const snap = ts . ScriptSnapshot . fromString ( body )
109
- snap . getChangeRange = ( _ ) => undefined
110
- const existing = this . files [ fileName ]
111
- if ( existing ) {
112
- this . files [ fileName ] . ver ++
113
- this . files [ fileName ] . file = snap
114
- } else {
115
- this . files [ fileName ] = { ver : 1 , file : snap }
116
- }
117
- }
118
-
119
- readFile ( fileName : string ) {
120
- const file = this . files [ fileName ]
121
- return file
122
- ? file . file . getText ( 0 , file . file . getLength ( ) )
123
- : languageServiceHost . readFile ( fileName )
124
- }
125
- fileExists ( fileName : string ) {
126
- return (
127
- this . files [ fileName ] !== undefined ||
128
- languageServiceHost . fileExists ( fileName )
129
- )
130
- }
131
- }
132
-
133
- cachedProxiedLanguageServiceHost = new ProxiedLanguageServiceHost ( )
134
- cachedProxiedLanguageService = ts . createLanguageService (
135
- cachedProxiedLanguageServiceHost ,
136
- ts . createDocumentRegistry ( )
137
- )
138
- return {
139
- languageService : cachedProxiedLanguageService as tsModule . LanguageService ,
140
- languageServiceHost :
141
- cachedProxiedLanguageServiceHost as tsModule . LanguageServiceHost & {
142
- addFile : ( fileName : string , body : string ) => void
143
- } ,
144
- }
145
- }
146
-
147
53
function updateVirtualFileWithType (
148
54
fileName : string ,
149
55
node : tsModule . VariableDeclaration | tsModule . FunctionDeclaration ,
@@ -178,8 +84,14 @@ function updateVirtualFileWithType(
178
84
annotation +
179
85
sourceText . slice ( nodeEnd ) +
180
86
TYPE_IMPORT
181
- const { languageServiceHost } = getProxiedLanguageService ( )
182
- languageServiceHost . addFile ( fileName , newSource )
87
+
88
+ if ( virtualTsEnv . sys . fileExists ( fileName ) ) {
89
+ log ( 'Updating file: ' + fileName )
90
+ virtualTsEnv . updateFile ( fileName , newSource )
91
+ } else {
92
+ log ( 'Creating file: ' + fileName )
93
+ virtualTsEnv . createFile ( fileName , newSource )
94
+ }
183
95
184
96
return [ nodeEnd , annotation . length ]
185
97
}
@@ -196,8 +108,9 @@ function proxyDiagnostics(
196
108
n : tsModule . VariableDeclaration | tsModule . FunctionDeclaration
197
109
) {
198
110
// Get diagnostics
199
- const { languageService } = getProxiedLanguageService ( )
200
- const diagnostics = languageService . getSemanticDiagnostics ( fileName )
111
+ const diagnostics = virtualTsEnv . languageService . getSemanticDiagnostics . bind (
112
+ virtualTsEnv . languageService
113
+ ) ( fileName )
201
114
const source = getSource ( fileName )
202
115
203
116
// Filter and map the results
@@ -239,13 +152,11 @@ const metadata = {
239
152
if ( pos === undefined ) return prior
240
153
241
154
// Get completions
242
- const { languageService } = getProxiedLanguageService ( )
243
155
const newPos = position <= pos [ 0 ] ? position : position + pos [ 1 ]
244
- const completions = languageService . getCompletionsAtPosition (
245
- fileName ,
246
- newPos ,
247
- undefined
248
- )
156
+ const completions =
157
+ virtualTsEnv . languageService . getCompletionsAtPosition . bind (
158
+ virtualTsEnv . languageService
159
+ ) ( fileName , newPos , undefined )
249
160
250
161
if ( completions ) {
251
162
completions . isIncomplete = true
@@ -465,18 +376,11 @@ const metadata = {
465
376
const pos = updateVirtualFileWithType ( fileName , node )
466
377
if ( pos === undefined ) return
467
378
468
- const { languageService } = getProxiedLanguageService ( )
469
379
const newPos = position <= pos [ 0 ] ? position : position + pos [ 1 ]
470
380
471
- const details = languageService . getCompletionEntryDetails (
472
- fileName ,
473
- newPos ,
474
- entryName ,
475
- formatOptions ,
476
- source ,
477
- preferences ,
478
- data
479
- )
381
+ const details = virtualTsEnv . languageService . getCompletionEntryDetails . bind (
382
+ virtualTsEnv . languageService
383
+ ) ( fileName , newPos , entryName , formatOptions , source , preferences , data )
480
384
return details
481
385
} ,
482
386
@@ -489,9 +393,10 @@ const metadata = {
489
393
const pos = updateVirtualFileWithType ( fileName , node )
490
394
if ( pos === undefined ) return
491
395
492
- const { languageService } = getProxiedLanguageService ( )
493
396
const newPos = position <= pos [ 0 ] ? position : position + pos [ 1 ]
494
- const insight = languageService . getQuickInfoAtPosition ( fileName , newPos )
397
+ const insight = virtualTsEnv . languageService . getQuickInfoAtPosition . bind (
398
+ virtualTsEnv . languageService
399
+ ) ( fileName , newPos )
495
400
return insight
496
401
} ,
497
402
@@ -503,11 +408,12 @@ const metadata = {
503
408
// We annotate with the type in a virtual language service
504
409
const pos = updateVirtualFileWithType ( fileName , node )
505
410
if ( pos === undefined ) return
506
- const { languageService } = getProxiedLanguageService ( )
507
411
const newPos = position <= pos [ 0 ] ? position : position + pos [ 1 ]
508
412
509
413
const definitionInfoAndBoundSpan =
510
- languageService . getDefinitionAndBoundSpan ( fileName , newPos )
414
+ virtualTsEnv . languageService . getDefinitionAndBoundSpan . bind (
415
+ virtualTsEnv . languageService
416
+ ) ( fileName , newPos )
511
417
512
418
if ( definitionInfoAndBoundSpan ) {
513
419
// Adjust the start position of the text span
0 commit comments