Skip to content

Commit

Permalink
fix(language-server): name casing request not working
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk committed Mar 20, 2024
1 parent b1cd804 commit 0dfe599
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 51 deletions.
19 changes: 14 additions & 5 deletions packages/language-server/node.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Connection } from '@volar/language-server';
import { createConnection, createServer, createSimpleProjectProviderFactory, createTypeScriptProjectProviderFactory, loadTsdkByPath } from '@volar/language-server/node';
import { ParsedCommandLine, VueCompilerOptions, createParsedCommandLine, createVueLanguagePlugin, parse, resolveVueCompilerOptions } from '@vue/language-core';
import { ServiceEnvironment, convertAttrName, convertTagName, createVueServicePlugins, detect } from '@vue/language-service';
import { ServiceEnvironment, convertAttrName, convertTagName, createDefaultGetTsPluginClient, createVueServicePlugins, detect } from '@vue/language-service';
import { DetectNameCasingRequest, GetConvertAttrCasingEditsRequest, GetConvertTagCasingEditsRequest, ParseSFCRequest } from './lib/protocol';
import type { VueInitializationOptions } from './lib/types';
import * as tsPluginClient from '@vue/typescript-plugin/lib/client';
Expand All @@ -15,6 +15,7 @@ export const server = createServer(connection);
const envToVueOptions = new WeakMap<ServiceEnvironment, VueCompilerOptions>();

let tsdk: ReturnType<typeof loadTsdkByPath>;
let getTsPluginClient: ReturnType<typeof createDefaultGetTsPluginClient>;

connection.listen();

Expand All @@ -33,6 +34,13 @@ connection.onInitialize(async params => {
}
}

if (hybridMode) {
getTsPluginClient = () => tsPluginClient;
}
else {
getTsPluginClient = createDefaultGetTsPluginClient(tsdk.typescript, env => envToVueOptions.get(env)!);
}

