Skip to content

Commit

Permalink
refactor(language-server): unused resolveLanguageServiceHost hook (#953)
Browse files Browse the repository at this point in the history
* refactor(language-server): unused resolveLanguageServiceHost hook

* bump volar

* fix: build

---------

Co-authored-by: Erika <[email protected]>
  • Loading branch information
johnsoncodehk and Princesseuh authored Sep 20, 2024
1 parent 45bede5 commit 35cf3bc
Show file tree
Hide file tree
Showing 9 changed files with 203 additions and 185 deletions.
12 changes: 6 additions & 6 deletions packages/language-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
"@astrojs/compiler": "^2.10.3",
"@astrojs/yaml2ts": "^0.2.1",
"@jridgewell/sourcemap-codec": "^1.4.15",
"@volar/kit": "~2.4.0",
"@volar/language-core": "~2.4.0",
"@volar/language-server": "~2.4.0",
"@volar/language-service": "~2.4.0",
"@volar/typescript": "~2.4.0",
"@volar/kit": "~2.4.5",
"@volar/language-core": "~2.4.5",
"@volar/language-server": "~2.4.5",
"@volar/language-service": "~2.4.5",
"@volar/typescript": "~2.4.5",
"fast-glob": "^3.2.12",
"muggle-string": "^0.4.1",
"volar-service-css": "0.0.61",
Expand All @@ -53,7 +53,7 @@
"@types/chai": "^4.3.5",
"@types/mocha": "^10.0.1",
"@types/node": "^18.17.8",
"@volar/test-utils": "~2.4.0",
"@volar/test-utils": "~2.4.5",
"astro": "^4.14.0",
"chai": "^4.3.7",
"mocha": "^10.2.0",
Expand Down
16 changes: 13 additions & 3 deletions packages/language-server/src/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as kit from '@volar/kit';
import { Diagnostic, DiagnosticSeverity } from '@volar/language-server';
import fg from 'fast-glob';
import { URI } from 'vscode-uri';
import { getAstroLanguagePlugin } from './core/index.js';
import { addAstroTypes, getAstroLanguagePlugin } from './core/index.js';
import { getSvelteLanguagePlugin } from './core/svelte.js';
import { getVueLanguagePlugin } from './core/vue.js';
import { getAstroInstall } from './utils.js';
Expand Down Expand Up @@ -137,9 +137,8 @@ export class AstroCheck {
this.ts = this.typescriptPath ? require(this.typescriptPath) : require('typescript');
const tsconfigPath = this.getTsconfig();

const astroInstall = getAstroInstall([this.workspacePath]);
const languagePlugins = [
getAstroLanguagePlugin(typeof astroInstall === 'string' ? undefined : astroInstall, this.ts),
getAstroLanguagePlugin(),
getSvelteLanguagePlugin(),
getVueLanguagePlugin(),
];
Expand All @@ -152,6 +151,12 @@ export class AstroCheck {
services,
tsconfigPath,
includeProjectReference,
({ project }) => {
const { languageServiceHost } = project.typescript!;
const astroInstall = getAstroInstall([this.workspacePath]);

addAstroTypes(typeof astroInstall === 'string' ? undefined : astroInstall, this.ts, languageServiceHost);
},
);
} else {
this.linter = kit.createTypeScriptInferredChecker(languagePlugins, services, () => {
Expand All @@ -160,6 +165,11 @@ export class AstroCheck {
ignore: ['node_modules'],
absolute: true,
});
}, undefined, ({ project }) => {
const { languageServiceHost } = project.typescript!;
const astroInstall = getAstroInstall([this.workspacePath]);

addAstroTypes(typeof astroInstall === 'string' ? undefined : astroInstall, this.ts, languageServiceHost);
});
}
}
Expand Down
133 changes: 71 additions & 62 deletions packages/language-server/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,79 @@ import { extractStylesheets } from './parseCSS';
import { parseHTML } from './parseHTML';
import { extractScriptTags } from './parseJS.js';

