3
3
var commondir = require ( 'commondir' ) ;
4
4
var events = require ( 'events' ) ;
5
5
var fs = require ( 'fs' ) ;
6
+ var realpath = require ( 'fs.realpath' )
6
7
var log = require ( 'util' ) . debuglog ( require ( '../package' ) . name ) ;
7
8
var os = require ( 'os' ) ;
8
9
var path = require ( 'path' ) ;
9
10
var util = require ( 'util' ) ;
10
11
11
12
module . exports = function ( ts ) {
12
- function replaceFileExtension ( file , extension ) {
13
- return file . replace ( / \. \w + $ / i, extension ) ;
14
- }
15
-
16
13
function Host ( currentDirectory , outputDirectory , languageVersion ) {
17
14
this . currentDirectory = this . getCanonicalFileName ( path . resolve ( currentDirectory ) ) ;
18
15
this . outputDirectory = this . getCanonicalFileName ( path . resolve ( outputDirectory ) ) ;
@@ -49,7 +46,7 @@ module.exports = function (ts) {
49
46
filename
50
47
)
51
48
) ) ;
52
- var canonical = this . _currentCanonical ( filename ) ;
49
+ var canonical = this . _canonical ( filename ) ;
53
50
log ( 'Parsing %s' , canonical ) ;
54
51
55
52
var text ;
@@ -94,7 +91,7 @@ module.exports = function (ts) {
94
91
if ( filename === '__lib.d.ts' ) {
95
92
return this . libDefault ;
96
93
}
97
- var canonical = this . _currentCanonical ( filename ) ;
94
+ var canonical = this . _canonical ( filename ) ;
98
95
if ( this . files [ canonical ] ) {
99
96
return this . files [ canonical ] . ts ;
100
97
}
@@ -108,9 +105,19 @@ module.exports = function (ts) {
108
105
} ;
109
106
110
107
Host . prototype . writeFile = function ( filename , data ) {
111
- var canonical = this . _currentCanonical ( filename ) ;
112
- log ( 'Cache write %s' , canonical ) ;
113
- this . output [ canonical ] = data ;
108
+
109
+ var outputCanonical = this . _canonical ( filename ) ;
110
+ log ( 'Cache write %s' , outputCanonical ) ;
111
+ this . output [ outputCanonical ] = data ;
112
+
113
+ var sourceCanonical = this . _inferSourceCanonical ( outputCanonical ) ;
114
+ var sourceFollowed = this . _follow ( path . dirname ( sourceCanonical ) ) + '/' + path . basename ( sourceCanonical ) ;
115
+
116
+ if ( sourceFollowed !== sourceCanonical ) {
117
+ outputCanonical = this . _inferOutputCanonical ( sourceFollowed ) ;
118
+ log ( 'Cache write (followed) %s' , outputCanonical ) ;
119
+ this . output [ outputCanonical ] = data ;
120
+ }
114
121
} ;
115
122
116
123
Host . prototype . getCurrentDirectory = function ( ) {
@@ -138,13 +145,6 @@ module.exports = function (ts) {
138
145
return ts . sys . readFile ( filename ) ;
139
146
} ;
140
147
141
- Host . prototype . _currentCanonical = function ( filename ) {
142
- return this . getCanonicalFileName ( path . resolve (
143
- this . currentDirectory ,
144
- filename
145
- ) ) ;
146
- }
147
-
148
148
Host . prototype . _rootDir = function ( ) {
149
149
var dirs = [ ] ;
150
150
for ( var filename in this . files ) {
@@ -169,25 +169,70 @@ module.exports = function (ts) {
169
169
return rootFilenames ;
170
170
}
171
171
172
- Host . prototype . _output = function ( filename , extension ) {
172
+ Host . prototype . _output = function ( filename ) {
173
+
174
+ var outputCanonical = this . _inferOutputCanonical ( filename ) ;
175
+ log ( 'Cache read %s' , outputCanonical ) ;
176
+
177
+ var output = this . output [ outputCanonical ] ;
178
+ if ( ! output ) {
179
+ log ( 'Cache miss on %s' , outputCanonical ) ;
180
+ }
181
+ return output ;
182
+ }
183
+
184
+ Host . prototype . _canonical = function ( filename ) {
185
+ return this . getCanonicalFileName ( path . resolve (
186
+ this . currentDirectory ,
187
+ filename
188
+ ) ) ;
189
+ }
190
+
191
+ Host . prototype . _inferOutputCanonical = function ( filename ) {
173
192
174
- var inputCanonical = this . _currentCanonical ( filename ) ;
193
+ var sourceCanonical = this . _canonical ( filename ) ;
175
194
var outputRelative = path . relative (
176
195
this . _rootDir ( ) ,
177
- replaceFileExtension ( inputCanonical , extension )
196
+ sourceCanonical
178
197
) ;
179
198
var outputCanonical = this . getCanonicalFileName ( path . resolve (
180
199
this . outputDirectory ,
181
200
outputRelative
182
201
) ) ;
183
- log ( 'Cache read %s' , outputCanonical ) ;
202
+ return outputCanonical ;
203
+ }
184
204
185
- var output = this . output [ outputCanonical ] ;
186
- if ( ! output ) {
187
- log ( 'Cache miss on %s' , outputCanonical ) ;
188
- }
189
- return output ;
205
+ Host . prototype . _inferSourceCanonical = function ( filename ) {
206
+
207
+ var outputCanonical = this . _canonical ( filename ) ;
208
+ var outputRelative = path . relative (
209
+ this . outputDirectory ,
210
+ outputCanonical
211
+ ) ;
212
+ var sourceCanonical = this . getCanonicalFileName ( path . resolve (
213
+ this . _rootDir ( ) ,
214
+ outputRelative
215
+ ) ) ;
216
+ return sourceCanonical ;
190
217
}
191
218
219
+ Host . prototype . _follow = function ( filename ) {
220
+
221
+ filename = this . _canonical ( filename ) ;
222
+ var parts = [ ] ;
223
+
224
+ while ( ! / ^ ( \/ | \w : \/ | \w : \\ ) $ / i. test ( filename ) ) {
225
+
226
+ var stats = fs . lstatSync ( filename ) ;
227
+ if ( stats . isSymbolicLink ( ) ) {
228
+ filename = realpath . realpathSync ( filename ) ;
229
+ } else {
230
+ parts . unshift ( path . basename ( filename ) ) ;
231
+ filename = path . dirname ( filename ) ;
232
+ }
233
+ }
234
+ return ts . normalizeSlashes ( filename + parts . join ( '/' ) ) ;
235
+ } ;
236
+
192
237
return Host ;
193
238
} ;
0 commit comments