funplus-cursor-cli
Version:
CLI工具用于自动生成Cursor项目规则
606 lines (512 loc) • 35 kB
JavaScript
import fs from 'fs-extra';
import path from 'path';
import { fileURLToPath } from 'url';
import { RULE_TYPES, RULE_APPLY_TYPES } from './constants.js';
// 获取当前文件的目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const TEMPLATES_DIR = path.resolve(__dirname, '../templates');
/**
* 生成Cursor规则文件
* @param {string} language - 项目主要编程语言
* @param {string} outputDir - 输出目录
*/
export async function generateRules(language, outputDir) {
// 确保输出目录存在
await fs.ensureDir(outputDir);
// 生成general.mdc
await generateGeneralRule(language, outputDir);
// 生成语言特定规则
await generateLanguageRule(language, outputDir);
// 生成文档规则
await generateDocumentRule(outputDir);
}
/**
* 清理内容,删除不可见字符和特殊符号,但保留空格和换行符
* @param {string} content - 原始内容
* @returns {string} 清理后的内容
*/
function sanitizeContent(content) {
// 只移除控制字符,但保留空格、制表符和换行符
content = content.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, '');
// 移除可能出现在文件末尾的特殊字符
content = content.replace(/[%\x80-\xff]+$/g, '');
// 确保内容以换行结束
if (!content.endsWith('\n')) {
content += '\n';
}
return content;
}
/**
* 生成通用规则文件
* @param {string} language - 项目主要编程语言
* @param {string} outputDir - 输出目录
*/
async function generateGeneralRule(language, outputDir) {
const templatePath = path.join(TEMPLATES_DIR, 'general.template.mdc');
const outputPath = path.join(outputDir, RULE_TYPES.GENERAL);
let content;
try {
content = await fs.readFile(templatePath, 'utf8');
} catch (error) {
// 如果模板文件不存在,使用默认模板
content = getDefaultGeneralTemplate(language);
}
// 替换模板中的变量
content = content.replace(/{LANGUAGE}/g, language);
content = content.replace(/{APPLY_TYPE}/g, RULE_APPLY_TYPES.ALWAYS);
// 清理内容
content = sanitizeContent(content);
await fs.writeFile(outputPath, content);
}
/**
* 生成语言特定规则文件
* @param {string} language - 项目编程语言
* @param {string} outputDir - 输出目录
*/
async function generateLanguageRule(language, outputDir) {
const templatePath = path.join(TEMPLATES_DIR, `${language}.template.mdc`);
const outputPath = path.join(outputDir, RULE_TYPES.LANGUAGE.replace('{lang}', language));
let content;
try {
content = await fs.readFile(templatePath, 'utf8');
} catch (error) {
// 如果特定语言模板不存在,使用默认模板
content = getDefaultLanguageTemplate(language);
}
// 替换模板中的变量
content = content.replace(/{LANGUAGE}/g, language);
content = content.replace(/{APPLY_TYPE}/g, RULE_APPLY_TYPES.AUTO_ATTACHED);
// 清理内容
content = sanitizeContent(content);
await fs.writeFile(outputPath, content);
}
/**
* 生成文档规则文件
* @param {string} outputDir - 输出目录
*/
async function generateDocumentRule(outputDir) {
const templatePath = path.join(TEMPLATES_DIR, 'document.template.mdc');
const outputPath = path.join(outputDir, RULE_TYPES.DOCUMENT);
let content;
try {
content = await fs.readFile(templatePath, 'utf8');
} catch (error) {
// 如果模板文件不存在,使用默认模板
content = getDefaultDocumentTemplate();
}
// 替换模板中的变量
content = content.replace(/{APPLY_TYPE}/g, RULE_APPLY_TYPES.ALWAYS);
// 清理内容
content = sanitizeContent(content);
await fs.writeFile(outputPath, content);
}
/**
* 获取默认通用规则模板
* @param {string} language - 项目主要编程语言
* @returns {string} 模板内容
*/
function getDefaultGeneralTemplate(language) {
return `# 项目通用规则
RuleType: {APPLY_TYPE}
## 项目描述
这是一个使用 ${language} 开发的项目。
## 通用编码规范
1. 代码应当清晰,易于阅读和维护
2. 变量和函数命名应当具有描述性
3. 应当包含必要的注释,但避免过度注释
4. 遵循DRY原则(Don't Repeat Yourself)
5. 遵循KISS原则(Keep It Simple, Stupid)
## 版本控制规范
1. 提交信息应当清晰描述变更内容
2. 较大的功能应当在单独的分支中开发
3. 合并前进行代码审查
## 项目结构
请遵循项目的目录结构组织代码。`;
}
/**
* 获取默认语言规则模板
* @param {string} language - 项目编程语言
* @returns {string} 模板内容
*/
function getDefaultLanguageTemplate(language) {
const templates = {
javascript: `# JavaScript 编码规范
RuleType: {APPLY_TYPE}
FileType: *.js,*.jsx
## 代码风格
- **ES6+语法**:使用ES6及以上语法特性,如箭头函数、解构赋值、扩展运算符等。
- **变量声明**:使用\`const\`和\`let\`声明变量,避免使用\`var\`。
- **箭头函数**:表示匿名函数时优先使用箭头函数,但注意避免在需要\`this\`上下文的场景中误用。
- **解构赋值**:在适当场景下使用解构赋值提升代码可读性,但避免过度解构导致代码晦涩。
- **模板字符串**:使用模板字符串代替字符串拼接,提升代码可读性和性能。
- **函数参数**:避免使用过多参数,必要时通过对象解构传递选项。
- **避免隐式全局变量**:确保所有变量都已声明,避免隐式创建全局变量。
## 命名规范
- **变量与函数**:使用驼峰命名法(\`camelCase\`),确保名称具有描述性,避免缩写。
- **类与组件**:使用帕斯卡命名法(\`PascalCase\`),体现其构造特性。
- **常量命名**:使用大写命名法(\`UPPER_CASE\`),所有字母大写并用下划线分隔。
- **文件与目录**:文件名使用\`kebab-case\`,目录结构清晰,模块划分明确。
- **布尔值变量**:使用\`is\`、\`has\`等前缀,体现其布尔语义。
## 代码格式
- **缩进**:使用2个空格进行缩进,确保代码对齐。
- **行长度**:每行代码最大长度不超过80个字符,过长代码进行合理换行。
- **分号使用**:语句末尾必须使用分号,避免自动分号插入带来的潜在问题。
- **空行与空格**:合理使用空行分隔逻辑块,操作符周围、括号内外使用空格提升可读性。
- **大括号**:即使单行代码,也使用大括号包裹,避免潜在错误。
## 最佳实践
- **严格比较**:使用\`===\`而非\`==\`进行比较,避免类型 coercion 带来的意外结果。
- **避免全局变量**:尽量减少全局变量的使用,使用模块化管理变量和函数。
- **Promise错误处理**:及时处理Promise的错误,避免未捕获的 rejection。
- **异步操作**:使用\`async/await\`处理异步操作,提升代码可读性和维护性。
- **防御式编程**:在函数入口对参数进行类型检查和边界条件验证。
- **性能优化**:避免不必要的计算和重复渲染,使用缓存和懒加载提升性能。
- **安全性**:对用户输入进行严格验证,避免XSS、CSRF等安全漏洞。`,
typescript: `# TypeScript 编码规范
RuleType: {APPLY_TYPE}
FileType: *.ts,*.tsx
## 类型系统
- **优先使用类型系统**:充分利用TypeScript的类型系统,避免使用\`any\`类型,尽可能使用\`unknown\`替代\`any\`。
- **函数类型注解**:所有函数参数和返回值都必须进行类型注解,包括函数重载。
- **接口定义对象结构**:使用\`interface\`定义对象结构,避免在类型声明中使用\`object\`。
- **联合类型与类型守卫**:合理使用联合类型,并配合类型守卫进行类型区分。
- **类型断言谨慎使用**:仅在确定类型安全时使用类型断言,避免滥用。
## 代码风格
- **ES6+语法**:使用ES6及以上语法特性,如箭头函数、解构赋值、扩展运算符等。
- **变量声明**:使用\`const\`和\`let\`声明变量,避免使用\`var\`。
- **解构赋值**:在适当场景下使用解构赋值提升代码可读性。
- **模板字符串**:使用模板字符串代替字符串拼接。
- **避免隐式any**:确保所有变量、函数参数和返回值都有明确的类型。
## 命名规范
- **变量与函数**:使用驼峰命名法(\`camelCase\`),确保名称具有描述性。
- **类与组件**:使用帕斯卡命名法(\`PascalCase\`),体现其构造特性。
- **接口命名**:使用帕斯卡命名法,避免使用\`I\`前缀,直接描述接口功能。
- **常量命名**:使用大写命名法(\`UPPER_CASE\`),所有字母大写并用下划线分隔。
- **文件与目录**:文件名使用\`kebab-case\`,目录结构清晰,模块划分明确。
## 代码格式
- **缩进**:使用2个空格进行缩进,确保代码对齐。
- **行长度**:每行代码最大长度不超过80个字符,过长代码进行合理换行。
- **分号使用**:语句末尾必须使用分号,避免自动分号插入带来的潜在问题。
- **空行与空格**:合理使用空行分隔逻辑块,操作符周围、括号内外使用空格提升可读性。
- **注释规范**:使用JSDoc格式为函数、类、接口等添加注释,描述其功能、参数和返回值。
## 代码组织
- **模块划分**:按照业务功能或组件划分模块,避免模块过大或过小。
- **单一职责**:每个文件、函数、类应遵循单一职责原则,确保代码可维护性。
- **导入顺序**:导入语句按字母顺序排列,分组导入时使用空行分隔不同来源的导入。
- **导出规范**:合理使用命名导出和默认导出,避免过多的默认导出导致模块结构不清晰。`,
python: `# Python 编码规范
RuleType: {APPLY_TYPE}
FileType: *.py
## 代码风格
- **遵循PEP 8**:严格遵守PEP 8编码规范,确保代码风格一致。
- **缩进**:使用4个空格进行缩进,禁止使用制表符。
- **行长度**:每行代码最大长度为79个字符,文档字符串不超过72个字符。
- **空行使用**:顶级函数和类定义用两个空行隔开,方法定义用一个空行隔开。
- **空格使用**:操作符周围、括号内外使用空格提升可读性,函数调用和定义时参数间使用空格。
- **注释规范**:使用完整的句子和正确的拼写,注释应解释代码的目的和功能。
## 命名规范
- **变量与函数**:使用小写字母和下划线命名(\`snake_case\`),确保名称具有描述性。
- **类命名**:使用大驼峰命名(\`CapWords\`),体现其构造特性。
- **常量命名**:使用大写命名(\`UPPER_CASE\`),所有字母大写并用下划线分隔。
- **非公开属性**:使用单下划线前缀(\`_single_leading_underscore\`)表示非公开的属性或方法。
- **特殊方法**:双下划线包裹(\`__double_leading_and_trailing_underscore__\`)用于特殊方法,避免自定义方法使用此格式。
## 最佳实践
- **类型注解**:使用类型注解(Python 3.6+),为函数参数和返回值提供类型提示。
- **文档字符串**:编写有意义的文档字符串(docstrings),遵循PEP 257规范。
- **推导式**:使用列表、字典推导式简化代码,但避免过于复杂的推导式。
- **上下文管理器**:使用\`with\`语句处理资源,确保资源正确释放。
- **异常处理**:使用\`try/except\`块捕获和处理异常,避免程序因未处理的异常而崩溃。
- **生成器**:合理使用生成器函数和表达式,处理大数据集或实现内存高效迭代。
## 包和模块
- **模块职责**:每个模块应有明确的职责,模块名使用短横线或小写形式。
- **避免循环导入**:通过调整模块结构或导入位置避免循环导入。
- **导入顺序**:按照标准库、第三方包、本地应用的顺序导入,同一组内的导入按字母顺序排列。
- **单一导入**:每个导入语句只导入一个模块,避免使用\`import *\`。
- **相对导入**:在包内使用相对导入,明确模块间的层级关系。`,
go: `# Go 编码规范
RuleType: {APPLY_TYPE}
FileType: *.go
## 代码风格
- **遵循官方规范**:严格遵守Go官方代码规范,确保代码风格一致。
- **代码格式化**:使用\`gofmt\`自动格式化代码,保持代码风格统一。
- **简洁性**:避免不必要的括号和分号,保持代码简洁。
- **短变量声明**:使用短变量声明(\`:=\`)进行局部变量初始化,但注意不要过度使用导致可读性下降。
- **多返回值**:利用多返回值处理错误,避免使用错误码。
## 命名规范
- **驼峰命名**:使用驼峰命名法,公开的标识符首字母大写,非公开的首字母小写。
- **包名规范**:包名使用小写单个单词,不使用下划线或大写,缩略词保持全部大写或全部小写。
- **常量与全局变量**:常量和全局变量使用大写命名,体现其不可变性。
- **接口命名**:接口名通常以\`er\`结尾,如\`Reader\`、\`Writer\`。
## 错误处理
- **显式处理**:显式处理所有错误,避免忽略错误导致程序行为异常。
- **错误包装**:使用错误包装添加上下文信息,便于定位问题。
- **避免过度嵌套**:避免过多嵌套的错误处理,使用\`if\`链或函数封装简化逻辑。
- **自定义错误**:合理定义自定义错误类型,提升错误处理的灵活性和可读性。
## 代码组织
- **按功能组织**:按功能而非类型组织代码,将相关功能的函数和类型放在一起。
- **包职责清晰**:每个包有清晰的职责边界,避免包功能过于宽泛。
- **避免导入循环**:通过合理划分包和调整导入位置避免导入循环。
- **接口抽象**:合理使用接口抽象,提升代码的可测试性和可维护性。
## 并发
- **goroutine并发**:使用goroutine实现并发,注意控制goroutine的数量避免资源耗尽。
- **channel通信**:通过channel实现通信,而非共享内存,遵循Go并发哲学。
- **生命周期管理**:妥善处理goroutine生命周期,避免泄漏,使用\`done\` channel等机制控制goroutine的启动和停止。
- **sync包使用**:合理使用\`sync\`包中的锁和等待组,但在使用锁时注意避免死锁。`,
java: `# Java 编码规范
RuleType: {APPLY_TYPE}
FileType: *.java
## 代码风格
- **遵循标准约定**:严格遵守标准 Java 代码约定,确保代码风格一致。
- **缩进与格式**:使用4个空格进行缩进,禁止使用制表符,保持代码对齐。
- **行长度**:每行代码最大长度为100个字符,过长代码进行合理换行。
- **注解使用**:使用\`@Override\`注解标记重写方法,提升代码可读性和维护性。
- **Lambda与流API**:使用Lambda表达式和流API简化代码,但避免过度使用导致代码晦涩。
- **括号与空格**:在控制结构(如\`if\`、\`for\`)中使用括号包裹条件表达式,操作符周围、括号内外使用空格提升可读性。
- **静态导入**:合理使用静态导入,但避免过多静态导入导致代码可读性下降。
## 命名规范
- **类命名**:使用大驼峰命名法(\`PascalCase\`),体现其构造特性。
- **方法与变量**:使用小驼峰命名法(\`camelCase\`),确保名称具有描述性。
- **常量命名**:使用全大写命名(\`SNAKE_CASE\`),所有字母大写并用下划线分隔。
- **包命名**:包名全部小写,使用点分隔的层次结构,避免使用单个字母作为包名。
- **布尔值变量**:使用\`is\`、\`has\`等前缀,体现其布尔语义。
- **泛型参数**:泛型参数使用单个大写字母(如\`T\`、\`E\`、\`K\`、\`V\`等)命名。
## 代码组织
- **一个类一个文件**:每个类定义单独存放在一个文件中,文件名与类名相同。
- **包内组织**:相关的类放在同一个包中,按照功能或层级进行划分。
- **避免深继承**:避免过深的继承层次,继承深度不超过3层。
- **优先组合**:优先使用组合而非继承,提升代码的灵活性和可维护性。
- **构造方法**:构造方法应初始化所有必要字段,避免出现不完整的对象状态。
- **访问修饰符**:明确指定访问修饰符,避免使用默认访问级别导致的潜在问题。
## 异常处理
- **只捕获可处理异常**:只捕获可以明确处理的异常,避免捕获过于宽泛的异常类型。
- **不忽略异常**:在\`catch\`块中必须对异常进行处理,至少记录日志,不得忽略异常。
- **受检与非受检异常**:适当使用受检异常和非受检异常,受检异常用于必须由调用者处理的异常情况。
- **捕获具体异常**:捕获最具体的异常类型,避免捕获过于宽泛的异常导致潜在问题。
- **异常链**:在抛出新的异常时,保留原始异常作为原因,便于后续调试和问题定位。
- **资源管理**:使用\`try-with-resources\`语句管理资源,确保资源正确释放。`,
csharp: `# C# 编码规范
RuleType: {APPLY_TYPE}
FileType: *.cs
## 代码风格
- **命名空间组织**:使用有意义的命名空间组织代码,反映项目结构,避免过深的嵌套命名空间。
- **缩进与格式**:使用4个空格进行缩进,保持代码对齐,避免使用制表符。
- **花括号风格**:开括号位于语句同行,闭括号位于新行,保持代码块清晰。
- **异步编程**:优先使用\`async/await\`模式进行异步编程,避免直接使用\`Task\`对象,确保异步方法返回\`Task\`或\`ValueTask\`。
- **LINQ使用**:合理使用LINQ提高代码可读性和简洁性,但避免过度复杂的LINQ表达式,必要时分解为多个步骤。
- **字符串格式化**:使用字符串插值(\`$"{}\`\)代替字符串格式化(\`string.Format\`),提升代码可读性。
- **语言特性**:利用最新C#语言特性,如属性表达式、模式匹配、记录类型等,提高代码简洁性和安全性。
- **空合并运算符**:使用空合并运算符(\`??\`)和 null 条件运算符(\`?.\`)简化空值处理。
- **只读属性**:使用\`get\`仅访问器的属性表示只读数据,提升代码安全性。
## 命名规范
- **类型和成员**:使用Pascal命名法(\`PascalCase\`)命名所有类型和成员,确保名称具有描述性。
- **参数和变量**:使用驼峰命名法(\`camelCase\`)命名参数和局部变量,避免使用单字母变量名。
- **接口命名**:接口使用\`I\`前缀,如\`IDisposable\`,避免使用过长的接口名称。
- **私有字段**:私有字段使用小驼峰命名,前缀下划线(\`_camelCase\`),但避免过多私有字段。
- **常量命名**:常量使用Pascal命名法,避免全大写,体现其不可变性。
- **枚举命名**:枚举值使用Pascal命名法,单数名称表示枚举类型,不使用前缀或后缀,避免枚举值过多。
- **事件命名**:事件使用\`PascalCase\`命名,并以\`Changed\`、\`Completed\`等后缀表示事件语义。
## 代码组织
- **文件组织**:每个文件包含一个主要类,文件名与类名匹配,避免一个文件包含多个类。
- **区域划分**:避免使用\`#region\`,通过合理的类结构和方法分解替代,保持代码清晰。
- **访问修饰符**:总是显式指定访问修饰符,避免使用默认可见性,明确类和成员的访问级别。
- **依赖注入**:使用依赖注入管理对象依赖,避免直接实例化依赖项,提升代码的可测试性和可维护性。
- **内部结构**:类成员顺序:常量、静态成员、实例字段、构造函数、属性、方法,保持代码结构一致。
- **方法长度**:方法应保持简短,避免过长的方法,必要时分解为多个小方法。
## 最佳实践
- **空值处理**:使用\`null\`检查或者可空引用类型(\`?.\`)防止空引用异常,避免不必要的空值异常。
- **异常处理**:只捕获预期的具体异常,避免捕获\`Exception\`,确保日志记录,避免异常被忽略。
- **资源管理**:使用\`using\`语句或\`using\`声明确保资源正确释放,避免资源泄漏。
- **代码重用**:通过扩展方法、基类或接口促进代码重用,避免复制粘贴代码,提升代码质量。
- **单元测试**:编写单元测试验证功能正确性,使用AAA(Arrange-Act-Assert)模式组织测试,确保测试覆盖。
- **性能优化**:避免不必要的装箱和拆箱,使用\`Span<T>\`等类型提升性能,避免性能瓶颈。
- **安全性**:对用户输入进行严格验证,避免SQL注入、XSS等安全漏洞,使用参数化查询。`,
cpp: `# C++ 编码规范
RuleType: {APPLY_TYPE}
FileType: *.cpp,*.cxx,*.cc,*.h,*.hpp,*.hxx
## 代码风格
- **缩进格式**:使用4个空格进行缩进,不使用制表符,保持代码对齐。
- **命名空间**:所有代码应在命名空间内,避免污染全局命名空间,命名空间名称应具有描述性。
- **花括号**:左花括号位于声明同行,右花括号独占一行,保持代码块清晰。
- **空白使用**:运算符前后、括号内外使用空格增强可读性,提升代码的可读性和维护性。
- **行长限制**:单行代码不超过100个字符,超长代码适当换行,避免水平滚动。
- **头文件保护**:使用\`#pragma once\`或传统的防重复包含宏保护头文件,避免头文件重复包含。
- **预处理器缩进**:预处理器指令在行首,不使用缩进,避免预处理器指令与代码块混淆。
## 命名规范
- **文件命名**:使用小写字母和下划线,如\`my_class.h\`、\`my_class.cpp\`,体现文件内容。
- **类型命名**:使用大驼峰命名法(\`PascalCase\`),如\`MyClass\`,避免过长的类型名称。
- **变量命名**:使用小驼峰或下划线分隔,如\`myVariable\`或\`my_variable\`,确保名称具有描述性。
- **常量命名**:使用\`kPascalCase\`或全大写\`SNAKE_CASE\`,体现其不可变性。
- **函数名**:使用大驼峰或小驼峰,如\`MyFunction\`或\`myFunction\`,根据团队约定统一风格。
- **成员变量**:私有成员变量使用尾部下划线,如\`myVariable_\`,区分成员变量与局部变量。
- **宏命名**:宏名全部大写,用下划线分隔,如\`MY_MACRO\`,避免与普通变量混淆。
## 内存管理
- **智能指针**:优先使用智能指针(\`unique_ptr\`、\`shared_ptr\`)管理资源,避免裸指针,提升资源管理安全性。
- **RAII原则**:遵循RAII原则,使用对象生命周期管理资源,避免手动资源管理,减少资源泄漏风险。
- **内存泄漏**:避免内存泄漏,确保所有动态分配的内存被正确释放,使用工具检测内存问题。
- **所有权明确**:明确对象所有权,避免悬垂指针和重复释放,通过智能指针的语义明确资源归属。
- **内存对齐**:注意特殊结构的内存对齐要求,优化访问性能,避免因对齐问题导致的性能损失。
## 错误处理
- **异常使用**:明确异常策略,在合适场景下使用异常处理错误,避免滥用异常影响性能。
- **错误码返回**:当不使用异常时,使用统一的错误码枚举或返回值,便于错误处理和统一管理。
- **资源释放**:在异常发生时确保所有资源正确释放,避免泄漏,使用RAII辅助资源管理。
- **异常安全**:编写异常安全的代码,满足基本、强或无异常保证,确保程序在异常情况下的稳定性。
- **不变量维护**:即使在错误处理中也要维护对象不变量,保持对象状态的一致性。
## 现代C++特性
- **型别推导**:适当使用\`auto\`简化代码,但避免损害可读性,确保类型清晰。
- **初始化列表**:使用统一初始化语法\`{}\`初始化变量和对象,提升代码一致性。
- **移动语义**:实现移动构造函数和移动赋值运算符提高性能,优化资源管理。
- **Lambda表达式**:使用lambda表达式简化代码,但控制复杂度,避免lambda过于臃肿。
- **标准库使用**:优先使用STL算法和容器,避免重新发明轮子,提升开发效率和代码质量。
- **并发支持**:使用\`<thread>\`、\`<mutex>\`等标准库组件支持并发编程,避免使用平台特定的API。`,
php: `# PHP 编码规范
RuleType: {APPLY_TYPE}
FileType: *.php
## 代码风格
- **PSR标准**:严格遵循PSR-1和PSR-12编码标准,保持代码风格一致性。
- **缩进格式**:使用4个空格进行缩进,不使用制表符,保持代码对齐。
- **行长度**:每行代码不超过120个字符,超长代码适当换行,提升可读性。
- **命名空间**:所有类都应该在命名空间下,遵循PSR-4自动加载规范,避免污染全局命名空间。
- **花括号位置**:控制结构的左花括号与声明在同一行,右花括号独占一行,保持代码块清晰。
- **PHP标签**:只使用\`<?php\`和\`<?=\`,不使用短标签,避免关闭标签\`?>\`,防止意外输出。
- **字符串引号**:字符串使用单引号,需要变量插值或转义时使用双引号,提升性能和可读性。
- **空格使用**:运算符前后、括号内外使用空格增强可读性,函数调用与参数间保持一致的间距。
## 命名规范
- **类与接口**:使用大驼峰命名法(\`PascalCase\`),如\`MyClass\`,接口以\`Interface\`结尾。
- **方法与函数**:使用小驼峰命名法(\`camelCase\`),如\`myFunction\`,私有方法可以加下划线前缀。
- **变量命名**:使用小驼峰命名法,确保名称具有描述性,避免使用单字母变量名。
- **常量命名**:使用全大写下划线分隔(\`SNAKE_CASE\`),如\`MY_CONSTANT\`,体现其不可变性。
- **属性命名**:属性使用小驼峰命名法,私有属性可以以下划线开头,避免与公共属性混淆。
- **函数参数**:使用小驼峰命名法,参数名应当具有描述性,避免模糊不清的参数名。
- **布尔型变量**:使用\`is\`、\`has\`、\`can\`等前缀,体现其布尔语义,提升代码可读性。
## 代码组织
- **文件组织**:每个类应放在单独的文件中,文件名与类名匹配,便于管理和维护。
- **声明顺序**:类中成员的顺序:常量、属性、构造函数、方法,保持代码结构一致。
- **可见性**:总是显式声明方法和属性的可见性(\`public\`、\`protected\`、\`private\`),避免使用默认可见性。
- **类型声明**:PHP 7.0+项目应当使用类型声明,增强代码可读性和安全性,包括参数类型和返回类型。
- **依赖注入**:通过构造函数注入依赖,减少类之间的耦合,提升代码的可测试性和可维护性。
- **Trait使用**:合理使用Trait复用代码,但避免过度使用导致代码结构混乱。
- **文件头部注释**:每个文件应包含版权信息和简要描述,便于追踪和管理。
## 最佳实践
- **错误处理**:使用异常处理错误,避免返回错误码或特殊值,确保错误能够被正确捕获和处理。
- **安全性**:防止SQL注入、XSS攻击和CSRF攻击,总是验证和过滤用户输入,使用参数化查询和ORM。
- **配置**:不要在代码中硬编码配置,使用环境变量或配置文件,便于部署和维护。
- **面向对象**:遵循SOLID原则,编写可维护和可扩展的面向对象代码,避免过大的类和方法。
- **避免全局**:避免使用全局变量、函数和常量,优先使用命名空间,减少全局污染和命名冲突。
- **性能优化**:避免不必要的计算和重复渲染,使用缓存和懒加载提升性能,优化数据库查询。
- **日志记录**:合理使用日志记录,帮助调试和监控应用运行状态,但避免记录敏感信息。
- **单元测试**:编写单元测试验证功能正确性,使用测试框架如PHPUnit,确保代码质量。`,
dart: `# Dart 编码规范
RuleType: {APPLY_TYPE}
FileType: *.dart
## 代码风格
- **缩进格式**:使用2个空格进行缩进,不使用制表符。
- **行长度**:行长度不超过80个字符,超长代码适当换行。
- **分号使用**:每个语句末尾必须使用分号。
- **花括号位置**:左花括号与声明放在同一行,右花括号独占一行。
- **注释风格**:使用\`///\`文档注释和\`//\`单行注释,避免使用\`/* */\`多行注释。
- **字符串引号**:优先使用单引号定义字符串,需要插值时使用双引号。
- **格式化工具**:使用\`dartfmt\`格式化代码,保持一致的代码风格。
## 命名规范
- **类与枚举**:使用大驼峰命名法(\`PascalCase\`),如\`MyClass\`。
- **变量与函数**:使用小驼峰命名法(\`camelCase\`),如\`myVariable\`。
- **常量命名**:使用小驼峰命名法,没有特殊前缀。
- **库与包名**:使用小写加下划线(\`snake_case\`),如\`dart:ui\`、\`package:flutter_test\`。
- **文件命名**:文件名使用小写加下划线(\`snake_case.dart\`)。
- **私有标识符**:使用下划线前缀(\`_privateMember\`)表示私有成员。
- **类型参数**:使用单个大写字母或大驼峰命名法,如\`T\`、\`Element\`、\`ChildType\`。
## Dart特性
- **异步编程**:使用\`async\`和\`await\`处理异步操作,避免嵌套回调。
- **空安全**:启用空安全,明确区分可空和非空类型,避免空引用异常。
- **集合字面量**:使用集合字面量创建列表、集合和映射,避免使用构造函数。
- **级联操作符**:适当使用级联操作符\`..\`简化对同一对象的连续操作。
- **可选参数**:使用命名参数提高调用清晰度,为可选参数提供默认值。
- **扩展方法**:使用扩展方法为现有类添加功能,避免修改原始类。
- **构造函数初始化**:使用初始化列表设置不可变字段,减少样板代码。
## Flutter相关
- **状态管理**:选择合适的状态管理方式(如Provider、Bloc、Redux),保持一致性。
- **Widget结构**:将复杂Widget分解为小型、可重用的组件,提高可维护性。
- **性能优化**:避免不必要的重建,使用\`const\`构造函数、\`RepaintBoundary\`和内存缓存。
- **响应式设计**:使用\`MediaQuery\`和灵活布局创建响应式UI,避免硬编码尺寸。
- **布局结构**:保持Widget树层次简洁,避免过深嵌套导致性能问题。`,
swift: `# Swift 编码规范
RuleType: {APPLY_TYPE}
FileType: *.swift
## 代码风格
- **缩进格式**:使用4个空格进行缩进,不使用制表符。
- **行长度**:每行代码不超过120个字符,超长代码适当换行。
- **大括号**:左大括号与声明同行,右大括号独占一行。
- **空白使用**:二元运算符前后使用空格,冒号后使用空格(如在字典和类型注释中)。
- **注释风格**:使用文档注释(\`///\`)生成文档,使用普通注释(\`//\`)解释实现细节。
- **分号使用**:不使用分号结束语句。
- **代码分组**:使用\`// MARK: -\`对代码进行分组,增强可读性。
## 命名规范
- **类型命名**:使用大驼峰命名法(\`PascalCase\`)命名类、结构体、枚举等。
- **变量函数**:使用小驼峰命名法(\`camelCase\`)命名变量、函数和方法。
- **常量命名**:使用小驼峰命名法,没有特定前缀。
- **协议命名**:描述能力的协议使用\`able\`、\`ible\`或\`ing\`结尾,如\`Comparable\`。
- **文件命名**:文件名应与其中主要类型名称匹配,使用大驼峰。
- **缩写规则**:常见缩写保持全大写或全小写,如\`URL\`或\`url\`。
- **私有属性**:使用小驼峰命名法,可选使用下划线前缀。
## Swift特性
- **类型推断**:当类型明确时使用类型推断,提高代码简洁性。
- **可选类型**:适当使用可选类型,但避免强制解包(\`!\`),优先使用可选链或\`if let\`/\`guard let\`。
- **闭包表达式**:利用Swift的简洁闭包语法,但避免过度简化导致可读性下降。
- **扩展使用**:使用扩展分离功能实现,遵循单一职责原则。
- **属性观察器**:适当使用\`willSet\`和\`didSet\`响应属性变化。
- **初始化方法**:提供清晰、一致的初始化方法,适当使用便利初始化方法。
- **访问控制**:明确指定访问级别,默认使用\`internal\`,限制外部访问使用\`private\`/\`fileprivate\`。
## 最佳实践
- **内存管理**:注意引用循环,使用弱引用(\`weak\`)或无主引用(\`unowned\`)解决。
- **错误处理**:使用\`do-catch\`处理错误,或使用\`try?\`处理可忽略错误。
- **函数设计**:函数应该简短且专注,遵循单一职责原则。
- **面向协议**:优先使用协议和协议扩展,而非继承实现代码重用。
- **泛型使用**:适当使用泛型创建灵活、可重用的组件。
- **命名空间**:使用嵌套类型创建命名空间,避免命名冲突。`,
// 其他语言的模板可以根据需要添加...
default: `# {LANGUAGE} 编码规范
RuleType: {APPLY_TYPE}
## 代码风格
- 遵循{LANGUAGE}社区公认的编码规范
- 使用一致的缩进和格式化规则
- 保持代码简洁清晰
## 命名规范
- 使用有意义的变量和函数名
- 遵循{LANGUAGE}常用的命名约定
## 最佳实践
- 编写简洁明了的注释
- 组织代码结构使其易于理解和维护
- 避免重复代码,提取公共功能
- 适当处理错误和异常情况`
};
// 如果有针对该语言的特定模板,则使用该模板,否则使用默认模板
return templates[language] || templates.default;
}
/**
* 获取默认文档规则模板
* @returns {string} 模板内容
*/
function getDefaultDocumentTemplate() {
return `# 文档规范
RuleType: {APPLY_TYPE}
FileType: *.md,*.txt,*.rst
## 通用文档准则
1. 文档应当清晰、简洁、准确
2. 使用标题层级组织内容
3. 重要信息应当突出显示
4. 包含必要的示例和说明
## README规范
README文件应当包含以下内容:
1. 项目简介
2. 安装说明
3. 使用方法
4. 示例代码
5. 贡献指南
6. 许可证信息
## API文档规范
API文档应当包含:
1. 函数/方法签名
2. 参数说明
3. 返回值说明
4. 错误处理
5. 使用示例`;
}