From adefbfd1fabe1dfeb59da7d6304bf913287be55e Mon Sep 17 00:00:00 2001 From: zjc_he Date: Fri, 10 May 2024 23:23:12 +0800 Subject: [PATCH] style(internal/parsers/clangtidy): fix naming convention --- examples/clang-tidy/sillycode | 2 +- internal/parsers/all.go | 2 +- internal/parsers/clang_tidy/formatter.go | 184 ------------------ .../{clang_tidy => clangtidy}/convert.go | 24 +-- internal/parsers/clangtidy/formatter.go | 184 ++++++++++++++++++ .../parsers/{clang_tidy => clangtidy}/meta.go | 4 +- .../{clang_tidy => clangtidy}/parser.go | 10 +- .../{clang_tidy => clangtidy}/score.go | 16 +- 8 files changed, 213 insertions(+), 213 deletions(-) delete mode 100644 internal/parsers/clang_tidy/formatter.go rename internal/parsers/{clang_tidy => clangtidy}/convert.go (84%) create mode 100644 internal/parsers/clangtidy/formatter.go rename internal/parsers/{clang_tidy => clangtidy}/meta.go (74%) rename internal/parsers/{clang_tidy => clangtidy}/parser.go (86%) rename internal/parsers/{clang_tidy => clangtidy}/score.go (79%) diff --git a/examples/clang-tidy/sillycode b/examples/clang-tidy/sillycode index a16c54c..a69a7e8 160000 --- a/examples/clang-tidy/sillycode +++ b/examples/clang-tidy/sillycode @@ -1 +1 @@ -Subproject commit a16c54c3ac3254437b8d523f1a3fa5bd3067a81a +Subproject commit a69a7e87fddaddf21fc4f9cd6774e310fa7137c1 diff --git a/internal/parsers/all.go b/internal/parsers/all.go index 64dddd9..4decc13 100644 --- a/internal/parsers/all.go +++ b/internal/parsers/all.go @@ -1,7 +1,7 @@ package parsers import ( - _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/clang_tidy" + _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/clangtidy" _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/cpplint" _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff" _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/dummy" diff --git a/internal/parsers/clang_tidy/formatter.go b/internal/parsers/clang_tidy/formatter.go deleted file mode 100644 index 2a955c3..0000000 --- a/internal/parsers/clang_tidy/formatter.go +++ /dev/null @@ -1,184 +0,0 @@ -// 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" - } -} diff --git a/internal/parsers/clang_tidy/convert.go b/internal/parsers/clangtidy/convert.go similarity index 84% rename from internal/parsers/clang_tidy/convert.go rename to internal/parsers/clangtidy/convert.go index 7bbf442..9d829dd 100644 --- a/internal/parsers/clang_tidy/convert.go +++ b/internal/parsers/clangtidy/convert.go @@ -1,5 +1,5 @@ // Referenced from https://github.com/yuriisk/clang-tidy-converter/blob/master/clang_tidy_converter/parser/clang_tidy_parser.py -package clang_tidy +package clangtidy import ( "path/filepath" @@ -49,7 +49,7 @@ func newClangMessage(filepath string, line int, column int, level Level, message } } -func LevelFromString(levelString string) Level { +func levelFromString(levelString string) Level { switch levelString { case "note": return NOTE @@ -66,12 +66,12 @@ func LevelFromString(levelString string) Level { } } -func is_ignored(line string) bool { +func isIgnored(line string) bool { IGNORE_REGEX := regexp.MustCompile("^error:.*$") return IGNORE_REGEX.MatchString(line) } -func parse_message(line string) ClangMessage { +func parseMessage(line string) ClangMessage { MESSAGE_REGEX := regexp.MustCompile(`^(?P.+):(?P\d+):(?P\d+): (?P\S+): (?P.*?)(?: \[(?P.*)\])?\n$`) regex_res := MESSAGE_REGEX.FindStringSubmatch(line) if len(regex_res) == 0 { @@ -80,7 +80,7 @@ func parse_message(line string) ClangMessage { filepath := regex_res[1] line, _ := strconv.Atoi(regex_res[2]) column, _ := strconv.Atoi(regex_res[3]) - level := LevelFromString(regex_res[4]) + level := levelFromString(regex_res[4]) message := regex_res[5] diagnostic_name := regex_res[6] @@ -97,7 +97,7 @@ func parse_message(line string) ClangMessage { } } -func group_messages(messages []ClangMessage) []ClangMessage { +func groupMessages(messages []ClangMessage) []ClangMessage { grouped_messages := make([]ClangMessage, 0) for _, message := range messages { if message.level == NOTE { @@ -109,26 +109,26 @@ func group_messages(messages []ClangMessage) []ClangMessage { return grouped_messages } -func convert_paths_to_relative(messages *[]ClangMessage, conf Conf) { +func convertPathsToRelative(messages *[]ClangMessage, conf Conf) { currentDir := conf.RootDir for i := range *messages { (*messages)[i].filepath, _ = filepath.Rel(currentDir, (*messages)[i].filepath) } } -func parse_lines(lines []string, conf Conf) []ClangMessage { +func ParseLines(lines []string, conf Conf) []ClangMessage { messages := make([]ClangMessage, 0) for _, line := range lines { - if is_ignored(string(line)) { + if isIgnored(string(line)) { continue } - message := parse_message(string(line)) + message := parseMessage(string(line)) if message.level == UNKNOWN && len(messages) > 0 { messages[len(messages)-1].detailsLines = append(messages[len(messages)-1].detailsLines, string(line)) } else { messages = append(messages, message) } } - convert_paths_to_relative(&messages, conf) - return group_messages(messages) + convertPathsToRelative(&messages, conf) + return groupMessages(messages) } diff --git a/internal/parsers/clangtidy/formatter.go b/internal/parsers/clangtidy/formatter.go new file mode 100644 index 0000000..5968eeb --- /dev/null +++ b/internal/parsers/clangtidy/formatter.go @@ -0,0 +1,184 @@ +// Referenced from https://github.com/yuriisk/clang-tidy-converter/blob/master/clang_tidy_converter/parser/clang_tidy_parser.py +package clangtidy + +import ( + "fmt" + "strings" +) + +type JsonMessage struct { + Type string `json:"type"` + CheckName 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) []JsonMessage { + formattedMessages := make([]JsonMessage, len(messages)) + for i, message := range messages { + formattedMessages[i] = formatMessage(message) + } + return formattedMessages +} + +func formatMessage(message ClangMessage) JsonMessage { + result := JsonMessage{ + Type: "issue", + CheckName: message.diagnosticName, + Description: message.message, + Content: extractContent(message), + Categories: extractCategories(message), + Location: extractLocation(message), + Trace: extractTrace(message), + Severity: extractSeverity(message), + } + return result +} + +func messagesToText(messages []ClangMessage) []string { + textLines := []string{} + for _, message := range messages { + textLines = append(textLines, fmt.Sprintf("%s:%d:%d: %s", message.filepath, message.line, message.column, message.message)) + textLines = append(textLines, message.detailsLines...) + textLines = append(textLines, messagesToText(message.children)...) + } + return textLines +} + +func extractContent(message ClangMessage) map[string]interface{} { + detailLines := "" + for _, line := range message.detailsLines { + if line == "" { + continue + } + detailLines += (line + "\n") + } + for _, line := range messagesToText(message.children) { + if line == "" { + continue + } + detailLines += (line + "\n") + } + result := map[string]interface{}{ + "body": "```\n" + detailLines + "```", + } + return result +} + +func removeDuplicates(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 extractCategories(message ClangMessage) []string { + bugriskCategory := "Bug Risk" + clarityCategory := "Clarity" + compatibilityCategory := "Compatibility" + complexityCategory := "Complexity" + duplicationCategory := "Duplication" + performanceCategory := "Performance" + securityCategory := "Security" + styleCategory := "Style" + + categories := []string{} + if strings.Contains(message.diagnosticName, "bugprone") { + categories = append(categories, bugriskCategory) + } + if strings.Contains(message.diagnosticName, "modernize") { + categories = append(categories, compatibilityCategory) + } + if strings.Contains(message.diagnosticName, "portability") { + categories = append(categories, compatibilityCategory) + } + if strings.Contains(message.diagnosticName, "performance") { + categories = append(categories, performanceCategory) + } + if strings.Contains(message.diagnosticName, "readability") { + categories = append(categories, clarityCategory) + } + if strings.Contains(message.diagnosticName, "cloexec") { + categories = append(categories, securityCategory) + } + if strings.Contains(message.diagnosticName, "security") { + categories = append(categories, securityCategory) + } + if strings.Contains(message.diagnosticName, "naming") { + categories = append(categories, styleCategory) + } + if strings.Contains(message.diagnosticName, "misc") { + categories = append(categories, styleCategory) + } + if strings.Contains(message.diagnosticName, "cppcoreguidelines") { + categories = append(categories, styleCategory) + } + if strings.Contains(message.diagnosticName, "hicpp") { + categories = append(categories, styleCategory) + } + if strings.Contains(message.diagnosticName, "simplify") { + categories = append(categories, complexityCategory) + } + if strings.Contains(message.diagnosticName, "redundant") { + categories = append(categories, duplicationCategory) + } + if strings.HasPrefix(message.diagnosticName, "boost-use-to-string") { + categories = append(categories, compatibilityCategory) + } + if len(categories) == 0 { + categories = append(categories, bugriskCategory) + } + return removeDuplicates(categories) +} + +func extractLocation(message ClangMessage) map[string]interface{} { + location := map[string]interface{}{ + "path": message.filepath, + "lines": map[string]interface{}{ + "begin": message.line, + }, + } + return location +} + +func extractOtherLocations(message ClangMessage) []map[string]interface{} { + location_list := []map[string]interface{}{} + for _, child := range message.children { + location_list = append(location_list, extractLocation(child)) + location_list = append(location_list, extractOtherLocations(child)...) + } + return location_list +} + +func extractTrace(message ClangMessage) map[string]interface{} { + result := map[string]interface{}{ + "locations": extractOtherLocations(message), + } + return result +} + +func extractSeverity(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" + } +} diff --git a/internal/parsers/clang_tidy/meta.go b/internal/parsers/clangtidy/meta.go similarity index 74% rename from internal/parsers/clang_tidy/meta.go rename to internal/parsers/clangtidy/meta.go index ea144c0..dcf7406 100644 --- a/internal/parsers/clang_tidy/meta.go +++ b/internal/parsers/clangtidy/meta.go @@ -1,8 +1,8 @@ -package clang_tidy +package clangtidy import "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" -var name = "clang-tidy" +var name = "clangtidy" func init() { stage.RegisterParser(name, &ClangTidy{}) diff --git a/internal/parsers/clang_tidy/parser.go b/internal/parsers/clangtidy/parser.go similarity index 86% rename from internal/parsers/clang_tidy/parser.go rename to internal/parsers/clangtidy/parser.go index a416b25..38940f0 100644 --- a/internal/parsers/clang_tidy/parser.go +++ b/internal/parsers/clangtidy/parser.go @@ -1,4 +1,4 @@ -package clang_tidy +package clangtidy import ( "fmt" @@ -26,8 +26,8 @@ func Parse(executorResult stage.ExecutorResult, conf Conf) stage.ParserResult { stderr := executorResult.Files["stderr"] lines := strings.SplitAfter(stdout, "\n") - messages := parse_lines(lines, conf) - formatted_messages := format(messages) + messages := ParseLines(lines, conf) + formattedMessages := Format(messages) if executorResult.Status != stage.Status(envexec.StatusAccepted) { if !((executorResult.Status == stage.Status(envexec.StatusNonzeroExitStatus)) && @@ -42,8 +42,8 @@ func Parse(executorResult stage.ExecutorResult, conf Conf) stage.ParserResult { } } return stage.ParserResult{ - Score: get_score(formatted_messages, conf), - Comment: get_comment(formatted_messages), + Score: GetScore(formattedMessages, conf), + Comment: GetComment(formattedMessages), } } diff --git a/internal/parsers/clang_tidy/score.go b/internal/parsers/clangtidy/score.go similarity index 79% rename from internal/parsers/clang_tidy/score.go rename to internal/parsers/clangtidy/score.go index 245b676..bb4c291 100644 --- a/internal/parsers/clang_tidy/score.go +++ b/internal/parsers/clangtidy/score.go @@ -1,11 +1,11 @@ -package clang_tidy +package clangtidy import ( "fmt" "strings" ) -func Contains(arr []string, element string) bool { +func contains(arr []string, element string) bool { for i := range arr { // TODO: The keyword in json report might also be an array, need to split it if strings.Contains(arr[i], element) { @@ -15,12 +15,12 @@ func Contains(arr []string, element string) bool { return false } -func get_score(json_messages []json_message, conf Conf) int { +func GetScore(json_messages []JsonMessage, conf Conf) int { fullmark := conf.Score for _, json_message := range json_messages { - keyword := json_message.Check_name + keyword := json_message.CheckName for _, match := range conf.Matches { - if Contains(match.Keyword, keyword) { + if contains(match.Keyword, keyword) { fullmark -= match.Score break } @@ -29,7 +29,7 @@ func get_score(json_messages []json_message, conf Conf) int { return fullmark } -func get_comment(json_messages []json_message) string { +func GetComment(jsonMessages []JsonMessage) string { res := "### Test results summary\n\n" keys := [...]string{ "codequality-unchecked-malloc-result", @@ -55,8 +55,8 @@ func get_comment(json_messages []json_message) string { for _, key := range keys { mapping[key] = 0 } - for _, json_message := range json_messages { - keyword := json_message.Check_name + for _, jsonMessage := range jsonMessages { + keyword := jsonMessage.CheckName flag := true for key := range mapping { if strings.Contains(keyword, key) {