class KlassVisitor(ASTVisitor): """ An AST visitor for classes. """ ########################################################################### # 'object' interface. ########################################################################### def __init__(self, klass): """ Creates a new visitor. """ self.klass = klass # Factories used to create klasses, functions and assignments from # AST nodes. self._function_factory = FunctionFactory() self._assign_factory = AssignFactory() return ########################################################################### # 'ASTVisitor' interface. ########################################################################### def visitFunction(self, node): """ Visits a function node. """ function = self._function_factory.from_ast(self.klass, node) self.klass.locals[node.name] = function self.klass.methods[node.name] = function return def visitAssign(self, node): """ Visits an assignment node. """ assign = self._assign_factory.from_ast(self.klass, node) # Does the assigment look like it *might* be a trait? (i.e., it is NOT # an expression or a constant etc.). if len(assign.source) > 0: assign.is_trait = self.klass.is_trait(assign.source) else: assign.is_trait = False for target in assign.targets: self.klass.locals[target] = assign self.klass._is_trait[target] = assign.is_trait if assign.is_trait: self.klass.traits[target] = assign else: self.klass.attributes[target] = assign return
class ModuleVisitor(ASTVisitor): """ An AST visitor for top-level modules. """ ########################################################################### # 'object' interface. ########################################################################### def __init__(self, module): """ Creates a new visitor. """ self.module = module # Factories used to create klasses, functions and assignments from # AST nodes. self._klass_factory = KlassFactory() self._function_factory = FunctionFactory() self._assign_factory = AssignFactory() return ########################################################################### # 'ASTVisitor' interface. ########################################################################### def visitClass(self, node): """ Visits a class node. """ klass = self._klass_factory.from_ast(self.module, node) self.module.locals[node.name] = klass self.module.klasses[node.name] = klass return def visitFunction(self, node): """ Visits a function node. """ function = self._function_factory.from_ast(self.module, node) self.module.locals[node.name] = function self.module.functions[node.name] = function return def visitAssign(self, node): """ Visits an assignment node. """ assign = self._assign_factory.from_ast(self.module, node) # Does the assigment look like it *might* be a trait? (i.e., it is NOT # an expression or a constant etc.). if len(assign.source) > 0: assign.is_trait = self.module.is_trait(assign.source) else: assign.is_trait = False for target in assign.targets: self.module.locals[target] = assign self.module.attributes[target] = assign self.module._is_trait[target] = assign.is_trait return def visitFrom(self, node): """ Visits a from node. """ for name, what in node.names: self.module.imports[name] = node.modname return def visitImport(self, node): """ Visits an import node. """ for name, what in node.names: # fixme: We currently use the fact that we add an empty string to # the imports dictionary to tell the difference later on between # 'import' and 'from import'. self.module.imports[name] = '' return