1 19 20 package jode.expr; 21 import jode.type.Type; 22 import jode.type.NullType; 23 import jode.type.ClassInterfacesType; 24 import jode.bytecode.FieldInfo; 25 import jode.bytecode.ClassInfo; 26 import jode.bytecode.Reference; 27 import jode.bytecode.InnerClassInfo; 28 import jode.bytecode.TypeSignature; 29 import jode.decompiler.MethodAnalyzer; 30 import jode.decompiler.ClassAnalyzer; 31 import jode.decompiler.MethodAnalyzer; 32 import jode.decompiler.FieldAnalyzer; 33 import jode.decompiler.Options; 34 import jode.decompiler.TabbedPrintWriter; 35 import jode.decompiler.Scope; 36 37 import java.lang.reflect.Modifier ; 38 import java.util.Collection ; 39 40 44 public abstract class FieldOperator extends Operator { 45 MethodAnalyzer methodAnalyzer; 46 boolean staticFlag; 47 Reference ref; 48 Type classType; 49 50 public FieldOperator(MethodAnalyzer methodAnalyzer, boolean staticFlag, 51 Reference ref) { 52 super(Type.tType(ref.getType())); 53 this.methodAnalyzer = methodAnalyzer; 54 this.staticFlag = staticFlag; 55 this.classType = Type.tType(ref.getClazz()); 56 this.ref = ref; 57 if (staticFlag) 58 methodAnalyzer.useType(classType); 59 initOperands(staticFlag ? 0 : 1); 60 } 61 62 public int getPriority() { 63 return 950; 64 } 65 66 public void updateSubTypes() { 67 if (!staticFlag) 68 subExpressions[0].setType(Type.tSubType(classType)); 69 } 70 71 public void updateType() { 72 updateParentType(getFieldType()); 73 } 74 75 public boolean isStatic() { 76 return staticFlag; 77 } 78 79 public ClassInfo getClassInfo() { 80 if (classType instanceof ClassInterfacesType) 81 return ((ClassInterfacesType) classType).getClassInfo(); 82 return null; 83 } 84 85 91 public FieldAnalyzer getField() { 92 ClassInfo clazz = getClassInfo(); 93 if (clazz != null) { 94 ClassAnalyzer ana = methodAnalyzer.getClassAnalyzer(); 95 while (true) { 96 if (clazz == ana.getClazz()) { 97 int field = ana.getFieldIndex 98 (ref.getName(), Type.tType(ref.getType())); 99 if (field >= 0) 100 return ana.getField(field); 101 return null; 102 } 103 if (ana.getParent() == null) 104 return null; 105 if (ana.getParent() instanceof MethodAnalyzer) 106 ana = ((MethodAnalyzer) ana.getParent()) 107 .getClassAnalyzer(); 108 else if (ana.getParent() instanceof ClassAnalyzer) 109 ana = (ClassAnalyzer) ana.getParent(); 110 else 111 throw new jode.AssertError("Unknown parent"); 112 } 113 } 114 return null; 115 } 116 117 public String getFieldName() { 118 return ref.getName(); 119 } 120 121 public Type getFieldType() { 122 return Type.tType(ref.getType()); 123 } 124 125 private static FieldInfo getFieldInfo(ClassInfo clazz, 126 String name, String type) { 127 while (clazz != null) { 128 FieldInfo field = clazz.findField(name, type); 129 if (field != null) 130 return field; 131 132 ClassInfo[] ifaces = clazz.getInterfaces(); 133 for (int i = 0; i < ifaces.length; i++) { 134 field = getFieldInfo(ifaces[i], name, type); 135 if (field != null) 136 return field; 137 } 138 139 clazz = clazz.getSuperclass(); 140 } 141 return null; 142 } 143 public FieldInfo getFieldInfo() { 144 ClassInfo clazz; 145 if (ref.getClazz().charAt(0) == '[') 146 clazz = ClassInfo.javaLangObject; 147 else 148 clazz = TypeSignature.getClassInfo(ref.getClazz()); 149 return getFieldInfo(clazz, ref.getName(), ref.getType()); 150 } 151 152 public boolean needsCast(Type type) { 153 if (type instanceof NullType) 154 return true; 155 if (!(type instanceof ClassInterfacesType 156 && classType instanceof ClassInterfacesType)) 157 return false; 158 159 ClassInfo clazz = ((ClassInterfacesType) classType).getClassInfo(); 160 ClassInfo parClazz = ((ClassInterfacesType) type).getClassInfo(); 161 FieldInfo field = clazz.findField(ref.getName(), ref.getType()); 162 163 find_field: 164 while (field == null) { 165 ClassInfo ifaces[] = clazz.getInterfaces(); 166 for (int i = 0; i < ifaces.length; i++) { 167 field = ifaces[i].findField(ref.getName(), ref.getType()); 168 if (field != null) 169 break find_field; 170 } 171 clazz = clazz.getSuperclass(); 172 if (clazz == null) 173 174 return false; 175 field = clazz.findField(ref.getName(), ref.getType()); 176 } 177 if (Modifier.isPrivate(field.getModifiers())) 178 return parClazz != clazz; 179 else if ((field.getModifiers() 180 & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) { 181 184 int lastDot = clazz.getName().lastIndexOf('.'); 185 if (lastDot == -1 186 || lastDot != parClazz.getName().lastIndexOf('.') 187 || !(parClazz.getName() 188 .startsWith(clazz.getName().substring(0,lastDot)))) 189 return true; 190 } 191 192 while (clazz != parClazz && clazz != null) { 193 FieldInfo[] fields = parClazz.getFields(); 194 for (int i = 0; i < fields.length; i++) { 195 if (fields[i].getName().equals(ref.getName())) 196 return true; 197 } 198 parClazz = parClazz.getSuperclass(); 199 } 200 return false; 201 } 202 203 public InnerClassInfo getOuterClassInfo(ClassInfo ci) { 204 if (ci != null) { 205 InnerClassInfo[] outers = ci.getOuterClasses(); 206 if (outers != null) 207 return outers[0]; 208 } 209 return null; 210 } 211 212 215 public void fillDeclarables(Collection used) { 216 ClassInfo clazz = getClassInfo(); 217 InnerClassInfo outer = getOuterClassInfo(clazz); 218 ClassAnalyzer clazzAna = methodAnalyzer.getClassAnalyzer(clazz); 219 220 if ((Options.options & Options.OPTION_ANON) != 0 221 && outer != null && outer.outer == null && outer.name != null 222 && clazzAna != null 223 && clazzAna.getParent() == methodAnalyzer) { 224 225 229 clazzAna.fillDeclarables(used); 230 used.add(clazzAna); 231 } 232 super.fillDeclarables(used); 233 } 234 235 public void dumpExpression(TabbedPrintWriter writer) 236 throws java.io.IOException { 237 boolean opIsThis = !staticFlag 238 && subExpressions[0] instanceof ThisOperator; 239 String fieldName = ref.getName(); 240 if (staticFlag) { 241 if (!classType.equals(Type.tClass(methodAnalyzer.getClazz())) 242 || methodAnalyzer.findLocal(fieldName) != null) { 243 writer.printType(classType); 244 writer.breakOp(); 245 writer.print("."); 246 } 247 writer.print(fieldName); 248 } else if (needsCast(subExpressions[0].getType().getCanonic())) { 249 writer.print("("); 250 writer.startOp(writer.EXPL_PAREN, 1); 251 writer.print("("); 252 writer.printType(classType); 253 writer.print(") "); 254 writer.breakOp(); 255 subExpressions[0].dumpExpression(writer, 700); 256 writer.endOp(); 257 writer.print(")"); 258 writer.breakOp(); 259 writer.print("."); 260 writer.print(fieldName); 261 } else { 262 if (opIsThis) { 263 ThisOperator thisOp = (ThisOperator) subExpressions[0]; 264 Scope scope = writer.getScope(thisOp.getClassInfo(), 265 Scope.CLASSSCOPE); 266 267 if (scope == null || writer.conflicts(fieldName, scope, 268 Scope.FIELDNAME)) { 269 thisOp.dumpExpression(writer, 950); 270 writer.breakOp(); 271 writer.print("."); 272 } else if (writer.conflicts(fieldName, scope, 273 Scope.AMBIGUOUSNAME) 274 || ( 277 getField() == null 278 && writer.conflicts(fieldName, null, 279 Scope.NOSUPERFIELDNAME))) { 280 thisOp.dumpExpression(writer, 950); 281 writer.breakOp(); 282 writer.print("."); 283 } 284 } else { 285 subExpressions[0].dumpExpression(writer, 950); 286 writer.breakOp(); 287 writer.print("."); 288 } 289 writer.print(fieldName); 290 } 291 } 292 } 293 | Popular Tags |