✨ feat(vscode): 代码阅读的注释和函数说明按 Markdown 渲染
This commit is contained in:
1 parent
aae9012f14
commit
a53c2a6aac
18 files changed
+394
-66
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import type { Access, Defines, FactBlock, FunctionFacts, ImportFacts, ImportItem, Node, PropertyRow, Segment, SourceSpan, TextBlock, TokenRole, Translator, VariableBlock } from '../contract'
|
||||
import type { Access, Defines, FactBlock, FunctionFacts, ImportFacts, ImportItem, Markdown, Node, PreviewText, PropertyRow, Segment, SourceSpan, TextBlock, TokenRole, Translator, VariableBlock } from '../contract'
|
||||
import { commonIndent, splitLines } from '../editText'
|
||||
|
||||
/** 按所在语法节点区分译法的关键字,例如 Python 的 else:if 后「否则」,for / while 后「未中断时」。 */
|
||||
@@ -102,13 +102,15 @@ function oneLine(text: string): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* 说明文字排版:去掉行尾空白、首尾空行和共同缩进,保留换行(段落之间的空行也留着)。
|
||||
* 第一行紧跟在引号 / 注释符号后面,本来就没有缩进,不参与算共同缩进(同 PEP 257 的做法)。
|
||||
* 注释的 Markdown 原文:各个注释节点去掉注释符号后(texts)拼起来,去掉行尾空白、首尾空行和共同缩进,保留换行(段落之间的空行也留着)。
|
||||
* 只有一个节点(块注释、docstring)时第一行紧跟在引号 / 注释符号后面,本来就没有缩进,不参与算共同缩进(同 PEP 257 的做法);
|
||||
* 几条行注释连成的一块每行地位相同,第一行也算,缩进四格的代码块才留得住。
|
||||
*/
|
||||
function docText(raw: string): string {
|
||||
const [first = '', ...rest] = splitLines(raw).map(line => line.trimEnd())
|
||||
const indent = commonIndent(rest).length
|
||||
return [first.trim(), ...rest.map(line => line.slice(indent))].join('\n').replace(/^\n+|\n+$/g, '')
|
||||
function docText(texts: string[]): string {
|
||||
const lines = splitLines(texts.join('\n')).map(line => line.trimEnd())
|
||||
const quoted = texts.length === 1
|
||||
const indent = commonIndent(quoted ? lines.slice(1) : lines).length
|
||||
return lines.map((line, i) => quoted && i === 0 ? line.trim() : line.slice(indent)).join('\n').replace(/^\n+|\n+$/g, '')
|
||||
}
|
||||
|
||||
/** 模板槽位引用的子节点;注释是语法之外的节点,不占具名子节点序号。 */
|
||||
@@ -261,15 +263,14 @@ export function createZhTemplateTranslator(table: ZhTable): Translator {
|
||||
return segments
|
||||
}
|
||||
|
||||
function translateComment(block: TextBlock): Segment[] {
|
||||
function translateComment(block: TextBlock): Markdown {
|
||||
const { startIndex, endIndex } = block.header
|
||||
const root = block.node.tree.rootNode
|
||||
const nodes = block.node.type === 'comment' ? commentsWithin(root.descendantForIndex(startIndex, endIndex) ?? root, block.header) : [block.node]
|
||||
const text = nodes.map(table.commentText).join('\n').split('\n').map(line => line.trim()).filter(Boolean).join(' ')
|
||||
return text ? [{ text, role: 'comment' }] : []
|
||||
return { markdown: docText(nodes.map(table.commentText)) }
|
||||
}
|
||||
|
||||
function translate(block: TextBlock, source: string): Segment[] {
|
||||
function translate(block: TextBlock, source: string): PreviewText {
|
||||
if (block.kind === 'comment')
|
||||
return translateComment(block)
|
||||
const tokens = tokensIn(block.node, block.header, source)
|
||||
@@ -299,8 +300,8 @@ export function createZhTemplateTranslator(table: ZhTable): Translator {
|
||||
module: node => stringNodes.has(node.type) ? [segment(node.text, 'string', offsetOf(node))] : verbatim(node, source, 'type'),
|
||||
name: (node, role) => [segment(node.text, role, offsetOf(node))],
|
||||
doc: (node) => {
|
||||
const text = docText(table.commentText(node))
|
||||
return text ? [{ text, role: 'comment' }] : []
|
||||
const markdown = docText([table.commentText(node)])
|
||||
return markdown ? { markdown } : undefined
|
||||
},
|
||||
}
|
||||
switch (block.kind) {
|
||||
@@ -362,8 +363,8 @@ interface Phrases {
|
||||
module: (node: Node) => Segment[]
|
||||
/** 源码里的一个名字原样照抄、按 role 着色(函数名称)。 */
|
||||
name: (node: Node, role: TokenRole) => Segment[]
|
||||
/** 函数的说明(JSDoc、docstring):去掉注释符号、引号和共同缩进,保留换行,按注释着色;没有文字时是空的。 */
|
||||
doc: (node: Node) => Segment[]
|
||||
/** 函数的说明(JSDoc、docstring):去掉注释符号、引号和共同缩进的 Markdown 原文;没有文字时没有。 */
|
||||
doc: (node: Node) => Markdown | undefined
|
||||
}
|
||||
|
||||
const ACCESS_ZH: Record<Access, string> = { public: '公共', private: '私有', protected: '受保护' }
|
||||
@@ -416,10 +417,10 @@ function aliased(item: Segment[], alias: Node | undefined, say: Phrases): Segmen
|
||||
/** 函数:名称 / 访问级别 / 异步 / 装饰器 / 输入参数(每个参数一行:名称、类型、默认值)/ 输出参数。 */
|
||||
function functionRows(facts: FunctionFacts, say: Phrases): PropertyRow[] {
|
||||
const decorators = facts.decorators.map(say.verbatim)
|
||||
const doc = facts.doc ? say.doc(facts.doc) : []
|
||||
const doc = facts.doc && say.doc(facts.doc)
|
||||
return [
|
||||
{ label: '名称', value: facts.name ? say.name(facts.name, 'function') : [hint('匿名')] },
|
||||
...(doc.length > 0 ? [{ label: '说明', value: doc }] : []),
|
||||
...(doc ? [{ label: '说明', value: doc }] : []),
|
||||
...accessRows(facts.access),
|
||||
{ label: '异步', value: yesNo(facts.async) },
|
||||
...(decorators.length > 0 ? [{ label: '装饰器', value: joined(decorators, '\n') }] : []),
|
||||
|
||||
Reference in new issue
Block a user