def VisitClass(self, cls): """Add superclass methods and constants to this Class.""" if any(base for base in cls.parents if isinstance(base, pytd.NamedType)): raise AssertionError("AddInheritedMethods needs a resolved AST") # Filter out only the types we can reason about. # TODO(kramm): Do we want handle UnionTypes and GenericTypes at some point? bases = [ base.cls for base in cls.parents if isinstance(base, pytd.ClassType) ] # Don't pull in methods that are named the same as existing methods in # this class, local methods override parent class methods. names = {m.name for m in cls.methods} | {c.name for c in cls.constants} # TODO(kramm): This should do full-blown MRO. adjust_self = visitors.AdjustSelf(force=True) adjust_self.class_types.append(visitors.ClassAsType(cls)) new_methods = list(cls.methods) for base in bases: for m in base.methods: if m.name not in names: new_methods.append(m.Visit(adjust_self)) new_constants = list(cls.constants) for base in bases: for c in base.constants: if c.name not in names: new_constants.append(c) return cls.Replace(methods=tuple(new_methods), constants=tuple(new_constants))
def VisitClass(self, cls): """Visit a class, and change constants to methods where possible.""" new_constants = [] new_methods = list(cls.methods) adjust_self = visitors.AdjustSelf(force=True) adjust_self.class_types.append(visitors.ClassAsType(cls)) for const in cls.constants: if self._IsSimpleCall(const.type): c = self._MaybeLookup(const.type) signatures = c.methods[0].signatures self._processed_count[c.name] += 1 new_method = pytd.Function(const.name, signatures, c.methods[0].kind) new_methods.append(new_method.Visit(adjust_self)) else: new_constants.append(const) # keep return cls.Replace(constants=tuple(new_constants), methods=tuple(new_methods))