✨ feat(vscode): 代码阅读的注释挂到它讲的代码块上成「注释」一行,重写注释改用技能一句话加结构化结果
- 普通注释不再单独成卡片:同一层挂到后面最近的块(隔空行也算),后面没有挂到前面那块,整层没代码挂到父块;只有文件开头隔着空行的注释、模块 docstring、//!、@file 单独成「文件开头的说明」 - 各语言(Python、TypeScript、Rust、Shell、Dockerfile)建好树后统一调 attachComments;块的编辑范围连着挂上的注释,差异、跳转、钉住卡片都按它 - 宿主统一给每张卡片(语言卡片、翻译插件的属性表、库规则卡片、一行译文的语句卡片)插「注释」一行,排在名称、说明后面 - TypeScript 的 JSDoc 也能当常量、变量的说明;sqlx、React 不再单独处理前面的注释 - 「重写注释」每块都有:提示只发 /ecc:writing-code-comments 路径:起-止,模型只读、按 --json-schema 交 body,没交结构化正文就失败不写;扩展换掉块前面的注释或在块上面新写一段
This commit is contained in:
1 parent
335cf9ca9f
commit
582ac4c987
49 files changed
+1730
-757
No files matched your search
@@ -4,9 +4,12 @@ import { describe, expect, it } from 'vitest'
|
||||
import { readBlockViews, readDefinitionKind, toBlockViews } from './blockView'
|
||||
import { replaceLines } from './editText'
|
||||
import { createBashAdapter } from './languages/bash'
|
||||
import { createDockerfileAdapter } from './languages/dockerfile'
|
||||
import { createPythonAdapter } from './languages/python'
|
||||
import { createTypeScriptAdapter } from './languages/typescript'
|
||||
import { previewText, propertyLines, readFixture, runtime, WASM_DIR, withBlocks } from './testSupport'
|
||||
import { commentText, DOCKERFILE_WASM_DIR, previewText, propertyLines, readFixture, runtime, WASM_DIR, withBlocks } from './testSupport'
|
||||
import { bashZhTranslator } from './translators/bashZh'
|
||||
import { dockerfileZhTranslator } from './translators/dockerfileZh'
|
||||
import { pythonZhTranslator } from './translators/pythonZh'
|
||||
import { typescriptZhTranslator } from './translators/typescriptZh'
|
||||
|
||||
@@ -159,7 +162,8 @@ describe('blockView', () => {
|
||||
' 管理员可查看任意用户,普通用户只能查看自己。',
|
||||
' """',
|
||||
])
|
||||
expect(getUser?.children[0]).toMatchObject({ kind: 'comment', startLine: 38, endLine: 38 })
|
||||
expect(getUser?.children[0]).toMatchObject({ kind: 'if', startLine: 38, endLine: 40, headerEndLine: 39 })
|
||||
expect(commentText(getUser?.children[0])).toBe('非管理员只能查看自己')
|
||||
})
|
||||
|
||||
it('类的说明同样算在类块的头部里:JSDoc 连着中间的装饰器,docstring 连着它前面的注释', async () => {
|
||||
@@ -385,3 +389,68 @@ describe('blockView', () => {
|
||||
expect(await kind('pass')).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('卡片上的「注释」一行', () => {
|
||||
it('luffy 的 acquisition/repository.py:讲类的注释是类卡片的「注释」一行(排在名称后面),类的编辑范围、源码连着这几行', async () => {
|
||||
const source = readFixture('acquisitionRepository.py')
|
||||
const list = await views(py, 'python', pythonZhTranslator, source)
|
||||
expect(list.some(view => view.kind === 'comment')).toBe(false)
|
||||
const repo = list.find(view => view.kind === 'class')
|
||||
expect(repo).toMatchObject({ startLine: 12, headerEndLine: 20, commentRow: 1, commentTarget: { kind: 'replace', startLine: 12, endLine: 15 } })
|
||||
expect('properties' in repo! && repo.properties.map(row => row.label).slice(0, 3)).toEqual(['名称', '注释', '访问级别'])
|
||||
expect(commentText(repo)).toBe([
|
||||
'luffy_agent.user.models.User 在各方法体内按需局部导入 (非模块顶层):',
|
||||
'user 包 __init__ 会级联加载到 acquisition.service, 而 acquisition 是整个',
|
||||
'应用最早被 import 的域之一 (见 api_routers.py 的 include 顺序), 顶层导入',
|
||||
'会与该级联互相等待, 构成循环导入。',
|
||||
].join('\n'))
|
||||
expect(repo?.code.split('\n').slice(0, 7)).toEqual([
|
||||
'# luffy_agent.user.models.User 在各方法体内按需局部导入 (非模块顶层):',
|
||||
'# user 包 __init__ 会级联加载到 acquisition.service, 而 acquisition 是整个',
|
||||
'# 应用最早被 import 的域之一 (见 api_routers.py 的 include 顺序), 顶层导入',
|
||||
'# 会与该级联互相等待, 构成循环导入。',
|
||||
'',
|
||||
'',
|
||||
'class AcquisitionChannelRepository(',
|
||||
])
|
||||
expect(replaceLines(source, repo!.startLine, repo!.endLine, repo!.code)).toBe(source)
|
||||
})
|
||||
|
||||
it('说明和注释都有时排成 名称、说明、注释;几段注释是几段 Markdown;一行译文的卡片「注释」一行排在译文下面', async () => {
|
||||
const source = [
|
||||
'import { readFile } from \'node:fs/promises\'',
|
||||
'',
|
||||
'// 讲 load',
|
||||
'',
|
||||
'// 第二段',
|
||||
'/** 读出配置。 */',
|
||||
'export async function load(path: string) {',
|
||||
' // 先检查',
|
||||
' if (!path) {',
|
||||
' return null',
|
||||
' }',
|
||||
' return readFile(path)',
|
||||
'}',
|
||||
].join('\n')
|
||||
const [, load] = await views(ts, 'typescript', typescriptZhTranslator, source)
|
||||
expect('properties' in load && load.properties.map(row => row.label).slice(0, 4)).toEqual(['名称', '说明', '注释', '访问级别'])
|
||||
expect(commentText(load)).toBe('讲 load\n\n第二段')
|
||||
expect(load).toMatchObject({ startLine: 2, commentRow: 2, commentTarget: { kind: 'replace', startLine: 2, endLine: 4 } })
|
||||
const [check, returned] = load.children
|
||||
expect(check).toMatchObject({ kind: 'if', startLine: 7, commentRow: 0, rows: [{ label: '注释', value: { markdown: '先检查' } }] })
|
||||
expect(returned).toMatchObject({ kind: 'return', commentTarget: { kind: 'insert', line: 11 } })
|
||||
expect(returned).not.toHaveProperty('commentRow')
|
||||
})
|
||||
|
||||
it('嵌着的代码里的块不能写注释:没有 commentTarget', async () => {
|
||||
const shell = createBashAdapter(WASM_DIR)
|
||||
const source = 'FROM node:22\nRUN npm ci && npm run build\n'
|
||||
const { blocks } = await readBlockViews(runtime, createDockerfileAdapter(DOCKERFILE_WASM_DIR), dockerfileZhTranslator, 'dockerfile', source, {
|
||||
embedded: languageId => languageId === 'shellscript' ? { adapter: shell, translator: bashZhTranslator } : undefined,
|
||||
})
|
||||
const run = flatten(blocks).find(view => view.kind === 'run')
|
||||
expect(run?.commentTarget).toEqual({ kind: 'insert', line: 1 })
|
||||
expect(run?.children.length).toBeGreaterThan(0)
|
||||
expect(run?.children.every(step => step.commentTarget === undefined)).toBe(true)
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user