WALA: Provide acces to JSR 308 Annotations via new Class TypeAnnotation.

Access is provided via corresponding methods in FieldImpl, ShrikeCTMethod and ShrikeClass.
Since we do not currently have implementation of these methods for front-ends other than Shrike, these new methods are not yet made available in the corresponding interfaces.
This commit is contained in:
Martin Hecker 2016-12-02 13:31:45 +01:00
parent 92dc2929f2
commit de0f9c2a1f
5 changed files with 1161 additions and 6 deletions

View File

@ -31,6 +31,7 @@ import com.ibm.wala.types.Selector;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.types.annotations.Annotation;
import com.ibm.wala.types.annotations.TypeAnnotation;
import com.ibm.wala.types.generics.TypeSignature;
import com.ibm.wala.util.collections.BimodalMap;
import com.ibm.wala.util.collections.HashMapFactory;
@ -568,7 +569,7 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
}
protected void addFieldToList(List<FieldImpl> L, Atom name, ImmutableByteArray fieldType, int accessFlags,
Collection<Annotation> annotations, TypeSignature sig) {
Collection<Annotation> annotations, Collection<TypeAnnotation> typeAnnotations, TypeSignature sig) {
TypeName T = null;
if (fieldType.get(fieldType.length() - 1) == ';') {
T = TypeName.findOrCreate(fieldType, 0, fieldType.length() - 1);
@ -577,7 +578,7 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
}
TypeReference type = TypeReference.findOrCreate(getClassLoader().getReference(), T);
FieldReference fr = FieldReference.findOrCreate(getReference(), name, type);
FieldImpl f = new FieldImpl(this, fr, accessFlags, annotations, sig);
FieldImpl f = new FieldImpl(this, fr, accessFlags, annotations, typeAnnotations, sig);
L.add(f);
}

View File

