File: /var/www/design.system/node_modules/@volar/typescript/lib/node/proxyCreateProgram.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.proxyCreateProgram = proxyCreateProgram;
const language_core_1 = require("@volar/language-core");
const resolveModuleName_1 = require("../resolveModuleName");
const decorateProgram_1 = require("./decorateProgram");
const common_1 = require("../common");
const arrayEqual = (a, b) => {
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
};
const objectEqual = (a, b) => {
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length) {
return false;
}
for (const key of keysA) {
if (a[key] !== b[key]) {
return false;
}
}
return true;
};
function proxyCreateProgram(ts, original, create) {
const sourceFileSnapshots = new language_core_1.FileMap(ts.sys.useCaseSensitiveFileNames);
const parsedSourceFiles = new WeakMap();
let lastOptions;
let languagePlugins;
let language;
let moduleResolutionCache;
return new Proxy(original, {
apply: (target, thisArg, args) => {
const options = args[0];
assert(!!options.host, '!!options.host');
if (!lastOptions
|| !languagePlugins
|| !language
|| !arrayEqual(options.rootNames, lastOptions.rootNames)
|| !objectEqual(options.options, lastOptions.options)) {
moduleResolutionCache = ts.createModuleResolutionCache(options.host.getCurrentDirectory(), options.host.getCanonicalFileName, options.options);
lastOptions = options;
const created = create(ts, options);
if (Array.isArray(created)) {
languagePlugins = created;
}
else {
languagePlugins = created.languagePlugins;
}
language = (0, language_core_1.createLanguage)([
...languagePlugins,
{ getLanguageId: common_1.resolveFileLanguageId },
], new language_core_1.FileMap(ts.sys.useCaseSensitiveFileNames), (fileName, includeFsFiles) => {
if (includeFsFiles && !sourceFileSnapshots.has(fileName)) {
const sourceFileText = originalHost.readFile(fileName);
if (sourceFileText !== undefined) {
sourceFileSnapshots.set(fileName, [undefined, {
getChangeRange() {
return undefined;
},
getLength() {
return sourceFileText.length;
},
getText(start, end) {
return sourceFileText.substring(start, end);
},
}]);
}
else {
sourceFileSnapshots.set(fileName, [undefined, undefined]);
}
}
const snapshot = sourceFileSnapshots.get(fileName)?.[1];
if (snapshot) {
language.scripts.set(fileName, snapshot);
}
else {
language.scripts.delete(fileName);
}
});
if ('setup' in created) {
created.setup?.(language);
}
}
const originalHost = options.host;
const extensions = languagePlugins
.map(plugin => plugin.typescript?.extraFileExtensions.map(({ extension }) => `.${extension}`) ?? [])
.flat();
options.host = { ...originalHost };
options.host.getSourceFile = (fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile) => {
const originalSourceFile = originalHost.getSourceFile(fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile);
if (!sourceFileSnapshots.has(fileName)
|| sourceFileSnapshots.get(fileName)?.[0] !== originalSourceFile) {
if (originalSourceFile) {
sourceFileSnapshots.set(fileName, [originalSourceFile, {
getChangeRange() {
return undefined;
},
getLength() {
return originalSourceFile.text.length;
},
getText(start, end) {
return originalSourceFile.text.substring(start, end);
},
}]);
}
else {
sourceFileSnapshots.set(fileName, [undefined, undefined]);
}
}
if (!originalSourceFile) {
return;
}
if (!parsedSourceFiles.has(originalSourceFile)) {
const sourceScript = language.scripts.get(fileName);
assert(!!sourceScript, '!!sourceScript');
parsedSourceFiles.set(originalSourceFile, undefined);
if (sourceScript.generated?.languagePlugin.typescript) {
const { getServiceScript, getExtraServiceScripts } = sourceScript.generated.languagePlugin.typescript;
const serviceScript = getServiceScript(sourceScript.generated.root);
if (serviceScript) {
let virtualContents;
if (!serviceScript.preventLeadingOffset) {
virtualContents = originalSourceFile.text.split('\n').map(line => ' '.repeat(line.length)).join('\n')
+ serviceScript.code.snapshot.getText(0, serviceScript.code.snapshot.getLength());
}
else {
virtualContents = serviceScript.code.snapshot.getText(0, serviceScript.code.snapshot.getLength());
}
const parsedSourceFile = ts.createSourceFile(fileName, virtualContents, languageVersionOrOptions, undefined, serviceScript.scriptKind);
// @ts-expect-error
parsedSourceFile.version = originalSourceFile.version;
parsedSourceFiles.set(originalSourceFile, parsedSourceFile);
}
if (getExtraServiceScripts) {
console.warn('getExtraServiceScripts() is not available in this use case.');
}
}
}
return parsedSourceFiles.get(originalSourceFile) ?? originalSourceFile;
};
if (extensions.length) {
options.options.allowArbitraryExtensions = true;
const resolveModuleName = (0, resolveModuleName_1.createResolveModuleName)(ts, ts.sys.getFileSize, originalHost, language.plugins, fileName => language.scripts.get(fileName));
const resolveModuleNameLiterals = originalHost.resolveModuleNameLiterals;
const resolveModuleNames = originalHost.resolveModuleNames;
options.host.resolveModuleNameLiterals = (moduleLiterals, containingFile, redirectedReference, compilerOptions, ...rest) => {
if (resolveModuleNameLiterals && moduleLiterals.every(name => !extensions.some(ext => name.text.endsWith(ext)))) {
return resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, compilerOptions, ...rest);
}
return moduleLiterals.map(moduleLiteral => {
return resolveModuleName(moduleLiteral.text, containingFile, compilerOptions, moduleResolutionCache, redirectedReference);
});
};
options.host.resolveModuleNames = (moduleNames, containingFile, reusedNames, redirectedReference, compilerOptions, containingSourceFile) => {
if (resolveModuleNames && moduleNames.every(name => !extensions.some(ext => name.endsWith(ext)))) {
return resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference, compilerOptions, containingSourceFile);
}
return moduleNames.map(moduleName => {
return resolveModuleName(moduleName, containingFile, compilerOptions, moduleResolutionCache, redirectedReference).resolvedModule;
});
};
}
const program = Reflect.apply(target, thisArg, args);
(0, decorateProgram_1.decorateProgram)(language, program);
// TODO: #128
program.__volar__ = { language };
return program;
},
});
}
function assert(condition, message) {
if (!condition) {
console.error(message);
throw new Error(message);
}
}
//# sourceMappingURL=proxyCreateProgram.js.map