def _trace_item_layout( node: qlast.CreateObject, *, obj: Optional[qltracer.NamedObject] = None, fq_name: Optional[s_name.QualName] = None, ctx: LayoutTraceContext, ) -> None: if obj is None: fq_name = ctx.get_local_name(node.name) local_obj = ctx.objects[fq_name] assert isinstance(local_obj, qltracer.NamedObject) obj = local_obj assert fq_name is not None if isinstance(node, qlast.BasesMixin): bases = [] # construct the parents set, used later in ancestors graph parents = set() for ref in _get_bases(node, ctx=ctx): bases.append(ref) # ignore std modules dependencies if ref.get_module_name() not in s_schema.STD_MODULES: parents.add(ref) if ( ref.module not in ctx.local_modules and ref not in ctx.inh_graph ): base_obj = type(obj)(name=ref) ctx.inh_graph[ref] = topological.DepGraphEntry(item=base_obj) base = ctx.schema.get(ref) if isinstance(base, s_sources.Source): assert isinstance(base_obj, qltracer.Source) base_pointers = base.get_pointers(ctx.schema) for pn, p in base_pointers.items(ctx.schema): base_obj.pointers[pn] = qltracer.Pointer( s_name.QualName('__', pn.name), source=base, target=p.get_target(ctx.schema), ) ctx.parents[fq_name] = parents ctx.inh_graph[fq_name] = topological.DepGraphEntry( item=obj, deps=set(bases), merge=set(bases), ) for decl in node.commands: if isinstance(decl, qlast.CreateConcretePointer): assert isinstance(obj, qltracer.Source) target: Optional[qltracer.TypeLike] if isinstance(decl.target, qlast.TypeExpr): target = _resolve_type_expr(decl.target, ctx=ctx) else: target = None pn = s_utils.ast_ref_to_unqualname(decl.name) ptr = qltracer.Pointer( s_name.QualName('__', pn.name), source=obj, target=target, ) obj.pointers[pn] = ptr ptr_name = s_name.QualName( module=fq_name.module, name=f'{fq_name.name}@{decl.name.name}', ) ctx.objects[ptr_name] = ptr ctx.defdeps[fq_name].add(ptr_name) _trace_item_layout( decl, obj=ptr, fq_name=ptr_name, ctx=ctx) elif isinstance(decl, qlast.CreateConcreteConstraint): # Validate that the constraint exists at all. _validate_schema_ref(decl, ctx=ctx) _, con_fq_name = ctx.get_fq_name(decl) con_name = s_name.QualName( module=fq_name.module, name=f'{fq_name.name}@{con_fq_name}', ) ctx.objects[con_name] = qltracer.ConcreteConstraint(con_name) ctx.constraints[fq_name].add(con_name) elif isinstance(decl, qlast.CreateAnnotationValue): # Validate that the constraint exists at all. _validate_schema_ref(decl, ctx=ctx)
def _trace_item_layout(node: qlast.CreateObject, *, obj=None, fq_name=None, ctx: LayoutTraceContext): if obj is None: fq_name = ctx.get_local_name(node.name) obj = ctx.objects[fq_name] if hasattr(node, "bases"): bases = [] # construct the parents set, used later in ancestors graph parents = set() for ref in _get_bases(node, ctx=ctx): bases.append(ref) # ignore std modules dependencies if ref.module not in s_schema.STD_MODULES: parents.add(ref) if (ref.module not in ctx.local_modules and ref not in ctx.inh_graph): base = ctx.schema.get(ref) base_obj = type(obj)(name=ref) for pn, p in base.get_pointers(ctx.schema).items(ctx.schema): base_obj.pointers[pn] = qltracer.Pointer( pn, source=base, target=p.get_target(ctx.schema), ) ctx.inh_graph[ref] = { "item": base_obj, } ctx.parents[fq_name] = parents ctx.inh_graph[fq_name] = { "item": obj, "deps": bases, "merge": bases, } for decl in node.commands: if isinstance(decl, qlast.CreateConcretePointer): if isinstance(decl.target, qlast.TypeExpr): target = _resolve_type_expr(decl.target, ctx=ctx) else: target = None ptr = qltracer.Pointer(decl.name.name, source=obj, target=target) obj.pointers[decl.name.name] = ptr ptr_name = f'{fq_name}@{decl.name.name}' ctx.objects[ptr_name] = ptr ctx.defdeps[fq_name].add(ptr_name) _trace_item_layout(decl, obj=ptr, fq_name=ptr_name, ctx=ctx) elif isinstance(decl, qlast.CreateConcreteConstraint): _, con_fq_name = ctx.get_fq_name(decl) con_name = f'{fq_name}@{con_fq_name}' ctx.objects[con_name] = qltracer.ConcreteConstraint(con_name) ctx.constraints[fq_name].add(con_name)