mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-29 12:11:09 +00:00
feat: 统一LSP工具并扩展操作支持
- 创建统一的LSP工具,整合了之前的多个分散LSP工具 - 增加对更多LSP操作的支持,包括hover、documentSymbol、goToImplementation等 - 扩展LSP类型定义,支持Call Hierarchy等高级功能 - 更新配置和测试文件以适配新的LSP工具架构 - 保持向后兼容性,同时引入新工具名称映射 Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> 此更改是LSP工具重构计划的一部分,旨在提供更统一和功能完备的LSP集成体验。
This commit is contained in:
parent
a14d1e27bb
commit
d9328fa478
13 changed files with 4092 additions and 141 deletions
|
|
@ -20,22 +20,24 @@ import { ExtensionStorage, type Extension } from './extension.js';
|
|||
import * as ServerConfig from '@qwen-code/qwen-code-core';
|
||||
import { isWorkspaceTrusted } from './trustedFolders.js';
|
||||
import { ExtensionEnablementManager } from './extensions/extensionEnablement.js';
|
||||
import { NativeLspService } from '../services/lsp/NativeLspService.js';
|
||||
|
||||
const mockDiscoverAndPrepare = vi.fn();
|
||||
const mockStartLsp = vi.fn();
|
||||
const mockDefinitions = vi.fn().mockResolvedValue([]);
|
||||
const mockReferences = vi.fn().mockResolvedValue([]);
|
||||
const mockWorkspaceSymbols = vi.fn().mockResolvedValue([]);
|
||||
const nativeLspServiceMock = vi.fn().mockImplementation(() => ({
|
||||
discoverAndPrepare: mockDiscoverAndPrepare,
|
||||
start: mockStartLsp,
|
||||
definitions: mockDefinitions,
|
||||
references: mockReferences,
|
||||
workspaceSymbols: mockWorkspaceSymbols,
|
||||
}));
|
||||
const createNativeLspServiceInstance = () => ({
|
||||
discoverAndPrepare: vi.fn(),
|
||||
start: vi.fn(),
|
||||
definitions: vi.fn().mockResolvedValue([]),
|
||||
references: vi.fn().mockResolvedValue([]),
|
||||
workspaceSymbols: vi.fn().mockResolvedValue([]),
|
||||
});
|
||||
|
||||
vi.mock('../services/lsp/NativeLspService.js', () => ({
|
||||
NativeLspService: nativeLspServiceMock,
|
||||
NativeLspService: vi.fn().mockImplementation(() => ({
|
||||
discoverAndPrepare: vi.fn(),
|
||||
start: vi.fn(),
|
||||
definitions: vi.fn().mockResolvedValue([]),
|
||||
references: vi.fn().mockResolvedValue([]),
|
||||
workspaceSymbols: vi.fn().mockResolvedValue([]),
|
||||
})),
|
||||
}));
|
||||
|
||||
vi.mock('./trustedFolders.js', () => ({
|
||||
|
|
@ -44,6 +46,17 @@ vi.mock('./trustedFolders.js', () => ({
|
|||
.mockReturnValue({ isTrusted: true, source: 'file' }), // Default to trusted
|
||||
}));
|
||||
|
||||
const nativeLspServiceMock = vi.mocked(NativeLspService);
|
||||
const getLastLspInstance = () => {
|
||||
const results = nativeLspServiceMock.mock.results;
|
||||
if (results.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return results[results.length - 1]?.value as ReturnType<
|
||||
typeof createNativeLspServiceInstance
|
||||
>;
|
||||
};
|
||||
|
||||
vi.mock('fs', async (importOriginal) => {
|
||||
const actualFs = await importOriginal<typeof import('fs')>();
|
||||
const pathMod = await import('node:path');
|
||||
|
|
@ -533,16 +546,10 @@ describe('loadCliConfig', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
mockDiscoverAndPrepare.mockReset();
|
||||
mockStartLsp.mockReset();
|
||||
mockWorkspaceSymbols.mockReset();
|
||||
mockWorkspaceSymbols.mockResolvedValue([]);
|
||||
nativeLspServiceMock.mockReset();
|
||||
nativeLspServiceMock.mockImplementation(() => ({
|
||||
discoverAndPrepare: mockDiscoverAndPrepare,
|
||||
start: mockStartLsp,
|
||||
workspaceSymbols: mockWorkspaceSymbols,
|
||||
}));
|
||||
nativeLspServiceMock.mockImplementation(() =>
|
||||
createNativeLspServiceInstance(),
|
||||
);
|
||||
vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
|
||||
vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
|
||||
});
|
||||
|
|
@ -637,8 +644,10 @@ describe('loadCliConfig', () => {
|
|||
expect(config.getLspAllowed()).toEqual(['typescript-language-server']);
|
||||
expect(config.getLspExcluded()).toEqual(['pylsp']);
|
||||
expect(nativeLspServiceMock).toHaveBeenCalledTimes(1);
|
||||
expect(mockDiscoverAndPrepare).toHaveBeenCalledTimes(1);
|
||||
expect(mockStartLsp).toHaveBeenCalledTimes(1);
|
||||
const lspInstance = getLastLspInstance();
|
||||
expect(lspInstance).toBeDefined();
|
||||
expect(lspInstance?.discoverAndPrepare).toHaveBeenCalledTimes(1);
|
||||
expect(lspInstance?.start).toHaveBeenCalledTimes(1);
|
||||
|
||||
const options = nativeLspServiceMock.mock.calls[0][5];
|
||||
expect(options?.allowedServers).toEqual(['typescript-language-server']);
|
||||
|
|
@ -664,7 +673,7 @@ describe('loadCliConfig', () => {
|
|||
|
||||
expect(config.isLspEnabled()).toBe(true);
|
||||
expect(nativeLspServiceMock).not.toHaveBeenCalled();
|
||||
expect(mockDiscoverAndPrepare).not.toHaveBeenCalled();
|
||||
expect(getLastLspInstance()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should set showMemoryUsage to false by default from settings if CLI flag is not present', async () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue