Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk committed Nov 16, 2023
1 parent 015a667 commit aa2ddd4
Show file tree
Hide file tree
Showing 16 changed files with 135 additions and 120 deletions.
2 changes: 1 addition & 1 deletion packages/astro-check/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export async function check(flags: Partial<Flags>): Promise<boolean | void> {
// Dynamically get the list of extensions to watch from the files already included in the project
const checkedExtensions = Array.from(
new Set(
checker.project.languageHost.getScriptFileNames().map((fileName) => path.extname(fileName))
checker.project.typescript!.projectHost.getScriptFileNames().map((fileName) => path.extname(fileName))
)
);
createWatcher(workspaceRoot, checkedExtensions)
Expand Down
33 changes: 16 additions & 17 deletions packages/language-server/src/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export interface CheckResult {

export class AstroCheck {
private ts!: typeof import('typescript/lib/tsserverlibrary.js');
public project!: ReturnType<typeof kit.createProject>;
public project!: kit.Project;
private linter!: ReturnType<typeof kit.createLinter>;

constructor(
Expand Down Expand Up @@ -61,7 +61,7 @@ export class AstroCheck {
| undefined;
}): Promise<CheckResult> {
const files =
fileNames !== undefined ? fileNames : this.project.languageHost.getScriptFileNames();
fileNames !== undefined ? fileNames : this.project.typescript!.projectHost.getScriptFileNames();

const result: CheckResult = {
status: undefined,
Expand Down Expand Up @@ -98,7 +98,7 @@ export class AstroCheck {
console.info(errorText);
}

const fileSnapshot = this.project.languageHost.getScriptSnapshot(file);
const fileSnapshot = this.project.typescript!.projectHost.getScriptSnapshot(file);
const fileContent = fileSnapshot?.getText(0, fileSnapshot.getLength());

result.fileResult.push({
Expand Down Expand Up @@ -130,26 +130,25 @@ export class AstroCheck {
this.ts = this.typescriptPath ? require(this.typescriptPath) : require('typescript');
const tsconfigPath = this.getTsconfig();

const config: kit.Config = {
languages: {
astro: getLanguageModule(getAstroInstall([this.workspacePath]), this.ts),
svelte: getSvelteLanguageModule(),
vue: getVueLanguageModule(),
},
services: {
typescript: createTypeScriptService(),
astro: createAstroService(),
},
};
const languages: kit.Language[] = [
getLanguageModule(getAstroInstall([this.workspacePath]), this.ts),
getSvelteLanguageModule(),
getVueLanguageModule(),
];
const services = [
createTypeScriptService(),
createAstroService(),
];
const env = kit.createServiceEnvironment();

if (tsconfigPath) {
this.project = kit.createProject(tsconfigPath, [
this.project = kit.createTypeScriptKitProject(languages, env, tsconfigPath, [
{ extension: 'astro', isMixedContent: true, scriptKind: 7 },
{ extension: 'vue', isMixedContent: true, scriptKind: 7 },
{ extension: 'svelte', isMixedContent: true, scriptKind: 7 },
]);
} else {
this.project = kit.createInferredProject(this.workspacePath, () => {
this.project = kit.createTypeScriptInferredKitProject(languages, env, () => {
return fg.sync('**/*.astro', {
cwd: this.workspacePath,
ignore: ['node_modules'],
Expand All @@ -158,7 +157,7 @@ export class AstroCheck {
});
}

this.linter = kit.createLinter(config, this.project.languageHost);
this.linter = kit.createLinter(services, env, this.project);
}

private getTsconfig() {
Expand Down
1 change: 1 addition & 0 deletions packages/language-server/src/core/astro2tsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ function getVirtualFileTSX(

return {
fileName: fileName + '.tsx',
languageId: 'typescriptreact',
kind: FileKind.TypeScriptHostFile,
capabilities: {
codeAction: true,
Expand Down
3 changes: 2 additions & 1 deletion packages/language-server/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function getLanguageModule(
updateVirtualFile(astroFile, snapshot) {
astroFile.update(snapshot);
},
resolveHost(host) {
resolveTypeScriptProjectHost(host) {
return {
...host,
resolveModuleName(moduleName, impliedNodeFormat) {
Expand Down Expand Up @@ -83,6 +83,7 @@ export class AstroFile implements VirtualFile {
capabilities = FileCapabilities.full;

fileName: string;
languageId = 'astro';
mappings!: VirtualFile['mappings'];
embeddedFiles!: VirtualFile['embeddedFiles'];
astroMeta!: ParseResult & { frontmatter: FrontmatterStatus };
Expand Down
2 changes: 2 additions & 0 deletions packages/language-server/src/core/parseCSS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export function extractStylesheets(

embeddedCSSFiles.push({
fileName: fileName + '.inline.css',
languageId: 'css',
codegenStacks: [],
snapshot: {
getText: (start, end) => text.substring(start, end),
Expand Down Expand Up @@ -78,6 +79,7 @@ function findEmbeddedStyles(
const styleText = snapshot.getText(node.startTagEnd, node.endTagStart);
embeddedCSSFiles.push({
fileName: fileName + `.${cssIndex}.css`,
languageId: 'css',
kind: FileKind.TextFile,
snapshot: {
getText: (start, end) => styleText.substring(start, end),
Expand Down
1 change: 1 addition & 0 deletions packages/language-server/src/core/parseHTML.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export function preprocessHTML(text: string, frontmatterEnd?: number) {
function getHTMLVirtualFile(fileName: string, preprocessedHTML: string): VirtualFile {
return {
fileName: fileName + `.html`,
languageId: 'html',
kind: FileKind.TextFile,
snapshot: {
getText: (start, end) => preprocessedHTML.substring(start, end),
Expand Down
2 changes: 2 additions & 0 deletions packages/language-server/src/core/parseJS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ function findIsolatedScripts(
const scriptText = snapshot.getText(node.startTagEnd, node.endTagStart);
embeddedScripts.push({
fileName: fileName + `.${scriptIndex}.mts`,
languageId: 'typescript',
kind: FileKind.TypeScriptHostFile,
snapshot: {
getText: (start, end) => scriptText.substring(start, end),
Expand Down Expand Up @@ -214,6 +215,7 @@ function mergeJSContexts(fileName: string, javascriptContexts: JavaScriptContext

return {
fileName: fileName + '.inline.mjs',
languageId: 'javascript',
codegenStacks: [],
snapshot: {
getText: (start, end) => text.substring(start, end),
Expand Down
1 change: 1 addition & 0 deletions packages/language-server/src/core/svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class SvelteFile implements VirtualFile {
capabilities = FileCapabilities.full;

fileName: string;
languageId = 'svelte';
mappings!: Mapping<FileRangeCapabilities>[];
embeddedFiles!: VirtualFile[];
codegenStacks = [];
Expand Down
1 change: 1 addition & 0 deletions packages/language-server/src/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export function framework2tsx(
function getVirtualFile(content: string): VirtualFile {
return {
fileName: fileName + '.tsx',
languageId: 'typescript',
capabilities: FileCapabilities.full,
kind: FileKind.TypeScriptHostFile,
snapshot: {
Expand Down
1 change: 1 addition & 0 deletions packages/language-server/src/core/vue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class VueFile implements VirtualFile {
capabilities = FileCapabilities.full;

fileName: string;
languageId = 'vue';
mappings!: Mapping<FileRangeCapabilities>[];
embeddedFiles!: VirtualFile[];
codegenStacks = [];
Expand Down
182 changes: 91 additions & 91 deletions packages/language-server/src/languageServerPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {
LanguageServerPlugin,
TypeScriptServerPlugin,
MessageType,
ShowMessageNotification,
Connection,
} from '@volar/language-server/node';
import { getLanguageModule } from './core';
import { getSvelteLanguageModule } from './core/svelte.js';
Expand All @@ -20,104 +21,103 @@ import { create as createHtmlService } from './plugins/html.js';
import { create as createTypescriptAddonsService } from './plugins/typescript-addons/index.js';
import { create as createTypeScriptService } from './plugins/typescript/index.js';

export const plugin: LanguageServerPlugin = (
initOptions,
modules
): ReturnType<LanguageServerPlugin> => ({
extraFileExtensions: [
{ extension: 'astro', isMixedContent: true, scriptKind: 7 },
{ extension: 'vue', isMixedContent: true, scriptKind: 7 },
{ extension: 'svelte', isMixedContent: true, scriptKind: 7 },
],
watchFileExtensions: [
'js',
'cjs',
'mjs',
'ts',
'cts',
'mts',
'jsx',
'tsx',
'json',
'astro',
'vue',
'svelte',
],
resolveConfig(config, ctx) {
config.languages ??= {};
if (ctx) {
const astroInstall = getAstroInstall([ctx.project.rootUri.fsPath]);
export function createPlugin(connection: Connection): TypeScriptServerPlugin {
return ({ modules }): ReturnType<TypeScriptServerPlugin> => ({
extraFileExtensions: [
{ extension: 'astro', isMixedContent: true, scriptKind: 7 },
{ extension: 'vue', isMixedContent: true, scriptKind: 7 },
{ extension: 'svelte', isMixedContent: true, scriptKind: 7 },
],
watchFileExtensions: [
'js',
'cjs',
'mjs',
'ts',
'cts',
'mts',
'jsx',
'tsx',
'json',
'astro',
'vue',
'svelte',
],
resolveConfig(config, env, projectHost) {
config.languages ??= {};
if (projectHost) {
const astroInstall = getAstroInstall([projectHost.getCurrentDirectory()]);

if (!astroInstall) {
ctx.server.connection.sendNotification(ShowMessageNotification.type, {
message: `Couldn't find Astro in workspace "${ctx.project.rootUri.fsPath}". 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 (!astroInstall) {
connection.sendNotification(ShowMessageNotification.type, {
message: `Couldn't find Astro in workspace "${projectHost.getCurrentDirectory()}". 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,
});
}

config.languages.astro = getLanguageModule(astroInstall, modules.typescript!);
config.languages.vue = getVueLanguageModule();
config.languages.svelte = getSvelteLanguageModule();
}
config.languages.astro = getLanguageModule(astroInstall, modules.typescript!);
config.languages.vue = getVueLanguageModule();
config.languages.svelte = getSvelteLanguageModule();
}

config.services ??= {};
config.services.html ??= createHtmlService();
config.services.css ??= createCssService();
config.services.emmet ??= createEmmetService();
config.services.typescript ??= createTypeScriptService();
config.services.typescripttwoslash ??= createTypeScriptTwoSlashService();
config.services.typescriptaddons ??= createTypescriptAddonsService();
config.services.astro ??= createAstroService();
config.services ??= {};
config.services.html ??= createHtmlService();
config.services.css ??= createCssService();
config.services.emmet ??= createEmmetService();
config.services.typescript ??= createTypeScriptService();
config.services.typescripttwoslash ??= createTypeScriptTwoSlashService();
config.services.typescriptaddons ??= createTypescriptAddonsService();
config.services.astro ??= createAstroService();

if (ctx) {
const rootDir = ctx.env.uriToFileName(ctx.project.rootUri.toString());
const prettier = importPrettier(rootDir);
const prettierPluginPath = getPrettierPluginPath(rootDir);
if (env && projectHost) {
const rootDir = projectHost.getCurrentDirectory();
const prettier = importPrettier(rootDir);
const prettierPluginPath = getPrettierPluginPath(rootDir);

if (prettier && prettierPluginPath) {
config.services.prettier ??= createPrettierService({
prettier: prettier,
languages: ['astro'],
ignoreIdeOptions: true,
useIdeOptionsFallback: true,
resolveConfigOptions: {
// This seems to be broken since Prettier 3, and it'll always use its cumbersome cache. Hopefully it works one day.
useCache: false,
},
additionalOptions: async (resolvedConfig) => {
async function getAstroPrettierPlugin() {
if (!prettier || !prettierPluginPath) {
return [];
}
if (prettier && prettierPluginPath) {
config.services.prettier ??= createPrettierService({
prettier: prettier,
languages: ['astro'],
ignoreIdeOptions: true,
useIdeOptionsFallback: true,
resolveConfigOptions: {
// This seems to be broken since Prettier 3, and it'll always use its cumbersome cache. Hopefully it works one day.
useCache: false,
},
additionalOptions: async (resolvedConfig) => {
async function getAstroPrettierPlugin() {
if (!prettier || !prettierPluginPath) {
return [];
}

const hasPluginLoadedAlready =
(await prettier.getSupportInfo()).languages.some((l: any) => l.name === 'astro') ||
resolvedConfig.plugins?.includes('prettier-plugin-astro'); // getSupportInfo doesn't seems to work very well in Prettier 3 for plugins
const hasPluginLoadedAlready =
(await prettier.getSupportInfo()).languages.some((l: any) => l.name === 'astro') ||
resolvedConfig.plugins?.includes('prettier-plugin-astro'); // getSupportInfo doesn't seems to work very well in Prettier 3 for plugins

return hasPluginLoadedAlready ? [] : [prettierPluginPath];
}
return hasPluginLoadedAlready ? [] : [prettierPluginPath];
}

const plugins = [
...(await getAstroPrettierPlugin()),
...(resolvedConfig.plugins ?? []),
];
const plugins = [
...(await getAstroPrettierPlugin()),
...(resolvedConfig.plugins ?? []),
];

return {
...resolvedConfig,
plugins: plugins,
parser: 'astro',
};
},
});
} else {
ctx.server.connection.sendNotification(ShowMessageNotification.type, {
message:
"Couldn't load `prettier` or `prettier-plugin-astro`. Formatting will not work. Please make sure those two packages are installed into your project.",
type: MessageType.Warning,
});
return {
...resolvedConfig,
plugins: plugins,
parser: 'astro',
};
},
});
} else {
connection.sendNotification(ShowMessageNotification.type, {
message:
"Couldn't load `prettier` or `prettier-plugin-astro`. Formatting will not work. Please make sure those two packages are installed into your project.",
type: MessageType.Warning,
});
}
}
}

return config;
},
});
return config;
},
});
}
9 changes: 6 additions & 3 deletions packages/language-server/src/nodeServer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { createConnection, startLanguageServer } from '@volar/language-server/node';
import { plugin } from './languageServerPlugin.js';
import { createConnection, startTypeScriptServer } from '@volar/language-server/node';
import { createPlugin } from './languageServerPlugin.js';

startLanguageServer(createConnection(), plugin);
const connection = createConnection();
const plugin = createPlugin(connection);

startTypeScriptServer(connection, plugin);
Loading

0 comments on commit aa2ddd4

Please sign in to comment.