@@ -11,110 +11,202 @@ import sys
1111# Tests that check for the behaviour of experimental/upcoming features, so
1212# they cannot automatically be checked.
1313EXCEPTIONAL_FILES = [
14- pathlib .Path ("test/Frontend/experimental-features-no-asserts.swift" ),
15- pathlib .Path ("test/Frontend/upcoming_feature.swift" ),
14+ pathlib .Path ("test/Frontend/experimental-features-no-asserts.swift" ),
15+ pathlib .Path ("test/Frontend/upcoming_feature.swift" ),
1616]
1717
18- FEATURE_USAGE_RE = re .compile (r"-enable-(?:experimental|upcoming)-feature (?:-Xfrontend )?([A-Za-z0-9]*)" )
18+ FEATURE_USAGE_RE = re .compile (
19+ r"-enable-(?:experimental|upcoming)-feature (?:-Xfrontend )?([A-Za-z0-9]*)"
20+ )
21+ # Be careful of not using REQUIRES or RUN with a colon after them or Lit will
22+ # pick them up.
23+ FEATURE_LIT_MARKER_RE = re .compile (r"swift_feature_([A-Za-z0-9]*)" )
1924
2025
2126def find_test_files_with_features_usage (swift_src_root ):
22- # Look for every test file in the test directories with `RUN` lines that
23- # mention `-enable-experimental-feature` or `-enable-upcoming-feature`.
24- # Be careful of not using REQUIRES or RUN with a colon after them or Lit will
25- # pick them up.
26- output = subprocess .check_output ([
27- "grep" ,
28- "--extended-regexp" ,
29- "--recursive" ,
30- "-e" ,
31- "RUN[:].*-enable-(experimental|upcoming)-feature" ,
32- "--files-with-matches" ,
33- str (swift_src_root / "test" ),
34- str (swift_src_root / "validation-test" ),
35- ], text = True )
36- return output .splitlines ()
27+ # Look for every test file in the test directories with `RUN` lines that
28+ # mention `-enable-experimental-feature` or `-enable-upcoming-feature`.
29+ # Be careful of not using REQUIRES or RUN with a colon after them or Lit will
30+ # pick them up.
31+ output = subprocess .check_output ([
32+ "grep" ,
33+ "--extended-regexp" ,
34+ "--recursive" ,
35+ "-e" ,
36+ "RUN[:].*-enable-(experimental|upcoming)-feature" ,
37+ "--files-with-matches" ,
38+ str (swift_src_root / "test" ),
39+ str (swift_src_root / "validation-test" ),
40+ ], text = True )
41+ return output .splitlines ()
42+
43+
44+ def find_test_files_with_marker_usage (swift_src_root ):
45+ # Look for every test file in the test directories with `REQUIRES` lines
46+ # that mention `swift_feature_`.
47+ # Be careful of not using REQUIRES with a colon after them or Lit will
48+ # pick them up.
49+ output = subprocess .check_output ([
50+ "grep" ,
51+ "--extended-regexp" ,
52+ "--recursive" ,
53+ "-e" ,
54+ "REQUIRES[:].*swift_feature_" ,
55+ "--files-with-matches" ,
56+ str (swift_src_root / "test" ),
57+ str (swift_src_root / "validation-test" ),
58+ ], text = True )
59+ return output .splitlines ()
3760
3861
3962def find_run_lines (test_file ):
40- output = subprocess .check_output ([
41- "grep" ,
42- "--extended-regexp" ,
43- "--no-filename" ,
44- "-e" ,
45- "RUN[:]" ,
46- str (test_file ),
47- ], text = True )
48- return output .splitlines ()
63+ output = subprocess .check_output ([
64+ "grep" ,
65+ "--extended-regexp" ,
66+ "--no-filename" ,
67+ "-e" ,
68+ "RUN[:]" ,
69+ str (test_file ),
70+ ], text = True )
71+ return output .splitlines ()
72+
73+
74+ def find_requires_lines (test_file ):
75+ output = subprocess .check_output ([
76+ "grep" ,
77+ "--extended-regexp" ,
78+ "--no-filename" ,
79+ "-e" ,
80+ "REQUIRES[:]" ,
81+ str (test_file ),
82+ ], text = True )
83+ return output .splitlines ()
4984
5085
5186def check_existing_requires (test_file , feature ):
52- returncode = subprocess .call ([
53- "grep" ,
54- "--extended-regexp" ,
55- "--quiet" ,
56- "-e" ,
57- "REQUIRES[:].*swift_feature_" + feature ,
58- str (test_file ),
59- ])
60- return returncode != 0
87+ returncode = subprocess .call ([
88+ "grep" ,
89+ "--extended-regexp" ,
90+ "--quiet" ,
91+ "-e" ,
92+ "REQUIRES[:].*swift_feature_" + feature ,
93+ str (test_file ),
94+ ])
95+ return returncode != 0
96+
97+
98+ def check_existing_feature_usage (test_file , feature ):
99+ returncode = subprocess .call ([
100+ "grep" ,
101+ "--extended-regexp" ,
102+ "--quiet" ,
103+ "-e" ,
104+ (
105+ "RUN[:].*-enable-(experimental|upcoming)-feature (-Xfrontend )?"
106+ + re .escape (feature )
107+ ),
108+ str (test_file ),
109+ ])
110+ return returncode != 0
61111
62112
63113def check_existing_error_message_checks (test_file , feature ):
64- returncode = subprocess .call ([
65- "grep" ,
66- "--extended-regexp" ,
67- "--quiet" ,
68- "-e" ,
69- "requires '-enable-(experimental|upcoming)-feature " + feature + "'" ,
70- str (test_file ),
71- ])
72- return returncode != 0
114+ returncode = subprocess .call ([
115+ "grep" ,
116+ "--extended-regexp" ,
117+ "--quiet" ,
118+ "-e" ,
119+ "requires '-enable-(experimental|upcoming)-feature " + feature + "'" ,
120+ str (test_file ),
121+ ])
122+ return returncode != 0
73123
74124
75125def check_test_file_feature_usage (test_file ):
76- run_lines = find_run_lines (test_file )
77- features = set (
78- feature
79- for line in run_lines
80- for feature in FEATURE_USAGE_RE .findall (line )
81- )
82- num_failures = 0
83- for feature in features :
84- # No warning if the necessary `REQUIRES` is already there
85- if not check_existing_requires (test_file , feature ):
86- continue
87-
88- # Some tests check for the errors themselves, so we can skip them as well
89- if not check_existing_error_message_checks (test_file , feature ):
90- continue
91-
92- # For everything else, print a warning and for an invalid exit code
93- print ("error: {}: Missing '{}: swift_feature_{}'" .format (str (test_file ), "REQUIRES" , feature ))
94- num_failures += 1
95- return num_failures == 0
126+ run_lines = find_run_lines (test_file )
127+ features = set (
128+ feature
129+ for line in run_lines
130+ for feature in FEATURE_USAGE_RE .findall (line )
131+ )
132+ num_failures = 0
133+ for feature in features :
134+ # No warning if the necessary `REQUIRES` is already there
135+ if not check_existing_requires (test_file , feature ):
136+ continue
137+
138+ # Some tests check for the errors themselves, so we can skip them as well
139+ if not check_existing_error_message_checks (test_file , feature ):
140+ continue
141+
142+ # For everything else, print a warning and add to the invalid exit code
143+ print (
144+ "error: {}: Missing '{}: swift_feature_{}'" .format (
145+ str (test_file ),
146+ "REQUIRES" ,
147+ feature
148+ )
149+ )
150+ num_failures += 1
151+ return num_failures == 0
152+
153+
154+ def check_test_file_marker_usage (test_file ):
155+ require_lines = find_requires_lines (test_file )
156+ features = set (
157+ feature
158+ for line in require_lines
159+ for feature in FEATURE_LIT_MARKER_RE .findall (line )
160+ )
161+ num_failures = 0
162+ for feature in features :
163+ # No warning if -enable-experimental/upcoming-feature is there
164+ if not check_existing_feature_usage (test_file , feature ):
165+ continue
166+
167+ # For everything else, print a warning and add to the invalid exit code
168+ print (
169+ "error: {}: Missing '-enable-experimental/upcoming-feature: {}'" .format (
170+ str (test_file ),
171+ feature
172+ )
173+ )
174+ num_failures += 1
175+ return num_failures == 0
96176
97177
98178def main ():
99- if len (sys .argv ) < 2 :
100- print ('Invalid number of arguments.' )
101- sys .exit (1 )
179+ if len (sys .argv ) < 2 :
180+ print ('Invalid number of arguments.' )
181+ sys .exit (1 )
102182
103- swift_src_root = pathlib .Path (sys .argv [1 ])
183+ swift_src_root = pathlib .Path (sys .argv [1 ])
104184
105- num_failures = 0
106- test_files_with_features_usage = find_test_files_with_features_usage (swift_src_root )
107- for test_file in test_files_with_features_usage :
108- test_file = pathlib .Path (test_file )
109- # First lets check this is not one of the exceptional files
110- if test_file .relative_to (swift_src_root ) in EXCEPTIONAL_FILES :
111- continue
185+ num_failures = 0
186+ test_files_with_features_usage = find_test_files_with_features_usage (swift_src_root )
187+ for test_file in test_files_with_features_usage :
188+ test_file = pathlib .Path (test_file )
189+ # First lets check this is not one of the exceptional files
190+ if test_file .relative_to (swift_src_root ) in EXCEPTIONAL_FILES :
191+ continue
112192
113- if not check_test_file_feature_usage (test_file ):
114- num_failures += 1
193+ if not check_test_file_feature_usage (test_file ):
194+ num_failures += 1
195+
196+ test_files_with_marker_usage = find_test_files_with_marker_usage (swift_src_root )
197+ for test_file in test_files_with_marker_usage :
198+ test_file = pathlib .Path (test_file )
199+
200+ # First lets check this is not one of the exceptional files
201+ if test_file .relative_to (swift_src_root ) in EXCEPTIONAL_FILES :
202+ continue
203+
204+ if not check_test_file_marker_usage (test_file ):
205+ num_failures += 1
206+
207+ if num_failures > 0 :
208+ sys .exit (1 )
115209
116- if num_failures > 0 :
117- sys .exit (1 )
118210
119211if __name__ == '__main__' :
120- main ()
212+ main ()
0 commit comments