✨ feat(vscode): 代码阅读 React 组件卡片按钩子分区:状态 / 引用 / 读取的数据 / 派生值 / 副作用 / 事件处理;副作用、处理函数成子卡片放进卡片那一行下面(库规则新增把子块放进属性表某一行的机制,事件处理表点名称展开)

This commit is contained in:
cruldra committed 2026-10-03 03:11:46 +08:00
1 parent 15f3a6600d
commit ee807ec7a4
19 files changed
+1057 -56

No files matched your search

+26 -7
View File
@@ -1,5 +1,6 @@
import type { BlockView, ChangedBlock, DiffStats, DocumentDiff, RemovedView } from './types'
import { inlineText } from './segments'
import { unfoldToShow } from './viewState'
/** 页面上怎么标差异:按块 id 取改动,按层取删掉的块。基准里没有这个文件(整份新增)时不逐块标,没有它。 */
export interface DiffTree {
@@ -88,8 +89,8 @@ export function foldUnchanged(blocks: readonly BlockView[], tree: DiffTree, show
block.children.forEach(fold)
}
const kept = (block: BlockView): boolean => keep.has(block.id) || block.children.some(kept)
const visit = (list: readonly BlockView[], owner: string): void => {
const breaks = new Set((tree.removed.get(owner) ?? []).map(item => item.after))
/** 画在同一处的一串兄弟块:连着没变的折成一段 */
function visitRun(list: readonly BlockView[], breaks: ReadonlySet<string | undefined>): void {
let run: BlockView[] = []
const close = (): void => {
if (run.length > 0 && !opened.has(run[0].id)) {
@@ -113,6 +114,22 @@ export function foldUnchanged(blocks: readonly BlockView[], tree: DiffTree, show
}
close()
}
/** 一层子块:放进父卡片里的按所在的行分开折(各画在各的地方),点子行才展开的不折、只往里看改动 */
function visit(list: readonly BlockView[], owner: string): void {
const breaks = new Set((tree.removed.get(owner) ?? []).map(item => item.after))
const places = new Map<string, BlockView[]>()
for (const block of list) {
if (block.slot?.item !== undefined) {
if (tree.changes.has(block.id) || kept(block))
visit(block.children, block.id)
continue
}
const place = block.slot ? `${block.slot.row}` : ''
places.set(place, [...places.get(place) ?? [], block])
}
for (const group of places.values())
visitRun(group, breaks)
}
visit(blocks, '')
return { runs, folded }
}
@@ -120,7 +137,7 @@ export function foldUnchanged(blocks: readonly BlockView[], tree: DiffTree, show
/**
* 「上一处 / 下一处」和总览条上的一处改动:新增的最外面那块、自己改了的修改块、删掉的块,照页面上的先后。
* id 是页面上的块 id(删掉的块是 PlacedRemoved.id);from / to 是它在新文件里的行(0 起),修改块只算它自己那几行(到第一个子块之前);
* ancestors 是要展开才看得见它的各层块。
* ancestors 是要展开才看得见它的各层块和属性行(放进父卡片里的子块要展开它所在的那一行,见 unfoldToShow)。
*/
export interface ChangeStop {
id: string
@@ -133,14 +150,16 @@ export interface ChangeStop {
/** 页面上的各处改动(见 ChangeStop);hidden 里的块(被筛掉的)连同子孙不算。 */
export function changeStops(blocks: readonly BlockView[], tree: DiffTree, hidden: ReadonlySet<string>): ChangeStop[] {
const stops: ChangeStop[] = []
const visit = (list: readonly BlockView[], owner: string, ancestors: string[]): void => {
/** 一层块:owner 是父块 id(顶层 ''),ancestorsOf 给出要让某个子块看得见得展开的,removedAncestors 是这一层删掉的块要展开的 */
const visit = (list: readonly BlockView[], owner: string, ancestorsOf: (block: BlockView) => string[], removedAncestors: string[]): void => {
const removed = tree.removed.get(owner) ?? []
const removedAfter = (id: string | undefined): void => {
for (const item of removed.filter(entry => entry.after === id))
stops.push({ id: item.id, change: 'del', from: item.removed.line, to: item.removed.line, ancestors })
stops.push({ id: item.id, change: 'del', from: item.removed.line, to: item.removed.line, ancestors: removedAncestors })
}
removedAfter(undefined)
for (const block of list) {
const ancestors = ancestorsOf(block)
const change = hidden.has(block.id) ? undefined : tree.changes.get(block.id)
if (change?.change === 'add' && change.outermost)
stops.push({ id: block.id, change: 'add', from: block.startLine, to: block.endLine, ancestors })
@@ -149,11 +168,11 @@ export function changeStops(blocks: readonly BlockView[], tree: DiffTree, hidden
stops.push({ id: block.id, change: 'mod', from: block.startLine, to: own, ancestors })
}
if (change?.change === 'mod')
visit(block.children, block.id, [...ancestors, block.id])
visit(block.children, block.id, child => [...ancestors, ...unfoldToShow(block.id, child)], [...ancestors, block.id])
removedAfter(block.id)
}
}
visit(blocks, '', [])
visit(blocks, '', () => [], [])
return stops
}