export function getAstroLanguagePlugin(
const decoratedHosts = new WeakSet<ts.LanguageServiceHost>();

export function addAstroTypes(
astroInstall: AstroInstall | undefined,
ts: typeof import('typescript'),
): LanguagePlugin<URI, AstroVirtualCode> {
host: ts.LanguageServiceHost
) {
if (decoratedHosts.has(host)) {
return;
}
decoratedHosts.add(host);

const getScriptFileNames = host.getScriptFileNames.bind(host);
const getCompilationSettings = host.getCompilationSettings.bind(host);

host.getScriptFileNames = () => {
const languageServerTypesDirectory = getLanguageServerTypesDir(ts);
const fileNames = getScriptFileNames();
const addedFileNames = [];

if (astroInstall) {
addedFileNames.push(
...['./env.d.ts', './astro-jsx.d.ts'].map((filePath) =>
ts.sys.resolvePath(path.resolve(astroInstall.path, filePath)),
),
);

// If Astro version is < 4.0.8, add jsx-runtime-augment.d.ts to the files to fake `JSX` being available from "astro/jsx-runtime".
// TODO: Remove this once a majority of users are on Astro 4.0.8+, erika - 2023-12-28
if (
astroInstall.version.major < 4 ||
(astroInstall.version.major === 4 &&
astroInstall.version.minor === 0 &&
astroInstall.version.patch < 8)
) {
addedFileNames.push(
...['./jsx-runtime-augment.d.ts'].map((filePath) =>
ts.sys.resolvePath(path.resolve(languageServerTypesDirectory, filePath)),
),
);
}
} else {
// If we don't have an Astro installation, add the fallback types from the language server.
// See the README in packages/language-server/types for more information.
addedFileNames.push(
...['./env.d.ts', './astro-jsx.d.ts', './jsx-runtime-fallback.d.ts'].map((f) =>
ts.sys.resolvePath(path.resolve(languageServerTypesDirectory, f)),
),
);
}

return [...fileNames, ...addedFileNames];
}
host.getCompilationSettings = () => {
const baseCompilationSettings = getCompilationSettings();
return {
...baseCompilationSettings,
module: ts.ModuleKind.ESNext ?? 99,
target: ts.ScriptTarget.ESNext ?? 99,
jsx: ts.JsxEmit.Preserve ?? 1,
resolveJsonModule: true,
allowJs: true, // Needed for inline scripts, which are virtual .js files
isolatedModules: true,
moduleResolution:
baseCompilationSettings.moduleResolution === ts.ModuleResolutionKind.Classic ||
!baseCompilationSettings.moduleResolution
? ts.ModuleResolutionKind.Node10
: baseCompilationSettings.moduleResolution,
};
};
}

export function getAstroLanguagePlugin(): LanguagePlugin<URI, AstroVirtualCode> {
return {
getLanguageId(uri) {
if (uri.path.endsWith('.astro')) {
Expand Down Expand Up @@ -66,66 +135,6 @@ export function getAstroLanguagePlugin(
}
return result;
},
resolveLanguageServiceHost(host) {
return {
...host,
getScriptFileNames() {
const languageServerTypesDirectory = getLanguageServerTypesDir(ts);
const fileNames = host.getScriptFileNames();
const addedFileNames = [];

if (astroInstall) {
addedFileNames.push(
...['./env.d.ts', './astro-jsx.d.ts'].map((filePath) =>
ts.sys.resolvePath(path.resolve(astroInstall.path, filePath)),
),
);

// If Astro version is < 4.0.8, add jsx-runtime-augment.d.ts to the files to fake `JSX` being available from "astro/jsx-runtime".
// TODO: Remove this once a majority of users are on Astro 4.0.8+, erika - 2023-12-28
if (
astroInstall.version.major < 4 ||
(astroInstall.version.major === 4 &&
astroInstall.version.minor === 0 &&
astroInstall.version.patch < 8)
) {
addedFileNames.push(
...['./jsx-runtime-augment.d.ts'].map((filePath) =>
ts.sys.resolvePath(path.resolve(languageServerTypesDirectory, filePath)),
),
);
}
} else {
// If we don't have an Astro installation, add the fallback types from the language server.
// See the README in packages/language-server/types for more information.
addedFileNames.push(
...['./env.d.ts', './astro-jsx.d.ts', './jsx-runtime-fallback.d.ts'].map((f) =>
ts.sys.resolvePath(path.resolve(languageServerTypesDirectory, f)),
),
);
}

return [...fileNames, ...addedFileNames];
},
getCompilationSettings() {
const baseCompilationSettings = host.getCompilationSettings();
return {
...baseCompilationSettings,
module: ts.ModuleKind.ESNext ?? 99,
target: ts.ScriptTarget.ESNext ?? 99,
jsx: ts.JsxEmit.Preserve ?? 1,
resolveJsonModule: true,
allowJs: true, // Needed for inline scripts, which are virtual .js files
isolatedModules: true,
moduleResolution:
baseCompilationSettings.moduleResolution === ts.ModuleResolutionKind.Classic ||
!baseCompilationSettings.moduleResolution
? ts.ModuleResolutionKind.Node10
: baseCompilationSettings.moduleResolution,
};
},
};
},
},
};
}
Expand Down
32 changes: 2 additions & 30 deletions packages/language-server/src/languageServerPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
type Connection,
type LanguagePlugin,
type LanguageServiceEnvironment,
MessageType,
ShowMessageNotification,
} from '@volar/language-server/node';
Expand All @@ -10,7 +9,6 @@ import { getAstroLanguagePlugin } from './core';
import { getSvelteLanguagePlugin } from './core/svelte.js';
import { getVueLanguagePlugin } from './core/vue.js';
import { getPrettierPluginPath, importPrettier } from './importPackage.js';
import { getAstroInstall } from './utils.js';

// Services
import { create as createCssService } from 'volar-service-css';
Expand All @@ -25,43 +23,17 @@ import { create as createTypescriptAddonsService } from './plugins/typescript-ad
import { create as createTypeScriptServices } from './plugins/typescript/index.js';
import { create as createYAMLService } from './plugins/yaml.js';

