JOJ3/internal/parsers/clang_tidy/formatter.go
张佳澈520370910044 09024b4c15
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
fix(internal/parsers/clang_tidy/formatter.go): remove unused code for fingerprints
2024-05-07 15:39:26 +08:00

185 lines
5.3 KiB
Go

// Referenced from https://github.com/yuriisk/clang-tidy-converter/blob/master/clang_tidy_converter/parser/clang_tidy_parser.py
package clang_tidy
import (
"fmt"
"strings"
)
type json_message struct {
Type string `json:"type"`
Check_name string `json:"check_name"`
Description string `json:"description"`
Content map[string]interface{} `json:"content"`
Categories []string `json:"categories"`
Location map[string]interface{} `json:"location"`
Trace map[string]interface{} `json:"trace"`
Severity string `json:"severity"`
}
func format(messages []ClangMessage) []json_message {
formatted_messages := make([]json_message, len(messages))
for i, message := range messages {
formatted_messages[i] = format_message(message)
}
return formatted_messages
}
func format_message(message ClangMessage) json_message {
result := json_message{
Type: "issue",
Check_name: message.diagnosticName,
Description: message.message,
Content: extract_content(message),
Categories: extract_categories(message),
Location: extract_location(message),
Trace: extract_trace(message),
Severity: extract_severity(message),
}
return result
}
func messages_to_text(messages []ClangMessage) []string {
text_lines := []string{}
for _, message := range messages {
text_lines = append(text_lines, fmt.Sprintf("%s:%d:%d: %s", message.filepath, message.line, message.column, message.message))
text_lines = append(text_lines, message.detailsLines...)
text_lines = append(text_lines, messages_to_text(message.children)...)
}
return text_lines
}
func extract_content(message ClangMessage) map[string]interface{} {
detailLines := ""
for _, line := range message.detailsLines {
if line == "" {
continue
}
detailLines += (line + "\n")
}
for _, line := range messages_to_text(message.children) {
if line == "" {
continue
}
detailLines += (line + "\n")
}
result := map[string]interface{}{
"body": "```\n" + detailLines + "```",
}
return result
}
func remove_duplicates(list []string) []string {
uniqueMap := make(map[string]bool)
for _, v := range list {
uniqueMap[v] = true
}
result := []string{}
for k := range uniqueMap {
result = append(result, k)
}
return result
}
func extract_categories(message ClangMessage) []string {
BUGRISC_CATEGORY := "Bug Risk"
CLARITY_CATEGORY := "Clarity"
COMPATIBILITY_CATEGORY := "Compatibility"
COMPLEXITY_CATEGORY := "Complexity"
DUPLICATION_CATEGORY := "Duplication"
PERFORMANCE_CATEGORY := "Performance"
SECURITY_CATEGORY := "Security"
STYLE_CATEGORY := "Style"
categories := []string{}
if strings.Contains(message.diagnosticName, "bugprone") {
categories = append(categories, BUGRISC_CATEGORY)
}
if strings.Contains(message.diagnosticName, "modernize") {
categories = append(categories, COMPATIBILITY_CATEGORY)
}
if strings.Contains(message.diagnosticName, "portability") {
categories = append(categories, COMPATIBILITY_CATEGORY)
}
if strings.Contains(message.diagnosticName, "performance") {
categories = append(categories, PERFORMANCE_CATEGORY)
}
if strings.Contains(message.diagnosticName, "readability") {
categories = append(categories, CLARITY_CATEGORY)
}
if strings.Contains(message.diagnosticName, "cloexec") {
categories = append(categories, SECURITY_CATEGORY)
}
if strings.Contains(message.diagnosticName, "security") {
categories = append(categories, SECURITY_CATEGORY)
}
if strings.Contains(message.diagnosticName, "naming") {
categories = append(categories, STYLE_CATEGORY)
}
if strings.Contains(message.diagnosticName, "misc") {
categories = append(categories, STYLE_CATEGORY)
}
if strings.Contains(message.diagnosticName, "cppcoreguidelines") {
categories = append(categories, STYLE_CATEGORY)
}
if strings.Contains(message.diagnosticName, "hicpp") {
categories = append(categories, STYLE_CATEGORY)
}
if strings.Contains(message.diagnosticName, "simplify") {
categories = append(categories, COMPLEXITY_CATEGORY)
}
if strings.Contains(message.diagnosticName, "redundant") {
categories = append(categories, DUPLICATION_CATEGORY)
}
if strings.HasPrefix(message.diagnosticName, "boost-use-to-string") {
categories = append(categories, COMPATIBILITY_CATEGORY)
}
if len(categories) == 0 {
categories = append(categories, BUGRISC_CATEGORY)
}
return remove_duplicates(categories)
}
func extract_location(message ClangMessage) map[string]interface{} {
location := map[string]interface{}{
"path": message.filepath,
"lines": map[string]interface{}{
"begin": message.line,
},
}
return location
}
func extract_other_locations(message ClangMessage) []map[string]interface{} {
location_list := []map[string]interface{}{}
for _, child := range message.children {
location_list = append(location_list, extract_location(child))
location_list = append(location_list, extract_other_locations(child)...)
}
return location_list
}
func extract_trace(message ClangMessage) map[string]interface{} {
result := map[string]interface{}{
"locations": extract_other_locations(message),
}
return result
}
func extract_severity(message ClangMessage) string {
switch message.level {
case NOTE:
return "info"
case REMARK:
return "minor"
case WARNING:
return "major"
case ERROR:
return "critical"
case FATAL:
return "blocker"
default:
return "unknown"
}
}