UNPKG

autosnippet

Version:

Extract code patterns into a knowledge base for AI coding assistants

186 lines (185 loc) 7.38 kB
/** * Go Web Enhancement Pack * 条件: { languages: ['go'], frameworks: ['gin', 'echo', 'fiber', 'chi', 'gorilla', 'beego'] } * * 覆盖所有主流 Go HTTP 框架: * - Gin, Echo, Fiber, Chi, Gorilla Mux, Beego */ import { EnhancementPack } from './EnhancementPack.js'; class GoWebEnhancement extends EnhancementPack { get id() { return 'go-web'; } get displayName() { return 'Go Web (Gin/Echo/Fiber/Chi) Enhancement'; } get conditions() { return { languages: ['go'], frameworks: ['gin', 'echo', 'fiber', 'chi', 'gorilla', 'beego'], }; } getExtraDimensions() { return [ { id: 'go-handler-scan', label: 'HTTP Handler 分析', guide: 'Go HTTP Handler 与 Middleware 链路分析 — handler 签名规范、中间件注册顺序、Context 传播、错误级联', tierHint: 2, knowledgeTypes: ['architecture', 'code-pattern'], skillWorthy: true, dualOutput: true, skillMeta: { name: 'project-go-handlers', description: 'Go HTTP handler patterns, middleware chains and context propagation (auto-generated by enhancement)', }, }, { id: 'go-route-scan', label: 'API Route 结构', guide: 'Go 路由结构分析 — 路由分组 (Group)、URI 命名规范、HTTP 方法分布、路由参数与通配符', tierHint: 2, knowledgeTypes: ['architecture'], skillWorthy: true, dualOutput: true, skillMeta: { name: 'project-go-routes', description: 'Go API route structure, grouping and URI naming conventions (auto-generated by enhancement)', }, }, ]; } getGuardRules() { return [ { ruleId: 'go-handler-abort-return', category: 'correctness', dimension: 'file', severity: 'warning', languages: ['go'], pattern: /\.Abort\w*\([^)]*\)[^}]*\n\s*[^}\s/]/, message: 'Abort/AbortWithStatus 后应立即 return,否则后续逻辑仍会执行', }, { ruleId: 'go-no-naked-goroutine', category: 'correctness', dimension: 'file', severity: 'warning', languages: ['go'], pattern: /go\s+func\s*\(/, message: 'HTTP handler 中启动 goroutine 应包含 recover() 防止 panic 导致整个进程崩溃', }, { ruleId: 'go-context-first-param', category: 'style', dimension: 'file', severity: 'info', languages: ['go'], pattern: /func\s+\w+\([^)]*\)\s*\([^)]*context\.Context/, message: 'context.Context 应作为函数的第一个参数,而非放在返回值或中间位置', }, ]; } detectPatterns(astSummary) { const patterns = []; // ── Struct-based Handler / Controller ── for (const cls of astSummary.classes || []) { if (cls.kind !== 'struct') { continue; } const nameLower = cls.name.toLowerCase(); if (nameLower.includes('handler') || nameLower.includes('controller') || nameLower.includes('server') || nameLower.includes('api')) { patterns.push({ type: 'go-handler-struct', className: cls.name, line: cls.line, confidence: 0.8, }); } } // ── HTTP Handler Interfaces ── for (const proto of astSummary.protocols || []) { if (proto.methods?.includes('ServeHTTP')) { patterns.push({ type: 'go-http-handler-interface', className: proto.name, line: proto.line, confidence: 0.95, }); } } // ── Handler / Middleware methods ── for (const m of astSummary.methods || []) { // Exported methods on structs — likely handlers if (m.className && m.isExported && !m.isClassMethod) { const nameLower = m.name.toLowerCase(); if (nameLower.startsWith('get') || nameLower.startsWith('post') || nameLower.startsWith('put') || nameLower.startsWith('delete') || nameLower.startsWith('patch') || nameLower.startsWith('handle') || nameLower.startsWith('list') || nameLower.startsWith('create') || nameLower.startsWith('update') || nameLower.startsWith('remove')) { patterns.push({ type: 'go-handler-method', className: m.className, methodName: m.name, line: m.line, confidence: 0.7, }); } } // Middleware pattern: package-level function returning HandlerFunc-like if (!m.className && m.isClassMethod && m.isExported) { const nameLower = m.name.toLowerCase(); if (nameLower.includes('middleware') || nameLower.includes('logger') || nameLower.includes('recovery') || nameLower.includes('cors') || nameLower.includes('auth') || nameLower.includes('ratelimit') || nameLower.includes('timeout')) { patterns.push({ type: 'go-middleware', methodName: m.name, line: m.line, confidence: 0.75, }); } } } // ── Engine / Router struct (framework core) ── for (const cls of astSummary.classes || []) { if (cls.kind !== 'struct') { continue; } if (/^(?:Engine|Router|App|Server|Mux|Group)$/.test(cls.name)) { patterns.push({ type: 'go-router-core', className: cls.name, line: cls.line, confidence: 0.85, }); } } // ── Concurrency in web context ── // goroutine + channel patterns from lang-go.js for (const p of astSummary.patterns || []) { if (p.type === 'goroutine' && (p.count ?? 0) > 0) { patterns.push({ type: 'go-web-concurrency', goroutineCount: p.count, confidence: 0.7, }); } } return patterns; } } export const pack = new GoWebEnhancement();