@@ -18,6 +18,9 @@ EXCEPTIONAL_FILES = [
1818FEATURE_USAGE_RE = re .compile (
1919 r"-enable-(?:experimental|upcoming)-feature (?:-Xfrontend )?([A-Za-z0-9]*)"
2020)
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]*)" )
2124
2225
2326def find_test_files_with_features_usage (swift_src_root ):
@@ -38,6 +41,24 @@ def find_test_files_with_features_usage(swift_src_root):
3841 return output .splitlines ()
3942
4043
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 ()
60+
61+
4162def find_run_lines (test_file ):
4263 output = subprocess .check_output ([
4364 "grep" ,
@@ -50,6 +71,18 @@ def find_run_lines(test_file):
5071 return output .splitlines ()
5172
5273
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 ()
84+
85+
5386def check_existing_requires (test_file , feature ):
5487 returncode = subprocess .call ([
5588 "grep" ,
@@ -62,6 +95,21 @@ def check_existing_requires(test_file, feature):
6295 return returncode != 0
6396
6497
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
111+
112+
65113def check_existing_error_message_checks (test_file , feature ):
66114 returncode = subprocess .call ([
67115 "grep" ,
@@ -103,6 +151,30 @@ def check_test_file_feature_usage(test_file):
103151 return num_failures == 0
104152
105153
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
176+
177+
106178def main ():
107179 if len (sys .argv ) < 2 :
108180 print ('Invalid number of arguments.' )
@@ -121,6 +193,17 @@ def main():
121193 if not check_test_file_feature_usage (test_file ):
122194 num_failures += 1
123195
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+
124207 if num_failures > 0 :
125208 sys .exit (1 )
126209
0 commit comments