Skip to content

Commit

Permalink
feat: support for typescript.tsdk setting
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk committed May 31, 2021
1 parent a2f5379 commit 39756bf
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 10 deletions.
10 changes: 10 additions & 0 deletions packages/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ export function getWordRange(wordPattern: RegExp, position: Position, document:
}
return undefined;
}
export function loadWorkspaceTypescript(root: string, tsdk: string): typeof import('typescript/lib/tsserverlibrary') {
const tsPath = path.join(root, tsdk, 'tsserverlibrary.js');
return require(path.toUnix(tsPath));
}
export function loadWorkspaceTypescriptLocalized(root: string, tsdk: string, lang: string): MapLike<string> | undefined {
const tsPath = path.join(root, tsdk, lang, 'diagnosticMessages.generated.json');
if (fs.existsSync(tsPath)) {
return require(path.toUnix(tsPath));
}
}
export function loadVscodeTypescript(appRoot: string): typeof import('typescript/lib/tsserverlibrary') {
const tsPath = path.join(appRoot, 'extensions', 'node_modules', 'typescript');
return require(path.toUnix(tsPath));
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export interface ServerInitializationOptions {
appRoot: string,
language: string,
tsPlugin: boolean,
tsdk: string | undefined,
}
1 change: 1 addition & 0 deletions packages/vscode-client/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ function createLanguageService(context: vscode.ExtensionContext, mode: 'api' | '
appRoot: vscode.env.appRoot,
language: vscode.env.language,
tsPlugin: tsPlugin.isTsPluginEnabled(),
tsdk: vscode.workspace.getConfiguration('typescript').get<string>('tsdk') ?? undefined,
};
const clientOptions: lsp.LanguageClientOptions = {
documentSelector: fileOnly ?
Expand Down
41 changes: 35 additions & 6 deletions packages/vscode-server/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
DocumentVersionRequest,
loadWorkspaceTypescript,
loadWorkspaceTypescriptLocalized,
loadVscodeTypescript,
loadVscodeTypescriptLocalized,
SemanticTokensChangedNotification,
Expand Down Expand Up @@ -27,10 +29,14 @@ const documents = new TextDocuments(TextDocument);

let options: ServerInitializationOptions;
let folders: string[] = [];
let updateTsdk: Function | undefined;

connection.onInitialize(onInitialize);
connection.onInitialized(onInitialized);
connection.onDidChangeConfiguration(() => updateConfigs(connection));
connection.onDidChangeConfiguration(() => {
updateTsdk?.();
updateConfigs(connection);
});
connection.listen();
documents.listen(connection);

Expand Down Expand Up @@ -74,14 +80,13 @@ async function onInitialized() {
let servicesManager: ServicesManager | undefined;

if (options.mode === 'html') {
const noStateLs = getDocumentLanguageService({ typescript: loadVscodeTypescript(options.appRoot) });
const noStateLs = getDocumentLanguageService({ typescript: getTs().module });
(await import('./features/htmlFeatures')).register(connection, documents, noStateLs);
}
else if (options.mode === 'api') {
servicesManager = createServicesManager(
'api',
loadVscodeTypescript(options.appRoot),
loadVscodeTypescriptLocalized(options.appRoot, options.language),
getTs,
connection,
documents,
folders,
Expand All @@ -90,8 +95,7 @@ async function onInitialized() {
else if (options.mode === 'doc') {
servicesManager = createServicesManager(
'doc',
loadVscodeTypescript(options.appRoot),
loadVscodeTypescriptLocalized(options.appRoot, options.language),
getTs,
connection,
documents,
folders,
Expand All @@ -112,4 +116,29 @@ async function onInitialized() {
}
connection.client.register(DidChangeConfigurationNotification.type, undefined);
updateConfigs(connection);
updateTsdk = async () => {
const newTsdk: string | undefined = await connection.workspace.getConfiguration('typescript.tsdk') ?? undefined;
if (newTsdk !== options.tsdk) {
options.tsdk = newTsdk;
servicesManager?.restartAll();
}
};
}

function getTs() {
if (options.tsdk) {
for (const folder of folders) {
const ts = loadWorkspaceTypescript(folder, options.tsdk);
if (ts) {
return {
module: ts,
localized: loadWorkspaceTypescriptLocalized(folder, options.tsdk, options.language),
};
}
}
}
return {
module: loadVscodeTypescript(options.appRoot),
localized: loadVscodeTypescriptLocalized(options.appRoot, options.language),
}
}
14 changes: 10 additions & 4 deletions packages/vscode-server/src/servicesManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ export type ServicesManager = ReturnType<typeof createServicesManager>;

export function createServicesManager(
mode: 'api' | 'doc',
ts: typeof import('typescript/lib/tsserverlibrary'),
tsLocalized: ts.MapLike<string> | undefined,
getTs: () => {
module: typeof import('typescript/lib/tsserverlibrary'),
localized: ts.MapLike<string> | undefined,
},
connection: Connection,
documents: TextDocuments<TextDocument>,
rootPaths: string[],
Expand All @@ -19,18 +21,19 @@ export function createServicesManager(
) {

let filesUpdateTrigger = false;
const originalTs = getTs().module;
const tsConfigNames = ['tsconfig.json', 'jsconfig.json'];
const tsConfigWatchers = new Map<string, ts.FileWatcher>();
const services = new Map<string, ServiceHandler>();
const tsConfigSet = new Set(rootPaths.map(rootPath => ts.sys.readDirectory(rootPath, tsConfigNames, undefined, ['**/*'])).flat());
const tsConfigSet = new Set(rootPaths.map(rootPath => originalTs.sys.readDirectory(rootPath, tsConfigNames, undefined, ['**/*'])).flat());
const tsConfigs = [...tsConfigSet].filter(tsConfig => tsConfigNames.includes(upath.basename(tsConfig)));
const checkedProject = new Set<string>();

for (const tsConfig of tsConfigs) {
onTsConfigChanged(tsConfig);
}
for (const rootPath of rootPaths) {
ts.sys.watchDirectory!(rootPath, async fileName => {
originalTs.sys.watchDirectory!(rootPath, async fileName => {
if (tsConfigNames.includes(upath.basename(fileName))) {
// tsconfig.json changed
onTsConfigChanged(fileName);
Expand Down Expand Up @@ -147,6 +150,9 @@ export function createServicesManager(
}
}
async function onTsConfigChanged(tsConfig: string) {
const _ts = getTs();
const ts = _ts.module;
const tsLocalized = _ts.localized;
for (const doc of documents.all()) {
if (doc.languageId === 'vue') {
connection.sendDiagnostics({ uri: doc.uri, diagnostics: [] });
Expand Down

0 comments on commit 39756bf

Please sign in to comment.