UNPKG

autosnippet

Version:

Extract code patterns into a knowledge base for AI coding assistants

140 lines (139 loc) 5.52 kB
/** * Go gRPC Enhancement Pack * 条件: { languages: ['go'], frameworks: ['grpc'] } * * 覆盖 gRPC Go 微服务项目: * - protobuf service 实现 * - Unimplemented*Server 嵌入 * - 流式/一元 RPC 方法 * - interceptor 链 */ import { EnhancementPack } from './EnhancementPack.js'; class GoGrpcEnhancement extends EnhancementPack { get id() { return 'go-grpc'; } get displayName() { return 'Go gRPC Enhancement'; } get conditions() { return { languages: ['go'], frameworks: ['grpc'] }; } getExtraDimensions() { return [ { id: 'go-grpc-service-scan', label: 'gRPC Service 分析', guide: 'gRPC Service 实现分析 — Protobuf 生成代码与手写代码分离、Unimplemented*Server 嵌入、一元/流式方法分布、错误码使用规范', tierHint: 2, knowledgeTypes: ['architecture', 'code-pattern'], skillWorthy: true, dualOutput: true, skillMeta: { name: 'project-go-grpc', description: 'Go gRPC service implementations, streaming patterns and error code usage (auto-generated by enhancement)', }, }, { id: 'go-grpc-interceptor-scan', label: 'gRPC Interceptor 分析', guide: 'gRPC Interceptor 链路分析 — UnaryServerInterceptor / StreamServerInterceptor 注册顺序、日志/认证/限流拦截器', tierHint: 2, knowledgeTypes: ['architecture'], skillWorthy: true, dualOutput: true, skillMeta: { name: 'project-go-grpc-interceptors', description: 'Go gRPC interceptor chain ordering and middleware patterns (auto-generated by enhancement)', }, }, ]; } getGuardRules() { return [ { ruleId: 'go-grpc-unimplemented-embed', category: 'correctness', dimension: 'file', severity: 'warning', languages: ['go'], pattern: /Unimplemented\w+Server\b/, message: 'gRPC service 应嵌入 Unimplemented*Server 以保证前向兼容(新增 RPC 方法时不会编译失败)', }, { ruleId: 'go-grpc-status-error', category: 'correctness', dimension: 'file', severity: 'info', languages: ['go'], pattern: /fmt\.Errorf|errors\.New/, message: 'gRPC handler 中应使用 status.Errorf/status.Error 返回标准 gRPC 错误码,而非 fmt.Errorf', }, ]; } detectPatterns(astSummary) { const patterns = []; // ── gRPC Service Implementations ── for (const cls of astSummary.classes || []) { if (cls.kind !== 'struct') { continue; } // Structs embedding Unimplemented*Server if (cls.embeddedTypes?.some((t) => /^Unimplemented\w+Server$/.test(t))) { patterns.push({ type: 'go-grpc-service-impl', className: cls.name, embeds: cls.embeddedTypes.filter((t) => /Unimplemented/.test(t)), line: cls.line, confidence: 0.95, }); } // Server structs (name ends with Server) if (/Server$/.test(cls.name) && (cls.fieldCount ?? 0) > 0) { patterns.push({ type: 'go-grpc-server-struct', className: cls.name, line: cls.line, confidence: 0.6, }); } } // ── gRPC Interfaces (generated *Server interfaces) ── for (const proto of astSummary.protocols || []) { if (/Server$/.test(proto.name) && !proto.name.startsWith('Unimplemented')) { patterns.push({ type: 'go-grpc-service-interface', className: proto.name, methods: proto.methods, line: proto.line, confidence: 0.8, }); } } // ── Interceptor functions ── for (const m of astSummary.methods || []) { if (!m.className && m.isExported) { const nameLower = m.name.toLowerCase(); if (nameLower.includes('interceptor') || nameLower.includes('middleware')) { patterns.push({ type: 'go-grpc-interceptor', methodName: m.name, line: m.line, confidence: 0.8, }); } } } // ── Protobuf imports ── const pbImports = (astSummary.imports || []).filter((imp) => imp.includes('/pb') || imp.includes('/proto') || imp.includes('google.golang.org/grpc')); if (pbImports.length > 0) { patterns.push({ type: 'go-grpc-proto-usage', importCount: pbImports.length, confidence: 0.85, }); } return patterns; } } export const pack = new GoGrpcEnhancement();