@ -18,6 +18,7 @@ import com.ibm.wala.shrikeCT.ClassConstants;
import com.ibm.wala.types.FieldReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.types.annotations.Annotation;
import com.ibm.wala.types.annotations.TypeAnnotation;
import com.ibm.wala.types.generics.TypeSignature;
import com.ibm.wala.util.strings.Atom;
@ -34,14 +35,22 @@ public final class FieldImpl implements IField {
private final int accessFlags;
private final Collection<Annotation> annotations;
private final Collection<TypeAnnotation> typeAnnotations;
private final TypeSignature genericSignature;
public FieldImpl(IClass declaringClass, FieldReference canonicalRef, int accessFlags, Collection<Annotation> annotations, TypeSignature sig) {
this(declaringClass, canonicalRef, accessFlags, annotations, null, sig);
}
public FieldImpl(IClass declaringClass, FieldReference canonicalRef, int accessFlags, Collection<Annotation> annotations,
Collection<TypeAnnotation> typeAnnotations, TypeSignature sig) {
this.declaringClass = declaringClass;
this.fieldRef = canonicalRef;
this.accessFlags = accessFlags;
this.annotations = annotations;
this.typeAnnotations = typeAnnotations;
this.genericSignature = sig;
if (declaringClass == null) {
throw new IllegalArgumentException("null declaringClass");
@ -155,6 +164,8 @@ public final class FieldImpl implements IField {
public Collection<Annotation> getAnnotations() {
return annotations == null ? null : Collections.unmodifiableCollection(annotations);
}
public Collection<TypeAnnotation> getTypeAnnotations() {
return typeAnnotations == null ? null : Collections.unmodifiableCollection(typeAnnotations);
}
}

View File

@ -29,9 +29,11 @@ import com.ibm.wala.shrikeCT.LocalVariableTableReader;
import com.ibm.wala.shrikeCT.SignatureReader;
import com.ibm.wala.shrikeCT.SourcePositionTableReader;
import com.ibm.wala.shrikeCT.SourcePositionTableReader.Position;
import com.ibm.wala.shrikeCT.TypeAnnotationsReader;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.types.annotations.Annotation;
import com.ibm.wala.types.annotations.TypeAnnotation;
import com.ibm.wala.types.generics.MethodTypeSignature;
import com.ibm.wala.util.collections.HashSetFactory;
import com.ibm.wala.util.debug.Assertions;
@ -392,6 +394,22 @@ public final class ShrikeCTMethod extends ShrikeBTMethod implements IBytecodeMet
return AnnotationsReader.getReaderForAnnotation(type, iter);
}
private TypeAnnotationsReader getTypeAnnotationsReaderAtMethodInfo(TypeAnnotationsReader.AnnotationType type) {
ClassReader.AttrIterator iter = new AttrIterator();
getClassReader().initMethodAttributeIterator(shrikeMethodIndex, iter);
return TypeAnnotationsReader.getReaderForAnnotationAtMethodInfo(type, iter, getExceptionReader(), getSignatureReader());
}
private TypeAnnotationsReader getTypeAnnotationsReaderAtCode(TypeAnnotationsReader.AnnotationType type) {
final CodeReader codeReader = getCodeReader();
if (codeReader == null) return null;
ClassReader.AttrIterator iter = new ClassReader.AttrIterator();
codeReader.initAttributeIterator(iter);
return TypeAnnotationsReader.getReaderForAnnotationAtCode(type, iter, getCodeReader());
}
private String computeGenericsSignature() throws InvalidClassFileException {
SignatureReader reader = getSignatureReader();
@ -452,6 +470,32 @@ public final class ShrikeCTMethod extends ShrikeBTMethod implements IBytecodeMet
: AnnotationType.RuntimeVisibleAnnotations);
return Annotation.getAnnotationsFromReader(r, getDeclaringClass().getClassLoader().getReference());
}
public Collection<TypeAnnotation> getTypeAnnotationsAtMethodInfo(boolean runtimeInvisible) throws InvalidClassFileException {
TypeAnnotationsReader r = getTypeAnnotationsReaderAtMethodInfo(
runtimeInvisible ? TypeAnnotationsReader.AnnotationType.RuntimeInvisibleTypeAnnotations
: TypeAnnotationsReader.AnnotationType.RuntimeVisibleTypeAnnotations
);
final ClassLoaderReference clRef = getDeclaringClass().getClassLoader().getReference();
return TypeAnnotation.getTypeAnnotationsFromReader(
r,
TypeAnnotation.targetConverterAtMethodInfo(clRef, this),
clRef
);
}
public Collection<TypeAnnotation> getTypeAnnotationsAtCode(boolean runtimeInvisible) throws InvalidClassFileException {
TypeAnnotationsReader r = getTypeAnnotationsReaderAtCode(
runtimeInvisible ? TypeAnnotationsReader.AnnotationType.RuntimeInvisibleTypeAnnotations
: TypeAnnotationsReader.AnnotationType.RuntimeVisibleTypeAnnotations
);
final ClassLoaderReference clRef = getDeclaringClass().getClassLoader().getReference();
return TypeAnnotation.getTypeAnnotationsFromReader(
r,
TypeAnnotation.targetConverterAtCode(clRef, this),
clRef
);
}
@Override
public Collection<Annotation> getAnnotations() {

View File

@ -25,9 +25,12 @@ import com.ibm.wala.shrikeCT.ClassReader.AttrIterator;
import com.ibm.wala.shrikeCT.InnerClassesReader;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.shrikeCT.SignatureReader;
import com.ibm.wala.shrikeCT.TypeAnnotationsReader;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.types.annotations.Annotation;
import com.ibm.wala.types.annotations.TypeAnnotation;
import com.ibm.wala.types.generics.ClassSignature;
import com.ibm.wala.types.generics.TypeSignature;
import com.ibm.wala.util.collections.HashSetFactory;
@ -89,6 +92,11 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
annotations.addAll(getRuntimeVisibleAnnotations(i));
annotations = annotations.isEmpty() ? null : annotations;
Collection<TypeAnnotation> typeAnnotations = HashSetFactory.make();
typeAnnotations.addAll(getRuntimeInvisibleTypeAnnotations(i));
typeAnnotations.addAll(getRuntimeVisibleTypeAnnotations(i));
typeAnnotations = typeAnnotations.isEmpty() ? null : typeAnnotations;
TypeSignature sig = null;
SignatureReader signatureReader = getSignatureReader(i);
if (signatureReader != null) {
@ -99,9 +107,9 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
}
if ((accessFlags & ClassConstants.ACC_STATIC) == 0) {
addFieldToList(instanceList, name, b, accessFlags, annotations, sig);
addFieldToList(instanceList, name, b, accessFlags, annotations, typeAnnotations, sig);
} else {
addFieldToList(staticList, name, b, accessFlags, annotations, sig);
addFieldToList(staticList, name, b, accessFlags, annotations, typeAnnotations, sig);
}
}
instanceFields = new IField[instanceList.size()];
@ -268,6 +276,29 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
return AnnotationsReader.getReaderForAnnotation(runtimeInvisable ? AnnotationType.RuntimeInvisibleAnnotations
: AnnotationType.RuntimeVisibleAnnotations, attrs);
}
public Collection<TypeAnnotation> getTypeAnnotations(boolean runtimeInvisible) throws InvalidClassFileException {
TypeAnnotationsReader r = getTypeAnnotationsReader(runtimeInvisible);
final ClassLoaderReference clRef = getClassLoader().getReference();
return TypeAnnotation.getTypeAnnotationsFromReader(
r,
TypeAnnotation.targetConverterAtClassFile(clRef),
clRef
);
}
private TypeAnnotationsReader getTypeAnnotationsReader(boolean runtimeInvisible) throws InvalidClassFileException {
ClassReader r = reader.get();
ClassReader.AttrIterator attrs = new ClassReader.AttrIterator();
r.initClassAttributeIterator(attrs);
return TypeAnnotationsReader.getReaderForAnnotationAtClassfile(
runtimeInvisible ? TypeAnnotationsReader.AnnotationType.RuntimeInvisibleTypeAnnotations
: TypeAnnotationsReader.AnnotationType.RuntimeVisibleTypeAnnotations,
attrs,
getSignatureReader(-1)
);
}
private InnerClassesReader getInnerClassesReader() throws InvalidClassFileException {
ClassReader r = reader.get();
@ -315,6 +346,43 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
AnnotationsReader r = getFieldAnnotationsReader(runtimeInvisible, fieldIndex);
return Annotation.getAnnotationsFromReader(r, getClassLoader().getReference());
}
private TypeAnnotationsReader getFieldTypeAnnotationsReader(boolean runtimeInvisible, int fieldIndex) throws InvalidClassFileException {
ClassReader.AttrIterator iter = new AttrIterator();
reader.get().initFieldAttributeIterator(fieldIndex, iter);
return TypeAnnotationsReader.getReaderForAnnotationAtFieldInfo(
runtimeInvisible ? TypeAnnotationsReader.AnnotationType.RuntimeInvisibleTypeAnnotations
: TypeAnnotationsReader.AnnotationType.RuntimeVisibleTypeAnnotations,
iter
);
}
/**
* read the runtime-invisible type annotations from the class file
*/
public Collection<TypeAnnotation> getRuntimeInvisibleTypeAnnotations(int fieldIndex) throws InvalidClassFileException {
return getFieldTypeAnnotations(fieldIndex, true);
}
/**
* read the runtime-visible type annotations from the class file
*/
public Collection<TypeAnnotation> getRuntimeVisibleTypeAnnotations(int fieldIndex) throws InvalidClassFileException {
return getFieldTypeAnnotations(fieldIndex, false);
}
protected Collection<TypeAnnotation> getFieldTypeAnnotations(int fieldIndex, boolean runtimeInvisible) throws InvalidClassFileException {
TypeAnnotationsReader r = getFieldTypeAnnotationsReader(runtimeInvisible, fieldIndex);
final ClassLoaderReference clRef = getClassLoader().getReference();
return TypeAnnotation.getTypeAnnotationsFromReader(
r,
TypeAnnotation.targetConverterAtFieldInfo(clRef),
clRef
);
}
private SignatureReader getSignatureReader(int index) throws InvalidClassFileException {
ClassReader r = reader.get();

File diff suppressed because it is too large Load Diff