Skip to content

Commit 161175d

Browse files
committed
Support loading detailed coverage data from GNATcoverage XML reports
1 parent 5ffc8ca commit 161175d

File tree

3 files changed

+278
-44
lines changed

3 files changed

+278
-44
lines changed

integration/vscode/ada/src/gnatcov.ts

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,17 @@ type coverage_level_type =
4444
| 'stmt+decision'
4545
| 'stmt+mcdc'
4646
| 'stmt+uc_mcdc';
47+
4748
type sources_type = {
48-
source: source_type[];
49+
source?: source_type[];
50+
'xi:include': xi_include_type[];
51+
};
52+
53+
type xi_include_type = {
54+
'@_parse': string;
55+
'@_href': string;
4956
};
57+
5058
type source_type = {
5159
'@_file': string;
5260
'@_coverage_level': coverage_level_type;
@@ -102,7 +110,34 @@ type statement_type = {
102110
'@_id': number;
103111
'@_text': string;
104112
};
113+
114+
/**
115+
*
116+
* . | No coverage obligation is attached to the line
117+
*
118+
* - | Coverage obligations attached to the line, none satisfied
119+
* ! | Coverage obligations attached to the line, some satisfied
120+
* ? | Coverage obligations attached to the line, undetermined coverage state
121+
* | (in the absence of other violations)
122+
* + | Coverage obligations attached to the line, all satisfied
123+
*
124+
* # | Zero violations in exempted region
125+
* * | One violation in exempted region
126+
* \@ | Also related to exemptions, unclear semantics
127+
*
128+
* 0 | not coverable code, only relevant in binary traces mode (no
129+
* | instrumentation) which is unsupported in VS Code
130+
*
131+
* v, \> | symbols for object level coverage which is not supported in VS
132+
* | Code. We only support source level coverage.
133+
* See
134+
* https://docs.adacore.com/gnatcoverage-docs/html/gnatcov/cov_source.html#annotated-sources-text-xcov
135+
* and
136+
* https://docs.adacore.com/gnatcoverage-docs/html/gnatcov/exemptions.html#reporting-about-coverage-exemptions
137+
* for more information.
138+
*/
105139
type coverage_type = '.' | '+' | '-' | '!' | '?' | '#' | '@' | '*' | '0' | 'v' | '>';
140+
106141
type decision_type = {
107142
src?: src_type;
108143
condition: condition_type[];
@@ -159,3 +194,40 @@ export function parseGnatcovIndexXml(path: string): CovIndex {
159194
throw Error(`Could not parse GNATcoverage report: ${path}`);
160195
}
161196
}
197+
198+
/**
199+
*
200+
* @param path - path to GNATcoverage <source-file>.xml report
201+
* @returns parsed report
202+
*/
203+
export function parseGnatcovFileXml(path: string): source_type {
204+
const fileContentAsBuffer = fs.readFileSync(path);
205+
206+
const options: Partial<X2jOptions> = {
207+
// By default the parser ignores attributes, so we set this option
208+
// to obtain attributes.
209+
ignoreAttributes: false,
210+
// This prefix is used in the JS objects resulting from the parsing
211+
// to differentiate attributes from child nodes.
212+
attributeNamePrefix: '@_',
213+
isArray: (_, jPath) => {
214+
return (['source.src_mapping.src.line'] as string[]).indexOf(jPath) !== -1;
215+
},
216+
/**
217+
* By default, attribute values are trimmed from leading and trailing
218+
* whitespace. GNATcov stores the content of source code lines in XML
219+
* attributes so we don't want to trim in order to preserve the
220+
* original content.
221+
*/
222+
trimValues: false,
223+
};
224+
const parser = new XMLParser(options);
225+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
226+
const parseResult = parser.parse(fileContentAsBuffer);
227+
if ('source' in parseResult) {
228+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
229+
return parseResult.source as source_type;
230+
} else {
231+
throw Error(`Could not parse GNATcoverage report: ${path}`);
232+
}
233+
}

0 commit comments

Comments
 (0)