127 lines
5.3 KiB
Plaintext
127 lines
5.3 KiB
Plaintext
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.createTypeScriptServerProject = void 0;
|
|
const language_service_1 = require("@volar/language-service");
|
|
const typescript_1 = require("@volar/typescript");
|
|
const path = require("path-browserify");
|
|
const vscode = require("vscode-languageserver");
|
|
const uriMap_1 = require("../utils/uriMap");
|
|
async function createTypeScriptServerProject(tsconfig, context, serviceEnv, serverOptions, servicePlugins) {
|
|
if (!context.ts) {
|
|
throw '!context.ts';
|
|
}
|
|
let parsedCommandLine;
|
|
let projectVersion = 0;
|
|
let languageService;
|
|
const { uriToFileName, fileNameToUri } = context.runtimeEnv;
|
|
const ts = context.ts;
|
|
const host = {
|
|
getCurrentDirectory: () => uriToFileName(serviceEnv.workspaceFolder),
|
|
getProjectVersion: () => projectVersion.toString(),
|
|
getScriptFileNames: () => rootFiles,
|
|
getScriptSnapshot: fileName => {
|
|
askedFiles.pathSet(fileName, true);
|
|
const doc = context.documents.get(fileNameToUri(fileName));
|
|
if (doc) {
|
|
return doc.getSnapshot();
|
|
}
|
|
},
|
|
getCompilationSettings: () => parsedCommandLine.options,
|
|
getLocalizedDiagnosticMessages: context.tsLocalized ? () => context.tsLocalized : undefined,
|
|
getProjectReferences: () => parsedCommandLine.projectReferences,
|
|
getLanguageId: uri => context.documents.get(uri)?.languageId ?? (0, language_service_1.resolveCommonLanguageId)(uri),
|
|
};
|
|
const sys = (0, typescript_1.createSys)(ts, serviceEnv, host);
|
|
const languagePlugins = await serverOptions.getLanguagePlugins(serviceEnv, {
|
|
typescript: {
|
|
configFileName: typeof tsconfig === 'string' ? tsconfig : undefined,
|
|
host,
|
|
sys,
|
|
},
|
|
});
|
|
const askedFiles = (0, uriMap_1.createUriMap)(fileNameToUri);
|
|
const docChangeWatcher = context.documents.onDidChangeContent(() => {
|
|
projectVersion++;
|
|
});
|
|
const fileWatch = serviceEnv.onDidChangeWatchedFiles?.(params => {
|
|
onWorkspaceFilesChanged(params.changes);
|
|
});
|
|
let rootFiles = await getRootFiles(languagePlugins);
|
|
return {
|
|
askedFiles,
|
|
serviceEnv,
|
|
getLanguageService,
|
|
getLanguageServiceDontCreate: () => languageService,
|
|
tryAddFile(fileName) {
|
|
if (!rootFiles.includes(fileName)) {
|
|
rootFiles.push(fileName);
|
|
projectVersion++;
|
|
}
|
|
},
|
|
dispose,
|
|
getParsedCommandLine: () => parsedCommandLine,
|
|
};
|
|
async function getRootFiles(languagePlugins) {
|
|
parsedCommandLine = await createParsedCommandLine(ts, sys, uriToFileName(serviceEnv.workspaceFolder), tsconfig, languagePlugins.map(plugin => plugin.typescript?.extraFileExtensions ?? []).flat());
|
|
return parsedCommandLine.fileNames;
|
|
}
|
|
function getLanguageService() {
|
|
if (!languageService) {
|
|
const language = (0, typescript_1.createLanguage)(ts, sys, languagePlugins, typeof tsconfig === 'string' ? tsconfig : undefined, host, {
|
|
fileNameToFileId: serviceEnv.typescript.fileNameToUri,
|
|
fileIdToFileName: serviceEnv.typescript.uriToFileName,
|
|
});
|
|
languageService = (0, language_service_1.createLanguageService)(language, servicePlugins, serviceEnv);
|
|
}
|
|
return languageService;
|
|
}
|
|
async function onWorkspaceFilesChanged(changes) {
|
|
const creates = changes.filter(change => change.type === vscode.FileChangeType.Created);
|
|
if (creates.length) {
|
|
rootFiles = await getRootFiles(languagePlugins);
|
|
}
|
|
projectVersion++;
|
|
}
|
|
function dispose() {
|
|
sys.dispose();
|
|
languageService?.dispose();
|
|
fileWatch?.dispose();
|
|
docChangeWatcher.dispose();
|
|
}
|
|
}
|
|
exports.createTypeScriptServerProject = createTypeScriptServerProject;
|
|
async function createParsedCommandLine(ts, sys, workspacePath, tsconfig, extraFileExtensions) {
|
|
let content = {
|
|
errors: [],
|
|
fileNames: [],
|
|
options: {},
|
|
};
|
|
let sysVersion;
|
|
let newSysVersion = await sys.sync();
|
|
while (sysVersion !== newSysVersion) {
|
|
sysVersion = newSysVersion;
|
|
try {
|
|
if (typeof tsconfig === 'string') {
|
|
const config = ts.readJsonConfigFile(tsconfig, sys.readFile);
|
|
content = ts.parseJsonSourceFileConfigFileContent(config, sys, path.dirname(tsconfig), {}, tsconfig, undefined, extraFileExtensions);
|
|
}
|
|
else {
|
|
content = ts.parseJsonConfigFileContent({ files: [] }, sys, workspacePath, tsconfig, workspacePath + '/jsconfig.json', undefined, extraFileExtensions);
|
|
}
|
|
// fix https://github.com/johnsoncodehk/volar/issues/1786
|
|
// https://github.com/microsoft/TypeScript/issues/30457
|
|
// patching ts server broke with outDir + rootDir + composite/incremental
|
|
content.options.outDir = undefined;
|
|
content.fileNames = content.fileNames.map(fileName => fileName.replace(/\\/g, '/'));
|
|
}
|
|
catch {
|
|
// will be failed if web fs host first result not ready
|
|
}
|
|
newSysVersion = await sys.sync();
|
|
}
|
|
if (content) {
|
|
return content;
|
|
}
|
|
return content;
|
|
}
|
|
//# sourceMappingURL=typescriptProject.js.map |