export function getLanguagePlugins(
connection: Connection,
ts: typeof import('typescript'),
serviceEnv: LanguageServiceEnvironment,
tsconfig: string | undefined,
collectionConfigs: CollectionConfig[],
) {
export function getLanguagePlugins(collectionConfigs: CollectionConfig[]) {
const languagePlugins: LanguagePlugin<URI>[] = [
getAstroLanguagePlugin(),
getVueLanguagePlugin(),
getSvelteLanguagePlugin(),
];

const rootPath = tsconfig
? tsconfig.split('/').slice(0, -1).join('/')
: serviceEnv.workspaceFolders[0]!.fsPath;
const nearestPackageJson = ts.findConfigFile(rootPath, ts.sys.fileExists, 'package.json');

const astroInstall = getAstroInstall([rootPath], {
nearestPackageJson: nearestPackageJson,
readDirectory: ts.sys.readDirectory,
});

if (astroInstall === 'not-found') {
connection.sendNotification(ShowMessageNotification.type, {
message: `Couldn't find Astro in workspace "${rootPath}". Experience might be degraded. For the best experience, please make sure Astro is installed into your project and restart the language server.`,
type: MessageType.Warning,
});
}

if (collectionConfigs.length) {
languagePlugins.push(getFrontmatterLanguagePlugin(collectionConfigs));
}

languagePlugins.unshift(
getAstroLanguagePlugin(typeof astroInstall === 'string' ? undefined : astroInstall, ts),
);

return languagePlugins;
}

Expand Down
45 changes: 36 additions & 9 deletions packages/language-server/src/nodeServer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {
MessageType,
ShowMessageNotification,
createConnection,
createServer,
createTypeScriptProject,
Expand All @@ -9,7 +11,9 @@ import {
type CollectionConfig,
SUPPORTED_FRONTMATTER_EXTENSIONS_KEYS,
} from './core/frontmatterHolders.js';
import { addAstroTypes } from './core/index.js';
import { getLanguagePlugins, getLanguageServicePlugins } from './languageServerPlugin.js';
import { getAstroInstall } from './utils.js';

const connection = createConnection();
const server = createServer(connection);
Expand Down Expand Up @@ -63,16 +67,39 @@ connection.onInitialize((params) => {

return server.initialize(
params,
createTypeScriptProject(typescript, diagnosticMessages, ({ env, configFileName }) => {
createTypeScriptProject(typescript, diagnosticMessages, ({ env }) => {
return {
languagePlugins: getLanguagePlugins(
connection,
typescript,
env,
configFileName,
collectionConfigs,
),
setup() {},
languagePlugins: getLanguagePlugins(collectionConfigs),
setup({ project }) {
const { languageServiceHost, configFileName } = project.typescript!;

const rootPath = configFileName
? configFileName.split('/').slice(0, -1).join('/')
: env.workspaceFolders[0]!.fsPath;
const nearestPackageJson = typescript.findConfigFile(
rootPath,
typescript.sys.fileExists,
'package.json',
);

const astroInstall = getAstroInstall([rootPath], {
nearestPackageJson: nearestPackageJson,
readDirectory: typescript.sys.readDirectory,
});

if (astroInstall === 'not-found') {
connection.sendNotification(ShowMessageNotification.type, {
message: `Couldn't find Astro in workspace "${rootPath}". Experience might be degraded. For the best experience, please make sure Astro is installed into your project and restart the language server.`,
type: MessageType.Warning,
});
}

addAstroTypes(
typeof astroInstall === 'string' ? undefined : astroInstall,
typescript,
languageServiceHost,
);
},
};
}),
getLanguageServicePlugins(connection, typescript, collectionConfigs),
Expand Down
4 changes: 2 additions & 2 deletions packages/ts-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
"@astrojs/compiler": "^2.10.3",
"@astrojs/yaml2ts": "^0.2.1",
"@jridgewell/sourcemap-codec": "^1.4.15",
"@volar/language-core": "~2.4.0",
"@volar/typescript": "~2.4.0",
"@volar/language-core": "~2.4.5",
"@volar/typescript": "~2.4.5",
"semver": "^7.3.8",
"vscode-languageserver-textdocument": "^1.0.11"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@
"@types/mocha": "^10.0.1",
"@types/node": "^18.17.8",
"@types/vscode": "^1.82.0",
"@volar/language-server": "~2.4.0",
"@volar/vscode": "~2.4.0",
"@volar/language-server": "~2.4.5",
"@volar/vscode": "~2.4.5",
"@vscode/test-electron": "^2.3.2",
"@vscode/vsce": "2.30.0",
"esbuild": "^0.17.19",
Expand Down
2 changes: 1 addition & 1 deletion packages/yaml2ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"yaml": "^2.5.0"
},
"devDependencies": {
"@volar/language-core": "~2.4.0",
"@volar/language-core": "~2.4.5",
"typescript": "^5.5.4"
}
}
Loading

0 comments on commit 35cf3bc

Please sign in to comment.