001 package org.mesopotamia.lang.java; 002 003 import java.util.List; 004 005 import org.mesopotamia.LanguageElement; 006 import org.mesopotamia.MesopotamiaException; 007 import org.mesopotamia.MesopotamiaNode; 008 import org.mesopotamia.NodeData; 009 import org.mesopotamia.RepositoryLanguage; 010 import org.mesopotamia.Scan; 011 import org.mesopotamia.lang.java.ref.Info; 012 import org.mesopotamia.lang.java.ref.Scope; 013 import org.mesopotamia.lang.java.ref.TypeInfo; 014 import org.mesopotamia.lang.java.ref.TypeSpecInfo; 015 import org.mesopotamia.lang.java.ref.VariableInfo; 016 import org.mesopotamia.util.UnmodifiableConvertingList; 017 import org.w3c.dom.Element; 018 019 import biz.hammurapi.util.CollectionVisitable; 020 import biz.hammurapi.util.Visitor; 021 022 public class Identifier extends PrimaryExpression implements Type { 023 024 public Identifier(NodeData xData, Class<?> context, Scan scan, RepositoryLanguage language, Object environment) throws MesopotamiaException { 025 super(xData, context, scan, language, environment); 026 } 027 028 public void toDom(Element holder) { 029 super.toDom(holder); 030 031 // Serialize attributes 032 setElement(holder, "TypeArguments", TypeArguments); 033 } 034 035 // Attributes 036 private UnmodifiableConvertingList<TypeArgument> TypeArguments; 037 038 /** 039 * Full text with dots. 040 */ 041 public String getPath() { 042 if (providerHandle==null) { 043 return nodeText(getNode()); 044 } 045 046 MesopotamiaNode providerNode = getSourceUnit().getSyntaxTree().findNode(providerHandle.getId()); 047 return nodeText("DOT".equals(providerNode.getParent().getTypeName()) ? providerNode.getParent() : providerNode); 048 } 049 050 // Accessors 051 public List<TypeArgument> getTypeArguments() { 052 return TypeArguments; 053 } 054 055 protected void acceptChildren(Visitor visitor) { 056 // super.acceptChildren(visitor); 057 // Visiting non-text attributes 058 new CollectionVisitable(TypeArguments, false).accept(visitor); 059 } 060 061 /** 062 * Constructs string from DOT tree. 063 * @param mn 064 * @return 065 */ 066 public static String nodeText(MesopotamiaNode mn) { 067 if ("DOT".equals(mn.getTypeName()) && mn.getChildren().size()==2) { 068 return nodeText((MesopotamiaNode) mn.getChildren().get(0))+"."+nodeText((MesopotamiaNode) mn.getChildren().get(1)); 069 } 070 071 if ("IDENT".equals(mn.getTypeName())) { 072 return mn.getText(); 073 } 074 075 if (mn.getChildren().size()==1) { 076 return nodeText((MesopotamiaNode) mn.getChildren().get(0)); 077 } 078 079 return null; 080 } 081 082 public Info getInfo() { 083 return getInfo(findParent(Scope.class)); 084 } 085 086 Info getInfo(Scope es) { 087 if (getText()==null) { 088 return null; 089 } 090 LanguageElement provider = getProvider(); 091 if (provider == null) { 092 if (es!=null) { 093 VariableInfo ret = es.findVariable(getText()); 094 if (ret!=null) { 095 return ret; 096 } 097 return es.findType(getText()); 098 } 099 } else { 100 TypeSpecInfo typeSpecInfo = null; 101 if (provider instanceof Identifier) { 102 typeSpecInfo = ((Identifier) provider).getTypeSpecInfo(es); 103 } else if (provider instanceof MethodCall) { 104 typeSpecInfo = ((MethodCall) provider).getTypeSpecInfo(es); 105 } else if (provider instanceof Expression) { 106 typeSpecInfo = ((Expression) provider).getTypeSpecInfo(); 107 } 108 109 if (typeSpecInfo!=null) { 110 TypeInfo ti = TypeSpecification.toTypeInfo(typeSpecInfo, es); 111 if (ti!=null) { 112 TypeInfo type = ti.findNestedType(getText()); 113 if (type!=null) { 114 return type; 115 } 116 return ti.findTypeVariable(getText()); 117 } 118 } 119 120 // FCN? 121 if (es!=null) { 122 String path = getPath(); 123 VariableInfo vi = es.findVariable(path); 124 if (vi!=null) { 125 return vi; 126 } 127 128 TypeInfo ti = es.findType(path); 129 if (ti!=null) { 130 return ti; 131 } 132 133 } 134 } 135 return null; 136 } 137 138 @Override 139 public TypeSpecInfo getTypeSpecInfo() { 140 return getTypeSpecInfo(findParent(Scope.class)); 141 } 142 143 public TypeSpecInfo getTypeSpecInfo(Scope scope) { 144 final Info info = getInfo(scope); 145 if (info instanceof TypeInfo) { 146 return new TypeSpecInfo() { 147 148 public int getDimensions() { 149 return 0; 150 } 151 152 public TypeInfo getTypeInfo() { 153 return (TypeInfo) info; 154 } 155 156 }; 157 } else if (info instanceof VariableInfo) { 158 return ((VariableInfo) info).getTypeSpecification(); 159 } 160 return null; 161 } 162 163 }