✨ feat(vscode): 新增「了解一块代码」:AI 找功能代码占一栏,对话里接着改
主栏标题栏的放大镜问要了解哪一块,占一个栏位建一栏(和收藏共用 30 个栏位,视图改名 slot1..30,按 slotKindN 分收藏 / 功能挂标题栏按钮),同时开对话页让 Claude 只读地在全部工作区文件夹里找,按 --json-schema 交回环节 → 文件 + 符号 + 一句话。 对话复用预览顶部的聊天(CodeQa.askTop:会话续接、进行中的一轮、记录存 workspaceState);结构不合格算这一轮没答成、留着能再画出来。 条目每次画、点时按眼下的代码找:有语言插件的解析成代码块按「类名.方法名」找,没有的问 VS Code 文档符号;找不到画成灰的。
This commit is contained in:
1 parent
16d27004d8
commit
880bf7fc57
38 files changed
+3386
-378
No files matched your search
@@ -0,0 +1,109 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { createBashAdapter } from '../languages/bash'
|
||||
import { createPythonAdapter } from '../languages/python'
|
||||
import { createRustAdapter } from '../languages/rust'
|
||||
import { createTypeScriptAdapter } from '../languages/typescript'
|
||||
import { runtime, WASM_DIR } from '../testSupport'
|
||||
import { locateInSource } from './featureLocate'
|
||||
|
||||
const typescript = createTypeScriptAdapter(WASM_DIR)
|
||||
const python = createPythonAdapter(WASM_DIR)
|
||||
const rust = createRustAdapter(WASM_DIR)
|
||||
const bash = createBashAdapter(WASM_DIR)
|
||||
|
||||
/** 找到的那块的名字在源码里是哪几个字、种类;找不到是 undefined */
|
||||
async function find(adapter: typeof typescript, languageId: string, source: string, symbol: string): Promise<{ text: string, kind: string } | undefined> {
|
||||
const found = await locateInSource(runtime, adapter, languageId, source, symbol)
|
||||
return found && { text: source.slice(found.range.startIndex, found.range.endIndex), kind: found.kind }
|
||||
}
|
||||
|
||||
const TS = `
|
||||
import { api } from './api'
|
||||
|
||||
export function login(name: string) {
|
||||
return api.post('/login', { name })
|
||||
}
|
||||
|
||||
export class AuthService {
|
||||
private token = ''
|
||||
|
||||
async login(name: string) {
|
||||
return login(name)
|
||||
}
|
||||
|
||||
static create() {
|
||||
return new AuthService()
|
||||
}
|
||||
}
|
||||
|
||||
export const LoginPage = () => {
|
||||
const submit = () => login('a')
|
||||
return submit
|
||||
}
|
||||
`
|
||||
|
||||
const PY = `
|
||||
class UserService:
|
||||
def renew(self, user):
|
||||
return self._charge(user)
|
||||
|
||||
class Retry:
|
||||
def schedule(self):
|
||||
pass
|
||||
|
||||
|
||||
def renew_all():
|
||||
pass
|
||||
`
|
||||
|
||||
const RS = `
|
||||
pub struct Order;
|
||||
|
||||
impl Order {
|
||||
pub fn pay(&self) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
`
|
||||
|
||||
describe('按符号名在源码里找(语言插件解析出的块)', () => {
|
||||
it('函数、类、组件按名字找;同名时取先出现的', async () => {
|
||||
expect(await find(typescript, 'typescript', TS, 'login')).toEqual({ text: 'login', kind: 'function' })
|
||||
expect(await find(typescript, 'typescript', TS, 'AuthService')).toEqual({ text: 'AuthService', kind: 'class' })
|
||||
expect(await find(typescript, 'typescriptreact', TS, 'LoginPage')).toEqual({ text: 'LoginPage', kind: 'function' })
|
||||
})
|
||||
|
||||
it('方法写成「类名.方法名」:先找类,再在里面找方法', async () => {
|
||||
const found = await locateInSource(runtime, typescript, 'typescript', TS, 'AuthService.login')
|
||||
expect(found?.kind).toBe('function')
|
||||
// 是类里的那个 login,不是文件开头的函数
|
||||
expect(found!.range.startIndex).toBeGreaterThan(TS.indexOf('class AuthService'))
|
||||
expect(await find(typescript, 'typescript', TS, 'AuthService.create')).toEqual({ text: 'create', kind: 'function' })
|
||||
expect(await find(typescript, 'typescript', TS, 'LoginPage.submit')).toEqual({ text: 'submit', kind: 'variable' })
|
||||
})
|
||||
|
||||
it('类里的方法、嵌套类里的方法(Python);impl 里的方法按类型名找(Rust)', async () => {
|
||||
expect(await find(python, 'python', PY, 'UserService.renew')).toEqual({ text: 'renew', kind: 'function' })
|
||||
expect(await find(python, 'python', PY, 'UserService.Retry.schedule')).toEqual({ text: 'schedule', kind: 'function' })
|
||||
expect(await find(python, 'python', PY, 'renew_all')).toEqual({ text: 'renew_all', kind: 'function' })
|
||||
expect(await find(rust, 'rust', RS, 'Order.pay')).toEqual({ text: 'pay', kind: 'function' })
|
||||
})
|
||||
|
||||
it('类型(interface、type)和它们的成员按声明的名字找;shell 命令不算名字', async () => {
|
||||
const types = 'export interface Favorite {\n uri: string\n}\ntype Slot = number\n'
|
||||
expect(await find(typescript, 'typescript', types, 'Favorite')).toEqual({ text: 'Favorite', kind: 'type' })
|
||||
expect(await find(typescript, 'typescript', types, 'Favorite.uri')).toEqual({ text: 'uri', kind: 'field' })
|
||||
expect(await find(typescript, 'typescript', types, 'Slot')).toEqual({ text: 'Slot', kind: 'type' })
|
||||
expect(await find(rust, 'rust', 'pub type Id = u32;\n', 'Id')).toEqual({ text: 'Id', kind: 'statement' })
|
||||
expect(await find(bash, 'shellscript', 'deploy() {\n echo hi\n}\n', 'deploy')).toEqual({ text: 'deploy', kind: 'function' })
|
||||
expect(await find(bash, 'shellscript', 'deploy() {\n echo hi\n}\n', 'deploy.echo')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('找不到:没有这个名字、类里没有这个方法、写法不对', async () => {
|
||||
expect(await find(typescript, 'typescript', TS, 'logout')).toBeUndefined()
|
||||
expect(await find(typescript, 'typescript', TS, 'AuthService.logout')).toBeUndefined()
|
||||
expect(await find(typescript, 'typescript', TS, 'Missing.login')).toBeUndefined()
|
||||
expect(await find(typescript, 'typescript', TS, 'AuthService.')).toBeUndefined()
|
||||
expect(await find(python, 'python', PY, 'UserService.schedule.renew')).toBeUndefined()
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user