001    package org.mesopotamia.lang.java;
002    
003    import java.util.ArrayList;
004    import java.util.List;
005    
006    import org.mesopotamia.LanguageElement;
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.Scope;
012    import org.mesopotamia.lang.java.ref.TypeInfo;
013    import org.mesopotamia.lang.java.ref.TypeSpecInfo;
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    @SuppressWarnings("unchecked")
021    public class Operation extends Code {
022    
023            public Operation(NodeData xData, Class<?> context, Scan scan,
024                            RepositoryLanguage language, Object environment) throws MesopotamiaException {
025                    super(xData, context, scan, language, environment);
026    
027                    // Select attributes
028                    if (language.supportsTokenName("TYPE_PARAMETERS")) {
029                            TypeParameters = select(TypeParameter.class, "TYPE_PARAMETERS/TYPE_PARAMETER");
030                    }
031                    Parameters = select(ParameterDefinition.class, "PARAMETERS/*");
032                    for(Identifier th: select(Identifier.class, "LITERAL_throws/*")) {
033                            Throws.add(th.getPath());
034                    }
035            }
036    
037            public void toDom(Element holder) {
038                    super.toDom(holder);
039    
040                    // Serialize attributes
041                    setElement(holder, "TypeParameters", TypeParameters);
042                    setElement(holder, "Parameters", Parameters);
043                    setElement(holder, "Throws", Throws);
044            }
045    
046            // Attributes
047            private List<TypeParameter> TypeParameters = emptyList;
048    
049            private List<ParameterDefinition> Parameters;
050    
051            private List<String> Throws = new ArrayList<String>();
052    
053            // Accessors
054            public List<TypeParameter> getTypeParameters() {
055                    return TypeParameters;
056            }
057    
058            public List<ParameterDefinition> getParameters() {
059                    return Parameters;
060            }
061    
062            public List<String> getThrows() {
063                    return Throws;
064            }
065    
066            protected void acceptChildren(Visitor visitor) {
067                    super.acceptChildren(visitor);
068                    // Visiting non-text attributes
069                    new CollectionVisitable(TypeParameters, false).accept(visitor);
070                    new CollectionVisitable(Parameters, false).accept(visitor);
071            }
072            
073            @Override
074            protected synchronized void setScope() {
075                    super.setScope();
076                    
077                    for (ParameterDefinition p: getParameters()) {
078                            variables.put(p.getName(), p);
079                    }
080            }
081            
082            @Override
083            public TypeInfo findType(String name) {
084                    for (TypeParameter tp: getTypeParameters()) {
085                            if (tp.getName().equals(name)) {
086                                    return tp;
087                            }
088                    }
089                    
090                    return super.findType(name);
091            }
092            
093            public List<TypeSpecInfo> getParameterTypes() {
094                    List<TypeSpecInfo> ret = new ArrayList<TypeSpecInfo>();
095                    for (ParameterDefinition pd: getParameters()) {
096                            ret.add(pd.getTypeSpecification());
097                    }
098                    return ret;
099            }
100    
101            public List<TypeInfo> getExceptionTypes() {
102                    List<TypeInfo> ret = new ArrayList<TypeInfo>();
103                    Scope ec = findParent(Scope.class);
104                    for (String et: getThrows()) {
105                            ret.add(ec==null ? null : ec.findType(et));
106                    }
107                    return ret;
108            }
109    
110            public TypeInfo getDeclaringType() {
111                    return findParent(TypeDefinitionOrAnonymous.class);
112            }
113            
114    }