✨ feat(vscode): FastAPI 接口卡片的调用树带上前端调用它的地方
This commit is contained in:
1 parent
d4459e93b3
commit
29cedcb751
30 files changed
+1316
-130
No files matched your search
@@ -5,6 +5,7 @@
|
||||
import type { ClaudeImage } from '../../cc/spawnClaude'
|
||||
import type { FileAttribute } from '../attributes'
|
||||
import type { BlockView } from '../blockView'
|
||||
import type { ContractMiss } from '../callTree/endpoint'
|
||||
import type { CallTree } from '../callTree/model'
|
||||
import type { DocumentDiff } from '../diff/previewDiff'
|
||||
import type { ShownName } from '../nameResolution'
|
||||
@@ -130,8 +131,9 @@ export interface StickyScrollSettings {
|
||||
* repoLinkBroken:这个仓库链接打不开。没有 symbol 是文件或目录没有;有 symbol 是文件在、这个符号没有;没有 path 是不带路径的引用找不到
|
||||
* repoLinkOpened:这个仓库链接打开了。路径在;带了 symbol 时这个符号也在;没有 path 是不带路径的引用找到了
|
||||
* repoImagesChecked:id 那次 checkRepoImages 的回答。src 是预览里能直接用的图片地址;没有 src 是文件不在
|
||||
* callTreeCounts:version 这份文档里,每个函数、类落在几棵调用树里(只包括大于 0 的)。不是页面上这个版本的不理
|
||||
* callTree:anchor 那块的调用树。trees 空着是没有调用它的地方。不是页面上这个版本的不理
|
||||
* callTreeCounts:version 这份文档里,每个能看调用树的块(BlockView.callTree)落在几棵调用树里(只包括大于 0 的)。不是页面上这个版本的不理
|
||||
* callTree:anchor 那块的调用树。trees 空着、又没有 contractMiss 是没有调用它的地方;接口卡片在契约文件里没对上时带 contractMiss。
|
||||
* 不是页面上这个版本的不理
|
||||
*/
|
||||
export type ExtensionToWebview
|
||||
= | DocumentMessage
|
||||
@@ -157,7 +159,7 @@ export type ExtensionToWebview
|
||||
| { type: 'repoImagesChecked', id: number, images: { path: string, src?: string }[] }
|
||||
| { type: 'focusPathAsk' }
|
||||
| { type: 'callTreeCounts', version: number, counts: Record<string, number> }
|
||||
| { type: 'callTree', version: number, anchor: string, name: string, where: string, trees: CallTree[] }
|
||||
| { type: 'callTree', version: number, anchor: string, name: string, where: string, trees: CallTree[], contractMiss?: ContractMiss }
|
||||
|
||||
/**
|
||||
* edit:把 startLine..endLine 这几行整行替换成 text(扩展端给每行补回原来的缩进)
|
||||
@@ -184,6 +186,7 @@ export type ExtensionToWebview
|
||||
* checkRepoLinks:预览里这批仓库路径问哪些文件或目录没有,这批不带路径的引用(symbols)问哪些找不到。id 标出是哪一次问
|
||||
* checkRepoImages:预览里这批仓库图片,问哪些文件在,在的要预览里能直接用的地址。id 标出是哪一次问
|
||||
* openCallTree:打开 anchor 那块的调用树。version 是这块所在的文档版本,对不上就不查
|
||||
* goToCallNode:点了调用树上的一个节点,打开 uri 那个文件,跳到 line 行 character 列(都从 0 起,见 CallTreeNode.jump)
|
||||
*/
|
||||
export type WebviewToExtension
|
||||
= | { type: 'ready' }
|
||||
@@ -208,3 +211,4 @@ export type WebviewToExtension
|
||||
| { type: 'checkRepoLinks', id: number, paths: string[], symbols: string[] }
|
||||
| { type: 'checkRepoImages', id: number, paths: string[] }
|
||||
| { type: 'openCallTree', version: number, anchor: string }
|
||||
| { type: 'goToCallNode', uri: string, line: number, character: number }
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { CustomTextEditorProvider, Disposable, DocumentSymbol, Event, TextDocument, TextDocumentShowOptions, WebviewPanel } from 'vscode'
|
||||
import type { ClaudeProfile } from '../../cc/profiles'
|
||||
import type { ClaudeImage } from '../../cc/spawnClaude'
|
||||
import type { IndexFind } from '../callTree/endpoint'
|
||||
import type { CommentEdit, RewriteOutcome, WriteResult } from '../commentRewrite'
|
||||
import type { BlockKind, LocalSymbol, RuleLocation, RuleReference, SourceRange, WorkspaceIndex } from '../contract'
|
||||
import type { BlockKind, LocalSymbol, RuleLocation, RuleReference, SourceRange } from '../contract'
|
||||
import type { DiffBase } from '../diff/diffBase'
|
||||
import type { OldDocument, SentDocument } from '../diff/previewDiff'
|
||||
import type { WorkspaceEntries } from '../entries/workspaceEntries'
|
||||
@@ -12,7 +13,6 @@ import type { CodeReaderRegistry } from '../registry'
|
||||
import type { LookupSources } from '../ruleLookups'
|
||||
import type { TreeSitterRuntime } from '../runtime'
|
||||
import type { ImportedName, LinkTarget, SymbolNode } from '../symbolLinks'
|
||||
import type { IndexedEntry } from '../workspaceIndex'
|
||||
import type { BlockFilter } from './blockFilter'
|
||||
import type { FoundLocation } from './definitions'
|
||||
import type { DefinitionPeek, ExtensionToWebview, Occurrence, Reveal, WebviewToExtension } from './messages'
|
||||
@@ -23,7 +23,7 @@ import { commands, EndOfLine, Position, Range, Uri, window, workspace, Workspace
|
||||
import { logger } from '../../logging/logger'
|
||||
import { webviewHtml, webviewUiRoot } from '../../webview/html'
|
||||
import { DocumentCallees } from '../calleeKinds'
|
||||
import { loadCallEdges } from '../callTree/query'
|
||||
import { loadBlockCalls } from '../callTree/query'
|
||||
import { CallTreeSession } from '../callTree/session'
|
||||
import { findBlock, rewriteBlockComment } from '../commentRewrite'
|
||||
import { PreviewDiff } from '../diff/previewDiff'
|
||||
@@ -82,8 +82,8 @@ export class PreviewEditorProvider implements CustomTextEditorProvider {
|
||||
readonly qa: CodeQa,
|
||||
/** 工作区里别的文件定义的、原名叫 name 的中文名(languageId 是查的这份文档的语言) */
|
||||
readonly indexedNames: (languageId: string, name: string) => Promise<IndexedName[]>,
|
||||
/** 库规则的工作区索引里键是 key 的各项(规则查名字的定义时用,见 ruleLookups.ts) */
|
||||
readonly indexed: (index: WorkspaceIndex, key: string) => Promise<IndexedEntry[]>,
|
||||
/** 工作区索引里键是 key 的各项(规则查名字的定义时用,见 ruleLookups.ts;接口的调用树查契约和前端请求时用) */
|
||||
readonly indexed: IndexFind,
|
||||
/** 预览标差异时对比什么 */
|
||||
readonly diffBases: DiffBases,
|
||||
/** 哪些文件是项目写明的入口、预览里哪些名字的块标成入口 */
|
||||
@@ -189,7 +189,7 @@ class Preview {
|
||||
private readonly rewriteStops = new Map<string, AbortController>()
|
||||
/** 最近一次发出去的文档(版本、块树、源码):问 AI 时按块的记号在里面找那块代码,对比基准变了时拿它重新比 */
|
||||
private sent: SentDocument | undefined
|
||||
/** 函数、类落在几棵调用树里。文档发出去之后再数,不挡住第一次预览 */
|
||||
/** 能看调用树的块(函数、类、接口卡片)落在几棵调用树里。文档发出去之后再数,不挡住第一次预览 */
|
||||
private readonly callTrees = new CallTreeSession(
|
||||
message => this.post(message),
|
||||
() => {
|
||||
@@ -198,7 +198,7 @@ class Preview {
|
||||
return {
|
||||
version: this.sent.version,
|
||||
blocks: this.sent.blocks,
|
||||
load: (offset, cancelled) => loadCallEdges(this.document, offset, cancelled),
|
||||
load: (block, cancelled) => loadBlockCalls(this.document, block, this.owner.indexed, cancelled),
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -630,6 +630,9 @@ class Preview {
|
||||
case 'openCallTree':
|
||||
this.callTrees.open(msg.version, msg.anchor)
|
||||
return
|
||||
case 'goToCallNode':
|
||||
await this.goToCallNode(Uri.parse(msg.uri), new Position(msg.line, msg.character))
|
||||
return
|
||||
case 'occurrenceNavigation':
|
||||
this.owner.navigation.update(this, msg.available)
|
||||
}
|
||||
@@ -777,6 +780,17 @@ class Preview {
|
||||
await open()
|
||||
}
|
||||
|
||||
/** 点了调用树上的一个节点:打开它在的文件,滚到这一处(同 ⌘ + 点击跳到别的文件)。 */
|
||||
private async goToCallNode(uri: Uri, position: Position): Promise<void> {
|
||||
try {
|
||||
const target = await workspace.openTextDocument(uri)
|
||||
await this.openElsewhere(uri, { range: new Range(position, position), offset: target.offsetAt(position) })
|
||||
}
|
||||
catch (err) {
|
||||
logger.add({ level: 'warn', source: 'codeReader', message: `调用树里的 ${uri.toString()} 打不开:${err instanceof Error ? err.message : String(err)}` })
|
||||
}
|
||||
}
|
||||
|
||||
/** 预览里这批仓库路径,哪些文件或目录不在;这批不带路径的引用,哪些找不到。 */
|
||||
private async checkRepoLinks(id: number, paths: string[], symbols: string[]): Promise<void> {
|
||||
const root = await repoRootOf(this.document.uri.fsPath)
|
||||
|
||||
Reference in new issue
Block a user