const result = await server.initialize(
params,
hybridMode
Expand All @@ -44,7 +52,8 @@ connection.onInitialize(async params => {
return createVueServicePlugins(
tsdk.typescript,
env => envToVueOptions.get(env)!,
hybridMode ? () => tsPluginClient : undefined,
getTsPluginClient,
hybridMode,
);
},
async getLanguagePlugins(serviceEnv, projectContext) {
Expand Down Expand Up @@ -130,21 +139,21 @@ connection.onRequest(ParseSFCRequest.type, params => {
connection.onRequest(DetectNameCasingRequest.type, async params => {
const languageService = await getService(params.textDocument.uri);
if (languageService) {
return await detect(languageService.context, params.textDocument.uri, tsPluginClient);
return await detect(languageService.context, params.textDocument.uri, getTsPluginClient(languageService.context));
}
});

connection.onRequest(GetConvertTagCasingEditsRequest.type, async params => {
const languageService = await getService(params.textDocument.uri);
if (languageService) {
return await convertTagName(languageService.context, params.textDocument.uri, params.casing, tsPluginClient);
return await convertTagName(languageService.context, params.textDocument.uri, params.casing, getTsPluginClient(languageService.context));
}
});

connection.onRequest(GetConvertAttrCasingEditsRequest.type, async params => {
const languageService = await getService(params.textDocument.uri);
if (languageService) {
return await convertAttrName(languageService.context, params.textDocument.uri, params.casing, tsPluginClient);
return await convertAttrName(languageService.context, params.textDocument.uri, params.casing, getTsPluginClient(languageService.context));
}
});

Expand Down
88 changes: 47 additions & 41 deletions packages/language-service/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ import { getQuickInfoAtPosition } from '@vue/typescript-plugin/lib/requests/getQ
export function createVueServicePlugins(
ts: typeof import('typescript'),
getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions,
getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined,
getTsPluginClient = createDefaultGetTsPluginClient(ts, getVueOptions),
hybridMode = false,
): ServicePlugin[] {
const plugins: ServicePlugin[] = [];
const hybridMode = !!getTsPluginClient;
if (!hybridMode) {
plugins.push(...createTypeScriptServicePlugins(ts));
for (let i = 0; i < plugins.length; i++) {
Expand All @@ -61,45 +61,6 @@ export function createVueServicePlugins(
break;
}
}
getTsPluginClient = context => {
if (!context.language.typescript) {
return;
}
const requestContext = {
typescript: ts,
files: context.language.files,
languageService: context.inject<(import('volar-service-typescript').Provide), 'typescript/languageService'>('typescript/languageService'),
vueOptions: getVueOptions(context.env),
isTsPlugin: false,
getFileId: context.env.typescript!.fileNameToUri,
};
return {
async collectExtractProps(...args) {
return await collectExtractProps.apply(requestContext, args);
},
async getPropertiesAtLocation(...args) {
return await getPropertiesAtLocation.apply(requestContext, args);
},
async getComponentEvents(...args) {
return await getComponentEvents.apply(requestContext, args);
},
async getComponentNames(...args) {
return await getComponentNames.apply(requestContext, args);
},
async getComponentProps(...args) {
return await getComponentProps.apply(requestContext, args);
},
async getElementAttrs(...args) {
return await getElementAttrs.apply(requestContext, args);
},
async getTemplateContextProps(...args) {
return await getTemplateContextProps.apply(requestContext, args);
},
async getQuickInfoAtPosition(...args) {
return await getQuickInfoAtPosition.apply(requestContext, args);
},
};
};
}
else {
plugins.push(
Expand Down Expand Up @@ -129,3 +90,48 @@ export function createVueServicePlugins(
);
return plugins;
}

export function createDefaultGetTsPluginClient(
ts: typeof import('typescript'),
getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions,
): (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined {
return context => {
if (!context.language.typescript) {
return;
}
const requestContext = {
typescript: ts,
files: context.language.files,
languageService: context.inject<(import('volar-service-typescript').Provide), 'typescript/languageService'>('typescript/languageService'),
vueOptions: getVueOptions(context.env),
isTsPlugin: false,
getFileId: context.env.typescript!.fileNameToUri,
};
return {
async collectExtractProps(...args) {
return await collectExtractProps.apply(requestContext, args);
},
async getPropertiesAtLocation(...args) {
return await getPropertiesAtLocation.apply(requestContext, args);
},
async getComponentEvents(...args) {
return await getComponentEvents.apply(requestContext, args);
},
async getComponentNames(...args) {
return await getComponentNames.apply(requestContext, args);
},
async getComponentProps(...args) {
return await getComponentProps.apply(requestContext, args);
},
async getElementAttrs(...args) {
return await getElementAttrs.apply(requestContext, args);
},
async getTemplateContextProps(...args) {
return await getTemplateContextProps.apply(requestContext, args);
},
async getQuickInfoAtPosition(...args) {
return await getQuickInfoAtPosition.apply(requestContext, args);
},
};
};;
}
10 changes: 5 additions & 5 deletions packages/language-service/lib/ideFeatures/nameCasing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export async function convertTagName(
context: ServiceContext,
uri: string,
casing: TagNameCasing,
tsPluginClient: typeof import('@vue/typescript-plugin/lib/client'),
tsPluginClient: typeof import('@vue/typescript-plugin/lib/client') | undefined,
) {

const sourceFile = context.language.files.get(uri);
Expand All @@ -31,7 +31,7 @@ export async function convertTagName(
const template = desc.template;
const document = context.documents.get(sourceFile.id, sourceFile.languageId, sourceFile.snapshot);
const edits: vscode.TextEdit[] = [];
const components = await tsPluginClient.getComponentNames(rootCode.fileName) ?? [];
const components = await tsPluginClient?.getComponentNames(rootCode.fileName) ?? [];
const tags = getTemplateTagsAndAttrs(rootCode);

for (const [tagName, { offsets }] of tags) {
Expand All @@ -58,7 +58,7 @@ export async function convertAttrName(
context: ServiceContext,
uri: string,
casing: AttrNameCasing,
tsPluginClient: typeof import('@vue/typescript-plugin/lib/client'),
tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client'),
) {

const sourceFile = context.language.files.get(uri);
Expand All @@ -79,13 +79,13 @@ export async function convertAttrName(
const template = desc.template;
const document = context.documents.get(uri, sourceFile.languageId, sourceFile.snapshot);
const edits: vscode.TextEdit[] = [];
const components = await tsPluginClient.getComponentNames(rootCode.fileName) ?? [];
const components = await tsPluginClient?.getComponentNames(rootCode.fileName) ?? [];
const tags = getTemplateTagsAndAttrs(rootCode);

for (const [tagName, { attrs }] of tags) {
const componentName = components.find(component => component === tagName || hyphenateTag(component) === tagName);
if (componentName) {
const props = await tsPluginClient.getComponentProps(rootCode.fileName, componentName) ?? [];
const props = await tsPluginClient?.getComponentProps(rootCode.fileName, componentName) ?? [];
for (const [attrName, { offsets }] of attrs) {
const propName = props.find(prop => prop === attrName || hyphenateAttr(prop) === attrName);
if (propName) {
Expand Down

0 comments on commit 0dfe599

Please sign in to comment.