Skip to content

Commit 2a434da

Browse files
Robert-Marton34Marton Robert Zsolt
andauthored
Add PMD analyzer support (#4750)
* Add PMD analyzer support to report converter --------- Co-authored-by: Marton Robert Zsolt <[email protected]>
1 parent cda7b38 commit 2a434da

File tree

7 files changed

+438
-0
lines changed

7 files changed

+438
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# -------------------------------------------------------------------------
2+
#
3+
# Part of the CodeChecker project, under the Apache License v2.0 with
4+
# LLVM Exceptions. See LICENSE for license information.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
# -------------------------------------------------------------------------
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# -------------------------------------------------------------------------
2+
#
3+
# Part of the CodeChecker project, under the Apache License v2.0 with
4+
# LLVM Exceptions. See LICENSE for license information.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
# -------------------------------------------------------------------------
8+
9+
from typing import List
10+
11+
from codechecker_report_converter.report import Report
12+
from codechecker_report_converter.report.hash import (
13+
HashType,
14+
get_report_hash,
15+
)
16+
17+
from ..analyzer_result import AnalyzerResultBase
18+
from .parser import PMDParser
19+
20+
21+
class AnalyzerResult(AnalyzerResultBase):
22+
"""Transform analyzer result of PMD JSON."""
23+
24+
TOOL_NAME = "pmd"
25+
NAME = "PMD"
26+
URL = "https://pmd.github.io/"
27+
28+
def get_reports(self, file_path: str) -> List[Report]:
29+
"""Get reports from the given PMD JSON file."""
30+
return PMDParser().get_reports(file_path)
31+
32+
def _add_report_hash(self, report: Report):
33+
report.report_hash = get_report_hash(
34+
report,
35+
HashType.PATH_SENSITIVE,
36+
)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# -------------------------------------------------------------------------
2+
#
3+
# Part of the CodeChecker project, under the Apache License v2.0 with
4+
# LLVM Exceptions. See LICENSE for license information.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
# -------------------------------------------------------------------------
8+
9+
import json
10+
import os
11+
from typing import List
12+
13+
from codechecker_report_converter.report import (
14+
BugPathEvent,
15+
Report,
16+
get_or_create_file,
17+
)
18+
19+
20+
class PMDParser:
21+
"""Parser for PMD JSON output."""
22+
23+
def __init__(self):
24+
self._file_cache = {}
25+
26+
def get_reports(self, file_path: str) -> List[Report]:
27+
reports: List[Report] = []
28+
29+
with open(file_path, "r", encoding="utf-8") as file:
30+
data = json.load(file)
31+
32+
for file_entry in data.get("files", []):
33+
filename = os.path.abspath(file_entry["filename"])
34+
35+
for violation in file_entry.get("violations", []):
36+
line = violation.get("beginline", 1)
37+
column = violation.get("begincolumn", 1)
38+
message = violation.get("description", "")
39+
checker_name = violation.get("rule", "unknown")
40+
41+
report = Report(
42+
get_or_create_file(filename, self._file_cache),
43+
line,
44+
column,
45+
message,
46+
checker_name,
47+
bug_path_events=[],
48+
)
49+
50+
report.bug_path_events.append(
51+
BugPathEvent(
52+
message,
53+
report.file,
54+
report.line,
55+
report.column,
56+
)
57+
)
58+
59+
report.category = violation.get("ruleset", "unknown")
60+
reports.append(report)
61+
62+
return reports
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
public class Main {
2+
public static void main(String[] args) {
3+
int j;
4+
if (1 == 1)
5+
j = 42;
6+
int i = 1 / 0;
7+
}
8+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>diagnostics</key>
6+
<array>
7+
<dict>
8+
<key>category</key>
9+
<string>Code Style</string>
10+
<key>check_name</key>
11+
<string>NoPackage</string>
12+
<key>description</key>
13+
<string>All classes, interfaces, enums and annotations must belong to a named package</string>
14+
<key>location</key>
15+
<dict>
16+
<key>col</key>
17+
<integer>8</integer>
18+
<key>file</key>
19+
<string>Main.java</string>
20+
<key>line</key>
21+
<integer>1</integer>
22+
</dict>
23+
<key>severity</key>
24+
<string>warning</string>
25+
</dict>
26+
<dict>
27+
<key>category</key>
28+
<string>Code Style</string>
29+
<key>check_name</key>
30+
<string>ShortClassName</string>
31+
<key>description</key>
32+
<string>Avoid short class names like Main</string>
33+
<key>location</key>
34+
<dict>
35+
<key>col</key>
36+
<integer>8</integer>
37+
<key>file</key>
38+
<string>Main.java</string>
39+
<key>line</key>
40+
<integer>1</integer>
41+
</dict>
42+
<key>severity</key>
43+
<string>warning</string>
44+
</dict>
45+
<dict>
46+
<key>category</key>
47+
<string>Code Style</string>
48+
<key>check_name</key>
49+
<string>ShortVariable</string>
50+
<key>description</key>
51+
<string>Avoid variables with short names like j</string>
52+
<key>location</key>
53+
<dict>
54+
<key>col</key>
55+
<integer>9</integer>
56+
<key>file</key>
57+
<string>Main.java</string>
58+
<key>line</key>
59+
<integer>3</integer>
60+
</dict>
61+
<key>severity</key>
62+
<string>warning</string>
63+
</dict>
64+
<dict>
65+
<key>category</key>
66+
<string>Code Style</string>
67+
<key>check_name</key>
68+
<string>ControlStatementBraces</string>
69+
<key>description</key>
70+
<string>This statement should have braces</string>
71+
<key>location</key>
72+
<dict>
73+
<key>col</key>
74+
<integer>7</integer>
75+
<key>file</key>
76+
<string>Main.java</string>
77+
<key>line</key>
78+
<integer>5</integer>
79+
</dict>
80+
<key>severity</key>
81+
<string>warning</string>
82+
</dict>
83+
<dict>
84+
<key>category</key>
85+
<string>Code Style</string>
86+
<key>check_name</key>
87+
<string>ShortVariable</string>
88+
<key>description</key>
89+
<string>Avoid variables with short names like i</string>
90+
<key>location</key>
91+
<dict>
92+
<key>col</key>
93+
<integer>9</integer>
94+
<key>file</key>
95+
<string>Main.java</string>
96+
<key>line</key>
97+
<integer>6</integer>
98+
</dict>
99+
<key>severity</key>
100+
<string>warning</string>
101+
</dict>
102+
</array>
103+
<key>files</key>
104+
<array>
105+
<string>Main.java</string>
106+
</array>
107+
<key>metadata</key>
108+
<dict>
109+
<key>generated_by</key>
110+
<dict>
111+
<key>name</key>
112+
<string>CodeChecker</string>
113+
<key>version</key>
114+
<string>x.y.z</string>
115+
</dict>
116+
</dict>
117+
</dict>
118+
</plist>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
{
2+
"formatVersion": 0,
3+
"pmdVersion": "7.20.0",
4+
"timestamp": "2026-01-01T18:18:34.271+01:00",
5+
"files": [
6+
{
7+
"filename": "Main.java",
8+
"violations": [
9+
{
10+
"beginline": 1,
11+
"begincolumn": 8,
12+
"endline": 1,
13+
"endcolumn": 13,
14+
"description": "All classes, interfaces, enums and annotations must belong to a named package",
15+
"rule": "NoPackage",
16+
"ruleset": "Code Style",
17+
"priority": 3,
18+
"externalInfoUrl": "https://docs.pmd-code.org/snapshot/pmd_rules_java_codestyle.html#nopackage"
19+
},
20+
{
21+
"beginline": 1,
22+
"begincolumn": 8,
23+
"endline": 1,
24+
"endcolumn": 13,
25+
"description": "Avoid short class names like Main",
26+
"rule": "ShortClassName",
27+
"ruleset": "Code Style",
28+
"priority": 4,
29+
"externalInfoUrl": "https://docs.pmd-code.org/snapshot/pmd_rules_java_codestyle.html#shortclassname"
30+
},
31+
{
32+
"beginline": 3,
33+
"begincolumn": 9,
34+
"endline": 3,
35+
"endcolumn": 10,
36+
"description": "Avoid variables with short names like j",
37+
"rule": "ShortVariable",
38+
"ruleset": "Code Style",
39+
"priority": 3,
40+
"externalInfoUrl": "https://docs.pmd-code.org/snapshot/pmd_rules_java_codestyle.html#shortvariable"
41+
},
42+
{
43+
"beginline": 5,
44+
"begincolumn": 7,
45+
"endline": 5,
46+
"endcolumn": 14,
47+
"description": "This statement should have braces",
48+
"rule": "ControlStatementBraces",
49+
"ruleset": "Code Style",
50+
"priority": 3,
51+
"externalInfoUrl": "https://docs.pmd-code.org/snapshot/pmd_rules_java_codestyle.html#controlstatementbraces"
52+
},
53+
{
54+
"beginline": 6,
55+
"begincolumn": 9,
56+
"endline": 6,
57+
"endcolumn": 10,
58+
"description": "Avoid variables with short names like i",
59+
"rule": "ShortVariable",
60+
"ruleset": "Code Style",
61+
"priority": 3,
62+
"externalInfoUrl": "https://docs.pmd-code.org/snapshot/pmd_rules_java_codestyle.html#shortvariable"
63+
}
64+
]
65+
}
66+
],
67+
"suppressedViolations": [],
68+
"processingErrors": [],
69+
"configurationErrors": []
70+
}

0 commit comments

Comments
 (0)