@@ -83,7 +83,7 @@ def _get_etor_value(value, prev):
83
83
"""
84
84
validate documents meet some basic (easily detectable) requirements of code generation
85
85
"""
86
- def _validate_doc (f , d , tags , line_num ):
86
+ def _validate_doc (f , d , tags , line_num , meta ):
87
87
is_iso = lambda x : re .match (r"[_a-zA-Z][_a-zA-Z0-9]{0,30}" , x )
88
88
89
89
def __validate_ordinal (d ):
@@ -265,7 +265,35 @@ def __validate_base(d):
265
265
elif type_traits .is_properties (d ['name' ]) and not d .get ('base' , "" ).endswith ("base_properties_t" ):
266
266
raise Exception ("'base' must be '%s_base_properties_t': %s" % (namespace , d ['name' ]))
267
267
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 ):
269
297
if 'members' not in d :
270
298
raise Exception ("'%s' requires the following sequence of mappings: {`members`}" % d ['type' ])
271
299
@@ -295,12 +323,19 @@ def __validate_members(d, tags):
295
323
if d ['type' ] == 'union' and item .get ('tag' ) is None :
296
324
raise Exception (prefix + f"union member { item ['name' ]} must include a 'tag' annotation" )
297
325
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
+
298
333
ver = __validate_version (item , prefix = prefix , base_version = d_ver )
299
334
if ver < max_ver :
300
335
raise Exception (prefix + "'version' must be increasing: %s" % item ['version' ])
301
336
max_ver = ver
302
337
303
- def __validate_params (d , tags ):
338
+ def __validate_params (d , tags , meta ):
304
339
if 'params' not in d :
305
340
raise Exception ("'function' requires the following sequence of mappings: {`params`}" )
306
341
@@ -347,6 +382,11 @@ def __validate_params(d, tags):
347
382
if not has_queue :
348
383
raise Exception (prefix + "bounds must only be used on entry points which take a `hQueue` parameter" )
349
384
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
+
350
390
ver = __validate_version (item , prefix = prefix , base_version = d_ver )
351
391
if ver < max_ver :
352
392
raise Exception (prefix + "'version' must be increasing: %s" % item ['version' ])
@@ -421,7 +461,7 @@ def __validate_union_tag(d):
421
461
__validate_union_tag (d )
422
462
__validate_type (d , 'name' , tags )
423
463
__validate_base (d )
424
- __validate_members (d , tags )
464
+ __validate_members (d , tags , meta )
425
465
__validate_details (d )
426
466
__validate_ordinal (d )
427
467
__validate_version (d )
@@ -435,7 +475,7 @@ def __validate_union_tag(d):
435
475
else :
436
476
__validate_name (d , 'name' , tags , case = 'camel' )
437
477
438
- __validate_params (d , tags )
478
+ __validate_params (d , tags , meta )
439
479
__validate_details (d )
440
480
__validate_ordinal (d )
441
481
__validate_version (d )
@@ -893,7 +933,7 @@ def parse(section, version, tags, meta, ref):
893
933
894
934
for i , d in enumerate (docs ):
895
935
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 ):
897
937
continue
898
938
899
939
d = _filter_version (d , float (version ))
0 commit comments