From 74c3e85d4dca927fbe93f8100ad4aed979734d92 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sat, 30 Mar 2024 10:49:18 +0800 Subject: [PATCH] Pre-work for #4125 --- packages/language-service/index.ts | 4 +++ .../lib/plugins/vue-document-drop.ts | 29 +++++++++++++++---- packages/typescript-plugin/lib/client.ts | 9 ++++++ .../lib/requests/getImportPathForFile.ts | 14 +++++++++ packages/typescript-plugin/lib/server.ts | 6 ++++ 5 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 packages/typescript-plugin/lib/requests/getImportPathForFile.ts diff --git a/packages/language-service/index.ts b/packages/language-service/index.ts index 312a50103..b3740034f 100644 --- a/packages/language-service/index.ts +++ b/packages/language-service/index.ts @@ -30,6 +30,7 @@ import { create as createVueVisualizeHiddenCallbackParamPlugin } from './lib/plu import { decorateLanguageServiceForVue } from '@vue/typescript-plugin/lib/common'; import { collectExtractProps } from '@vue/typescript-plugin/lib/requests/collectExtractProps'; import { getComponentEvents, getComponentNames, getComponentProps, getElementAttrs, getTemplateContextProps } from '@vue/typescript-plugin/lib/requests/componentInfos'; +import { getImportPathForFile } from '@vue/typescript-plugin/lib/requests/getImportPathForFile'; import { getPropertiesAtLocation } from '@vue/typescript-plugin/lib/requests/getPropertiesAtLocation'; import { getQuickInfoAtPosition } from '@vue/typescript-plugin/lib/requests/getQuickInfoAtPosition'; @@ -118,6 +119,9 @@ export function createDefaultGetTsPluginClient( async getPropertiesAtLocation(...args) { return await getPropertiesAtLocation.apply(requestContext, args); }, + async getImportPathForFile(...args) { + return await getImportPathForFile.apply(requestContext, args); + }, async getComponentEvents(...args) { return await getComponentEvents.apply(requestContext, args); }, diff --git a/packages/language-service/lib/plugins/vue-document-drop.ts b/packages/language-service/lib/plugins/vue-document-drop.ts index 64bc64e58..3037c217a 100644 --- a/packages/language-service/lib/plugins/vue-document-drop.ts +++ b/packages/language-service/lib/plugins/vue-document-drop.ts @@ -3,15 +3,20 @@ import { camelize, capitalize, hyphenate } from '@vue/shared'; import * as path from 'path-browserify'; import type * as vscode from 'vscode-languageserver-protocol'; import { createAddComponentToOptionEdit, getLastImportNode } from '../plugins/vue-extract-file'; -import { LanguageServicePlugin, LanguageServicePluginInstance, TagNameCasing } from '../types'; +import { LanguageServicePlugin, LanguageServicePluginInstance, ServiceContext, TagNameCasing } from '../types'; -export function create(ts: typeof import('typescript')): LanguageServicePlugin { +export function create( + ts: typeof import('typescript'), + getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined, +): LanguageServicePlugin { return { name: 'vue-document-drop', create(context): LanguageServicePluginInstance { let casing: TagNameCasing = TagNameCasing.Pascal; // TODO + const tsPluginClient = getTsPluginClient?.(context); + return { async provideDocumentDropEdits(document, _position, dataTransfer) { @@ -52,11 +57,23 @@ export function create(ts: typeof import('typescript')): LanguageServicePlugin { const code = [...forEachEmbeddedCode(vueVirtualCode)].find(code => code.id === (sfc.scriptSetup ? 'scriptSetupFormat' : 'scriptFormat'))!; const lastImportNode = getLastImportNode(ts, script.ast); - let importPath = path.relative(path.dirname(document.uri), importUri) - || importUri.substring(importUri.lastIndexOf('/') + 1); + let importPath: string | undefined; + + if (tsPluginClient) { + const importFileName = context.env.typescript!.uriToFileName(importUri); + const importPathRequest = await tsPluginClient.getImportPathForFile(vueVirtualCode.fileName, importFileName); + if (importPathRequest) { + importPath = importPathRequest; + } + } + + if (!importPath) { + importPath = path.relative(path.dirname(document.uri), importUri) + || importUri.substring(importUri.lastIndexOf('/') + 1); - if (!importPath.startsWith('./') && !importPath.startsWith('../')) { - importPath = './' + importPath; + if (!importPath.startsWith('./') && !importPath.startsWith('../')) { + importPath = './' + importPath; + } } additionalEdit.changes ??= {}; diff --git a/packages/typescript-plugin/lib/client.ts b/packages/typescript-plugin/lib/client.ts index 884ec1a4e..26e71f17e 100644 --- a/packages/typescript-plugin/lib/client.ts +++ b/packages/typescript-plugin/lib/client.ts @@ -10,6 +10,15 @@ export function collectExtractProps( }); } +export async function getImportPathForFile( + ...args: Parameters +) { + return await sendRequest>({ + type: 'getImportPathForFile', + args, + }); +} + export async function getPropertiesAtLocation( ...args: Parameters ) { diff --git a/packages/typescript-plugin/lib/requests/getImportPathForFile.ts b/packages/typescript-plugin/lib/requests/getImportPathForFile.ts new file mode 100644 index 000000000..b8064fdd4 --- /dev/null +++ b/packages/typescript-plugin/lib/requests/getImportPathForFile.ts @@ -0,0 +1,14 @@ +import type * as ts from 'typescript'; + +export function getImportPathForFile( + this: { + typescript: typeof import('typescript'); + languageService: ts.LanguageService; + }, + fileName: string, + importFileName: string, +) { + const { typescript: ts, languageService } = this; + // TODO + return importFileName.replace('./', '@/'); +} diff --git a/packages/typescript-plugin/lib/server.ts b/packages/typescript-plugin/lib/server.ts index 99c558561..586b16a37 100644 --- a/packages/typescript-plugin/lib/server.ts +++ b/packages/typescript-plugin/lib/server.ts @@ -3,6 +3,7 @@ import * as net from 'net'; import type * as ts from 'typescript'; import { collectExtractProps } from './requests/collectExtractProps'; import { getComponentEvents, getComponentNames, getComponentProps, getElementAttrs, getTemplateContextProps } from './requests/componentInfos'; +import { getImportPathForFile } from './requests/getImportPathForFile'; import { getPropertiesAtLocation } from './requests/getPropertiesAtLocation'; import { getQuickInfoAtPosition } from './requests/getQuickInfoAtPosition'; import { NamedPipeServer, connect, readPipeTable, updatePipeTable } from './utils'; @@ -11,6 +12,7 @@ import type { Language, VueCompilerOptions } from '@vue/language-core'; export interface Request { type: 'containsFile' | 'collectExtractProps' + | 'getImportPathForFile' | 'getPropertiesAtLocation' | 'getQuickInfoAtPosition' // Component Infos @@ -59,6 +61,10 @@ export function startNamedPipeServer( const result = collectExtractProps.apply(requestContext, request.args as any); connection.write(JSON.stringify(result ?? null)); } + else if (request.type === 'getImportPathForFile') { + const result = getImportPathForFile.apply(requestContext, request.args as any); + connection.write(JSON.stringify(result ?? null)); + } else if (request.type === 'getPropertiesAtLocation') { const result = getPropertiesAtLocation.apply(requestContext, request.args as any); connection.write(JSON.stringify(result ?? null));