1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.getSolutionErrors = exports.makeSolutionBuilderHost = exports.makeWatchHost = exports.updateFileWithText = exports.makeServicesHost = void 0;
|
4 | const path = require("path");
|
5 | const config_1 = require("./config");
|
6 | const constants = require("./constants");
|
7 | const instances_1 = require("./instances");
|
8 | const resolver_1 = require("./resolver");
|
9 | const utils_1 = require("./utils");
|
10 | function makeResolversAndModuleResolutionHost(scriptRegex, loader, instance, fileExists, enableFileCaching) {
|
11 | const { compiler, compilerOptions, appendTsTsxSuffixesIfRequired, loaderOptions: { resolveModuleName: customResolveModuleName, resolveTypeReferenceDirective: customResolveTypeReferenceDirective, }, } = instance;
|
12 | const newLine = compilerOptions.newLine === constants.CarriageReturnLineFeedCode
|
13 | ? constants.CarriageReturnLineFeed
|
14 | : compilerOptions.newLine === constants.LineFeedCode
|
15 | ? constants.LineFeed
|
16 | : constants.EOL;
|
17 |
|
18 | const getCurrentDirectory = () => loader.context;
|
19 |
|
20 | const resolveSync = resolver_1.makeResolver(loader._compiler.options);
|
21 | const moduleResolutionHost = {
|
22 | trace: logData => instance.log.log(logData),
|
23 | fileExists,
|
24 | readFile,
|
25 | realpath: compiler.sys.realpath && realpath,
|
26 | directoryExists,
|
27 | getCurrentDirectory,
|
28 | getDirectories,
|
29 | readDirectory,
|
30 | useCaseSensitiveFileNames: () => utils_1.useCaseSensitiveFileNames(compiler, instance.loaderOptions),
|
31 | getNewLine: () => newLine,
|
32 | getDefaultLibFileName: options => compiler.getDefaultLibFilePath(options),
|
33 | };
|
34 | if (enableFileCaching) {
|
35 | addCache(moduleResolutionHost);
|
36 | }
|
37 | return makeResolvers(compiler, compilerOptions, moduleResolutionHost, customResolveTypeReferenceDirective, customResolveModuleName, resolveSync, appendTsTsxSuffixesIfRequired, scriptRegex, instance);
|
38 | function readFile(filePath, encoding) {
|
39 | return (instance.compiler.sys.readFile(filePath, encoding) ||
|
40 | utils_1.fsReadFile(filePath, encoding));
|
41 | }
|
42 | function directoryExists(directoryName) {
|
43 | return compiler.sys.directoryExists(directoryName);
|
44 | }
|
45 | function realpath(path) {
|
46 | return compiler.sys.realpath(path);
|
47 | }
|
48 | function getDirectories(path) {
|
49 | return compiler.sys.getDirectories(path);
|
50 | }
|
51 | function readDirectory(path, extensions, exclude, include, depth) {
|
52 | return compiler.sys.readDirectory(path, extensions, exclude, include, depth);
|
53 | }
|
54 | }
|
55 |
|
56 |
|
57 |
|
58 | function makeServicesHost(scriptRegex, loader, instance, projectReferences) {
|
59 | const { compiler, compilerOptions, files, filePathKeyMapper } = instance;
|
60 | const { moduleResolutionHost, resolveModuleNames, resolveTypeReferenceDirectives, } = makeResolversAndModuleResolutionHost(scriptRegex, loader, instance, filePathToCheck => compiler.sys.fileExists(filePathToCheck) ||
|
61 | utils_1.fsReadFile(filePathToCheck) !== undefined, instance.loaderOptions.experimentalFileCaching);
|
62 | const servicesHost = Object.assign(Object.assign({ getProjectVersion: () => `${instance.version}`, getProjectReferences: () => projectReferences, getScriptFileNames: () => [...files.values()]
|
63 | .map(({ fileName }) => fileName)
|
64 | .filter(filePath => filePath.match(scriptRegex)), getScriptVersion: (fileName) => {
|
65 | var _a;
|
66 | fileName = path.normalize(fileName);
|
67 | const key = filePathKeyMapper(fileName);
|
68 | const file = files.get(key);
|
69 | if (file) {
|
70 | return file.version.toString();
|
71 | }
|
72 | const outputFileAndKey = (_a = instance.solutionBuilderHost) === null || _a === void 0 ? void 0 : _a.getOutputFileAndKeyFromReferencedProject(fileName);
|
73 | if (outputFileAndKey !== undefined) {
|
74 | instance.solutionBuilderHost.outputAffectingInstanceVersion.set(outputFileAndKey.key, true);
|
75 | }
|
76 | return outputFileAndKey && outputFileAndKey.outputFile
|
77 | ? outputFileAndKey.outputFile
|
78 | : '';
|
79 | }, getScriptSnapshot: (fileName) => {
|
80 |
|
81 |
|
82 | fileName = path.normalize(fileName);
|
83 | const key = filePathKeyMapper(fileName);
|
84 | let file = files.get(key);
|
85 | if (file === undefined) {
|
86 | if (instance.solutionBuilderHost) {
|
87 | const outputFileAndKey = instance.solutionBuilderHost.getOutputFileTextAndKeyFromReferencedProject(fileName);
|
88 | if (outputFileAndKey !== undefined) {
|
89 | instance.solutionBuilderHost.outputAffectingInstanceVersion.set(outputFileAndKey.key, true);
|
90 | return outputFileAndKey && outputFileAndKey.text !== undefined
|
91 | ? compiler.ScriptSnapshot.fromString(outputFileAndKey.text)
|
92 | : undefined;
|
93 | }
|
94 | }
|
95 | const text = moduleResolutionHost.readFile(fileName);
|
96 | if (text === undefined) {
|
97 | return undefined;
|
98 | }
|
99 | file = { fileName, version: 0, text };
|
100 | files.set(key, file);
|
101 | }
|
102 | return compiler.ScriptSnapshot.fromString(file.text);
|
103 | } }, moduleResolutionHost), { getCompilationSettings: () => compilerOptions, log: moduleResolutionHost.trace,
|
104 |
|
105 | resolveTypeReferenceDirectives,
|
106 | resolveModuleNames, getCustomTransformers: () => instance.transformers });
|
107 | return servicesHost;
|
108 | }
|
109 | exports.makeServicesHost = makeServicesHost;
|
110 | function makeResolvers(compiler, compilerOptions, moduleResolutionHost, customResolveTypeReferenceDirective, customResolveModuleName, resolveSync, appendTsTsxSuffixesIfRequired, scriptRegex, instance) {
|
111 | const resolveTypeReferenceDirective = makeResolveTypeReferenceDirective(compiler, compilerOptions, moduleResolutionHost, customResolveTypeReferenceDirective);
|
112 | const resolveTypeReferenceDirectives = (typeDirectiveNames, containingFile, _redirectedReference) => typeDirectiveNames.map(directive => resolveTypeReferenceDirective(directive, containingFile, _redirectedReference).resolvedTypeReferenceDirective);
|
113 | const resolveModuleName = makeResolveModuleName(compiler, compilerOptions, moduleResolutionHost, customResolveModuleName);
|
114 | const resolveModuleNames = (moduleNames, containingFile, _reusedNames, _redirectedReference) => {
|
115 | const resolvedModules = moduleNames.map(moduleName => resolveModule(resolveSync, resolveModuleName, appendTsTsxSuffixesIfRequired, scriptRegex, moduleName, containingFile));
|
116 | utils_1.populateDependencyGraph(resolvedModules, instance, containingFile);
|
117 | return resolvedModules;
|
118 | };
|
119 | return {
|
120 | resolveTypeReferenceDirectives,
|
121 | resolveModuleNames,
|
122 | moduleResolutionHost,
|
123 | };
|
124 | }
|
125 | function createWatchFactory(filePathKeyMapper, compiler) {
|
126 | const watchedFiles = new Map();
|
127 | const watchedDirectories = new Map();
|
128 | const watchedDirectoriesRecursive = new Map();
|
129 | return {
|
130 | watchedFiles,
|
131 | watchedDirectories,
|
132 | watchedDirectoriesRecursive,
|
133 | invokeFileWatcher,
|
134 | watchFile,
|
135 | watchDirectory,
|
136 | };
|
137 | function invokeWatcherCallbacks(map, key, fileName, eventKind) {
|
138 | var _a;
|
139 | const callbacks = (_a = map.get(filePathKeyMapper(key))) === null || _a === void 0 ? void 0 : _a.callbacks;
|
140 | if (callbacks !== undefined && callbacks.length) {
|
141 |
|
142 |
|
143 | const cbs = callbacks.slice();
|
144 | for (const cb of cbs) {
|
145 | cb(fileName, eventKind);
|
146 | }
|
147 | return true;
|
148 | }
|
149 | return false;
|
150 | }
|
151 | function invokeFileWatcher(fileName, eventKind) {
|
152 | fileName = path.normalize(fileName);
|
153 | let result = invokeWatcherCallbacks(watchedFiles, fileName, fileName, eventKind);
|
154 | if (eventKind !== compiler.FileWatcherEventKind.Changed) {
|
155 | const directory = path.dirname(fileName);
|
156 | result =
|
157 | invokeWatcherCallbacks(watchedDirectories, directory, fileName) ||
|
158 | result;
|
159 | result = invokeRecursiveDirectoryWatcher(directory, fileName) || result;
|
160 | }
|
161 | return result;
|
162 | }
|
163 | ``;
|
164 | function invokeRecursiveDirectoryWatcher(directory, fileAddedOrRemoved) {
|
165 | directory = path.normalize(directory);
|
166 | let result = invokeWatcherCallbacks(watchedDirectoriesRecursive, directory, fileAddedOrRemoved);
|
167 | const basePath = path.dirname(directory);
|
168 | if (directory !== basePath) {
|
169 | result =
|
170 | invokeRecursiveDirectoryWatcher(basePath, fileAddedOrRemoved) || result;
|
171 | }
|
172 | return result;
|
173 | }
|
174 | function createWatcher(file, callbacks, callback) {
|
175 | const key = filePathKeyMapper(file);
|
176 | const existing = callbacks.get(key);
|
177 | if (existing === undefined) {
|
178 | callbacks.set(key, {
|
179 | fileName: path.normalize(file),
|
180 | callbacks: [callback],
|
181 | });
|
182 | }
|
183 | else {
|
184 | existing.callbacks.push(callback);
|
185 | }
|
186 | return {
|
187 | close: () => {
|
188 | const existing = callbacks.get(key);
|
189 | if (existing !== undefined) {
|
190 | utils_1.unorderedRemoveItem(existing.callbacks, callback);
|
191 | if (!existing.callbacks.length) {
|
192 | callbacks.delete(key);
|
193 | }
|
194 | }
|
195 | },
|
196 | };
|
197 | }
|
198 | function watchFile(fileName, callback, _pollingInterval) {
|
199 | return createWatcher(fileName, watchedFiles, callback);
|
200 | }
|
201 | function watchDirectory(fileName, callback, recursive) {
|
202 | return createWatcher(fileName, recursive === true ? watchedDirectoriesRecursive : watchedDirectories, callback);
|
203 | }
|
204 | }
|
205 | function updateFileWithText(instance, key, filePath, text) {
|
206 | const nFilePath = path.normalize(filePath);
|
207 | const file = instance.files.get(key) || instance.otherFiles.get(key);
|
208 | if (file !== undefined) {
|
209 | const newText = text(nFilePath);
|
210 | if (newText !== file.text) {
|
211 | file.text = newText;
|
212 | file.version++;
|
213 | file.modifiedTime = new Date();
|
214 | instance.version++;
|
215 | if (!instance.modifiedFiles) {
|
216 | instance.modifiedFiles = new Map();
|
217 | }
|
218 | instance.modifiedFiles.set(key, true);
|
219 | if (instance.watchHost !== undefined) {
|
220 | instance.watchHost.invokeFileWatcher(nFilePath, instance.compiler.FileWatcherEventKind.Changed);
|
221 | }
|
222 | }
|
223 | }
|
224 | }
|
225 | exports.updateFileWithText = updateFileWithText;
|
226 |
|
227 |
|
228 |
|
229 | function makeWatchHost(scriptRegex, loader, instance, projectReferences) {
|
230 | const { compiler, compilerOptions, files, otherFiles, filePathKeyMapper, } = instance;
|
231 | const { watchFile, watchDirectory, invokeFileWatcher } = createWatchFactory(filePathKeyMapper, compiler);
|
232 | const { moduleResolutionHost, resolveModuleNames, resolveTypeReferenceDirectives, } = makeResolversAndModuleResolutionHost(scriptRegex, loader, instance, fileName => files.has(filePathKeyMapper(fileName)) ||
|
233 | compiler.sys.fileExists(fileName),
|
234 | false);
|
235 | const watchHost = Object.assign(Object.assign({ rootFiles: getRootFileNames(), options: compilerOptions }, moduleResolutionHost), { readFile: readFileWithCachingText, watchFile: (fileName, callback, pollingInterval, options) => {
|
236 | var _a;
|
237 | const outputFileKey = (_a = instance.solutionBuilderHost) === null || _a === void 0 ? void 0 : _a.getOutputFileKeyFromReferencedProject(fileName);
|
238 | if (!outputFileKey || outputFileKey === filePathKeyMapper(fileName)) {
|
239 | return watchFile(fileName, callback, pollingInterval, options);
|
240 | }
|
241 |
|
242 | const outputFileName = instance.solutionBuilderHost.realpath(fileName);
|
243 | return watchFile(outputFileName, (_fileName, eventKind) => callback(fileName, eventKind), pollingInterval, options);
|
244 | }, watchDirectory,
|
245 |
|
246 | resolveTypeReferenceDirectives,
|
247 | resolveModuleNames,
|
248 | invokeFileWatcher, updateRootFileNames: () => {
|
249 | instance.changedFilesList = false;
|
250 | if (instance.watchOfFilesAndCompilerOptions !== undefined) {
|
251 | instance.watchOfFilesAndCompilerOptions.updateRootFileNames(getRootFileNames());
|
252 | }
|
253 | }, createProgram: projectReferences === undefined
|
254 | ? compiler.createEmitAndSemanticDiagnosticsBuilderProgram
|
255 | : createBuilderProgramWithReferences, outputFiles: new Map() });
|
256 | return watchHost;
|
257 | function getRootFileNames() {
|
258 | return [...files.values()]
|
259 | .map(({ fileName }) => fileName)
|
260 | .filter(filePath => filePath.match(scriptRegex));
|
261 | }
|
262 | function readFileWithCachingText(fileName, encoding) {
|
263 | var _a;
|
264 | fileName = path.normalize(fileName);
|
265 | const key = filePathKeyMapper(fileName);
|
266 | const file = files.get(key) || otherFiles.get(key);
|
267 | if (file !== undefined) {
|
268 | return file.text;
|
269 | }
|
270 | const text = moduleResolutionHost.readFile(fileName, encoding);
|
271 | if (text === undefined) {
|
272 | return undefined;
|
273 | }
|
274 | if (!((_a = instance.solutionBuilderHost) === null || _a === void 0 ? void 0 : _a.getOutputFileKeyFromReferencedProject(fileName))) {
|
275 | otherFiles.set(key, { fileName, version: 0, text });
|
276 | }
|
277 | return text;
|
278 | }
|
279 | function createBuilderProgramWithReferences(rootNames, options, host, oldProgram, configFileParsingDiagnostics) {
|
280 | const program = compiler.createProgram({
|
281 | rootNames: rootNames,
|
282 | options: options,
|
283 | host,
|
284 | oldProgram: oldProgram && oldProgram.getProgram(),
|
285 | configFileParsingDiagnostics,
|
286 | projectReferences,
|
287 | });
|
288 | const builderProgramHost = host;
|
289 | return compiler.createEmitAndSemanticDiagnosticsBuilderProgram(program, builderProgramHost, oldProgram, configFileParsingDiagnostics);
|
290 | }
|
291 | }
|
292 | exports.makeWatchHost = makeWatchHost;
|
293 | const missingFileModifiedTime = new Date(0);
|
294 |
|
295 |
|
296 |
|
297 | function makeSolutionBuilderHost(scriptRegex, loader, instance) {
|
298 | const { compiler, loaderOptions: { transpileOnly }, filePathKeyMapper, } = instance;
|
299 |
|
300 | const formatDiagnosticHost = {
|
301 | getCurrentDirectory: compiler.sys.getCurrentDirectory,
|
302 | getCanonicalFileName: utils_1.useCaseSensitiveFileNames(compiler, instance.loaderOptions)
|
303 | ? s => s
|
304 | : s => s.toLowerCase(),
|
305 | getNewLine: () => compiler.sys.newLine,
|
306 | };
|
307 | const diagnostics = {
|
308 | global: [],
|
309 | perFile: new Map(),
|
310 | transpileErrors: [],
|
311 | };
|
312 | const reportDiagnostic = (d) => {
|
313 | if (transpileOnly) {
|
314 | const filePath = d.file ? filePathKeyMapper(d.file.fileName) : undefined;
|
315 | const last = diagnostics.transpileErrors[diagnostics.transpileErrors.length - 1];
|
316 | if (diagnostics.transpileErrors.length && last[0] === filePath) {
|
317 | last[1].push(d);
|
318 | }
|
319 | else {
|
320 | diagnostics.transpileErrors.push([filePath, [d]]);
|
321 | }
|
322 | }
|
323 | else if (d.file) {
|
324 | const filePath = filePathKeyMapper(d.file.fileName);
|
325 | const existing = diagnostics.perFile.get(filePath);
|
326 | if (existing) {
|
327 | existing.push(d);
|
328 | }
|
329 | else {
|
330 | diagnostics.perFile.set(filePath, [d]);
|
331 | }
|
332 | }
|
333 | else {
|
334 | diagnostics.global.push(d);
|
335 | }
|
336 | instance.log.logInfo(compiler.formatDiagnostic(d, formatDiagnosticHost));
|
337 | };
|
338 | const reportSolutionBuilderStatus = (d) => instance.log.logInfo(compiler.formatDiagnostic(d, formatDiagnosticHost));
|
339 | const reportWatchStatus = (d, newLine, _options) => instance.log.logInfo(`${compiler.flattenDiagnosticMessageText(d.messageText, compiler.sys.newLine)}${newLine + newLine}`);
|
340 | const outputFiles = new Map();
|
341 | const inputFiles = new Map();
|
342 | const writtenFiles = [];
|
343 | const outputAffectingInstanceVersion = new Map();
|
344 | let timeoutId;
|
345 | const { resolveModuleNames, resolveTypeReferenceDirectives, moduleResolutionHost, } = makeResolversAndModuleResolutionHost(scriptRegex, loader, instance, fileName => !!instance.files.has(filePathKeyMapper(fileName)) ||
|
346 | !!instance.otherFiles.get(filePathKeyMapper(fileName)) ||
|
347 | compiler.sys.fileExists(fileName),
|
348 | true);
|
349 | const configFileInfo = new Map();
|
350 | const allWatches = [];
|
351 | const sysHost = compiler.createSolutionBuilderWithWatchHost(compiler.sys, compiler.createEmitAndSemanticDiagnosticsBuilderProgram, reportDiagnostic, reportSolutionBuilderStatus, reportWatchStatus);
|
352 | const solutionBuilderHost = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, sysHost), moduleResolutionHost), { resolveModuleNames,
|
353 | resolveTypeReferenceDirectives,
|
354 | diagnostics }), createWatchFactory(filePathKeyMapper, compiler)), {
|
355 |
|
356 | writeFile: (name, text, writeByteOrderMark) => {
|
357 | var _a;
|
358 | const key = filePathKeyMapper(name);
|
359 | updateFileWithText(instance, key, name, () => text);
|
360 | const existing = ensureOutputFile(name);
|
361 | const hash = hashOutputText(text);
|
362 | outputFiles.set(key, hash);
|
363 | writtenFiles.push({
|
364 | name,
|
365 | text,
|
366 | writeByteOrderMark: !!writeByteOrderMark,
|
367 | });
|
368 | compiler.sys.writeFile(name, text, writeByteOrderMark);
|
369 | (_a = moduleResolutionHost.fileExistsCache) === null || _a === void 0 ? void 0 : _a.delete(name);
|
370 | if (outputAffectingInstanceVersion.has(key) &&
|
371 | (!existing || existing !== hash)) {
|
372 | instance.version++;
|
373 | }
|
374 | if (instance.watchHost &&
|
375 | !instance.files.has(key) &&
|
376 | !instance.otherFiles.has(key)) {
|
377 |
|
378 | if (!existing) {
|
379 | instance.hasUnaccountedModifiedFiles =
|
380 | instance.watchHost.invokeFileWatcher(name, compiler.FileWatcherEventKind.Created) || instance.hasUnaccountedModifiedFiles;
|
381 | }
|
382 | else if (existing !== hash) {
|
383 | instance.hasUnaccountedModifiedFiles =
|
384 | instance.watchHost.invokeFileWatcher(name, compiler.FileWatcherEventKind.Changed) || instance.hasUnaccountedModifiedFiles;
|
385 | }
|
386 | }
|
387 | }, createDirectory: sysHost.createDirectory &&
|
388 | (directory => {
|
389 | var _a;
|
390 | sysHost.createDirectory(directory);
|
391 | (_a = moduleResolutionHost.directoryExistsCache) === null || _a === void 0 ? void 0 : _a.delete(directory);
|
392 | }), afterProgramEmitAndDiagnostics: transpileOnly ? undefined : storeDtsFiles, setTimeout: (callback, _time, ...args) => {
|
393 | timeoutId = [callback, args];
|
394 | return timeoutId;
|
395 | }, clearTimeout: _timeoutId => {
|
396 | timeoutId = undefined;
|
397 | }, getParsedCommandLine: file => {
|
398 | const config = config_1.getParsedCommandLine(compiler, instance.loaderOptions, file);
|
399 | configFileInfo.set(filePathKeyMapper(file), { config });
|
400 | return config;
|
401 | }, writtenFiles,
|
402 | configFileInfo,
|
403 | outputAffectingInstanceVersion,
|
404 | getInputFileStamp,
|
405 | updateSolutionBuilderInputFile,
|
406 | getOutputFileKeyFromReferencedProject,
|
407 | getOutputFileAndKeyFromReferencedProject,
|
408 | getOutputFileTextAndKeyFromReferencedProject, getInputFileNameFromOutput: fileName => {
|
409 | const result = getInputFileNameFromOutput(fileName);
|
410 | return typeof result === 'string' ? result : undefined;
|
411 | }, getOutputFilesFromReferencedProjectInput,
|
412 | buildReferences,
|
413 | ensureAllReferenceTimestamps,
|
414 | clearCache,
|
415 | close });
|
416 | return solutionBuilderHost;
|
417 | function close() {
|
418 | allWatches.slice().forEach(w => w.close());
|
419 | }
|
420 | function clearCache() {
|
421 | moduleResolutionHost.clearCache();
|
422 | outputFiles.clear();
|
423 | inputFiles.clear();
|
424 | }
|
425 | function buildReferences() {
|
426 | if (!timeoutId) {
|
427 | ensureAllReferenceTimestamps();
|
428 | return;
|
429 | }
|
430 | diagnostics.global.length = 0;
|
431 | diagnostics.perFile.clear();
|
432 | diagnostics.transpileErrors.length = 0;
|
433 | while (timeoutId) {
|
434 | const [callback, args] = timeoutId;
|
435 | timeoutId = undefined;
|
436 | callback(...args);
|
437 | }
|
438 | ensureAllReferenceTimestamps();
|
439 | }
|
440 | function ensureAllReferenceTimestamps() {
|
441 | if (inputFiles.size !== solutionBuilderHost.watchedFiles.size) {
|
442 | for (const { fileName, } of instance.solutionBuilderHost.watchedFiles.values()) {
|
443 | instance.solutionBuilderHost.getInputFileStamp(fileName);
|
444 | }
|
445 | }
|
446 | }
|
447 | function storeDtsFiles(builderProgram) {
|
448 | const program = builderProgram.getProgram();
|
449 | for (const configInfo of configFileInfo.values()) {
|
450 | if (!configInfo.config ||
|
451 | program.getRootFileNames() !== configInfo.config.fileNames ||
|
452 | program.getCompilerOptions() !== configInfo.config.options ||
|
453 | program.getProjectReferences() !== configInfo.config.projectReferences) {
|
454 | continue;
|
455 | }
|
456 | configInfo.dtsFiles = program
|
457 | .getSourceFiles()
|
458 | .map(file => path.resolve(file.fileName))
|
459 | .filter(fileName => fileName.match(constants.dtsDtsxOrDtsDtsxMapRegex));
|
460 | return;
|
461 | }
|
462 | }
|
463 | function getInputFileNameFromOutput(outputFileName) {
|
464 | const resolvedFileName = filePathKeyMapper(outputFileName);
|
465 | for (const configInfo of configFileInfo.values()) {
|
466 | ensureInputOutputInfo(configInfo);
|
467 | if (configInfo.outputFileNames) {
|
468 | for (const { inputFileName, outputNames, } of configInfo.outputFileNames.values()) {
|
469 | if (outputNames.some(outputName => resolvedFileName === filePathKeyMapper(outputName))) {
|
470 | return inputFileName;
|
471 | }
|
472 | }
|
473 | }
|
474 | if (configInfo.tsbuildInfoFile &&
|
475 | filePathKeyMapper(configInfo.tsbuildInfoFile) === resolvedFileName) {
|
476 | return true;
|
477 | }
|
478 | }
|
479 | const realPath = solutionBuilderHost.realpath(outputFileName);
|
480 | return filePathKeyMapper(realPath) !== resolvedFileName
|
481 | ? getInputFileNameFromOutput(realPath)
|
482 | : undefined;
|
483 | }
|
484 | function ensureInputOutputInfo(configInfo) {
|
485 | if (configInfo.outputFileNames || !configInfo.config) {
|
486 | return;
|
487 | }
|
488 | configInfo.outputFileNames = new Map();
|
489 | configInfo.config.fileNames.forEach(inputFile => configInfo.outputFileNames.set(filePathKeyMapper(inputFile), {
|
490 | inputFileName: path.resolve(inputFile),
|
491 | outputNames: instances_1.getOutputFileNames(instance, configInfo.config, inputFile),
|
492 | }));
|
493 | configInfo.tsbuildInfoFile = instance.compiler
|
494 | .getTsBuildInfoEmitOutputFilePath
|
495 | ? instance.compiler.getTsBuildInfoEmitOutputFilePath(configInfo.config.options)
|
496 | :
|
497 | instance.compiler.getOutputPathForBuildInfo(configInfo.config.options);
|
498 | }
|
499 | function getOutputFileAndKeyFromReferencedProject(outputFileName) {
|
500 | const outputFile = ensureOutputFile(outputFileName);
|
501 | return outputFile !== undefined
|
502 | ? {
|
503 | key: getOutputFileKeyFromReferencedProject(outputFileName),
|
504 | outputFile,
|
505 | }
|
506 | : undefined;
|
507 | }
|
508 | function getOutputFileTextAndKeyFromReferencedProject(outputFileName) {
|
509 | const key = getOutputFileKeyFromReferencedProject(outputFileName);
|
510 | if (!key) {
|
511 | return undefined;
|
512 | }
|
513 | const file = writtenFiles.find(w => filePathKeyMapper(w.name) === key);
|
514 | if (file) {
|
515 | return { key, text: file.text };
|
516 | }
|
517 | const outputFile = outputFiles.get(key);
|
518 | return {
|
519 | key,
|
520 | text: outputFile !== false
|
521 | ? compiler.sys.readFile(outputFileName)
|
522 | : undefined,
|
523 | };
|
524 | }
|
525 | function getOutputFileKeyFromReferencedProject(outputFileName) {
|
526 | const key = filePathKeyMapper(outputFileName);
|
527 | if (outputFiles.has(key))
|
528 | return key;
|
529 | const realKey = filePathKeyMapper(solutionBuilderHost.realpath(outputFileName));
|
530 | if (realKey !== key && outputFiles.has(realKey))
|
531 | return realKey;
|
532 | return getInputFileNameFromOutput(outputFileName) ? realKey : undefined;
|
533 | }
|
534 | function hashOutputText(text) {
|
535 | return compiler.sys.createHash ? compiler.sys.createHash(text) : text;
|
536 | }
|
537 | function ensureOutputFile(outputFileName) {
|
538 | const key = getOutputFileKeyFromReferencedProject(outputFileName);
|
539 | if (!key) {
|
540 | return undefined;
|
541 | }
|
542 | const outputFile = outputFiles.get(key);
|
543 | if (outputFile !== undefined) {
|
544 | return outputFile;
|
545 | }
|
546 | if (!getInputFileNameFromOutput(outputFileName)) {
|
547 | return undefined;
|
548 | }
|
549 | const text = compiler.sys.readFile(outputFileName);
|
550 | const hash = text === undefined ? false : hashOutputText(text);
|
551 | outputFiles.set(key, hash);
|
552 | return hash;
|
553 | }
|
554 | function getTypeScriptOutputFile(outputFileName) {
|
555 | const key = filePathKeyMapper(outputFileName);
|
556 | const writtenFile = writtenFiles.find(w => filePathKeyMapper(w.name) === key);
|
557 | if (writtenFile)
|
558 | return writtenFile;
|
559 |
|
560 | const text = compiler.sys.readFile(outputFileName);
|
561 | return text !== undefined
|
562 | ? {
|
563 | name: outputFileName,
|
564 | text,
|
565 | writeByteOrderMark: false,
|
566 | }
|
567 | : undefined;
|
568 | }
|
569 | function getOutputFilesFromReferencedProjectInput(inputFileName) {
|
570 | const resolvedFileName = filePathKeyMapper(inputFileName);
|
571 | for (const configInfo of configFileInfo.values()) {
|
572 | ensureInputOutputInfo(configInfo);
|
573 | if (configInfo.outputFileNames) {
|
574 | const result = configInfo.outputFileNames.get(resolvedFileName);
|
575 | if (result) {
|
576 | return result.outputNames
|
577 | .map(getTypeScriptOutputFile)
|
578 | .filter(output => !!output);
|
579 | }
|
580 | }
|
581 | }
|
582 | return [];
|
583 | }
|
584 | function getInputFileStamp(fileName) {
|
585 | const key = filePathKeyMapper(fileName);
|
586 | const existing = inputFiles.get(key);
|
587 | if (existing !== undefined) {
|
588 | return existing;
|
589 | }
|
590 | const time = compiler.sys.getModifiedTime(fileName) || missingFileModifiedTime;
|
591 | inputFiles.set(key, time);
|
592 | return time;
|
593 | }
|
594 | function updateSolutionBuilderInputFile(fileName) {
|
595 | const key = filePathKeyMapper(fileName);
|
596 | const existing = inputFiles.get(key) || missingFileModifiedTime;
|
597 | const newTime = compiler.sys.getModifiedTime(fileName) || missingFileModifiedTime;
|
598 | if (existing === newTime) {
|
599 | return;
|
600 | }
|
601 | const eventKind = existing == missingFileModifiedTime
|
602 | ? compiler.FileWatcherEventKind.Created
|
603 | : newTime === missingFileModifiedTime
|
604 | ? compiler.FileWatcherEventKind.Deleted
|
605 | : compiler.FileWatcherEventKind.Changed;
|
606 | solutionBuilderHost.invokeFileWatcher(fileName, eventKind);
|
607 | }
|
608 | }
|
609 | exports.makeSolutionBuilderHost = makeSolutionBuilderHost;
|
610 | function getSolutionErrors(instance, context) {
|
611 | const solutionErrors = [];
|
612 | if (instance.solutionBuilderHost &&
|
613 | instance.solutionBuilderHost.diagnostics.transpileErrors.length) {
|
614 | instance.solutionBuilderHost.diagnostics.transpileErrors.forEach(([filePath, errors]) => solutionErrors.push(...utils_1.formatErrors(errors, instance.loaderOptions, instance.colors, instance.compiler, { file: filePath ? undefined : 'tsconfig.json' }, context)));
|
615 | }
|
616 | return solutionErrors;
|
617 | }
|
618 | exports.getSolutionErrors = getSolutionErrors;
|
619 | function makeResolveTypeReferenceDirective(compiler, compilerOptions, moduleResolutionHost, customResolveTypeReferenceDirective) {
|
620 | if (customResolveTypeReferenceDirective === undefined) {
|
621 | return (directive, containingFile, redirectedReference) => compiler.resolveTypeReferenceDirective(directive, containingFile, compilerOptions, moduleResolutionHost, redirectedReference);
|
622 | }
|
623 | return (directive, containingFile) => customResolveTypeReferenceDirective(directive, containingFile, compilerOptions, moduleResolutionHost, compiler.resolveTypeReferenceDirective);
|
624 | }
|
625 | function isJsImplementationOfTypings(resolvedModule, tsResolution) {
|
626 | return (resolvedModule.resolvedFileName.endsWith('js') &&
|
627 | /\.d\.ts$/.test(tsResolution.resolvedFileName));
|
628 | }
|
629 | function resolveModule(resolveSync, resolveModuleName, appendTsTsxSuffixesIfRequired, scriptRegex, moduleName, containingFile) {
|
630 | let resolutionResult;
|
631 | try {
|
632 | const originalFileName = resolveSync(undefined, path.normalize(path.dirname(containingFile)), moduleName);
|
633 | const resolvedFileName = appendTsTsxSuffixesIfRequired(originalFileName);
|
634 | if (resolvedFileName.match(scriptRegex) !== null) {
|
635 | resolutionResult = { resolvedFileName, originalFileName };
|
636 | }
|
637 | }
|
638 | catch (e) { }
|
639 | const tsResolution = resolveModuleName(moduleName, containingFile);
|
640 | if (tsResolution.resolvedModule !== undefined) {
|
641 | const resolvedFileName = path.normalize(tsResolution.resolvedModule.resolvedFileName);
|
642 | const tsResolutionResult = {
|
643 | originalFileName: resolvedFileName,
|
644 | resolvedFileName,
|
645 | isExternalLibraryImport: tsResolution.resolvedModule.isExternalLibraryImport,
|
646 | };
|
647 | return resolutionResult === undefined ||
|
648 | resolutionResult.resolvedFileName ===
|
649 | tsResolutionResult.resolvedFileName ||
|
650 | isJsImplementationOfTypings(resolutionResult, tsResolutionResult)
|
651 | ? tsResolutionResult
|
652 | : resolutionResult;
|
653 | }
|
654 | return resolutionResult;
|
655 | }
|
656 | function makeResolveModuleName(compiler, compilerOptions, moduleResolutionHost, customResolveModuleName) {
|
657 | if (customResolveModuleName === undefined) {
|
658 | return (moduleName, containingFile) => compiler.resolveModuleName(moduleName, containingFile, compilerOptions, moduleResolutionHost);
|
659 | }
|
660 | return (moduleName, containingFile) => customResolveModuleName(moduleName, containingFile, compilerOptions, moduleResolutionHost, compiler.resolveModuleName);
|
661 | }
|
662 | function addCache(host) {
|
663 | host.fileExists = createCache(host.fileExists, (host.fileExistsCache = new Map()));
|
664 | host.directoryExists = createCache(host.directoryExists, (host.directoryExistsCache = new Map()));
|
665 | host.realpath =
|
666 | host.realpath &&
|
667 | createCache(host.realpath, (host.realpathCache = new Map()));
|
668 | host.clearCache = clearCache;
|
669 | function createCache(originalFunction, cache) {
|
670 | return function getCached(arg) {
|
671 | let res = cache.get(arg);
|
672 | if (res !== undefined) {
|
673 | return res;
|
674 | }
|
675 | res = originalFunction(arg);
|
676 | cache.set(arg, res);
|
677 | return res;
|
678 | };
|
679 | }
|
680 | function clearCache() {
|
681 | var _a, _b, _c;
|
682 | (_a = host.fileExistsCache) === null || _a === void 0 ? void 0 : _a.clear();
|
683 | (_b = host.directoryExistsCache) === null || _b === void 0 ? void 0 : _b.clear();
|
684 | (_c = host.realpathCache) === null || _c === void 0 ? void 0 : _c.clear();
|
685 | }
|
686 | }
|
687 |
|
\ | No newline at end of file |