@@ -83,7 +83,7 @@ def _get_etor_value(value, prev):
8383"""
8484 validate documents meet some basic (easily detectable) requirements of code generation
8585"""
86- def _validate_doc (f , d , tags , line_num ):
86+ def _validate_doc (f , d , tags , line_num , meta ):
8787 is_iso = lambda x : re .match (r"[_a-zA-Z][_a-zA-Z0-9]{0,30}" , x )
8888
8989 def __validate_ordinal (d ):
@@ -265,7 +265,35 @@ def __validate_base(d):
265265 elif type_traits .is_properties (d ['name' ]) and not d .get ('base' , "" ).endswith ("base_properties_t" ):
266266 raise Exception ("'base' must be '%s_base_properties_t': %s" % (namespace , d ['name' ]))
267267
268- def __validate_members (d , tags ):
268+ def __validate_struct_range_members (name , members , meta ):
269+ def has_handle (members , meta ):
270+ for m in members :
271+ if type_traits .is_handle (m ):
272+ return True
273+ if type_traits .is_struct (m , meta ):
274+ return has_handle (
275+ type_traits .get_struct_members (m ['type' ]), meta )
276+ return False
277+
278+ for m in members :
279+ if param_traits .is_range (m ) and type_traits .is_handle (m ['type' ]):
280+ raise Exception (
281+ f"struct range { name } must not contain range of object handles { m ['name' ]} "
282+ )
283+ if type_traits .is_struct (m ['type' ], meta ):
284+ member_members = type_traits .get_struct_members (
285+ m ['type' ], meta )
286+ # We can't handle a range of structs with handles within a range of structs
287+ if param_traits .is_range (m ) and has_handle (
288+ member_members , meta ):
289+ raise Exception (
290+ f"struct range { m ['name' ]} is already within struct range { name } , and must not contain an object handle"
291+ )
292+ # We keep passing the original name so we can report it in
293+ # exception messages.
294+ __validate_struct_range_members (name , member_members , meta )
295+
296+ def __validate_members (d , tags , meta ):
269297 if 'members' not in d :
270298 raise Exception ("'%s' requires the following sequence of mappings: {`members`}" % d ['type' ])
271299
@@ -295,12 +323,19 @@ def __validate_members(d, tags):
295323 if d ['type' ] == 'union' and item .get ('tag' ) is None :
296324 raise Exception (prefix + f"union member { item ['name' ]} must include a 'tag' annotation" )
297325
326+ if type_traits .is_struct (item ['type' ],
327+ meta ) and param_traits .is_range (item ):
328+ member_members = type_traits .get_struct_members (
329+ item ['type' ], meta )
330+ __validate_struct_range_members (item ['name' ], member_members ,
331+ meta )
332+
298333 ver = __validate_version (item , prefix = prefix , base_version = d_ver )
299334 if ver < max_ver :
300335 raise Exception (prefix + "'version' must be increasing: %s" % item ['version' ])
301336 max_ver = ver
302337
303- def __validate_params (d , tags ):
338+ def __validate_params (d , tags , meta ):
304339 if 'params' not in d :
305340 raise Exception ("'function' requires the following sequence of mappings: {`params`}" )
306341
@@ -347,6 +382,11 @@ def __validate_params(d, tags):
347382 if not has_queue :
348383 raise Exception (prefix + "bounds must only be used on entry points which take a `hQueue` parameter" )
349384
385+ if type_traits .is_struct (item ['type' ],
386+ meta ) and param_traits .is_range (item ):
387+ members = type_traits .get_struct_members (item ['type' ], meta )
388+ __validate_struct_range_members (item ['name' ], members , meta )
389+
350390 ver = __validate_version (item , prefix = prefix , base_version = d_ver )
351391 if ver < max_ver :
352392 raise Exception (prefix + "'version' must be increasing: %s" % item ['version' ])
@@ -421,7 +461,7 @@ def __validate_union_tag(d):
421461 __validate_union_tag (d )
422462 __validate_type (d , 'name' , tags )
423463 __validate_base (d )
424- __validate_members (d , tags )
464+ __validate_members (d , tags , meta )
425465 __validate_details (d )
426466 __validate_ordinal (d )
427467 __validate_version (d )
@@ -435,7 +475,7 @@ def __validate_union_tag(d):
435475 else :
436476 __validate_name (d , 'name' , tags , case = 'camel' )
437477
438- __validate_params (d , tags )
478+ __validate_params (d , tags , meta )
439479 __validate_details (d )
440480 __validate_ordinal (d )
441481 __validate_version (d )
@@ -893,7 +933,7 @@ def parse(section, version, tags, meta, ref):
893933
894934 for i , d in enumerate (docs ):
895935 d = _preprocess (d )
896- if not _validate_doc (f , d , tags , line_nums [i ]):
936+ if not _validate_doc (f , d , tags , line_nums [i ], meta ):
897937 continue
898938
899939 d = _filter_version (d , float (version ))
0 commit comments