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