001 package org.mesopotamia.lang.java; 002 003 import java.util.HashMap; 004 import java.util.List; 005 import java.util.Map; 006 007 import org.mesopotamia.MesopotamiaException; 008 import org.mesopotamia.NodeData; 009 import org.mesopotamia.RepositoryLanguage; 010 import org.mesopotamia.Scan; 011 import org.mesopotamia.lang.java.ref.MethodInfo; 012 import org.mesopotamia.lang.java.ref.Scope; 013 import org.mesopotamia.lang.java.ref.TypeInfo; 014 import org.mesopotamia.lang.java.ref.VariableInfo; 015 import org.w3c.dom.Element; 016 017 import biz.hammurapi.util.CollectionVisitable; 018 import biz.hammurapi.util.Visitor; 019 020 public class Code extends Field implements Scope { 021 022 public Code(NodeData xData, Class<?> context, Scan scan, 023 RepositoryLanguage language, Object environment) throws MesopotamiaException { 024 super(xData, context, scan, language, environment); 025 026 // Select attributes 027 Statements = select(Statement.class, "SLIST/*"); 028 029 } 030 031 public void toDom(Element holder) { 032 super.toDom(holder); 033 034 // Serialize attributes 035 setElement(holder, "Statements", Statements); 036 } 037 038 // Attributes 039 private List<Statement> Statements; 040 041 // Accessors 042 public List<Statement> getStatements() { 043 return Statements; 044 } 045 046 protected void acceptChildren(Visitor visitor) { 047 super.acceptChildren(visitor); 048 // Visiting non-text attributes 049 new CollectionVisitable(Statements, false).accept(visitor); 050 } 051 052 private Scope enclosingScope; 053 protected Map<String, VariableInfo> variables; 054 private Map<String, TypeDefinition> types; 055 private boolean scopeSet; 056 057 public MethodInfo findMethod(String name, String[] parameterTypes) { 058 if (!scopeSet) { 059 setScope(); 060 } 061 062 return enclosingScope == null ? null : enclosingScope.findMethod(name, parameterTypes); 063 } 064 065 protected synchronized void setScope() { 066 if (!scopeSet) { 067 scopeSet = true; 068 } 069 variables = new HashMap<String, VariableInfo>(); 070 types = new HashMap<String, TypeDefinition>(); 071 enclosingScope = findParent(Scope.class); 072 073 for (Statement child: getStatements()) { 074 if (child instanceof VariableDefinition) { 075 VariableDefinition vd = (VariableDefinition) child; 076 variables.put(vd.getName(), vd); 077 } else if (child instanceof TypeDefinition) { 078 TypeDefinition td = (TypeDefinition) child; 079 types.put(td.getName(), td); 080 } 081 } 082 } 083 084 public TypeInfo findType(String name) { 085 if (!scopeSet) { 086 setScope(); 087 } 088 089 TypeDefinition td = types.get(name); 090 if (td!=null) { 091 return td; 092 } 093 094 return enclosingScope == null ? null : enclosingScope.findType(name); 095 } 096 097 public VariableInfo findVariable(String name) { 098 if (!scopeSet) { 099 setScope(); 100 } 101 102 VariableInfo vd = variables.get(name); 103 if (vd!=null) { 104 return vd; 105 } 106 107 return enclosingScope == null ? null : enclosingScope.findVariable(name); 108 } 109 110 }