1
1
import type * as ts from 'typescript' ;
2
2
import { decorateProgram } from './decorateProgram' ;
3
3
import { LanguagePlugin , createLanguage } from '@volar/language-core' ;
4
+ import { createResolveModuleName } from '../resolveModuleName' ;
4
5
5
6
export function proxyCreateProgram (
6
7
ts : typeof import ( 'typescript' ) ,
@@ -24,8 +25,7 @@ export function proxyCreateProgram(
24
25
ts . sys . useCaseSensitiveFileNames ,
25
26
fileName => {
26
27
let snapshot : ts . IScriptSnapshot | undefined ;
27
- assert ( originalSourceFiles . has ( fileName ) , `originalSourceFiles.has(${ fileName } )` ) ;
28
- const sourceFile = originalSourceFiles . get ( fileName ) ;
28
+ const sourceFile = originalHost . getSourceFile ( fileName , 99 satisfies ts . ScriptTarget . ESNext ) ;
29
29
if ( sourceFile ) {
30
30
snapshot = sourceFileToSnapshotMap . get ( sourceFile ) ;
31
31
if ( ! snapshot ) {
@@ -51,35 +51,17 @@ export function proxyCreateProgram(
51
51
}
52
52
}
53
53
) ;
54
- const originalSourceFiles = new Map < string , ts . SourceFile | undefined > ( ) ;
55
54
const parsedSourceFiles = new WeakMap < ts . SourceFile , ts . SourceFile > ( ) ;
56
- const arbitraryExtensions = extensions . map ( ext => `.d${ ext } .ts` ) ;
57
55
const originalHost = options . host ;
58
- const moduleResolutionHost : ts . ModuleResolutionHost = {
59
- ...originalHost ,
60
- fileExists ( fileName ) {
61
- for ( let i = 0 ; i < arbitraryExtensions . length ; i ++ ) {
62
- if ( fileName . endsWith ( arbitraryExtensions [ i ] ) ) {
63
- return originalHost . fileExists ( fileName . slice ( 0 , - arbitraryExtensions [ i ] . length ) + extensions [ i ] ) ;
64
- }
65
- }
66
- return originalHost . fileExists ( fileName ) ;
67
- } ,
68
- } ;
69
56
70
57
options . host = { ...originalHost } ;
71
- options . options . allowArbitraryExtensions = true ;
72
58
options . host . getSourceFile = (
73
59
fileName ,
74
60
languageVersionOrOptions ,
75
61
onError ,
76
62
shouldCreateNewSourceFile ,
77
63
) => {
78
-
79
64
const originalSourceFile = originalHost . getSourceFile ( fileName , languageVersionOrOptions , onError , shouldCreateNewSourceFile ) ;
80
-
81
- originalSourceFiles . set ( fileName , originalSourceFile ) ;
82
-
83
65
if ( originalSourceFile && extensions . some ( ext => fileName . endsWith ( ext ) ) ) {
84
66
let sourceFile2 = parsedSourceFiles . get ( originalSourceFile ) ;
85
67
if ( ! sourceFile2 ) {
@@ -88,14 +70,14 @@ export function proxyCreateProgram(
88
70
let patchedText = originalSourceFile . text . split ( '\n' ) . map ( line => ' ' . repeat ( line . length ) ) . join ( '\n' ) ;
89
71
let scriptKind = ts . ScriptKind . TS ;
90
72
if ( sourceScript . generated ?. languagePlugin . typescript ) {
91
- const { getServiceScript : getScript , getExtraServiceScripts : getExtraScripts } = sourceScript . generated . languagePlugin . typescript ;
92
- const serviceScript = getScript ( sourceScript . generated . root ) ;
73
+ const { getServiceScript, getExtraServiceScripts } = sourceScript . generated . languagePlugin . typescript ;
74
+ const serviceScript = getServiceScript ( sourceScript . generated . root ) ;
93
75
if ( serviceScript ) {
94
76
scriptKind = serviceScript . scriptKind ;
95
77
patchedText += serviceScript . code . snapshot . getText ( 0 , serviceScript . code . snapshot . getLength ( ) ) ;
96
78
}
97
- if ( getExtraScripts ) {
98
- console . warn ( 'getExtraScripts () is not available in this use case.' ) ;
79
+ if ( getExtraServiceScripts ) {
80
+ console . warn ( 'getExtraServiceScripts () is not available in this use case.' ) ;
99
81
}
100
82
}
101
83
sourceFile2 = ts . createSourceFile (
@@ -114,57 +96,54 @@ export function proxyCreateProgram(
114
96
115
97
return originalSourceFile ;
116
98
} ;
117
- options . host . resolveModuleNameLiterals = (
118
- moduleNames ,
119
- containingFile ,
120
- redirectedReference ,
121
- options ,
122
- ) => {
123
- return moduleNames . map < ts . ResolvedModuleWithFailedLookupLocations > ( name => {
124
- return resolveModuleName ( name . text , containingFile , options , redirectedReference ) ;
125
- } ) ;
126
- } ;
127
- options . host . resolveModuleNames = (
128
- moduleNames ,
129
- containingFile ,
130
- _reusedNames ,
131
- redirectedReference ,
132
- options ,
133
- ) => {
134
- return moduleNames . map < ts . ResolvedModule | undefined > ( name => {
135
- return resolveModuleName ( name , containingFile , options , redirectedReference ) . resolvedModule ;
136
- } ) ;
137
- } ;
138
99
139
- const program = Reflect . apply ( target , thisArg , [ options ] ) as ts . Program ;
100
+ if ( extensions . length ) {
101
+ options . options . allowArbitraryExtensions = true ;
102
+
103
+ const resolveModuleName = createResolveModuleName ( ts , originalHost , language . plugins , fileName => language . scripts . get ( fileName ) ) ;
104
+ const resolveModuleNameLiterals = originalHost . resolveModuleNameLiterals ;
105
+ const resolveModuleNames = originalHost . resolveModuleNames ;
106
+ const moduleResolutionCache = ts . createModuleResolutionCache ( originalHost . getCurrentDirectory ( ) , originalHost . getCanonicalFileName , options . options ) ;
107
+
108
+ options . host . resolveModuleNameLiterals = (
109
+ moduleLiterals ,
110
+ containingFile ,
111
+ redirectedReference ,
112
+ compilerOptions ,
113
+ ...rest
114
+ ) => {
115
+ if ( resolveModuleNameLiterals && moduleLiterals . every ( name => ! extensions . some ( ext => name . text . endsWith ( ext ) ) ) ) {
116
+ return resolveModuleNameLiterals ( moduleLiterals , containingFile , redirectedReference , compilerOptions , ...rest ) ;
117
+ }
118
+ return moduleLiterals . map ( moduleLiteral => {
119
+ return resolveModuleName ( moduleLiteral . text , containingFile , compilerOptions , moduleResolutionCache , redirectedReference ) ;
120
+ } ) ;
121
+ } ;
122
+ options . host . resolveModuleNames = (
123
+ moduleNames ,
124
+ containingFile ,
125
+ reusedNames ,
126
+ redirectedReference ,
127
+ compilerOptions ,
128
+ containingSourceFile
129
+ ) => {
130
+ if ( resolveModuleNames && moduleNames . every ( name => ! extensions . some ( ext => name . endsWith ( ext ) ) ) ) {
131
+ return resolveModuleNames ( moduleNames , containingFile , reusedNames , redirectedReference , compilerOptions , containingSourceFile ) ;
132
+ }
133
+ return moduleNames . map ( moduleName => {
134
+ return resolveModuleName ( moduleName , containingFile , compilerOptions , moduleResolutionCache , redirectedReference ) . resolvedModule ;
135
+ } ) ;
136
+ } ;
137
+ }
138
+
139
+ const program = Reflect . apply ( target , thisArg , args ) as ts . Program ;
140
140
141
141
decorateProgram ( language , program ) ;
142
142
143
143
// TODO: #128
144
144
( program as any ) . __volar__ = { language } ;
145
145
146
146
return program ;
147
-
148
- function resolveModuleName ( name : string , containingFile : string , options : ts . CompilerOptions , redirectedReference : ts . ResolvedProjectReference | undefined ) {
149
- const resolved = ts . resolveModuleName (
150
- name ,
151
- containingFile ,
152
- options ,
153
- moduleResolutionHost ,
154
- originalHost . getModuleResolutionCache ?.( ) ,
155
- redirectedReference
156
- ) ;
157
- if ( resolved . resolvedModule ) {
158
- for ( let i = 0 ; i < arbitraryExtensions . length ; i ++ ) {
159
- if ( resolved . resolvedModule . resolvedFileName . endsWith ( arbitraryExtensions [ i ] ) ) {
160
- const sourceFileName = resolved . resolvedModule . resolvedFileName . slice ( 0 , - arbitraryExtensions [ i ] . length ) + extensions [ i ] ;
161
- resolved . resolvedModule . resolvedFileName = sourceFileName ;
162
- resolved . resolvedModule . extension = extensions [ i ] ;
163
- }
164
- }
165
- }
166
- return resolved ;
167
- }
168
147
} ,
169
148
} ) ;
170
149
}
0 commit comments