1 11 package org.eclipse.jdt.internal.compiler.classfmt; 12 13 import org.eclipse.jdt.core.compiler.CharOperation; 14 import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants; 15 import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation; 16 import org.eclipse.jdt.internal.compiler.env.IBinaryField; 17 import org.eclipse.jdt.internal.compiler.impl.*; 18 import org.eclipse.jdt.internal.compiler.lookup.TypeIds; 19 import org.eclipse.jdt.internal.compiler.util.Util; 20 21 public class FieldInfo extends ClassFileStruct implements IBinaryField, Comparable { 22 protected int accessFlags; 23 protected int attributeBytes; 24 protected Constant constant; 25 protected char[] descriptor; 26 protected char[] name; 27 protected char[] signature; 28 protected int signatureUtf8Offset; 29 protected long tagBits; 30 protected Object wrappedConstantValue; 31 32 public static FieldInfo createField(byte classFileBytes[], int offsets[], int offset) { 33 FieldInfo fieldInfo = new FieldInfo(classFileBytes, offsets, offset); 34 AnnotationInfo[] annotations = fieldInfo.readAttributes(); 35 if (annotations == null) 36 return fieldInfo; 37 return new FieldInfoWithAnnotation(fieldInfo, annotations); 38 } 39 40 45 protected FieldInfo (byte classFileBytes[], int offsets[], int offset) { 46 super(classFileBytes, offsets, offset); 47 this.accessFlags = -1; 48 this.signatureUtf8Offset = -1; 49 } 50 private AnnotationInfo[] decodeAnnotations(int offset, boolean runtimeVisible) { 51 int numberOfAnnotations = u2At(offset + 6); 52 if (numberOfAnnotations > 0) { 53 int readOffset = offset + 8; 54 AnnotationInfo[] newInfos = null; 55 int newInfoCount = 0; 56 for (int i = 0; i < numberOfAnnotations; i++) { 57 AnnotationInfo newInfo = new AnnotationInfo(this.reference, this.constantPoolOffsets, 59 readOffset + this.structOffset, runtimeVisible, false); 60 readOffset += newInfo.readOffset; 61 long standardTagBits = newInfo.standardAnnotationTagBits; 62 if (standardTagBits != 0) { 63 this.tagBits |= standardTagBits; 64 } else { 65 if (newInfos == null) 66 newInfos = new AnnotationInfo[numberOfAnnotations - i]; 67 newInfos[newInfoCount++] = newInfo; 68 } 69 } 70 if (newInfos != null) { 71 if (newInfoCount != newInfos.length) 72 System.arraycopy(newInfos, 0, newInfos = new AnnotationInfo[newInfoCount], 0, newInfoCount); 73 return newInfos; 74 } 75 } 76 return null; } 78 public int compareTo(Object o) { 79 if (!(o instanceof FieldInfo)) { 80 throw new ClassCastException (); 81 } 82 return new String (this.getName()).compareTo(new String (((FieldInfo) o).getName())); 83 } 84 89 public Constant getConstant() { 90 if (constant == null) { 91 readConstantAttribute(); 93 } 94 return constant; 95 } 96 public char[] getGenericSignature() { 97 if (this.signatureUtf8Offset != -1) { 98 if (this.signature == null) { 99 this.signature = utf8At(this.signatureUtf8Offset + 3, u2At(this.signatureUtf8Offset + 1)); 101 } 102 return this.signature; 103 } 104 return null; 105 } 106 112 public int getModifiers() { 113 if (this.accessFlags == -1) { 114 this.accessFlags = u2At(0); 116 readModifierRelatedAttributes(); 117 } 118 return this.accessFlags; 119 } 120 124 public char[] getName() { 125 if (name == null) { 126 int utf8Offset = constantPoolOffsets[u2At(2)] - structOffset; 128 name = utf8At(utf8Offset + 3, u2At(utf8Offset + 1)); 129 } 130 return name; 131 } 132 public long getTagBits() { 133 return this.tagBits; 134 } 135 146 public char[] getTypeName() { 147 if (descriptor == null) { 148 int utf8Offset = constantPoolOffsets[u2At(4)] - structOffset; 150 descriptor = utf8At(utf8Offset + 3, u2At(utf8Offset + 1)); 151 } 152 return descriptor; 153 } 154 157 public IBinaryAnnotation[] getAnnotations() { 158 return null; 159 } 160 164 public Object getWrappedConstantValue() { 165 166 if (this.wrappedConstantValue == null) { 167 if (hasConstant()) { 168 Constant fieldConstant = getConstant(); 169 switch (fieldConstant.typeID()) { 170 case TypeIds.T_int : 171 this.wrappedConstantValue = new Integer (fieldConstant.intValue()); 172 break; 173 case TypeIds.T_byte : 174 this.wrappedConstantValue = new Byte (fieldConstant.byteValue()); 175 break; 176 case TypeIds.T_short : 177 this.wrappedConstantValue = new Short (fieldConstant.shortValue()); 178 break; 179 case TypeIds.T_char : 180 this.wrappedConstantValue = new Character (fieldConstant.charValue()); 181 break; 182 case TypeIds.T_float : 183 this.wrappedConstantValue = new Float (fieldConstant.floatValue()); 184 break; 185 case TypeIds.T_double : 186 this.wrappedConstantValue = new Double (fieldConstant.doubleValue()); 187 break; 188 case TypeIds.T_boolean : 189 this.wrappedConstantValue = Util.toBoolean(fieldConstant.booleanValue()); 190 break; 191 case TypeIds.T_long : 192 this.wrappedConstantValue = new Long (fieldConstant.longValue()); 193 break; 194 case TypeIds.T_JavaLangString : 195 this.wrappedConstantValue = fieldConstant.stringValue(); 196 } 197 } 198 } 199 return this.wrappedConstantValue; 200 } 201 205 public boolean hasConstant() { 206 return getConstant() != Constant.NotAConstant; 207 } 208 212 protected void initialize() { 213 getModifiers(); 214 getName(); 215 getConstant(); 216 getTypeName(); 217 getGenericSignature(); 218 reset(); 219 } 220 224 public boolean isSynthetic() { 225 return (getModifiers() & ClassFileConstants.AccSynthetic) != 0; 226 } 227 private AnnotationInfo[] readAttributes() { 228 int attributesCount = u2At(6); 229 int readOffset = 8; 230 AnnotationInfo[] annotations = null; 231 for (int i = 0; i < attributesCount; i++) { 232 int utf8Offset = this.constantPoolOffsets[u2At(readOffset)] - this.structOffset; 234 char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1)); 235 if (attributeName.length > 0) { 236 switch(attributeName[0]) { 237 case 'S' : 238 if (CharOperation.equals(AttributeNamesConstants.SignatureName, attributeName)) 239 this.signatureUtf8Offset = this.constantPoolOffsets[u2At(readOffset + 6)] - this.structOffset; 240 break; 241 case 'R' : 242 AnnotationInfo[] decodedAnnotations = null; 243 if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeVisibleAnnotationsName)) { 244 decodedAnnotations = decodeAnnotations(readOffset, true); 245 } else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeInvisibleAnnotationsName)) { 246 decodedAnnotations = decodeAnnotations(readOffset, false); 247 } 248 if (decodedAnnotations != null) { 249 if (annotations == null) { 250 annotations = decodedAnnotations; 251 } else { 252 int length = annotations.length; 253 AnnotationInfo[] combined = new AnnotationInfo[length + decodedAnnotations.length]; 254 System.arraycopy(annotations, 0, combined, 0, length); 255 System.arraycopy(decodedAnnotations, 0, combined, length, decodedAnnotations.length); 256 annotations = combined; 257 } 258 } 259 } 260 } 261 readOffset += (6 + u4At(readOffset + 2)); 262 } 263 this.attributeBytes = readOffset; 264 return annotations; 265 } 266 private void readConstantAttribute() { 267 int attributesCount = u2At(6); 268 int readOffset = 8; 269 boolean isConstant = false; 270 for (int i = 0; i < attributesCount; i++) { 271 int utf8Offset = constantPoolOffsets[u2At(readOffset)] - structOffset; 272 char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1)); 273 if (CharOperation 274 .equals(attributeName, AttributeNamesConstants.ConstantValueName)) { 275 isConstant = true; 276 int relativeOffset = constantPoolOffsets[u2At(readOffset + 6)] - structOffset; 278 switch (u1At(relativeOffset)) { 279 case ClassFileConstants.IntegerTag : 280 char[] sign = getTypeName(); 281 if (sign.length == 1) { 282 switch (sign[0]) { 283 case 'Z' : constant = BooleanConstant.fromValue(i4At(relativeOffset + 1) == 1); 285 break; 286 case 'I' : constant = IntConstant.fromValue(i4At(relativeOffset + 1)); 288 break; 289 case 'C' : constant = CharConstant.fromValue((char) i4At(relativeOffset + 1)); 291 break; 292 case 'B' : constant = ByteConstant.fromValue((byte) i4At(relativeOffset + 1)); 294 break; 295 case 'S' : constant = ShortConstant.fromValue((short) i4At(relativeOffset + 1)); 297 break; 298 default: 299 constant = Constant.NotAConstant; 300 } 301 } else { 302 constant = Constant.NotAConstant; 303 } 304 break; 305 case ClassFileConstants.FloatTag : 306 constant = FloatConstant.fromValue(floatAt(relativeOffset + 1)); 307 break; 308 case ClassFileConstants.DoubleTag : 309 constant = DoubleConstant.fromValue(doubleAt(relativeOffset + 1)); 310 break; 311 case ClassFileConstants.LongTag : 312 constant = LongConstant.fromValue(i8At(relativeOffset + 1)); 313 break; 314 case ClassFileConstants.StringTag : 315 utf8Offset = constantPoolOffsets[u2At(relativeOffset + 1)] - structOffset; 316 constant = 317 StringConstant.fromValue( 318 String.valueOf(utf8At(utf8Offset + 3, u2At(utf8Offset + 1)))); 319 break; 320 } 321 } 322 readOffset += (6 + u4At(readOffset + 2)); 323 } 324 if (!isConstant) { 325 constant = Constant.NotAConstant; 326 } 327 } 328 private void readModifierRelatedAttributes() { 329 int attributesCount = u2At(6); 330 int readOffset = 8; 331 for (int i = 0; i < attributesCount; i++) { 332 int utf8Offset = constantPoolOffsets[u2At(readOffset)] - structOffset; 333 char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1)); 334 if (attributeName.length != 0) { 336 switch(attributeName[0]) { 337 case 'D' : 338 if (CharOperation.equals(attributeName, AttributeNamesConstants.DeprecatedName)) 339 this.accessFlags |= ClassFileConstants.AccDeprecated; 340 break; 341 case 'S' : 342 if (CharOperation.equals(attributeName, AttributeNamesConstants.SyntheticName)) 343 this.accessFlags |= ClassFileConstants.AccSynthetic; 344 break; 345 } 346 } 347 readOffset += (6 + u4At(readOffset + 2)); 348 } 349 } 350 355 public int sizeInBytes() { 356 return attributeBytes; 357 } 358 public void throwFormatException() throws ClassFormatException { 359 throw new ClassFormatException(ClassFormatException.ErrBadFieldInfo); 360 } 361 public String toString() { 362 StringBuffer buffer = new StringBuffer (this.getClass().getName()); 363 toStringContent(buffer); 364 return buffer.toString(); 365 } 366 protected void toStringContent(StringBuffer buffer) { 367 int modifiers = getModifiers(); 368 buffer 369 .append('{') 370 .append( 371 ((modifiers & ClassFileConstants.AccDeprecated) != 0 ? "deprecated " : Util.EMPTY_STRING) + ((modifiers & 0x0001) == 1 ? "public " : Util.EMPTY_STRING) + ((modifiers & 0x0002) == 0x0002 ? "private " : Util.EMPTY_STRING) + ((modifiers & 0x0004) == 0x0004 ? "protected " : Util.EMPTY_STRING) + ((modifiers & 0x0008) == 0x000008 ? "static " : Util.EMPTY_STRING) + ((modifiers & 0x0010) == 0x0010 ? "final " : Util.EMPTY_STRING) + ((modifiers & 0x0040) == 0x0040 ? "volatile " : Util.EMPTY_STRING) + ((modifiers & 0x0080) == 0x0080 ? "transient " : Util.EMPTY_STRING)) .append(getTypeName()) 380 .append(' ') 381 .append(getName()) 382 .append(' ') 383 .append(getConstant()) 384 .append('}') 385 .toString(); 386 } 387 } 388 | Popular Tags |