✨ feat(vscode): 代码阅读加 Celery 库规则,定时任务表里的任务名能跳到任务函数

This commit is contained in:
cruldra committed 2026-09-26 19:41:07 +08:00
1 parent 905d7845b5
commit 68104e2cba
22 files changed
+2228 -139

No files matched your search

+42 -1
View File
@@ -1,4 +1,4 @@
import type { CodeBlock, ImportFacts, LibraryRule, Node, RuleBlock, RuleContext } from './contract'
import type { CodeBlock, ImportFacts, Inline, LibraryRule, Node, PropertyItem, PropertyRow, RuleBlock, RuleContext, RuleLocation, RuleReference, RuleWorkspace, Segment } from './contract'
/** 宿主这边怎么用库规则:什么时候启用、问哪个规则、认领了之后哪些子块并进去。规则本身只经 contract 拿信息。 */
@@ -44,6 +44,14 @@ function problemOf(rule: LibraryRule, block: CodeBlock, claimed: RuleBlock): str
return `种类 id「${claimed.kind}」没以「${rule.id}.」开头`
if (claimed.absorbs.some(child => !block.children.includes(child)))
return '要并进来的块不是这块的子块'
for (const { reference, offset } of referencedSegments(claimed.rows)) {
if (reference?.rule !== rule.id)
return `引用「${reference?.key}」标的规则是「${reference?.rule}」,不是自己`
if (!rule.resolve)
return `标了引用「${reference.key}」却没给 resolve`
if (offset === undefined)
return `引用「${reference.key}」没带源码下标`
}
return undefined
}
@@ -82,3 +90,36 @@ export function absorbedRange(block: CodeBlock, absorbs: readonly CodeBlock[]):
const endRow = Math.max(block.header.endRow, ...absorbs.map(child => Math.max(child.header.endRow, child.node.endPosition.row)))
return { endRow, kept: block.children.filter(child => child.header.startRow > endRow) }
}
/** 文字里(连框里)带引用的段。 */
function referencesInText(pieces: readonly Inline[]): Segment[] {
return pieces.flatMap(piece => 'role' in piece ? (piece.reference ? [piece] : []) : referencesInText(piece.segments))
}
function referencesInItems(items: readonly PropertyItem[] | undefined): Segment[] {
return (items ?? []).flatMap(item => [...item.cells.flatMap(referencesInText), ...referencesInItems(item.items)])
}
/** 属性表里(值、各层子行的格子)带引用的段。 */
export function referencedSegments(rows: readonly PropertyRow[]): Segment[] {
return rows.flatMap(row => [...('markdown' in row.value ? [] : referencesInText(row.value)), ...referencesInItems(row.items)])
}
/**
* 查规则引用的定义:交给标它的那个规则的 resolve。规则已经注销、没给 resolve、查的时候出错,都记日志、当作没有定义,
* 预览照常不动。
*/
export async function resolveReference(reference: RuleReference, rules: readonly LibraryRule[], workspace: RuleWorkspace, report: (message: string) => void): Promise<RuleLocation[]> {
const rule = rules.find(candidate => candidate.id === reference.rule)
if (!rule?.resolve) {
report(`没有能查引用「${reference.key}」的库规则 ${reference.rule}`)
return []
}
try {
return await rule.resolve(reference.key, workspace)
}
catch (err) {
report(`库规则 ${rule.id} 查「${reference.key}」的定义时出错:${err instanceof Error ? err.message : String(err)}`)
return []
}
}