-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCheckStyleParser.js
More file actions
102 lines (83 loc) · 2.42 KB
/
Copy pathCheckStyleParser.js
File metadata and controls
102 lines (83 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { XMLParser } from "fast-xml-parser";
import { BaseParser, ReportCategory } from "./BaseParser.js";
import { ReportData, LintIssue } from "../models/ReportData.js";
/**
* Parser for CheckStyle XML format
* Used by many linters including CheckStyle (Java), PHP_CodeSniffer, etc.
*/
export class CheckStyleParser extends BaseParser {
constructor() {
super();
this.xmlParser = new XMLParser({
ignoreAttributes: false,
attributeNamePrefix: "@_",
});
}
canParse(filePath, content) {
const normalizedPath = filePath.toLowerCase();
const hasSupportedName =
this.matchesAutoPatterns(filePath) ||
normalizedPath.includes("checkstyle") ||
normalizedPath.endsWith(".xml");
const hasCheckstyleRoot = /<\s*checkstyle\b/i.test(content);
return hasSupportedName && hasCheckstyleRoot;
}
getPriority() {
return 8;
}
getCategory() {
return ReportCategory.LINT;
}
getAutoPatterns() {
return this.buildBasenamePatterns(
["checkstyle-result.xml", "checkstyle.xml"],
{ includePrefixed: true },
);
}
parse(content) {
const reportData = new ReportData();
reportData.reportType = "lint";
try {
const parsed = this.xmlParser.parse(content);
const checkstyle = parsed.checkstyle;
if (!checkstyle?.file) {
return reportData;
}
const files = Array.isArray(checkstyle.file)
? checkstyle.file
: [checkstyle.file];
for (const file of files) {
this._parseFile(file, reportData);
}
} catch (error) {
throw new Error(`Failed to parse CheckStyle XML: ${error.message}`);
}
return reportData;
}
_parseFile(file, reportData) {
const fileName = file["@_name"] || "unknown";
if (!file.error) {
return;
}
const errors = Array.isArray(file.error) ? file.error : [file.error];
for (const error of errors) {
const issue = new LintIssue({
file: fileName,
line: parseInt(error["@_line"] || 0, 10),
column: parseInt(error["@_column"] || 0, 10),
severity: this._mapSeverity(error["@_severity"]),
rule: error["@_source"] || "unknown",
message: error["@_message"] || "",
});
reportData.addLintIssue(issue);
}
}
_mapSeverity(severity) {
if (!severity) return "info";
const severityStr = String(severity).toLowerCase();
if (severityStr === "error") return "error";
if (severityStr === "warning" || severityStr === "warn") return "warning";
if (severityStr === "info" || severityStr === "information") return "info";
return "info";
}
}