def type_suffix(self, fdef: FuncDef, info: TypeInfo = None) -> str: """Return the suffix for a mangled name. This includes an optional type suffix for a function or method. """ if not info: info = fdef.info # If info is None, we have a global function => no suffix. Also if the # method is not an override, we need no suffix. if not info or (not info.bases or not info.bases[0].type.has_method(fdef.name())): return "" elif is_simple_override(fdef, info): return self.type_suffix(fdef, info.bases[0].type) elif self.is_pretty: return "`" + info.name() else: return "__" + info.name()
def type_suffix(self, fdef, info=None): """Return the suffix for a mangled name. This includes an optional type suffix for a function or method. """ if not info: info = fdef.info # If info is None, we have a global function => no suffix. Also if the # method is not an override, we need no suffix. if not info or not info.base or not info.base.has_method(fdef.name()): return '' elif is_simple_override(fdef, info): return self.type_suffix(fdef, info.base) elif self.is_pretty: return '`' + info.name() else: return '__' + info.name()
def transform_method(self, fdef: FuncDef) -> List[FuncDef]: """Transform a method. The result is one or more methods. """ # Transform the body of the method. self.tf.transform_function_body(fdef) res = Undefined # type: List[FuncDef] if fdef.is_constructor(): # The method is a constructor. Constructors are transformed to one # method. res = [self.transform_method_implementation(fdef, fdef.name())] else: # Normal methods are transformed to 1-3 variants. The # first is the main implementation of the method, and the # second is the dynamically-typed wrapper. The third # variant is for method overrides, and represents the # overridden supertype method. res = [ self.transform_method_implementation( fdef, fdef.name() + self.tf.type_suffix(fdef)) ] if fdef.info.bases and fdef.info.mro[1].has_method(fdef.name()): # Override. # TODO do not assume single inheritance # Is is an override with a different signature? For # trivial overrides we can inherit wrappers. if not is_simple_override(fdef, fdef.info): # Create a wrapper for overridden superclass method. res.append(self.override_method_wrapper(fdef)) # Create a dynamically-typed method wrapper. res.append(self.dynamic_method_wrapper(fdef)) else: # Not an override. # Create a dynamically-typed method wrapper. res.append(self.dynamic_method_wrapper(fdef)) return res
def type_suffix(self, fdef: FuncDef, info: TypeInfo = None) -> str: """Return the suffix for a mangled name. This includes an optional type suffix for a function or method. """ if not info: info = fdef.info # If info is None, we have a global function => no suffix. Also if the # method is not an override, we need no suffix. if not info or (not info.bases or not info.bases[0].type.has_method(fdef.name())): return '' elif is_simple_override(fdef, info): return self.type_suffix(fdef, info.bases[0].type) elif self.is_pretty: return '`' + info.name() else: return '__' + info.name()
def transform_method(self, fdef: FuncDef) -> List[FuncDef]: """Transform a method. The result is one or more methods. """ # Transform the body of the method. self.tf.transform_function_body(fdef) res = Undefined # type: List[FuncDef] if fdef.is_constructor(): # The method is a constructor. Constructors are transformed to one # method. res = [self.transform_method_implementation(fdef, fdef.name())] else: # Normal methods are transformed to 1-3 variants. The # first is the main implementation of the method, and the # second is the dynamically-typed wrapper. The third # variant is for method overrides, and represents the # overridden supertype method. res = [self.transform_method_implementation( fdef, fdef.name() + self.tf.type_suffix(fdef))] if fdef.info.bases and fdef.info.mro[1].has_method(fdef.name()): # Override. # TODO do not assume single inheritance # Is is an override with a different signature? For # trivial overrides we can inherit wrappers. if not is_simple_override(fdef, fdef.info): # Create a wrapper for overridden superclass method. res.append(self.override_method_wrapper(fdef)) # Create a dynamically-typed method wrapper. res.append(self.dynamic_method_wrapper(fdef)) else: # Not an override. # Create a dynamically-typed method wrapper. res.append(self.dynamic_method_wrapper(fdef)) return res
else: # Normal methods are transformed to 1-3 variants. The # first is the main implementation of the method, and the # second is the dynamically-typed wrapper. The third # variant is for method overrides, and represents the # overridden supertype method. res = [self.transform_method_implementation( fdef, fdef.name() + self.tf.type_suffix(fdef))] if fdef.info.base and fdef.info.base.has_method(fdef.name()): # Override. # Is is an override with a different signature? For # trivial overrides we can inherit wrappers. if not is_simple_override(fdef, fdef.info): # Create a wrapper for overridden superclass method. res.append(self.override_method_wrapper(fdef)) # Create a dynamically-typed method wrapper. res.append(self.dynamic_method_wrapper(fdef)) else: # Not an override. # Create a dynamically-typed method wrapper. res.append(self.dynamic_method_wrapper(fdef)) return res FuncDef transform_method_implementation(self, FuncDef fdef, str name): """Transform the implementation of a method (i.e. unwrapped).""" args = fdef.args