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    }