Add 14 advanced AST analysis tools for code quality and testing
This commit is contained in:
1121
ast_advanced.go
Normal file
1121
ast_advanced.go
Normal file
File diff suppressed because it is too large
Load Diff
362
main.go
362
main.go
@@ -186,6 +186,138 @@ func main() {
|
||||
)
|
||||
mcpServer.AddTool(findGenericsTool, findGenericsHandler)
|
||||
|
||||
// Define the find_dead_code tool
|
||||
findDeadCodeTool := mcp.NewTool("find_dead_code",
|
||||
mcp.WithDescription("Find unreachable code, unused variables, and dead branches"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(findDeadCodeTool, findDeadCodeHandler)
|
||||
|
||||
// Define the find_duplicates tool
|
||||
findDuplicatesTool := mcp.NewTool("find_duplicates",
|
||||
mcp.WithDescription("Detect code duplication and similar function patterns"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
mcp.WithNumber("threshold",
|
||||
mcp.Description("Similarity threshold (0.0-1.0, default: 0.8)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(findDuplicatesTool, findDuplicatesHandler)
|
||||
|
||||
// Define the find_inefficiencies tool
|
||||
findInefficienciesTool := mcp.NewTool("find_inefficiencies",
|
||||
mcp.WithDescription("Find performance inefficiencies like string concatenation in loops"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(findInefficienciesTool, findInefficienciesHandler)
|
||||
|
||||
// Define the extract_api tool
|
||||
extractApiTool := mcp.NewTool("extract_api",
|
||||
mcp.WithDescription("Extract public API surface and detect breaking changes"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(extractApiTool, extractApiHandler)
|
||||
|
||||
// Define the generate_docs tool
|
||||
generateDocsTool := mcp.NewTool("generate_docs",
|
||||
mcp.WithDescription("Auto-generate documentation from code structure"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
mcp.WithString("format",
|
||||
mcp.Description("Output format: 'markdown' or 'json' (default: 'markdown')"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(generateDocsTool, generateDocsHandler)
|
||||
|
||||
// Define the find_deprecated tool
|
||||
findDeprecatedTool := mcp.NewTool("find_deprecated",
|
||||
mcp.WithDescription("Find deprecated usage and suggest alternatives"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(findDeprecatedTool, findDeprecatedHandler)
|
||||
|
||||
// Define the analyze_coupling tool
|
||||
analyzeCouplingTool := mcp.NewTool("analyze_coupling",
|
||||
mcp.WithDescription("Analyze package/module coupling and suggest refactoring"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(analyzeCouplingTool, analyzeCouplingHandler)
|
||||
|
||||
// Define the find_patterns tool
|
||||
findPatternsTool := mcp.NewTool("find_patterns",
|
||||
mcp.WithDescription("Find design patterns usage (singleton, factory, etc.)"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(findPatternsTool, findPatternsHandler)
|
||||
|
||||
// Define the analyze_architecture tool
|
||||
analyzeArchitectureTool := mcp.NewTool("analyze_architecture",
|
||||
mcp.WithDescription("Analyze layer violations and dependency direction"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(analyzeArchitectureTool, analyzeArchitectureHandler)
|
||||
|
||||
// Define the analyze_go_idioms tool
|
||||
analyzeGoIdiomsTool := mcp.NewTool("analyze_go_idioms",
|
||||
mcp.WithDescription("Check for idiomatic Go patterns and suggest improvements"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(analyzeGoIdiomsTool, analyzeGoIdiomsHandler)
|
||||
|
||||
// Define the find_context_usage tool
|
||||
findContextUsageTool := mcp.NewTool("find_context_usage",
|
||||
mcp.WithDescription("Analyze Context.Context usage patterns and find missing contexts"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(findContextUsageTool, findContextUsageHandler)
|
||||
|
||||
// Define the analyze_embedding tool
|
||||
analyzeEmbeddingTool := mcp.NewTool("analyze_embedding",
|
||||
mcp.WithDescription("Analyze interface and struct embedding patterns"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(analyzeEmbeddingTool, analyzeEmbeddingHandler)
|
||||
|
||||
// Define the analyze_test_quality tool
|
||||
analyzeTestQualityTool := mcp.NewTool("analyze_test_quality",
|
||||
mcp.WithDescription("Analyze test patterns, assertion quality, and mock usage"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(analyzeTestQualityTool, analyzeTestQualityHandler)
|
||||
|
||||
// Define the find_missing_tests tool
|
||||
findMissingTestsTool := mcp.NewTool("find_missing_tests",
|
||||
mcp.WithDescription("Find missing tests based on complexity and criticality"),
|
||||
mcp.WithString("dir",
|
||||
mcp.Description("Directory to search (default: current directory)"),
|
||||
),
|
||||
)
|
||||
mcpServer.AddTool(findMissingTestsTool, findMissingTestsHandler)
|
||||
|
||||
// Start the server
|
||||
if err := server.ServeStdio(mcpServer); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Server error: %v\n", err)
|
||||
@@ -493,5 +625,235 @@ func findGenericsHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal generics: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func findDeadCodeHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
deadCode, err := findDeadCode(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to find dead code: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(deadCode)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal dead code: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func findDuplicatesHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
threshold := request.GetFloat("threshold", 0.8)
|
||||
|
||||
duplicates, err := findDuplicates(dir, threshold)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to find duplicates: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(duplicates)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal duplicates: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func findInefficienciesHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
inefficiencies, err := findInefficiencies(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to find inefficiencies: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(inefficiencies)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal inefficiencies: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func extractApiHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
api, err := extractApi(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to extract API: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(api)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal API: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func generateDocsHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
format := request.GetString("format", "markdown")
|
||||
|
||||
docs, err := generateDocs(dir, format)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to generate docs: %v", err)), nil
|
||||
}
|
||||
|
||||
if format == "markdown" {
|
||||
return mcp.NewToolResultText(docs.(string)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(docs)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal docs: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func findDeprecatedHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
deprecated, err := findDeprecated(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to find deprecated: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(deprecated)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal deprecated: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func analyzeCouplingHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
coupling, err := analyzeCoupling(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to analyze coupling: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(coupling)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal coupling: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func findPatternsHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
patterns, err := findPatterns(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to find patterns: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(patterns)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal patterns: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func analyzeArchitectureHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
architecture, err := analyzeArchitecture(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to analyze architecture: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(architecture)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal architecture: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func analyzeGoIdiomsHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
idioms, err := analyzeGoIdioms(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to analyze Go idioms: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(idioms)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal idioms: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func findContextUsageHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
contextUsage, err := findContextUsage(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to find context usage: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(contextUsage)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal context usage: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func analyzeEmbeddingHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
embedding, err := analyzeEmbedding(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to analyze embedding: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(embedding)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal embedding: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func analyzeTestQualityHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
testQuality, err := analyzeTestQuality(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to analyze test quality: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(testQuality)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal test quality: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
|
||||
func findMissingTestsHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
dir := request.GetString("dir", "./")
|
||||
|
||||
missingTests, err := findMissingTests(dir)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to find missing tests: %v", err)), nil
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(missingTests)
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("failed to marshal missing tests: %v", err)), nil
|
||||
}
|
||||
|
||||
return mcp.NewToolResultText(string(jsonData)), nil
|
||||
}
|
||||
Reference in New Issue
Block a user