1 3 package org.python.compiler; 4 5 import org.python.parser.*; 6 import org.python.parser.ast.*; 7 import java.util.*; 8 9 public class ScopesCompiler extends Visitor implements ScopeConstants { 10 11 private CompilationContext code_compiler; 12 13 private Stack scopes; 14 private ScopeInfo cur = null; 15 private Hashtable nodeScopes; 16 17 private int level = 0; 18 private int func_level = 0; 19 20 public ScopesCompiler(CompilationContext code_compiler, 21 Hashtable nodeScopes) 22 { 23 this.code_compiler = code_compiler; 24 this.nodeScopes = nodeScopes; 25 scopes = new Stack(); 26 } 27 28 public void beginScope(String name, int kind, SimpleNode node, 29 ArgListCompiler ac) 30 { 31 if (cur != null) { 32 scopes.push(cur); 33 } 34 if (kind == FUNCSCOPE) func_level++; 35 cur = new ScopeInfo(name, node, level++, kind, 36 func_level, ac); 37 nodeScopes.put(node, cur); 38 } 39 40 public void endScope() throws Exception { 41 if (cur.kind == FUNCSCOPE) func_level--; 42 level--; 43 ScopeInfo up = (!scopes.empty())?(ScopeInfo)scopes.pop():null; 44 cur.cook(up,code_compiler); 45 cur.dump(); cur = up; 47 } 48 49 public void parse(SimpleNode node) throws Exception { 50 try { 51 visit(node); 52 } catch(Throwable t) { 53 throw org.python.core.parser.fixParseError(null, t, 54 code_compiler.getFilename()); 55 } 56 } 57 58 public Object visitInteractive(Interactive node) throws Exception { 59 beginScope("<single-top>", TOPSCOPE, node, null); 60 suite(node.body); 61 endScope(); 62 return null; 63 } 64 65 public Object visitModule(org.python.parser.ast.Module node) 66 throws Exception 67 { 68 beginScope("<file-top>", TOPSCOPE, node, null); 69 suite(node.body); 70 endScope(); 71 return null; 72 } 73 74 public Object visitExpression(Expression node) throws Exception { 75 beginScope("<eval-top>", TOPSCOPE, node, null); 76 visit(new Return(node.body)); 77 endScope(); 78 return null; 79 } 80 81 private void def(String name) { 82 cur.addBound(name); 83 } 84 85 public Object visitFunctionDef(FunctionDef node) throws Exception { 86 def(node.name); 87 ArgListCompiler ac = new ArgListCompiler(); 88 ac.visitArgs(node.args); 89 90 exprType[] defaults = ac.getDefaults(); 91 int defc = defaults.length; 92 for (int i = 0; i < defc; i++) { 93 visit(defaults[i]); 94 } 95 96 beginScope(node.name, FUNCSCOPE, node, ac); 97 int n = ac.names.size(); 98 for (int i = 0; i < n; i++) { 99 cur.addParam((String )ac.names.elementAt(i)); 100 } 101 for (int i = 0; i < ac.init_code.size(); i++) { 102 visit((stmtType) ac.init_code.elementAt(i)); 103 } 104 cur.markFromParam(); 105 suite(node.body); 106 endScope(); 107 return null; 108 } 109 110 public Object visitLambda(Lambda node) throws Exception { 111 ArgListCompiler ac = new ArgListCompiler(); 112 ac.visitArgs(node.args); 113 114 SimpleNode[] defaults = ac.getDefaults(); 115 int defc = defaults.length; 116 for (int i = 0; i < defc; i++) { 117 visit(defaults[i]); 118 } 119 120 beginScope("<lambda>", FUNCSCOPE, node, ac); 121 int n = ac.names.size(); 122 for (int i = 0; i < n; i++) { 123 cur.addParam((String )ac.names.elementAt(i)); 124 } 125 for (int i = 0; i < ac.init_code.size(); i++) 126 visit((stmtType) ac.init_code.elementAt(i)); 127 cur.markFromParam(); 128 visit(node.body); 129 endScope(); 130 return null; 131 } 132 133 public void suite(stmtType[] stmts) throws Exception { 134 int n = stmts.length; 135 for (int i = 0; i < n; i++) 136 visit(stmts[i]); 137 } 138 139 public Object visitImport(Import node) throws Exception { 140 int n = node.names.length; 141 for (int i = 0; i < n; i++) { 142 if (node.names[i].asname != null) 143 cur.addBound(node.names[i].asname); 144 else { 145 String name = node.names[i].name; 146 if (name.indexOf('.') > 0) 147 name = name.substring(0, name.indexOf('.')); 148 cur.addBound(name); 149 } 150 } 151 return null; 152 } 153 154 public Object visitImportFrom(ImportFrom node) throws Exception { 155 Future.checkFromFuture(node); int n = node.names.length; 157 if (n == 0) { 158 cur.from_import_star = true; 159 return null; 160 } 161 for (int i = 0; i < n; i++) { 162 if (node.names[i].asname != null) 163 cur.addBound(node.names[i].asname); 164 else 165 cur.addBound(node.names[i].name); 166 } 167 return null; 168 } 169 170 public Object visitGlobal(Global node) throws Exception { 171 int n = node.names.length; 172 for (int i = 0; i < n; i++) { 173 String name = node.names[i]; 174 int prev = cur.addGlobal(name); 175 if (prev >= 0) { 176 if ((prev&FROM_PARAM) != 0) 177 code_compiler.error("name '"+name+"' is local and global", 178 true,node); 179 if ((prev&GLOBAL) != 0) continue; 180 String what; 181 if ((prev&BOUND) != 0) what = "assignment"; else what = "use"; 182 code_compiler.error("name '"+name+"' declared global after "+ 183 what,false,node); 184 } 185 } 186 return null; 187 } 188 189 public Object visitExec(Exec node) throws Exception { 190 cur.exec = true; 191 if (node.globals == null && node.locals == null) 192 cur.unqual_exec = true; 193 traverse(node); 194 return null; 195 } 196 197 208 209 public Object visitClassDef(ClassDef node) throws Exception { 210 def(node.name); 211 int n = node.bases.length; 212 for (int i = 0; i < n; i++) 213 visit(node.bases[i]); 214 beginScope(node.name, CLASSSCOPE, node, null); 215 suite(node.body); 216 endScope(); 217 return null; 218 } 219 220 public Object visitName(Name node) throws Exception { 221 String name = node.id; 222 if (node.ctx != expr_contextType.Load) { 223 if (name.equals("__debug__")) 224 code_compiler.error("can not assign to __debug__", true,node); 225 cur.addBound(name); 226 } 227 else cur.addUsed(name); 228 return null; 229 } 230 231 public Object visitListComp(ListComp node) throws Exception { 232 String tmp = "_[" + (++cur.list_comprehension_count) + "]"; 233 cur.addBound(tmp); 234 traverse(node); 235 return null; 236 } 237 238 239 public Object visitYield(Yield node) throws Exception { 240 cur.generator = true; 241 cur.yield_count++; 242 traverse(node); 243 return null; 244 } 245 } 246 | Popular Tags |