def specialize_parent_vtable(cls: ClassIR, parent: ClassIR) -> VTableEntries: """Generate the part of a vtable corresponding to a parent class or trait""" updated = [] for entry in parent.vtable_entries: if isinstance(entry, VTableMethod): # Find the original method corresponding to this vtable entry. # (This may not be the method in the entry, if it was overridden.) orig_parent_method = entry.cls.get_method(entry.name) assert orig_parent_method method_cls = cls.get_method_and_class(entry.name) if method_cls: child_method, defining_cls = method_cls # TODO: emit a wrapper for __init__ that raises or something if (is_same_method_signature(orig_parent_method.sig, child_method.sig) or orig_parent_method.name == '__init__'): entry = VTableMethod(entry.cls, entry.name, child_method, entry.shadow_method) else: entry = VTableMethod(entry.cls, entry.name, defining_cls.glue_methods[(entry.cls, entry.name)], entry.shadow_method) else: # If it is an attribute from a trait, we need to find out # the real class it got mixed in at and point to that. if parent.is_trait: _, origin_cls = cls.attr_details(entry.name) entry = VTableAttr(origin_cls, entry.name, entry.is_setter) updated.append(entry) return updated
def check_deletable_declaration(builder: IRBuilder, cl: ClassIR, line: int) -> None: for attr in cl.deletable: if attr not in cl.attributes: if not cl.has_attr(attr): builder.error('Attribute "{}" not defined'.format(attr), line) continue for base in cl.mro: if attr in base.property_types: builder.error('Cannot make property "{}" deletable'.format(attr), line) break else: _, base = cl.attr_details(attr) builder.error(('Attribute "{}" not defined in "{}" ' + '(defined in "{}")').format(attr, cl.name, base.name), line)