001    package org.mesopotamia.lang.java;
002    
003    import java.util.ArrayList;
004    import java.util.List;
005    
006    import org.mesopotamia.MesopotamiaException;
007    import org.mesopotamia.NodeData;
008    import org.mesopotamia.RepositoryLanguage;
009    import org.mesopotamia.Scan;
010    import org.mesopotamia.lang.java.ref.MethodInfo;
011    import org.mesopotamia.lang.java.ref.Scope;
012    import org.mesopotamia.lang.java.ref.TypeInfo;
013    import org.mesopotamia.lang.java.ref.VariableInfo;
014    import org.w3c.dom.Element;
015    
016    public class ClassDefinition extends ClassOrInterfaceDefinition implements Statement {
017    
018            public ClassDefinition(NodeData xData, Class<?> context, Scan scan,
019                            RepositoryLanguage language, Object environment) throws MesopotamiaException {
020                    super(xData, context, scan, language, environment);
021    
022                    // Select attributes
023                    Identifier ext = selectSingleElement(Identifier.class, "EXTENDS_CLAUSE/*");
024                    if (ext!=null) {
025                            Extends = ext.getPath();
026                    }
027                    
028                    for(Identifier impl: select(Identifier.class, "IMPLEMENTS_CLAUSE/*")) {
029                            Implements.add(impl.getPath());
030                    }
031    
032            }
033    
034            public void toDom(Element holder) {
035                    super.toDom(holder);
036    
037                    // Serialize attributes
038                    setAttribute(holder, "Extends", Extends);
039                    setElement(holder, "Implements", Implements);
040            }
041    
042            // Attributes
043            private String Extends;
044    
045            private List<String> Implements = new ArrayList<String>();
046    
047            // Accessors
048            public String getExtends() {
049                    return Extends;
050            }
051    
052            public List<String> getImplements() {
053                    return Implements;
054            }
055            
056            @Override
057            protected boolean isKindOfInternal(String superFcn) {
058                    if (super.isKindOfInternal(superFcn)) {
059                            return true;
060                    }
061                    
062                    Scope scope = getEnclosingScope();
063                    if (scope!=null) {
064                            String sc = getExtends();
065                            if (sc!=null) {
066                                    TypeInfo sti = scope.findType(sc);
067                                    if (sti!=null && !fcn.equals(sti.getFcn()) && sti.isKindOf(superFcn)) {
068                                            return true;
069                                    }
070                            }
071                            
072                            for (String si: getImplements()) {
073                                    TypeInfo sti = scope.findType(si);
074                                    if (sti!=null && sti.isKindOf(superFcn)) {
075                                            return true;
076                                    }
077                            }
078                    }
079                    
080                    return false;
081            }
082    
083            @Override
084            protected TypeInfo findNestedTypeInternal(String name) {
085                    TypeInfo ret = super.findNestedTypeInternal(name);
086                    if (ret!=null) {
087                            return ret;
088                    }
089                    
090                    Scope ec = getEnclosingScope();
091                    if (ec!=null) {
092                            if (getExtends()!=null) {
093                                    TypeInfo spr = ec.findType(getExtends());
094                                    if (spr!=null) {
095                                            ret = spr.findNestedType(name);
096                                            if (ret!=null) {
097                                                    return ret;
098                                            }
099                                    }
100                            }
101                            
102                            for (String cInterface: getImplements()) {
103                                    TypeInfo spr = ec.findType(cInterface);
104                                    if (spr!=null) {
105                                            ret = spr.findNestedType(name);
106                                            if (ret!=null) {
107                                                    return ret;
108                                            }
109                                    }
110                            }
111                    }
112                    return null;
113            }
114            
115            @Override
116            protected MethodInfo findTypeMethodInternal(String name, String[] parameterTypes) {
117                    MethodInfo candidate = super.findTypeMethodInternal(name, parameterTypes);
118                    
119                    Scope ec = getEnclosingScope();
120                    if (ec!=null) {
121                            if (getExtends()!=null) {
122                                    TypeInfo spr = ec.findType(getExtends());
123                                    if (spr!=null) {
124                                            candidate = selectMoreSpecific(candidate, spr.findTypeMethod(name, parameterTypes));
125                                    }
126                            }
127                            
128                            for (String cInterface: getImplements()) {
129                                    TypeInfo spr = ec.findType(cInterface);
130                                    if (spr!=null) {
131                                            candidate = selectMoreSpecific(candidate, spr.findTypeMethod(name, parameterTypes));
132                                    }
133                            }
134                    }
135                    return candidate;
136            }
137            
138            @Override
139            protected VariableInfo findTypeVariableInternal(String name) {
140                    VariableInfo ret = super.findTypeVariableInternal(name);
141                    if (ret!=null) {
142                            return ret;
143                    }
144                    
145                    Scope ec = getEnclosingScope();
146                    if (ec!=null) {
147                            if (getExtends()!=null) {
148                                    TypeInfo spr = ec.findType(getExtends());
149                                    if (spr!=null) {
150                                            ret = spr.findTypeVariable(name);
151                                            if (ret!=null) {
152                                                    return ret;
153                                            }
154                                    }
155                            }
156                            
157                            for (String cInterface: getImplements()) {
158                                    TypeInfo spr = ec.findType(cInterface);
159                                    if (spr!=null) {
160                                            ret = spr.findTypeVariable(name);
161                                            if (ret!=null) {
162                                                    return ret;
163                                            }
164                                    }
165                            }
166                    }
167                    return null;
168            }
169            
170    }