3
3
Parses compiler output with -fdiagnostics-format=json and checks that warnings exist
4
4
only in files that are expected to have warnings.
5
5
"""
6
- import sys
7
- from pathlib import Path
8
6
import argparse
9
7
import json
10
8
import re
9
+ import sys
10
+ from pathlib import Path
11
11
12
12
def extract_warnings_from_compiler_output (compiler_output : str ) -> list [dict ]:
13
13
"""
@@ -24,63 +24,67 @@ def extract_warnings_from_compiler_output(compiler_output: str) -> list[dict]:
24
24
try :
25
25
json_data = json .loads (array )
26
26
json_objects_in_array = [entry for entry in json_data ]
27
- compiler_warnings .extend ([entry for entry in json_objects_in_array if entry .get ('kind' ) == 'warning' ])
27
+ compiler_warnings .extend ([entry for entry in json_objects_in_array
28
+ if entry .get ('kind' ) == 'warning' ])
28
29
except json .JSONDecodeError :
29
30
continue # Skip malformed JSON
30
31
31
32
return compiler_warnings
32
33
34
+ # Create a function that returns a dictionary where the key is the file and the data is the warnings in that file
35
+ def get_warnings_by_file (warnings : list [dict ]) -> dict [str , list [dict ]]:
36
+ """
37
+ Returns a dictionary where the key is the file and the data is the warnings in that file
38
+ """
39
+ warnings_by_file = {}
40
+ for warning in warnings :
41
+ locations = warning ['locations' ]
42
+ for location in locations :
43
+ for key in ['caret' , 'start' , 'end' ]:
44
+ if key in location :
45
+ file = location [key ]['file' ]
46
+ file = file .lstrip ('./' ) # Remove leading current directory if present
47
+ if file not in warnings_by_file :
48
+ warnings_by_file [file ] = []
49
+ warnings_by_file [file ].append (warning )
50
+
51
+ return warnings_by_file
52
+
33
53
def get_unexpected_warnings (
34
54
warnings : list [dict ],
35
55
files_with_expected_warnings : set [str ],
56
+ files_with_warnings : set [str ],
36
57
) -> int :
37
58
"""
38
59
Returns failure status if warnings discovered in list of warnings are associated with a file
39
60
that is not found in the list of files with expected warnings
40
61
"""
41
62
unexpected_warnings = []
42
- for warning in warnings :
43
- locations = warning ['locations' ]
44
- for location in locations :
45
- for key in ['caret' , 'start' , 'end' ]:
46
- if key in location :
47
- file = location [key ]['file' ]
48
- file = file .lstrip ('./' ) # Remove leading curdir if present
49
- if file not in files_with_expected_warnings :
50
- unexpected_warnings .append (warning )
63
+ for file in files_with_warnings .keys ():
64
+ if file not in files_with_expected_warnings :
65
+ unexpected_warnings .extend (files_with_warnings [file ])
51
66
52
67
if unexpected_warnings :
53
68
print ("Unexpected warnings:" )
54
69
for warning in unexpected_warnings :
55
70
print (warning )
56
71
return 1
57
-
72
+
58
73
return 0
59
74
60
75
61
76
def get_unexpected_improvements (
62
77
warnings : list [dict ],
63
78
files_with_expected_warnings : set [str ],
79
+ files_with_warnings : set [str ],
64
80
) -> int :
65
81
"""
66
82
Returns failure status if there are no warnings in the list of warnings for a file
67
83
that is in the list of files with expected warnings
68
84
"""
69
-
70
- # Create set of files with warnings
71
- files_with_warnings = set ()
72
- for warning in warnings :
73
- locations = warning ['locations' ]
74
- for location in locations :
75
- for key in ['caret' , 'start' , 'end' ]:
76
- if key in location :
77
- file = location [key ]['file' ]
78
- file = file .lstrip ('./' ) # Remove leading curdir if present
79
- files_with_warnings .add (file )
80
-
81
85
unexpected_improvements = []
82
86
for file in files_with_expected_warnings :
83
- if file not in files_with_warnings :
87
+ if file not in files_with_warnings . keys () :
84
88
unexpected_improvements .append (file )
85
89
86
90
if unexpected_improvements :
@@ -143,11 +147,12 @@ def main(argv: list[str] | None = None) -> int:
143
147
}
144
148
145
149
warnings = extract_warnings_from_compiler_output (compiler_output_file_contents )
150
+ files_with_warnings = get_warnings_by_file (warnings )
146
151
147
- status = get_unexpected_warnings (warnings , files_with_expected_warnings )
152
+ status = get_unexpected_warnings (warnings , files_with_expected_warnings , files_with_warnings )
148
153
if args .fail_on_regression : exit_code |= status
149
154
150
- status = get_unexpected_improvements (warnings , files_with_expected_warnings )
155
+ status = get_unexpected_improvements (warnings , files_with_expected_warnings , files_with_warnings )
151
156
if args .fail_on_improvement : exit_code |= status
152
157
153
158
return exit_code
0 commit comments