@@ -165,6 +165,18 @@ def extract_inner_enums(source):
165165 for constant in body .split ("," ):
166166 constant = constant .strip ()
167167
168+ # Enum constants with a constructor argument, e.g.
169+ # x86("i686", 32)
170+ value_match = re .match (
171+ r"[A-Za-z_][A-Za-z0-9_]*\s*\(\s*\"([^\"]+)\"" ,
172+ constant ,
173+ )
174+
175+ if value_match :
176+ constants .append (value_match .group (1 ))
177+ continue
178+
179+ # Plain enum constants, e.g. LEAKS, ALL
168180 constant_match = re .match (
169181 r"([A-Z][A-Z0-9_]*)\b" ,
170182 constant ,
@@ -178,6 +190,31 @@ def extract_inner_enums(source):
178190
179191 return enums
180192
193+ def build_enum_index ():
194+ enum_index = {}
195+
196+ for path in find_java_files ():
197+ source = path .read_text (encoding = "utf-8" )
198+ enums = extract_inner_enums (source )
199+
200+ for enum_name , values in enums .items ():
201+ enum_index [enum_name ] = values
202+
203+ return enum_index
204+
205+ def extract_allowed_value_type (block ):
206+ match = re .search (
207+ r"\ballowedValueType\s*=\s*([A-Za-z_][A-Za-z0-9_]*)(?:\.([A-Za-z_][A-Za-z0-9_]*))?\.class" ,
208+ block ,
209+ )
210+
211+ if not match :
212+ return None
213+
214+ if match .group (2 ):
215+ return match .group (2 )
216+
217+ return match .group (1 )
181218
182219def extract_parameter_field_name (source , parameter_end ):
183220 match = re .match (
@@ -205,22 +242,21 @@ def find_enum_for_parameter(source, parameter_end, field_name):
205242
206243 return None
207244
208- def check_file (path ):
245+ def check_file (path , enum_index = None ):
209246 source = Path (path ).read_text (encoding = "utf-8" )
210247 violations = []
211-
212248 enums = extract_inner_enums (source )
213249
250+ if enum_index is None :
251+ enum_index = {}
252+
214253 for start , block in extract_parameter_blocks (source ):
215254 if not is_string_parameter (block ):
216255 continue
217256
218257 if re .search (r"\ballowedValues\s*=" , block ):
219258 continue
220259
221- if re .search (r"\ballowedValueType\s*=" , block ):
222- continue
223-
224260 parameter_end = start + len (block )
225261 field_name = extract_parameter_field_name (
226262 source ,
@@ -233,28 +269,51 @@ def check_file(path):
233269 field_name ,
234270 )
235271
272+ if not enum_name :
273+ enum_name = extract_allowed_value_type (block )
274+
275+ description = extract_description (block )
276+ values = extract_valid_values (description ) if description else []
277+
278+ enum_values = None
236279 if enum_name and enum_name in enums :
237- line = source [:start ].count ("\n " ) + 1
238- name = extract_parameter_name (block )
239-
240- violations .append (
241- (
242- str (path ),
243- line ,
244- enums [enum_name ],
245- name ,
280+ enum_values = enums [enum_name ]
281+ elif enum_name and enum_name in enum_index :
282+ enum_values = enum_index [enum_name ]
283+
284+ if enum_values is not None :
285+
286+ if re .search (r"\ballowedValueType\s*=" , block ):
287+ if values and values != enum_values :
288+ line = source [:start ].count ("\n " ) + 1
289+ name = extract_parameter_name (block )
290+
291+ violations .append (
292+ (
293+ str (path ),
294+ line ,
295+ enum_values ,
296+ name ,
297+ )
298+ )
299+ else :
300+ line = source [:start ].count ("\n " ) + 1
301+ name = extract_parameter_name (block )
302+
303+ violations .append (
304+ (
305+ str (path ),
306+ line ,
307+ enum_values ,
308+ name ,
309+ )
246310 )
247- )
248311
249312 continue
250313
251- description = extract_description (block )
252-
253- if not description :
314+ if re .search (r"\ballowedValueType\s*=" , block ):
254315 continue
255316
256- values = extract_valid_values (description )
257-
258317 if not values :
259318 continue
260319
@@ -269,9 +328,10 @@ def check_file(path):
269328
270329def main ():
271330 violations = []
331+ enum_index = build_enum_index ()
272332
273333 for path in find_java_files ():
274- violations .extend (check_file (path ))
334+ violations .extend (check_file (path , enum_index ))
275335
276336 if violations :
277337 print ("Missing allowedValues annotations:" )
0 commit comments