def get_type(self): if self.cached_type: return self.cached_type # Callers are already visiting this node, so we cannot return its type # right now. Return None so that it doesn't contribute to type # resolution. if self.is_processing_type: return None try: self.is_processing_type = True types = set() for m in self.parsers: t = m.get_type() if t: types.add(t) # There are two possibilities: # - if all alternatives return AST nodes: then this parser's # return type is the common ancestor for all of these. # - otherwise, make sure that all alternatives return exactly the # same type. if all(issubclass(t, ASTNode) for t in types): res = common_ancestor(*types) else: typs = list(types) assert all(type(t) == type(typs[0]) for t in typs) res = typs[0] self.cached_type = res return res finally: self.is_processing_type = False
def unify(cls, other): """ Assuming "cls" and "other" are types that match, return the most general type to cover both. An AssertionError is raised if they don't match. :param CompiledType cls: Type parameter. :param CompiledType other: Type parameter. :rtype: CompiledType """ assert cls.matches(other) if issubclass(other, ASTNode): return common_ancestor(cls, other) else: return cls
def get_type(self): if self.revtree_class: return common_ancestor(self.parser.get_type(), self.revtree_class) else: return self.parser.get_type().list_type()