1 #!/usr/bin/env python 2 3 """ 4 Common classes. 5 6 Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 from micropython.data import Attr, Instance, UnresolvedName 23 from micropython.errors import * 24 import sys 25 26 # Visitors and activities related to node annotations. 27 28 class ASTVisitor: 29 30 "A base class for visitors." 31 32 def default(self, node, *args): 33 for n in node.getChildNodes(): 34 self.dispatch(n) 35 36 def dispatch(self, node, *args): 37 38 "Dispatch using 'node', annotating any raised exceptions." 39 40 # Dispatch via a generic visit method. 41 42 try: 43 return node.visit(self, *args) 44 45 # Annotate the exception in case of failure. 46 47 except NodeProcessingError, exc: 48 if exc.astnode is None: 49 exc.astnode = node 50 51 # NOTE: Should perhaps specialise the subclasses appropriately. 52 53 if hasattr(self, "unit"): 54 exc.unit_name = self.unit.full_name() 55 else: 56 exc.unit_name = self.full_name() 57 raise 58 59 def possible_accessor_types(self, node, defining_users=1): 60 61 """ 62 Given annotations made during the inspection process, return all possible 63 type names and indications of static usage for a 'node' involved in 64 attribute access. 65 66 If 'defining_users' is set to a false value, attempt to get the type 67 names specifically applicable to the node, rather than retrieving more 68 general definition-based type observations. 69 """ 70 71 target_names = set() 72 73 if hasattr(node, "_attr") and not isinstance(node._attr, (Instance, UnresolvedName)): 74 attr = node._attr 75 if isinstance(attr, Attr): 76 target_names.add((attr.parent.full_name(), attr.is_static_attribute())) 77 else: 78 target_names.add((attr.full_name(), attr.is_static_attribute())) 79 80 elif hasattr(node, "_attrusers"): 81 82 # Visit each attribute user. 83 84 for user in node._attrusers: 85 86 # Since users such as branches may not provide type information, 87 # attempt to find defining users. 88 89 if defining_users: 90 for def_user in user._attrdefs or [user]: 91 for target_name, is_static in def_user._attrtypes.get(node._username, []): 92 target_names.add((target_name, is_static)) 93 else: 94 for target_name, is_static in user._attrspecifictypes.get(node._username, []): 95 target_names.add((target_name, is_static)) 96 97 return target_names 98 99 def used_by_unit(node): 100 101 """ 102 Return whether the definition made by a 'node' is actually employed by the 103 program unit within which it is found. 104 """ 105 106 return hasattr(node, "unit") and node.unit.parent.has_key(node.unit.name) 107 108 # Useful data. 109 110 operator_functions = { 111 112 # Binary operations. 113 114 "Add" : "add", 115 "Bitand" : "and_", 116 "Bitor" : "or_", 117 "Bitxor" : "xor", 118 "Div" : "div", 119 "FloorDiv" : "floordiv", 120 "LeftShift" : "lshift", 121 "Mod" : "mod", 122 "Mul" : "mul", 123 "Power" : "pow", 124 "RightShift" : "rshift", 125 "Sub" : "sub", 126 127 # Unary operations. 128 129 "Invert" : "invert", 130 "UnaryAdd" : "pos", 131 "UnarySub" : "neg", 132 133 # Augmented assignment. 134 135 "+=" : "iadd", 136 "-=" : "isub", 137 "*=" : "imul", 138 "/=" : "idiv", 139 "//=" : "ifloordiv", 140 "%=" : "imod", 141 "**=" : "ipow", 142 "<<=" : "ilshift", 143 ">>=" : "irshift", 144 "&=" : "iand", 145 "^=" : "ixor", 146 "|=" : "ior", 147 148 # Comparisons. 149 150 "==" : "eq", 151 "!=" : "ne", 152 "<" : "lt", 153 "<=" : "le", 154 ">=" : "ge", 155 ">" : "gt", 156 157 # Access and slicing. 158 159 "AssSlice" : "setslice", 160 "Slice" : "getslice", 161 "AssSubscript" : "setitem", 162 "Subscript" : "getitem", 163 } 164 165 # vim: tabstop=4 expandtab shiftwidth=4