This commit is contained in:
3
node_modules/@volar/language-server/lib/project/inferredCompilerOptions.d.ts
generated
vendored
3
node_modules/@volar/language-server/lib/project/inferredCompilerOptions.d.ts
generated
vendored
@@ -1,3 +0,0 @@
|
||||
import type * as ts from 'typescript';
|
||||
import type { LanguageServer } from '../types';
|
||||
export declare function getInferredCompilerOptions(server: LanguageServer): Promise<ts.CompilerOptions>;
|
||||
65
node_modules/@volar/language-server/lib/project/inferredCompilerOptions.js
generated
vendored
65
node_modules/@volar/language-server/lib/project/inferredCompilerOptions.js
generated
vendored
@@ -1,65 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getInferredCompilerOptions = getInferredCompilerOptions;
|
||||
async function getInferredCompilerOptions(server) {
|
||||
const [implicitProjectConfig_1 = {}, implicitProjectConfig_2 = {},] = await Promise.all([
|
||||
server.configurations.get('js/ts.implicitProjectConfig'),
|
||||
server.configurations.get('javascript.implicitProjectConfig'),
|
||||
]);
|
||||
const checkJs = readCheckJs();
|
||||
const experimentalDecorators = readExperimentalDecorators();
|
||||
const strictNullChecks = readImplicitStrictNullChecks();
|
||||
const strictFunctionTypes = readImplicitStrictFunctionTypes();
|
||||
const options = {
|
||||
...inferredProjectCompilerOptions('typescript'),
|
||||
allowJs: true,
|
||||
allowSyntheticDefaultImports: true,
|
||||
allowNonTsExtensions: true,
|
||||
resolveJsonModule: true,
|
||||
jsx: 1,
|
||||
};
|
||||
return options;
|
||||
function readCheckJs() {
|
||||
return implicitProjectConfig_1['checkJs']
|
||||
?? implicitProjectConfig_2['checkJs']
|
||||
?? false;
|
||||
}
|
||||
function readExperimentalDecorators() {
|
||||
return implicitProjectConfig_1['experimentalDecorators']
|
||||
?? implicitProjectConfig_2['experimentalDecorators']
|
||||
?? false;
|
||||
}
|
||||
function readImplicitStrictNullChecks() {
|
||||
return implicitProjectConfig_1['strictNullChecks'] ?? false;
|
||||
}
|
||||
function readImplicitStrictFunctionTypes() {
|
||||
return implicitProjectConfig_1['strictFunctionTypes'] ?? true;
|
||||
}
|
||||
function inferredProjectCompilerOptions(projectType) {
|
||||
const projectConfig = {
|
||||
module: 1,
|
||||
target: 7,
|
||||
jsx: 1,
|
||||
};
|
||||
if (checkJs) {
|
||||
projectConfig.checkJs = true;
|
||||
if (projectType === 'typescript') {
|
||||
projectConfig.allowJs = true;
|
||||
}
|
||||
}
|
||||
if (experimentalDecorators) {
|
||||
projectConfig.experimentalDecorators = true;
|
||||
}
|
||||
if (strictNullChecks) {
|
||||
projectConfig.strictNullChecks = true;
|
||||
}
|
||||
if (strictFunctionTypes) {
|
||||
projectConfig.strictFunctionTypes = true;
|
||||
}
|
||||
if (projectType === 'typescript') {
|
||||
projectConfig.sourceMap = true;
|
||||
}
|
||||
return projectConfig;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=inferredCompilerOptions.js.map
|
||||
5
node_modules/@volar/language-server/lib/project/simpleProject.d.ts
generated
vendored
5
node_modules/@volar/language-server/lib/project/simpleProject.d.ts
generated
vendored
@@ -1,5 +0,0 @@
|
||||
import type { LanguagePlugin, LanguageServiceEnvironment } from '@volar/language-service';
|
||||
import type { URI } from 'vscode-uri';
|
||||
import type { LanguageServer, LanguageServerProject } from '../types';
|
||||
export declare function createSimpleProject(languagePlugins: LanguagePlugin<URI>[]): LanguageServerProject;
|
||||
export declare function createLanguageServiceEnvironment(server: LanguageServer, workspaceFolders: URI[]): LanguageServiceEnvironment;
|
||||
49
node_modules/@volar/language-server/lib/project/simpleProject.js
generated
vendored
49
node_modules/@volar/language-server/lib/project/simpleProject.js
generated
vendored
@@ -1,49 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createSimpleProject = createSimpleProject;
|
||||
exports.createLanguageServiceEnvironment = createLanguageServiceEnvironment;
|
||||
const language_service_1 = require("@volar/language-service");
|
||||
function createSimpleProject(languagePlugins) {
|
||||
let server;
|
||||
let languageService;
|
||||
return {
|
||||
setup(_server) {
|
||||
server = _server;
|
||||
const language = (0, language_service_1.createLanguage)([
|
||||
{ getLanguageId: uri => server.documents.get(uri)?.languageId },
|
||||
...languagePlugins,
|
||||
], (0, language_service_1.createUriMap)(false), uri => {
|
||||
const document = server.documents.get(uri);
|
||||
if (document) {
|
||||
language.scripts.set(uri, document.getSnapshot(), document.languageId);
|
||||
}
|
||||
else {
|
||||
language.scripts.delete(uri);
|
||||
}
|
||||
});
|
||||
languageService = (0, language_service_1.createLanguageService)(language, server.languageServicePlugins, createLanguageServiceEnvironment(server, server.workspaceFolders.all), {});
|
||||
},
|
||||
getLanguageService() {
|
||||
return languageService;
|
||||
},
|
||||
getExistingLanguageServices() {
|
||||
return [languageService];
|
||||
},
|
||||
reload() {
|
||||
languageService.dispose();
|
||||
this.setup(server);
|
||||
},
|
||||
};
|
||||
}
|
||||
function createLanguageServiceEnvironment(server, workspaceFolders) {
|
||||
return {
|
||||
workspaceFolders,
|
||||
fs: server.fileSystem,
|
||||
locale: server.initializeParams?.locale,
|
||||
clientCapabilities: server.initializeParams?.capabilities,
|
||||
getConfiguration: server.configurations.get,
|
||||
onDidChangeConfiguration: server.configurations.onDidChange,
|
||||
onDidChangeWatchedFiles: server.fileWatcher.onDidChangeWatchedFiles,
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=simpleProject.js.map
|
||||
22
node_modules/@volar/language-server/lib/project/typescriptProject.d.ts
generated
vendored
22
node_modules/@volar/language-server/lib/project/typescriptProject.d.ts
generated
vendored
@@ -1,22 +0,0 @@
|
||||
import { Language, LanguagePlugin, ProjectContext, ProviderResult } from '@volar/language-service';
|
||||
import type * as ts from 'typescript';
|
||||
import { URI } from 'vscode-uri';
|
||||
import type { LanguageServerProject } from '../types';
|
||||
import { ProjectExposeContext } from './typescriptProjectLs';
|
||||
export declare function createTypeScriptProject(ts: typeof import('typescript'), tsLocalized: ts.MapLike<string> | undefined, create: (projectContext: ProjectExposeContext) => ProviderResult<{
|
||||
languagePlugins: LanguagePlugin<URI>[];
|
||||
setup?(options: {
|
||||
language: Language;
|
||||
project: ProjectContext;
|
||||
}): void;
|
||||
}>): LanguageServerProject;
|
||||
export declare function createUriConverter(rootFolders: URI[]): {
|
||||
asFileName: (parsed: URI) => string;
|
||||
asUri: (fileName: string) => URI;
|
||||
};
|
||||
export declare function sortTSConfigs(file: string, a: string, b: string): number;
|
||||
export declare function isFileInDir(fileName: string, dir: string): boolean;
|
||||
export declare function getWorkspaceFolder(uri: URI, workspaceFolders: {
|
||||
has(uri: URI): boolean;
|
||||
all: URI[];
|
||||
}): URI;
|
||||
306
node_modules/@volar/language-server/lib/project/typescriptProject.js
generated
vendored
306
node_modules/@volar/language-server/lib/project/typescriptProject.js
generated
vendored
@@ -1,306 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createTypeScriptProject = createTypeScriptProject;
|
||||
exports.createUriConverter = createUriConverter;
|
||||
exports.sortTSConfigs = sortTSConfigs;
|
||||
exports.isFileInDir = isFileInDir;
|
||||
exports.getWorkspaceFolder = getWorkspaceFolder;
|
||||
const language_service_1 = require("@volar/language-service");
|
||||
const path = require("path-browserify");
|
||||
const vscode = require("vscode-languageserver");
|
||||
const vscode_uri_1 = require("vscode-uri");
|
||||
const inferredCompilerOptions_1 = require("./inferredCompilerOptions");
|
||||
const simpleProject_1 = require("./simpleProject");
|
||||
const typescriptProjectLs_1 = require("./typescriptProjectLs");
|
||||
const rootTsConfigNames = ['tsconfig.json', 'jsconfig.json'];
|
||||
function createTypeScriptProject(ts, tsLocalized, create) {
|
||||
let server;
|
||||
let uriConverter;
|
||||
const configProjects = (0, language_service_1.createUriMap)();
|
||||
const inferredProjects = (0, language_service_1.createUriMap)();
|
||||
const rootTsConfigs = new Set();
|
||||
const searchedDirs = new Set();
|
||||
return {
|
||||
setup(_server) {
|
||||
uriConverter = createUriConverter(_server.workspaceFolders.all);
|
||||
server = _server;
|
||||
server.fileWatcher.onDidChangeWatchedFiles(({ changes }) => {
|
||||
const tsConfigChanges = changes.filter(change => rootTsConfigNames.includes(change.uri.substring(change.uri.lastIndexOf('/') + 1)));
|
||||
for (const change of tsConfigChanges) {
|
||||
const changeUri = vscode_uri_1.URI.parse(change.uri);
|
||||
const changeFileName = uriConverter.asFileName(changeUri);
|
||||
if (change.type === vscode.FileChangeType.Created) {
|
||||
rootTsConfigs.add(changeFileName);
|
||||
}
|
||||
else if ((change.type === vscode.FileChangeType.Changed || change.type === vscode.FileChangeType.Deleted) && configProjects.has(changeUri)) {
|
||||
if (change.type === vscode.FileChangeType.Deleted) {
|
||||
rootTsConfigs.delete(changeFileName);
|
||||
}
|
||||
const project = configProjects.get(changeUri);
|
||||
configProjects.delete(changeUri);
|
||||
project?.then(project => project.dispose());
|
||||
}
|
||||
}
|
||||
server.languageFeatures.requestRefresh(!!tsConfigChanges.length);
|
||||
});
|
||||
},
|
||||
async getLanguageService(uri) {
|
||||
const tsconfig = await findMatchTSConfig(server, uri);
|
||||
if (tsconfig) {
|
||||
const project = await getOrCreateConfiguredProject(server, tsconfig);
|
||||
return project.languageService;
|
||||
}
|
||||
const workspaceFolder = getWorkspaceFolder(uri, server.workspaceFolders);
|
||||
const project = await getOrCreateInferredProject(server, uri, workspaceFolder);
|
||||
return project.languageService;
|
||||
},
|
||||
async getExistingLanguageServices() {
|
||||
const projects = await Promise.all([
|
||||
...configProjects.values() ?? [],
|
||||
...inferredProjects.values() ?? [],
|
||||
]);
|
||||
return projects.map(project => project.languageService);
|
||||
},
|
||||
reload() {
|
||||
for (const project of [
|
||||
...configProjects.values() ?? [],
|
||||
...inferredProjects.values() ?? [],
|
||||
]) {
|
||||
project.then(p => p.dispose());
|
||||
}
|
||||
configProjects.clear();
|
||||
inferredProjects.clear();
|
||||
},
|
||||
};
|
||||
async function findMatchTSConfig(server, uri) {
|
||||
const fileName = uriConverter.asFileName(uri);
|
||||
let dir = path.dirname(fileName);
|
||||
while (true) {
|
||||
if (searchedDirs.has(dir)) {
|
||||
break;
|
||||
}
|
||||
searchedDirs.add(dir);
|
||||
for (const tsConfigName of rootTsConfigNames) {
|
||||
const tsconfigPath = path.join(dir, tsConfigName);
|
||||
if ((await server.fileSystem.stat?.(uriConverter.asUri(tsconfigPath)))?.type === language_service_1.FileType.File) {
|
||||
rootTsConfigs.add(tsconfigPath);
|
||||
}
|
||||
}
|
||||
dir = path.dirname(dir);
|
||||
}
|
||||
await prepareClosestootCommandLine();
|
||||
return await findDirectIncludeTsconfig() ?? await findIndirectReferenceTsconfig();
|
||||
async function prepareClosestootCommandLine() {
|
||||
let matches = [];
|
||||
for (const rootTsConfig of rootTsConfigs) {
|
||||
if (isFileInDir(fileName, path.dirname(rootTsConfig))) {
|
||||
matches.push(rootTsConfig);
|
||||
}
|
||||
}
|
||||
matches = matches.sort((a, b) => sortTSConfigs(fileName, a, b));
|
||||
if (matches.length) {
|
||||
await getCommandLine(matches[0]);
|
||||
}
|
||||
}
|
||||
function findIndirectReferenceTsconfig() {
|
||||
return findTSConfig(async (tsconfig) => {
|
||||
const tsconfigUri = uriConverter.asUri(tsconfig);
|
||||
const project = await configProjects.get(tsconfigUri);
|
||||
const languageService = project?.languageService.context.inject('typescript/languageService');
|
||||
return !!languageService?.getProgram()?.getSourceFile(fileName);
|
||||
});
|
||||
}
|
||||
function findDirectIncludeTsconfig() {
|
||||
return findTSConfig(async (tsconfig) => {
|
||||
const map = (0, language_service_1.createUriMap)();
|
||||
const commandLine = await getCommandLine(tsconfig);
|
||||
for (const fileName of commandLine?.fileNames ?? []) {
|
||||
const uri = uriConverter.asUri(fileName);
|
||||
map.set(uri, true);
|
||||
}
|
||||
return map.has(uri);
|
||||
});
|
||||
}
|
||||
async function findTSConfig(match) {
|
||||
const checked = new Set();
|
||||
for (const rootTsConfig of [...rootTsConfigs].sort((a, b) => sortTSConfigs(fileName, a, b))) {
|
||||
const tsconfigUri = uriConverter.asUri(rootTsConfig);
|
||||
const project = await configProjects.get(tsconfigUri);
|
||||
if (project) {
|
||||
let chains = await getReferencesChains(project.getCommandLine(), rootTsConfig, []);
|
||||
// This is to be consistent with tsserver behavior
|
||||
chains = chains.reverse();
|
||||
for (const chain of chains) {
|
||||
for (let i = chain.length - 1; i >= 0; i--) {
|
||||
const tsconfig = chain[i];
|
||||
if (checked.has(tsconfig)) {
|
||||
continue;
|
||||
}
|
||||
checked.add(tsconfig);
|
||||
if (await match(tsconfig)) {
|
||||
return tsconfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
async function getReferencesChains(commandLine, tsConfig, before) {
|
||||
if (commandLine.projectReferences?.length) {
|
||||
const newChains = [];
|
||||
for (const projectReference of commandLine.projectReferences) {
|
||||
let tsConfigPath = projectReference.path.replace(/\\/g, '/');
|
||||
// fix https://github.com/johnsoncodehk/volar/issues/712
|
||||
if ((await server.fileSystem.stat?.(uriConverter.asUri(tsConfigPath)))?.type === language_service_1.FileType.File) {
|
||||
const newTsConfigPath = path.join(tsConfigPath, 'tsconfig.json');
|
||||
const newJsConfigPath = path.join(tsConfigPath, 'jsconfig.json');
|
||||
if ((await server.fileSystem.stat?.(uriConverter.asUri(newTsConfigPath)))?.type === language_service_1.FileType.File) {
|
||||
tsConfigPath = newTsConfigPath;
|
||||
}
|
||||
else if ((await server.fileSystem.stat?.(uriConverter.asUri(newJsConfigPath)))?.type === language_service_1.FileType.File) {
|
||||
tsConfigPath = newJsConfigPath;
|
||||
}
|
||||
}
|
||||
const beforeIndex = before.indexOf(tsConfigPath); // cycle
|
||||
if (beforeIndex >= 0) {
|
||||
newChains.push(before.slice(0, Math.max(beforeIndex, 1)));
|
||||
}
|
||||
else {
|
||||
const referenceCommandLine = await getCommandLine(tsConfigPath);
|
||||
if (referenceCommandLine) {
|
||||
for (const chain of await getReferencesChains(referenceCommandLine, tsConfigPath, [...before, tsConfig])) {
|
||||
newChains.push(chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return newChains;
|
||||
}
|
||||
else {
|
||||
return [[...before, tsConfig]];
|
||||
}
|
||||
}
|
||||
async function getCommandLine(tsConfig) {
|
||||
const project = await getOrCreateConfiguredProject(server, tsConfig);
|
||||
return project?.getCommandLine();
|
||||
}
|
||||
}
|
||||
function getOrCreateConfiguredProject(server, tsconfig) {
|
||||
tsconfig = tsconfig.replace(/\\/g, '/');
|
||||
const tsconfigUri = uriConverter.asUri(tsconfig);
|
||||
let projectPromise = configProjects.get(tsconfigUri);
|
||||
if (!projectPromise) {
|
||||
const workspaceFolder = getWorkspaceFolder(tsconfigUri, server.workspaceFolders);
|
||||
const serviceEnv = (0, simpleProject_1.createLanguageServiceEnvironment)(server, [workspaceFolder]);
|
||||
projectPromise = (0, typescriptProjectLs_1.createTypeScriptLS)(ts, tsLocalized, tsconfig, server, serviceEnv, workspaceFolder, uriConverter, create);
|
||||
configProjects.set(tsconfigUri, projectPromise);
|
||||
}
|
||||
return projectPromise;
|
||||
}
|
||||
async function getOrCreateInferredProject(server, uri, workspaceFolder) {
|
||||
if (!inferredProjects.has(workspaceFolder)) {
|
||||
inferredProjects.set(workspaceFolder, (async () => {
|
||||
const inferOptions = await (0, inferredCompilerOptions_1.getInferredCompilerOptions)(server);
|
||||
const serviceEnv = (0, simpleProject_1.createLanguageServiceEnvironment)(server, [workspaceFolder]);
|
||||
return (0, typescriptProjectLs_1.createTypeScriptLS)(ts, tsLocalized, inferOptions, server, serviceEnv, workspaceFolder, uriConverter, create);
|
||||
})());
|
||||
}
|
||||
const project = await inferredProjects.get(workspaceFolder);
|
||||
project.tryAddFile(uriConverter.asFileName(uri));
|
||||
return project;
|
||||
}
|
||||
}
|
||||
function createUriConverter(rootFolders) {
|
||||
const encodeds = new Map();
|
||||
const isFileScheme = rootFolders.every(folder => folder.scheme === 'file');
|
||||
return {
|
||||
asFileName,
|
||||
asUri,
|
||||
};
|
||||
function asFileName(parsed) {
|
||||
if (rootFolders.every(folder => folder.scheme === parsed.scheme && folder.authority === parsed.authority)) {
|
||||
if (isFileScheme) {
|
||||
return parsed.fsPath.replace(/\\/g, '/');
|
||||
}
|
||||
else {
|
||||
return parsed.path;
|
||||
}
|
||||
}
|
||||
const encoded = encodeURIComponent(`${parsed.scheme}://${parsed.authority}`);
|
||||
encodeds.set(encoded, parsed);
|
||||
return `/${encoded}${parsed.path}`;
|
||||
}
|
||||
function asUri(fileName) {
|
||||
for (const [encoded, uri] of encodeds) {
|
||||
const prefix = `/${encoded}`;
|
||||
if (fileName === prefix) {
|
||||
return vscode_uri_1.URI.from({
|
||||
scheme: uri.scheme,
|
||||
authority: uri.authority,
|
||||
});
|
||||
}
|
||||
if (uri.authority) {
|
||||
if (fileName.startsWith(prefix + '/')) {
|
||||
return vscode_uri_1.URI.from({
|
||||
scheme: uri.scheme,
|
||||
authority: uri.authority,
|
||||
path: fileName.substring(prefix.length),
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (fileName.startsWith(prefix)) {
|
||||
return vscode_uri_1.URI.from({
|
||||
scheme: uri.scheme,
|
||||
authority: uri.authority,
|
||||
path: fileName.substring(prefix.length),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isFileScheme) {
|
||||
for (const folder of rootFolders) {
|
||||
return vscode_uri_1.URI.parse(`${folder.scheme}://${folder.authority}${fileName}`);
|
||||
}
|
||||
}
|
||||
return vscode_uri_1.URI.file(fileName);
|
||||
}
|
||||
}
|
||||
function sortTSConfigs(file, a, b) {
|
||||
const inA = isFileInDir(file, path.dirname(a));
|
||||
const inB = isFileInDir(file, path.dirname(b));
|
||||
if (inA !== inB) {
|
||||
const aWeight = inA ? 1 : 0;
|
||||
const bWeight = inB ? 1 : 0;
|
||||
return bWeight - aWeight;
|
||||
}
|
||||
const aLength = a.split('/').length;
|
||||
const bLength = b.split('/').length;
|
||||
if (aLength === bLength) {
|
||||
const aWeight = path.basename(a) === 'tsconfig.json' ? 1 : 0;
|
||||
const bWeight = path.basename(b) === 'tsconfig.json' ? 1 : 0;
|
||||
return bWeight - aWeight;
|
||||
}
|
||||
return bLength - aLength;
|
||||
}
|
||||
function isFileInDir(fileName, dir) {
|
||||
const relative = path.relative(dir, fileName);
|
||||
return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative);
|
||||
}
|
||||
function getWorkspaceFolder(uri, workspaceFolders) {
|
||||
while (true) {
|
||||
if (workspaceFolders.has(uri)) {
|
||||
return uri;
|
||||
}
|
||||
const next = uri.with({ path: uri.path.substring(0, uri.path.lastIndexOf('/')) });
|
||||
if (next.path === uri.path) {
|
||||
break;
|
||||
}
|
||||
uri = next;
|
||||
}
|
||||
for (const folder of workspaceFolders.all) {
|
||||
return folder;
|
||||
}
|
||||
return uri.with({ path: '/' });
|
||||
}
|
||||
//# sourceMappingURL=typescriptProject.js.map
|
||||
31
node_modules/@volar/language-server/lib/project/typescriptProjectLs.d.ts
generated
vendored
31
node_modules/@volar/language-server/lib/project/typescriptProjectLs.d.ts
generated
vendored
@@ -1,31 +0,0 @@
|
||||
import { Language, LanguagePlugin, LanguageService, LanguageServiceEnvironment, ProjectContext, ProviderResult } from '@volar/language-service';
|
||||
import { TypeScriptProjectHost, createSys } from '@volar/typescript';
|
||||
import type * as ts from 'typescript';
|
||||
import { URI } from 'vscode-uri';
|
||||
import type { LanguageServer } from '../types';
|
||||
export interface TypeScriptProjectLS {
|
||||
tryAddFile(fileName: string): void;
|
||||
getCommandLine(): ts.ParsedCommandLine;
|
||||
languageService: LanguageService;
|
||||
dispose(): void;
|
||||
}
|
||||
export interface ProjectExposeContext {
|
||||
env: LanguageServiceEnvironment;
|
||||
configFileName: string | undefined;
|
||||
projectHost: TypeScriptProjectHost;
|
||||
sys: ReturnType<typeof createSys>;
|
||||
uriConverter: {
|
||||
asUri(fileName: string): URI;
|
||||
asFileName(uri: URI): string;
|
||||
};
|
||||
}
|
||||
export declare function createTypeScriptLS(ts: typeof import('typescript'), tsLocalized: ts.MapLike<string> | undefined, tsconfig: string | ts.CompilerOptions, server: LanguageServer, serviceEnv: LanguageServiceEnvironment, workspaceFolder: URI, uriConverter: {
|
||||
asUri(fileName: string): URI;
|
||||
asFileName(uri: URI): string;
|
||||
}, create: (projectContext: ProjectExposeContext) => ProviderResult<{
|
||||
languagePlugins: LanguagePlugin<URI>[];
|
||||
setup?(options: {
|
||||
language: Language;
|
||||
project: ProjectContext;
|
||||
}): void;
|
||||
}>): Promise<TypeScriptProjectLS>;
|
||||
232
node_modules/@volar/language-server/lib/project/typescriptProjectLs.js
generated
vendored
232
node_modules/@volar/language-server/lib/project/typescriptProjectLs.js
generated
vendored
@@ -1,232 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createTypeScriptLS = createTypeScriptLS;
|
||||
const language_service_1 = require("@volar/language-service");
|
||||
const typescript_1 = require("@volar/typescript");
|
||||
const utilities_1 = require("@volar/typescript/lib/typescript/utilities");
|
||||
const path = require("path-browserify");
|
||||
const vscode = require("vscode-languageserver");
|
||||
const vscode_uri_1 = require("vscode-uri");
|
||||
const fsFileSnapshots = (0, language_service_1.createUriMap)();
|
||||
async function createTypeScriptLS(ts, tsLocalized, tsconfig, server, serviceEnv, workspaceFolder, uriConverter, create) {
|
||||
let commandLine;
|
||||
let projectVersion = 0;
|
||||
const getCurrentDirectory = () => uriConverter.asFileName(workspaceFolder);
|
||||
const sys = (0, typescript_1.createSys)(ts.sys, serviceEnv, getCurrentDirectory, uriConverter);
|
||||
const projectHost = {
|
||||
getCurrentDirectory,
|
||||
getProjectVersion() {
|
||||
return projectVersion.toString();
|
||||
},
|
||||
getScriptFileNames() {
|
||||
return commandLine.fileNames;
|
||||
},
|
||||
getCompilationSettings() {
|
||||
return commandLine.options;
|
||||
},
|
||||
getLocalizedDiagnosticMessages: tsLocalized ? () => tsLocalized : undefined,
|
||||
getProjectReferences() {
|
||||
return commandLine.projectReferences;
|
||||
},
|
||||
};
|
||||
const { languagePlugins, setup } = await create({
|
||||
env: serviceEnv,
|
||||
configFileName: typeof tsconfig === 'string' ? tsconfig : undefined,
|
||||
projectHost,
|
||||
sys,
|
||||
uriConverter,
|
||||
});
|
||||
const unsavedRootFileUris = (0, language_service_1.createUriMap)();
|
||||
const disposables = [
|
||||
server.documents.onDidOpen(({ document }) => updateFsCacheFromSyncedDocument(document)),
|
||||
server.documents.onDidSave(({ document }) => updateFsCacheFromSyncedDocument(document)),
|
||||
server.documents.onDidChangeContent(() => projectVersion++),
|
||||
serviceEnv.onDidChangeWatchedFiles?.(async ({ changes }) => {
|
||||
const createdOrDeleted = changes.some(change => change.type !== vscode.FileChangeType.Changed);
|
||||
if (createdOrDeleted) {
|
||||
await updateCommandLine();
|
||||
}
|
||||
projectVersion++;
|
||||
}),
|
||||
server.documents.onDidOpen(async ({ document }) => {
|
||||
const uri = vscode_uri_1.URI.parse(document.uri);
|
||||
const isWorkspaceFile = workspaceFolder.scheme === uri.scheme;
|
||||
if (!isWorkspaceFile) {
|
||||
return;
|
||||
}
|
||||
const stat = await serviceEnv.fs?.stat(uri);
|
||||
const isUnsaved = stat?.type !== 1;
|
||||
if (isUnsaved) {
|
||||
const lastProjectVersion = projectVersion;
|
||||
await updateCommandLine();
|
||||
if (lastProjectVersion !== projectVersion) {
|
||||
unsavedRootFileUris.set(uri, true);
|
||||
}
|
||||
}
|
||||
}),
|
||||
server.documents.onDidClose(async ({ document }) => {
|
||||
const uri = vscode_uri_1.URI.parse(document.uri);
|
||||
if (unsavedRootFileUris.has(uri)) {
|
||||
unsavedRootFileUris.delete(uri);
|
||||
await updateCommandLine();
|
||||
}
|
||||
}),
|
||||
].filter(d => !!d);
|
||||
await updateCommandLine();
|
||||
const language = (0, language_service_1.createLanguage)([
|
||||
{ getLanguageId: uri => server.documents.get(uri)?.languageId },
|
||||
...languagePlugins,
|
||||
{ getLanguageId: uri => (0, typescript_1.resolveFileLanguageId)(uri.path) },
|
||||
], (0, language_service_1.createUriMap)(sys.useCaseSensitiveFileNames), (uri, includeFsFiles) => {
|
||||
const syncedDocument = server.documents.get(uri);
|
||||
let snapshot;
|
||||
if (syncedDocument) {
|
||||
snapshot = syncedDocument.getSnapshot();
|
||||
}
|
||||
else if (includeFsFiles) {
|
||||
const cache = fsFileSnapshots.get(uri);
|
||||
const fileName = uriConverter.asFileName(uri);
|
||||
const modifiedTime = sys.getModifiedTime?.(fileName)?.valueOf();
|
||||
if (!cache || cache[0] !== modifiedTime) {
|
||||
if (sys.fileExists(fileName)) {
|
||||
const text = sys.readFile(fileName);
|
||||
const snapshot = text !== undefined ? ts.ScriptSnapshot.fromString(text) : undefined;
|
||||
fsFileSnapshots.set(uri, [modifiedTime, snapshot]);
|
||||
}
|
||||
else {
|
||||
fsFileSnapshots.set(uri, [modifiedTime, undefined]);
|
||||
}
|
||||
}
|
||||
snapshot = fsFileSnapshots.get(uri)?.[1];
|
||||
}
|
||||
if (snapshot) {
|
||||
language.scripts.set(uri, snapshot);
|
||||
}
|
||||
else {
|
||||
language.scripts.delete(uri);
|
||||
}
|
||||
});
|
||||
const project = {
|
||||
typescript: {
|
||||
configFileName: typeof tsconfig === 'string' ? tsconfig : undefined,
|
||||
sys,
|
||||
uriConverter,
|
||||
...(0, typescript_1.createLanguageServiceHost)(ts, sys, language, s => uriConverter.asUri(s), projectHost),
|
||||
},
|
||||
};
|
||||
setup?.({ language, project });
|
||||
const languageService = (0, language_service_1.createLanguageService)(language, server.languageServicePlugins, serviceEnv, project);
|
||||
return {
|
||||
languageService,
|
||||
tryAddFile(fileName) {
|
||||
if (!commandLine.fileNames.includes(fileName)) {
|
||||
commandLine.fileNames.push(fileName);
|
||||
projectVersion++;
|
||||
}
|
||||
},
|
||||
dispose: () => {
|
||||
sys.dispose();
|
||||
languageService?.dispose();
|
||||
disposables.forEach(({ dispose }) => dispose());
|
||||
disposables.length = 0;
|
||||
},
|
||||
getCommandLine: () => commandLine,
|
||||
};
|
||||
function updateFsCacheFromSyncedDocument(document) {
|
||||
const uri = vscode_uri_1.URI.parse(document.uri);
|
||||
const fileName = uriConverter.asFileName(uri);
|
||||
if (fsFileSnapshots.has(uri) || sys.fileExists(fileName)) {
|
||||
const modifiedTime = sys.getModifiedTime?.(fileName);
|
||||
fsFileSnapshots.set(uri, [modifiedTime?.valueOf(), document.getSnapshot()]);
|
||||
}
|
||||
}
|
||||
async function updateCommandLine() {
|
||||
const oldFileNames = new Set(commandLine?.fileNames ?? []);
|
||||
commandLine = await parseConfig(ts, sys, uriConverter.asFileName(workspaceFolder), tsconfig, languagePlugins.map(plugin => plugin.typescript?.extraFileExtensions ?? []).flat());
|
||||
const newFileNames = new Set(commandLine.fileNames);
|
||||
if (oldFileNames.size !== newFileNames.size || [...oldFileNames].some(fileName => !newFileNames.has(fileName))) {
|
||||
projectVersion++;
|
||||
}
|
||||
}
|
||||
async function parseConfig(ts, sys, workspacePath, tsconfig, extraFileExtensions) {
|
||||
let commandLine = {
|
||||
errors: [],
|
||||
fileNames: [],
|
||||
options: {},
|
||||
};
|
||||
let sysVersion;
|
||||
let newSysVersion = await sys.sync();
|
||||
while (sysVersion !== newSysVersion) {
|
||||
sysVersion = newSysVersion;
|
||||
try {
|
||||
commandLine = await parseConfigWorker(ts, sys, workspacePath, tsconfig, extraFileExtensions);
|
||||
}
|
||||
catch {
|
||||
// will be failed if web fs host first result not ready
|
||||
}
|
||||
newSysVersion = await sys.sync();
|
||||
}
|
||||
return commandLine;
|
||||
}
|
||||
function parseConfigWorker(ts, _host, workspacePath, tsconfig, extraFileExtensions) {
|
||||
let content = {
|
||||
errors: [],
|
||||
fileNames: [],
|
||||
options: {},
|
||||
};
|
||||
const maybeUnsavedFileNames = server.documents.all()
|
||||
.map(document => vscode_uri_1.URI.parse(document.uri))
|
||||
.filter(uri => uri.scheme === workspaceFolder.scheme)
|
||||
.map(uri => uriConverter.asFileName(uri));
|
||||
const host = {
|
||||
..._host,
|
||||
readDirectory(rootDir, extensions, excludes, includes, depth) {
|
||||
const fsFiles = _host.readDirectory(rootDir, extensions, excludes, includes, depth);
|
||||
const unsavedFiles = (0, utilities_1.matchFiles)(rootDir, extensions, excludes, includes, sys.useCaseSensitiveFileNames, getCurrentDirectory(), depth, dirPath => {
|
||||
dirPath = dirPath.replace(/\\/g, '/');
|
||||
const files = [];
|
||||
const dirs = [];
|
||||
for (const fileName of maybeUnsavedFileNames) {
|
||||
const match = sys.useCaseSensitiveFileNames
|
||||
? fileName.startsWith(dirPath + '/')
|
||||
: fileName.toLowerCase().startsWith(dirPath.toLowerCase() + '/');
|
||||
if (match) {
|
||||
const name = fileName.slice(dirPath.length + 1);
|
||||
if (name.includes('/')) {
|
||||
const dir = name.split('/')[0];
|
||||
if (!dirs.includes(dir)) {
|
||||
dirs.push(dir);
|
||||
}
|
||||
}
|
||||
else {
|
||||
files.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
files,
|
||||
directories: dirs,
|
||||
};
|
||||
}, path => path);
|
||||
if (!unsavedFiles.length) {
|
||||
return fsFiles;
|
||||
}
|
||||
return [...new Set([...fsFiles, ...unsavedFiles])];
|
||||
},
|
||||
};
|
||||
if (typeof tsconfig === 'string') {
|
||||
const config = ts.readJsonConfigFile(tsconfig, host.readFile);
|
||||
content = ts.parseJsonSourceFileConfigFileContent(config, host, path.dirname(tsconfig), {}, tsconfig, undefined, extraFileExtensions);
|
||||
}
|
||||
else {
|
||||
content = ts.parseJsonConfigFileContent({ files: [] }, host, 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, '/'));
|
||||
return content;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=typescriptProjectLs.js.map
|
||||
Reference in New Issue
Block a user