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 try: 27 set 28 except NameError: 29 from sets import Set as set 30 31 # Visitors and activities related to node annotations. 32 33 class ASTVisitor: 34 35 "A base class for visitors." 36 37 def default(self, node, *args): 38 for n in node.getChildNodes(): 39 self.dispatch(n) 40 41 def dispatch(self, node, *args): 42 43 "Dispatch using 'node', annotating any raised exceptions." 44 45 # Dispatch via a generic visit method. 46 47 try: 48 return node.visit(self, *args) 49 50 # Annotate the exception in case of failure. 51 52 except NodeProcessingError, exc: 53 if exc.astnode is None: 54 exc.astnode = node 55 56 # NOTE: Should perhaps specialise the subclasses appropriately. 57 58 if hasattr(self, "unit"): 59 exc.unit_name = self.unit.full_name() 60 else: 61 exc.unit_name = self.full_name() 62 raise 63 64 def possible_accessor_types(self, node, defining_users=1): 65 66 """ 67 Given annotations made during the inspection process, return all possible 68 type names and indications of static usage for a 'node' involved in 69 attribute access. 70 71 If 'defining_users' is set to a false value, attempt to get the type 72 names specifically applicable to the node, rather than retrieving more 73 general definition-based type observations. 74 """ 75 76 target_names = set() 77 78 # Where an attribute could already be detected and where its nature is 79 # not that of a general instance or an unresolved name, attempt to 80 # identify it. 81 82 if hasattr(node, "_attr") and not isinstance(node._attr, (Instance, UnresolvedName)): 83 attr = node._attr 84 if isinstance(attr, Attr): 85 target_names.add((attr.parent.full_name(), attr.is_static_attribute())) 86 else: 87 target_names.add((attr.full_name(), attr.is_static_attribute())) 88 89 # Otherwise, attempt to employ the attribute usage observations. 90 91 elif hasattr(node, "_attrusers"): 92 93 # Visit each attribute user. 94 95 for user in node._attrusers: 96 97 # Since users such as branches may not provide type information, 98 # attempt to find defining users. 99 100 if defining_users: 101 for def_user in user._attrdefs or [user]: 102 for target_name, is_static in def_user._attrtypes.get(node._username, []): 103 target_names.add((target_name, is_static)) 104 else: 105 for target_name, is_static in user._attrspecifictypes.get(node._username, []): 106 target_names.add((target_name, is_static)) 107 108 return target_names 109 110 def used_by_unit(node): 111 112 """ 113 Return whether the definition made by a 'node' is actually employed by the 114 program unit within which it is found. 115 """ 116 117 return hasattr(node, "unit") and node.unit.parent.has_key(node.unit.name) 118 119 # Useful data. 120 121 operator_functions = { 122 123 # Binary operations. 124 125 "Add" : "add", 126 "Bitand" : "and_", 127 "Bitor" : "or_", 128 "Bitxor" : "xor", 129 "Div" : "div", 130 "FloorDiv" : "floordiv", 131 "LeftShift" : "lshift", 132 "Mod" : "mod", 133 "Mul" : "mul", 134 "Power" : "pow", 135 "RightShift" : "rshift", 136 "Sub" : "sub", 137 138 # Unary operations. 139 140 "Invert" : "invert", 141 "UnaryAdd" : "pos", 142 "UnarySub" : "neg", 143 144 # Augmented assignment. 145 146 "+=" : "iadd", 147 "-=" : "isub", 148 "*=" : "imul", 149 "/=" : "idiv", 150 "//=" : "ifloordiv", 151 "%=" : "imod", 152 "**=" : "ipow", 153 "<<=" : "ilshift", 154 ">>=" : "irshift", 155 "&=" : "iand", 156 "^=" : "ixor", 157 "|=" : "ior", 158 159 # Comparisons. 160 161 "==" : "eq", 162 "!=" : "ne", 163 "<" : "lt", 164 "<=" : "le", 165 ">=" : "ge", 166 ">" : "gt", 167 168 # Access and slicing. 169 170 "AssSlice" : "setslice", 171 "Slice" : "getslice", 172 "AssSubscript" : "setitem", 173 "Subscript" : "getitem", 174 } 175 176 # vim: tabstop=4 expandtab shiftwidth=4