amis-rpc-design/node_modules/ts-loader/dist/servicesHost.js
2023-10-07 19:42:30 +08:00

812 lines
38 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSolutionErrors = exports.makeSolutionBuilderHost = exports.makeWatchHost = exports.updateFileWithText = exports.makeServicesHost = void 0;
const path = require("path");
const config_1 = require("./config");
const constants = require("./constants");
const instances_1 = require("./instances");
const resolver_1 = require("./resolver");
const utils_1 = require("./utils");
function makeResolversAndModuleResolutionHost(scriptRegex, loader, instance, fileExists, enableFileCaching) {
const { compiler, compilerOptions, appendTsTsxSuffixesIfRequired, loaderOptions: { resolveModuleName: customResolveModuleName, resolveTypeReferenceDirective: customResolveTypeReferenceDirective, }, } = instance;
const newLine = compilerOptions.newLine === constants.CarriageReturnLineFeedCode
? constants.CarriageReturnLineFeed
: compilerOptions.newLine === constants.LineFeedCode
? constants.LineFeed
: constants.EOL;
// loader.context seems to work fine on Linux / Mac regardless causes problems for @types resolution on Windows for TypeScript < 2.3
const getCurrentDirectory = () => loader.context;
// make a (sync) resolver that follows webpack's rules
const resolveSync = (0, resolver_1.makeResolver)(loader._compiler.options);
const moduleResolutionHost = {
trace: logData => instance.log.log(logData),
fileExists,
readFile,
realpath: compiler.sys.realpath && realpath,
directoryExists,
getCurrentDirectory,
getDirectories,
readDirectory,
useCaseSensitiveFileNames: () => (0, utils_1.useCaseSensitiveFileNames)(compiler, instance.loaderOptions),
getNewLine: () => newLine,
getDefaultLibFileName: options => compiler.getDefaultLibFilePath(options),
};
if (enableFileCaching) {
addCache(moduleResolutionHost);
}
return makeResolvers(compiler, compilerOptions, moduleResolutionHost, customResolveTypeReferenceDirective, customResolveModuleName, resolveSync, appendTsTsxSuffixesIfRequired, scriptRegex, instance);
function readFile(filePath, encoding) {
return (instance.compiler.sys.readFile(filePath, encoding) ||
(0, utils_1.fsReadFile)(filePath, encoding));
}
function directoryExists(directoryName) {
return compiler.sys.directoryExists(directoryName);
}
function realpath(path) {
return compiler.sys.realpath(path);
}
function getDirectories(path) {
return compiler.sys.getDirectories(path);
}
function readDirectory(path, extensions, exclude, include, depth) {
return compiler.sys.readDirectory(path, extensions, exclude, include, depth);
}
}
/**
* Create the TypeScript language service
*/
function makeServicesHost(scriptRegex, loader, instance, projectReferences) {
const { compiler, compilerOptions, files, filePathKeyMapper } = instance;
const { moduleResolutionHost, resolveModuleNames, resolveTypeReferenceDirectives, } = makeResolversAndModuleResolutionHost(scriptRegex, loader, instance, filePathToCheck => compiler.sys.fileExists(filePathToCheck) ||
(0, utils_1.fsReadFile)(filePathToCheck) !== undefined, instance.loaderOptions.experimentalFileCaching);
const servicesHost = {
getProjectVersion: () => `${instance.version}`,
getProjectReferences: () => projectReferences,
getScriptFileNames: () => [...files.values()]
.map(({ fileName }) => fileName)
.filter(filePath => filePath.match(scriptRegex)),
getScriptVersion: (fileName) => {
var _a;
fileName = path.normalize(fileName);
const key = filePathKeyMapper(fileName);
const file = files.get(key);
if (file) {
return file.version.toString();
}
const outputFileAndKey = (_a = instance.solutionBuilderHost) === null || _a === void 0 ? void 0 : _a.getOutputFileAndKeyFromReferencedProject(fileName);
if (outputFileAndKey !== undefined) {
instance.solutionBuilderHost.outputAffectingInstanceVersion.set(outputFileAndKey.key, true);
}
return outputFileAndKey && outputFileAndKey.outputFile
? outputFileAndKey.outputFile
: '';
},
getScriptSnapshot: (fileName) => {
// This is called any time TypeScript needs a file's text
// We either load from memory or from disk
fileName = path.normalize(fileName);
const key = filePathKeyMapper(fileName);
let file = files.get(key);
if (file === undefined) {
if (instance.solutionBuilderHost) {
const outputFileAndKey = instance.solutionBuilderHost.getOutputFileTextAndKeyFromReferencedProject(fileName);
if (outputFileAndKey !== undefined) {
instance.solutionBuilderHost.outputAffectingInstanceVersion.set(outputFileAndKey.key, true);
return outputFileAndKey && outputFileAndKey.text !== undefined
? compiler.ScriptSnapshot.fromString(outputFileAndKey.text)
: undefined;
}
}
const text = moduleResolutionHost.readFile(fileName);
if (text === undefined) {
return undefined;
}
file = { fileName, version: 0, text };
files.set(key, file);
}
return compiler.ScriptSnapshot.fromString(file.text);
},
...moduleResolutionHost,
getCompilationSettings: () => compilerOptions,
log: moduleResolutionHost.trace,
// used for (/// <reference types="...">) see https://github.com/Realytics/fork-ts-checker-webpack-plugin/pull/250#issuecomment-485061329
resolveTypeReferenceDirectives,
resolveModuleNames,
getCustomTransformers: () => instance.transformers,
};
return servicesHost;
}
exports.makeServicesHost = makeServicesHost;
function makeResolvers(compiler, compilerOptions, moduleResolutionHost, customResolveTypeReferenceDirective, customResolveModuleName, resolveSync, appendTsTsxSuffixesIfRequired, scriptRegex, instance) {
const resolveModuleName = makeResolveModuleName(compiler, compilerOptions, moduleResolutionHost, customResolveModuleName, instance);
const resolveModuleNames = (moduleNames, containingFile, _reusedNames, redirectedReference, _, containingSourceFile) => {
const resolvedModules = moduleNames.map(moduleName => resolveModule(resolveSync, resolveModuleName, appendTsTsxSuffixesIfRequired, scriptRegex, moduleName, containingFile, redirectedReference, containingSourceFile));
(0, utils_1.populateDependencyGraph)(resolvedModules, instance, containingFile);
return resolvedModules;
};
const resolveTypeReferenceDirective = makeResolveTypeReferenceDirective(compiler, compilerOptions, moduleResolutionHost, customResolveTypeReferenceDirective, instance);
const resolveTypeReferenceDirectives = (typeDirectiveNames, containingFile, redirectedReference, options, containingFileMode // new impliedNodeFormat is accepted by compilerHost
) => typeDirectiveNames.map(directive => resolveTypeReferenceDirective(directive, containingFile, options, redirectedReference, containingFileMode).resolvedTypeReferenceDirective);
return {
resolveTypeReferenceDirectives,
resolveModuleNames,
moduleResolutionHost,
};
}
function createWatchFactory(filePathKeyMapper, compiler) {
const watchedFiles = new Map();
const watchedDirectories = new Map();
const watchedDirectoriesRecursive = new Map();
return {
watchedFiles,
watchedDirectories,
watchedDirectoriesRecursive,
invokeFileWatcher,
watchFile,
watchDirectory,
};
function invokeWatcherCallbacks(map, key, fileName, eventKind) {
var _a;
const callbacks = (_a = map.get(filePathKeyMapper(key))) === null || _a === void 0 ? void 0 : _a.callbacks;
if (callbacks !== undefined && callbacks.length) {
// The array copy is made to ensure that even if one of the callback removes the callbacks,
// we dont miss any callbacks following it
const cbs = callbacks.slice();
for (const cb of cbs) {
cb(fileName, eventKind);
}
return true;
}
return false;
}
function invokeFileWatcher(fileName, eventKind) {
fileName = path.normalize(fileName);
let result = invokeWatcherCallbacks(watchedFiles, fileName, fileName, eventKind);
if (eventKind !== compiler.FileWatcherEventKind.Changed) {
const directory = path.dirname(fileName);
result =
invokeWatcherCallbacks(watchedDirectories, directory, fileName) ||
result;
result = invokeRecursiveDirectoryWatcher(directory, fileName) || result;
}
return result;
}
``;
function invokeRecursiveDirectoryWatcher(directory, fileAddedOrRemoved) {
directory = path.normalize(directory);
let result = invokeWatcherCallbacks(watchedDirectoriesRecursive, directory, fileAddedOrRemoved);
const basePath = path.dirname(directory);
if (directory !== basePath) {
result =
invokeRecursiveDirectoryWatcher(basePath, fileAddedOrRemoved) || result;
}
return result;
}
function createWatcher(file, callbacks, callback) {
const key = filePathKeyMapper(file);
const existing = callbacks.get(key);
if (existing === undefined) {
callbacks.set(key, {
fileName: path.normalize(file),
callbacks: [callback],
});
}
else {
existing.callbacks.push(callback);
}
return {
close: () => {
const existing = callbacks.get(key);
if (existing !== undefined) {
(0, utils_1.unorderedRemoveItem)(existing.callbacks, callback);
if (!existing.callbacks.length) {
callbacks.delete(key);
}
}
},
};
}
function watchFile(fileName, callback, _pollingInterval) {
return createWatcher(fileName, watchedFiles, callback);
}
function watchDirectory(fileName, callback, recursive) {
return createWatcher(fileName, recursive === true ? watchedDirectoriesRecursive : watchedDirectories, callback);
}
}
function updateFileWithText(instance, key, filePath, text) {
const nFilePath = path.normalize(filePath);
const file = instance.files.get(key) || instance.otherFiles.get(key);
if (file !== undefined) {
const newText = text(nFilePath);
if (newText !== file.text) {
file.text = newText;
file.version++;
file.modifiedTime = new Date();
instance.version++;
if (!instance.modifiedFiles) {
instance.modifiedFiles = new Map();
}
instance.modifiedFiles.set(key, true);
if (instance.watchHost !== undefined) {
instance.watchHost.invokeFileWatcher(nFilePath, instance.compiler.FileWatcherEventKind.Changed);
}
}
}
}
exports.updateFileWithText = updateFileWithText;
/**
* Create the TypeScript Watch host
*/
function makeWatchHost(scriptRegex, loader, instance, projectReferences) {
const { compiler, compilerOptions, files, otherFiles, filePathKeyMapper } = instance;
const { watchFile, watchDirectory, invokeFileWatcher } = createWatchFactory(filePathKeyMapper, compiler);
const { moduleResolutionHost, resolveModuleNames, resolveTypeReferenceDirectives, } = makeResolversAndModuleResolutionHost(scriptRegex, loader, instance, fileName => files.has(filePathKeyMapper(fileName)) ||
compiler.sys.fileExists(fileName), instance.loaderOptions.experimentalFileCaching);
const watchHost = {
rootFiles: getRootFileNames(),
options: compilerOptions,
...moduleResolutionHost,
readFile: readFileWithCachingText,
watchFile: (fileName, callback, pollingInterval, options) => {
var _a;
const outputFileKey = (_a = instance.solutionBuilderHost) === null || _a === void 0 ? void 0 : _a.getOutputFileKeyFromReferencedProject(fileName);
if (!outputFileKey || outputFileKey === filePathKeyMapper(fileName)) {
return watchFile(fileName, callback, pollingInterval, options);
}
// Handle symlink to outputFile
const outputFileName = instance.solutionBuilderHost.realpath(fileName);
return watchFile(outputFileName, (_fileName, eventKind) => callback(fileName, eventKind), pollingInterval, options);
},
watchDirectory,
// used for (/// <reference types="...">) see https://github.com/Realytics/fork-ts-checker-webpack-plugin/pull/250#issuecomment-485061329
resolveTypeReferenceDirectives,
resolveModuleNames,
invokeFileWatcher,
updateRootFileNames: () => {
instance.changedFilesList = false;
if (instance.watchOfFilesAndCompilerOptions !== undefined) {
instance.watchOfFilesAndCompilerOptions.updateRootFileNames(getRootFileNames());
}
},
createProgram: projectReferences === undefined
? compiler.createEmitAndSemanticDiagnosticsBuilderProgram
: createBuilderProgramWithReferences,
outputFiles: new Map(),
};
return watchHost;
function getRootFileNames() {
return [...files.values()]
.map(({ fileName }) => fileName)
.filter(filePath => filePath.match(scriptRegex));
}
function readFileWithCachingText(fileName, encoding) {
var _a;
fileName = path.normalize(fileName);
const key = filePathKeyMapper(fileName);
const file = files.get(key) || otherFiles.get(key);
if (file !== undefined) {
return file.text;
}
const text = moduleResolutionHost.readFile(fileName, encoding);
if (text === undefined) {
return undefined;
}
if (!((_a = instance.solutionBuilderHost) === null || _a === void 0 ? void 0 : _a.getOutputFileKeyFromReferencedProject(fileName))) {
otherFiles.set(key, { fileName, version: 0, text });
}
return text;
}
function createBuilderProgramWithReferences(rootNames, options, host, oldProgram, configFileParsingDiagnostics) {
const program = compiler.createProgram({
rootNames: rootNames,
options: options,
host,
oldProgram: oldProgram && oldProgram.getProgram(),
configFileParsingDiagnostics,
projectReferences,
});
const builderProgramHost = host;
return compiler.createEmitAndSemanticDiagnosticsBuilderProgram(program, builderProgramHost, oldProgram, configFileParsingDiagnostics);
}
}
exports.makeWatchHost = makeWatchHost;
const missingFileModifiedTime = new Date(0);
function identity(x) {
return x;
}
function toLowerCase(x) {
return x.toLowerCase();
}
const fileNameLowerCaseRegExp = /[^\u0130\u0131\u00DFa-z0-9\\/:\-_\. ]+/g;
function toFileNameLowerCase(x) {
return fileNameLowerCaseRegExp.test(x)
? x.replace(fileNameLowerCaseRegExp, toLowerCase)
: x;
}
function createGetCanonicalFileName(instance) {
return (0, utils_1.useCaseSensitiveFileNames)(instance.compiler, instance.loaderOptions)
? identity
: toFileNameLowerCase;
}
function createModuleResolutionCache(instance, moduleResolutionHost) {
const cache = instance.compiler.createModuleResolutionCache(moduleResolutionHost.getCurrentDirectory(), createGetCanonicalFileName(instance), instance.compilerOptions);
// Add new API optional methods
if (!cache.clear) {
cache.clear = () => {
cache.directoryToModuleNameMap.clear();
cache.moduleNameToDirectoryMap.clear();
};
}
if (!cache.update) {
cache.update = options => {
if (!options.configFile)
return;
const ref = {
sourceFile: options.configFile,
commandLine: { options },
};
cache.directoryToModuleNameMap.setOwnMap(cache.directoryToModuleNameMap.getOrCreateMapOfCacheRedirects(ref));
cache.moduleNameToDirectoryMap.setOwnMap(cache.moduleNameToDirectoryMap.getOrCreateMapOfCacheRedirects(ref));
cache.directoryToModuleNameMap.setOwnOptions(options);
cache.moduleNameToDirectoryMap.setOwnOptions(options);
};
}
return cache;
}
/**
* Create the TypeScript Watch host
*/
function makeSolutionBuilderHost(scriptRegex, loader, instance) {
const { compiler, loaderOptions: { transpileOnly }, filePathKeyMapper, } = instance;
// loader.context seems to work fine on Linux / Mac regardless causes problems for @types resolution on Windows for TypeScript < 2.3
const formatDiagnosticHost = {
getCurrentDirectory: compiler.sys.getCurrentDirectory,
getCanonicalFileName: createGetCanonicalFileName(instance),
getNewLine: () => compiler.sys.newLine,
};
const diagnostics = {
global: [],
perFile: new Map(),
transpileErrors: [],
};
const reportDiagnostic = (d) => {
if (transpileOnly) {
const filePath = d.file ? filePathKeyMapper(d.file.fileName) : undefined;
const last = diagnostics.transpileErrors[diagnostics.transpileErrors.length - 1];
if (diagnostics.transpileErrors.length && last[0] === filePath) {
last[1].push(d);
}
else {
diagnostics.transpileErrors.push([filePath, [d]]);
}
}
else if (d.file) {
const filePath = filePathKeyMapper(d.file.fileName);
const existing = diagnostics.perFile.get(filePath);
if (existing) {
existing.push(d);
}
else {
diagnostics.perFile.set(filePath, [d]);
}
}
else {
diagnostics.global.push(d);
}
instance.log.logInfo(compiler.formatDiagnostic(d, formatDiagnosticHost));
};
const reportSolutionBuilderStatus = (d) => instance.log.logInfo(compiler.formatDiagnostic(d, formatDiagnosticHost));
const reportWatchStatus = (d, newLine, _options) => instance.log.logInfo(`${compiler.flattenDiagnosticMessageText(d.messageText, compiler.sys.newLine)}${newLine + newLine}`);
const outputFiles = new Map();
const inputFiles = new Map();
const writtenFiles = [];
const outputAffectingInstanceVersion = new Map();
let timeoutId;
const { resolveModuleNames, resolveTypeReferenceDirectives, moduleResolutionHost, } = makeResolversAndModuleResolutionHost(scriptRegex, loader, instance, fileName => {
const filePathKey = filePathKeyMapper(fileName);
return (instance.files.has(filePathKey) ||
instance.otherFiles.has(filePathKey) ||
compiler.sys.fileExists(fileName));
},
/*enableFileCaching*/ true);
const configFileInfo = new Map();
const allWatches = [];
const sysHost = compiler.createSolutionBuilderWithWatchHost(compiler.sys, compiler.createEmitAndSemanticDiagnosticsBuilderProgram, reportDiagnostic, reportSolutionBuilderStatus, reportWatchStatus);
// Keeps track of the various `typescript.CustomTransformers` for each program that is created.
const customTransformers = new Map();
// let lastBuilderProgram: typescript.CreateProgram | undefined = undefined;
const solutionBuilderHost = {
...sysHost,
...moduleResolutionHost,
createProgram: (rootNames, options, host, oldProgram, configFileParsingDiagnostics, projectReferences) => {
var _a, _b, _c, _d;
(_a = instance.moduleResolutionCache) === null || _a === void 0 ? void 0 : _a.update(options || {});
(_b = instance.typeReferenceResolutionCache) === null || _b === void 0 ? void 0 : _b.update(options || {});
const result = sysHost.createProgram(rootNames, options, host, oldProgram, configFileParsingDiagnostics, projectReferences);
(_c = instance.typeReferenceResolutionCache) === null || _c === void 0 ? void 0 : _c.update(instance.compilerOptions);
(_d = instance.moduleResolutionCache) === null || _d === void 0 ? void 0 : _d.update(instance.compilerOptions);
if (options) {
// The `configFilePath` is the same value that is used as the `project` parameter of
// `getCustomtransformers` below.
const project = options.configFilePath;
if (typeof project === "string") {
// Custom transformers need a reference to the `typescript.Program`, that reference is
// unavailable during the the `getCustomTransformers` callback below.
const transformers = (0, instances_1.getCustomTransformers)(instance.loaderOptions, result.getProgram(), result.getProgram);
customTransformers.set(project, transformers);
}
}
return result;
},
resolveModuleNames,
resolveTypeReferenceDirectives,
diagnostics,
...createWatchFactory(filePathKeyMapper, compiler),
getCustomTransformers: function (project) {
return customTransformers.get(project);
},
// Overrides
writeFile: (name, text, writeByteOrderMark) => {
var _a;
const key = filePathKeyMapper(name);
updateFileWithText(instance, key, name, () => text);
const existing = ensureOutputFile(name);
const hash = hashOutputText(text);
outputFiles.set(key, hash);
writtenFiles.push({
name,
text,
writeByteOrderMark: !!writeByteOrderMark,
});
compiler.sys.writeFile(name, text, writeByteOrderMark);
(_a = moduleResolutionHost.fileExistsCache) === null || _a === void 0 ? void 0 : _a.delete(name);
if (outputAffectingInstanceVersion.has(key) &&
(!existing || existing !== hash)) {
instance.version++;
}
if (instance.watchHost &&
!instance.files.has(key) &&
!instance.otherFiles.has(key)) {
// If file wasnt updated in files or other files of instance, let watch host know of the change
if (!existing) {
instance.hasUnaccountedModifiedFiles =
instance.watchHost.invokeFileWatcher(name, compiler.FileWatcherEventKind.Created) || instance.hasUnaccountedModifiedFiles;
}
else if (existing !== hash) {
instance.hasUnaccountedModifiedFiles =
instance.watchHost.invokeFileWatcher(name, compiler.FileWatcherEventKind.Changed) || instance.hasUnaccountedModifiedFiles;
}
}
},
createDirectory: sysHost.createDirectory &&
(directory => {
var _a;
sysHost.createDirectory(directory);
(_a = moduleResolutionHost.directoryExistsCache) === null || _a === void 0 ? void 0 : _a.delete(directory);
}),
afterProgramEmitAndDiagnostics: transpileOnly ? undefined : storeDtsFiles,
setTimeout: (callback, _time, ...args) => {
timeoutId = [callback, args];
return timeoutId;
},
clearTimeout: _timeoutId => {
timeoutId = undefined;
},
getParsedCommandLine: file => {
const config = (0, config_1.getParsedCommandLine)(compiler, instance.loaderOptions, file);
configFileInfo.set(filePathKeyMapper(file), { config });
return config;
},
writtenFiles,
configFileInfo,
outputAffectingInstanceVersion,
getInputFileStamp,
updateSolutionBuilderInputFile,
getOutputFileKeyFromReferencedProject,
getOutputFileAndKeyFromReferencedProject,
getOutputFileTextAndKeyFromReferencedProject,
getInputFileNameFromOutput: fileName => {
const result = getInputFileNameFromOutput(fileName);
return typeof result === 'string' ? result : undefined;
},
getOutputFilesFromReferencedProjectInput,
buildReferences,
ensureAllReferenceTimestamps,
clearCache,
close,
};
return solutionBuilderHost;
function close() {
allWatches.slice().forEach(w => w.close());
}
function clearCache() {
moduleResolutionHost.clearCache();
outputFiles.clear();
inputFiles.clear();
}
function buildReferences() {
if (!timeoutId) {
ensureAllReferenceTimestamps();
return;
}
diagnostics.global.length = 0;
diagnostics.perFile.clear();
diagnostics.transpileErrors.length = 0;
while (timeoutId) {
const [callback, args] = timeoutId;
timeoutId = undefined;
callback(...args);
}
ensureAllReferenceTimestamps();
}
function ensureAllReferenceTimestamps() {
if (inputFiles.size !== solutionBuilderHost.watchedFiles.size) {
for (const { fileName, } of instance.solutionBuilderHost.watchedFiles.values()) {
instance.solutionBuilderHost.getInputFileStamp(fileName);
}
}
}
function storeDtsFiles(builderProgram) {
const program = builderProgram.getProgram();
for (const configInfo of configFileInfo.values()) {
if (!configInfo.config ||
program.getRootFileNames() !== configInfo.config.fileNames ||
program.getCompilerOptions() !== configInfo.config.options ||
program.getProjectReferences() !== configInfo.config.projectReferences) {
continue;
}
configInfo.dtsFiles = program
.getSourceFiles()
.map(file => path.resolve(file.fileName))
.filter(fileName => fileName.match(constants.dtsDtsxOrDtsDtsxMapRegex));
return;
}
}
function getInputFileNameFromOutput(outputFileName) {
const resolvedFileName = filePathKeyMapper(outputFileName);
for (const configInfo of configFileInfo.values()) {
ensureInputOutputInfo(configInfo);
if (configInfo.outputFileNames) {
for (const { inputFileName, outputNames, } of configInfo.outputFileNames.values()) {
if (outputNames.some(outputName => resolvedFileName === filePathKeyMapper(outputName))) {
return inputFileName;
}
}
}
if (configInfo.tsbuildInfoFile &&
filePathKeyMapper(configInfo.tsbuildInfoFile) === resolvedFileName) {
return true;
}
}
const realPath = solutionBuilderHost.realpath(outputFileName);
return filePathKeyMapper(realPath) !== resolvedFileName
? getInputFileNameFromOutput(realPath)
: undefined;
}
function ensureInputOutputInfo(configInfo) {
if (configInfo.outputFileNames || !configInfo.config) {
return;
}
configInfo.outputFileNames = new Map();
configInfo.config.fileNames.forEach(inputFile => configInfo.outputFileNames.set(filePathKeyMapper(inputFile), {
inputFileName: path.resolve(inputFile),
outputNames: (0, instances_1.getOutputFileNames)(instance, configInfo.config, inputFile),
}));
configInfo.tsbuildInfoFile = instance.compiler
.getTsBuildInfoEmitOutputFilePath
? instance.compiler.getTsBuildInfoEmitOutputFilePath(configInfo.config.options)
: // before api
instance.compiler.getOutputPathForBuildInfo(configInfo.config.options);
}
function getOutputFileAndKeyFromReferencedProject(outputFileName) {
const outputFile = ensureOutputFile(outputFileName);
return outputFile !== undefined
? {
key: getOutputFileKeyFromReferencedProject(outputFileName),
outputFile,
}
: undefined;
}
function getOutputFileTextAndKeyFromReferencedProject(outputFileName) {
const key = getOutputFileKeyFromReferencedProject(outputFileName);
if (!key) {
return undefined;
}
const file = writtenFiles.find(w => filePathKeyMapper(w.name) === key);
if (file) {
return { key, text: file.text };
}
const outputFile = outputFiles.get(key);
return {
key,
text: outputFile !== false
? compiler.sys.readFile(outputFileName)
: undefined,
};
}
function getOutputFileKeyFromReferencedProject(outputFileName) {
const key = filePathKeyMapper(outputFileName);
if (outputFiles.has(key))
return key;
const realKey = filePathKeyMapper(solutionBuilderHost.realpath(outputFileName));
if (realKey !== key && outputFiles.has(realKey))
return realKey;
return getInputFileNameFromOutput(outputFileName) ? realKey : undefined;
}
function hashOutputText(text) {
return compiler.sys.createHash ? compiler.sys.createHash(text) : text;
}
function ensureOutputFile(outputFileName) {
const key = getOutputFileKeyFromReferencedProject(outputFileName);
if (!key) {
return undefined;
}
const outputFile = outputFiles.get(key);
if (outputFile !== undefined) {
return outputFile;
}
if (!getInputFileNameFromOutput(outputFileName)) {
return undefined;
}
const text = compiler.sys.readFile(outputFileName);
const hash = text === undefined ? false : hashOutputText(text);
outputFiles.set(key, hash);
return hash;
}
function getTypeScriptOutputFile(outputFileName) {
const key = filePathKeyMapper(outputFileName);
const writtenFile = writtenFiles.find(w => filePathKeyMapper(w.name) === key);
if (writtenFile)
return writtenFile;
// Read from sys
const text = compiler.sys.readFile(outputFileName);
return text !== undefined
? {
name: outputFileName,
text,
writeByteOrderMark: false,
}
: undefined;
}
function getOutputFilesFromReferencedProjectInput(inputFileName) {
const resolvedFileName = filePathKeyMapper(inputFileName);
for (const configInfo of configFileInfo.values()) {
ensureInputOutputInfo(configInfo);
if (configInfo.outputFileNames) {
const result = configInfo.outputFileNames.get(resolvedFileName);
if (result) {
return result.outputNames
.map(getTypeScriptOutputFile)
.filter(output => !!output);
}
}
}
return [];
}
function getInputFileStamp(fileName) {
const key = filePathKeyMapper(fileName);
const existing = inputFiles.get(key);
if (existing !== undefined) {
return existing;
}
const time = compiler.sys.getModifiedTime(fileName) || missingFileModifiedTime;
inputFiles.set(key, time);
return time;
}
function updateSolutionBuilderInputFile(fileName) {
const key = filePathKeyMapper(fileName);
const existing = inputFiles.get(key) || missingFileModifiedTime;
const newTime = compiler.sys.getModifiedTime(fileName) || missingFileModifiedTime;
if (existing.getTime() === newTime.getTime()) {
return;
}
const eventKind = existing == missingFileModifiedTime
? compiler.FileWatcherEventKind.Created
: newTime === missingFileModifiedTime
? compiler.FileWatcherEventKind.Deleted
: compiler.FileWatcherEventKind.Changed;
solutionBuilderHost.invokeFileWatcher(fileName, eventKind);
}
}
exports.makeSolutionBuilderHost = makeSolutionBuilderHost;
function getSolutionErrors(instance, context) {
const solutionErrors = [];
if (instance.solutionBuilderHost &&
instance.solutionBuilderHost.diagnostics.transpileErrors.length) {
instance.solutionBuilderHost.diagnostics.transpileErrors.forEach(([filePath, errors]) => solutionErrors.push(...(0, utils_1.formatErrors)(errors, instance.loaderOptions, instance.colors, instance.compiler, { file: filePath ? undefined : 'tsconfig.json' }, context)));
}
return solutionErrors;
}
exports.getSolutionErrors = getSolutionErrors;
function makeResolveTypeReferenceDirective(compiler, compilerOptions, moduleResolutionHost, customResolveTypeReferenceDirective, instance) {
var _a, _b;
if (customResolveTypeReferenceDirective === undefined) {
// Until the api is published
if (compiler.createTypeReferenceDirectiveResolutionCache !== undefined &&
!instance.typeReferenceResolutionCache) {
instance.typeReferenceResolutionCache =
compiler.createTypeReferenceDirectiveResolutionCache(moduleResolutionHost.getCurrentDirectory(), createGetCanonicalFileName(instance), instance.compilerOptions, (_b = (_a = instance.moduleResolutionCache) === null || _a === void 0 ? void 0 : _a.getPackageJsonInfoCache) === null || _b === void 0 ? void 0 : _b.call(_a));
}
return (typeDirectiveName, containingFile, options, redirectedReference, containingFileMode) => {
// Copy-pasted from https://github.com/TypeStrong/ts-node/blob/9f789d0d91c6eba30ac7f7aad45194a23b44f159/src/resolver-functions.ts#L139
const nameIsString = typeof typeDirectiveName === 'string';
const mode = nameIsString
? undefined
: compiler.getModeForFileReference(typeDirectiveName, containingFileMode);
const strName = nameIsString
? typeDirectiveName
: typeDirectiveName.fileName.toLowerCase();
return compiler.resolveTypeReferenceDirective(strName, containingFile, options, moduleResolutionHost, redirectedReference, undefined, mode);
};
}
return (directive, containingFile) => customResolveTypeReferenceDirective(directive, // unsure whether we should evolve this further
containingFile, compilerOptions, moduleResolutionHost, compiler.resolveTypeReferenceDirective);
}
function isJsImplementationOfTypings(resolvedModule, tsResolution) {
return (resolvedModule.resolvedFileName.endsWith('js') &&
/\.d\.ts$/.test(tsResolution.resolvedFileName));
}
function resolveModule(resolveSync, resolveModuleName, appendTsTsxSuffixesIfRequired, scriptRegex, moduleName, containingFile, redirectedReference, containingSourceFile) {
let resolutionResult;
try {
const originalFileName = resolveSync(path.normalize(path.dirname(containingFile)), moduleName);
if (originalFileName) {
const resolvedFileName = appendTsTsxSuffixesIfRequired(originalFileName);
if (resolvedFileName.match(scriptRegex) !== null) {
resolutionResult = { resolvedFileName, originalFileName };
}
}
}
catch (e) { }
const tsResolution = resolveModuleName(moduleName, containingFile, redirectedReference, containingSourceFile);
if (tsResolution.resolvedModule !== undefined) {
const resolvedFileName = path.normalize(tsResolution.resolvedModule.resolvedFileName);
const tsResolutionResult = {
...tsResolution.resolvedModule,
originalFileName: resolvedFileName,
resolvedFileName,
};
return resolutionResult === undefined ||
resolutionResult.resolvedFileName ===
tsResolutionResult.resolvedFileName ||
isJsImplementationOfTypings(resolutionResult, tsResolutionResult)
? tsResolutionResult
: resolutionResult;
}
return resolutionResult;
}
function makeResolveModuleName(compiler, compilerOptions, moduleResolutionHost, customResolveModuleName, instance) {
if (customResolveModuleName === undefined) {
if (!instance.moduleResolutionCache) {
instance.moduleResolutionCache = createModuleResolutionCache(instance, moduleResolutionHost);
}
return (moduleName, containingFileName, redirectedReference, containingFile) => compiler.resolveModuleName(moduleName, containingFileName, compilerOptions, moduleResolutionHost, instance.moduleResolutionCache, redirectedReference, containingFile === null || containingFile === void 0 ? void 0 : containingFile.impliedNodeFormat);
}
return (moduleName, containingFile) => customResolveModuleName(moduleName, containingFile, compilerOptions, moduleResolutionHost, compiler.resolveModuleName);
}
function addCache(host) {
host.fileExists = createCache(host.fileExists, (host.fileExistsCache = new Map()));
host.directoryExists = createCache(host.directoryExists, (host.directoryExistsCache = new Map()));
host.realpath =
host.realpath &&
createCache(host.realpath, (host.realpathCache = new Map()));
host.clearCache = clearCache;
function createCache(originalFunction, cache) {
return function getCached(arg) {
let res = cache.get(arg);
if (res !== undefined) {
return res;
}
res = originalFunction(arg);
cache.set(arg, res);
return res;
};
}
function clearCache() {
var _a, _b, _c;
(_a = host.fileExistsCache) === null || _a === void 0 ? void 0 : _a.clear();
(_b = host.directoryExistsCache) === null || _b === void 0 ? void 0 : _b.clear();
(_c = host.realpathCache) === null || _c === void 0 ? void 0 : _c.clear();
}
}
//# sourceMappingURL=servicesHost.js.map