support for reading method parameter annotations from Java bytecodes

This commit is contained in:
Manu Sridharan 2013-06-28 11:00:31 -04:00
parent 31d3bf835e
commit b984760100
9 changed files with 246 additions and 156 deletions

View File

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2013 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package annotations;
public class ParameterAnnotations1 {
public static void foo(@RuntimeVisableAnnotation String s) {
}
public static void bar(@AnnotationWithParams(enumParam=AnnotationEnum.VAL1,strArrParam={"biz","boz"},annotParam=@AnnotationWithSingleParam("sdfevs"),strParam="sdfsevs",intParam=25,klassParam=Integer.class) Integer i) {
}
public static void foo2(@RuntimeVisableAnnotation String s, @RuntimeInvisableAnnotation Integer i) {
}
public void foo3(@RuntimeVisableAnnotation String s, @RuntimeInvisableAnnotation Integer i) {
}
public void foo4(@RuntimeInvisableAnnotation @RuntimeVisableAnnotation String s, Integer i) {
}
}

View File

@ -172,4 +172,43 @@ public class AnnotationTest extends WalaTestCase {
annots.toString());
}
@Test
public void testParamAnnotations1() throws Exception {
TypeReference typeRef = TypeReference.findOrCreate(ClassLoaderReference.Application, "Lannotations/ParameterAnnotations1");
checkParameterAnnots(typeRef, "foo(Ljava/lang/String;)V",
"[Annotation type <Application,Lannotations/RuntimeVisableAnnotation>]");
checkParameterAnnots(
typeRef,
"bar(Ljava/lang/Integer;)V",
"[Annotation type <Application,Lannotations/AnnotationWithParams> {enumParam=EnumElementValue [type=Lannotations/AnnotationEnum;, val=VAL1], strArrParam=ArrayElementValue [vals=[biz, boz]], annotParam=AnnotationElementValue [type=Lannotations/AnnotationWithSingleParam;, elementValues={value=sdfevs}], strParam=sdfsevs, intParam=25, klassParam=Ljava/lang/Integer;}]");
checkParameterAnnots(typeRef, "foo2(Ljava/lang/String;Ljava/lang/Integer;)V",
"[Annotation type <Application,Lannotations/RuntimeVisableAnnotation>]",
"[Annotation type <Application,Lannotations/RuntimeInvisableAnnotation>]");
checkParameterAnnots(typeRef, "foo3(Ljava/lang/String;Ljava/lang/Integer;)V",
"[Annotation type <Application,Lannotations/RuntimeVisableAnnotation>]",
"[Annotation type <Application,Lannotations/RuntimeInvisableAnnotation>]");
checkParameterAnnots(typeRef, "foo4(Ljava/lang/String;Ljava/lang/Integer;)V",
"[Annotation type <Application,Lannotations/RuntimeInvisableAnnotation>, Annotation type <Application,Lannotations/RuntimeVisableAnnotation>]",
"[]");
}
protected void checkParameterAnnots(TypeReference typeRef, String selector, String... expected) {
MethodReference methodRefUnderTest = MethodReference.findOrCreate(typeRef, Selector.make(selector));
IMethod methodUnderTest = cha.resolveMethod(methodRefUnderTest);
Assert.assertNotNull(methodRefUnderTest.toString() + " not found", methodUnderTest);
Assert.assertTrue(methodUnderTest instanceof ShrikeCTMethod);
ShrikeCTMethod shrikeCTMethodUnderTest = (ShrikeCTMethod) methodUnderTest;
Collection<Annotation>[] parameterAnnotations = shrikeCTMethodUnderTest.getParameterAnnotations();
Assert.assertEquals(expected.length, parameterAnnotations.length);
for (int i = 0; i < expected.length; i++) {
Assert.assertEquals(expected[i], parameterAnnotations[i].toString());
}
}
}

View File

@ -17,6 +17,7 @@ import com.ibm.wala.shrikeBT.Decoder;
import com.ibm.wala.shrikeBT.IndirectionData;
import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder;
import com.ibm.wala.shrikeCT.AnnotationsReader;
import com.ibm.wala.shrikeCT.AnnotationsReader.AnnotationType;
import com.ibm.wala.shrikeCT.ClassReader;
import com.ibm.wala.shrikeCT.ClassReader.AttrIterator;
import com.ibm.wala.shrikeCT.CodeReader;
@ -24,9 +25,8 @@ import com.ibm.wala.shrikeCT.ExceptionsReader;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.shrikeCT.LineNumberTableReader;
import com.ibm.wala.shrikeCT.LocalVariableTableReader;
import com.ibm.wala.shrikeCT.RuntimeInvisibleAnnotationsReader;
import com.ibm.wala.shrikeCT.RuntimeVisibleAnnotationsReader;
import com.ibm.wala.shrikeCT.SignatureReader;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.types.annotations.Annotation;
import com.ibm.wala.types.generics.MethodTypeSignature;
@ -273,30 +273,11 @@ public final class ShrikeCTMethod extends ShrikeBTMethod implements IBytecodeMet
return result;
}
private AnnotationsReader getAnnotationsReader(boolean runtimeInvisible) {
private AnnotationsReader getAnnotationsReader(AnnotationType type) {
ClassReader.AttrIterator iter = new AttrIterator();
getClassReader().initMethodAttributeIterator(shrikeMethodIndex, iter);
// search for the desired attribute
AnnotationsReader result = null;
try {
for (; iter.isValid(); iter.advance()) {
if (runtimeInvisible) {
if (iter.getName().equals(RuntimeInvisibleAnnotationsReader.attrName)) {
result = new RuntimeInvisibleAnnotationsReader(iter);
break;
}
} else {
if (iter.getName().equals(RuntimeVisibleAnnotationsReader.attrName)) {
result = new RuntimeVisibleAnnotationsReader(iter);
break;
}
}
}
} catch (InvalidClassFileException e) {
Assertions.UNREACHABLE();
}
return result;
return AnnotationsReader.getReaderForAnnotation(type, iter);
}
private String computeGenericsSignature() throws InvalidClassFileException {
@ -353,7 +334,8 @@ public final class ShrikeCTMethod extends ShrikeBTMethod implements IBytecodeMet
}
public Collection<Annotation> getAnnotations(boolean runtimeInvisible) throws InvalidClassFileException {
AnnotationsReader r = getAnnotationsReader(runtimeInvisible);
AnnotationsReader r = getAnnotationsReader(runtimeInvisible ? AnnotationType.RuntimeInvisibleAnnotations
: AnnotationType.RuntimeVisibleAnnotations);
return Annotation.getAnnotationsFromReader(r, getDeclaringClass().getClassLoader().getReference());
}
@ -369,6 +351,42 @@ public final class ShrikeCTMethod extends ShrikeBTMethod implements IBytecodeMet
return result;
}
/**
* get annotations on parameters as an array of Collections, where each array
* element gives the annotations on the corresponding parameter. Note that the
* 'this' parameter for an instance method cannot have annotations.
*/
public Collection<Annotation>[] getParameterAnnotations() {
int numAnnotatedParams = isStatic() ? getNumberOfParameters() : getNumberOfParameters() - 1;
@SuppressWarnings("unchecked")
Collection<Annotation>[] result = new Collection[numAnnotatedParams];
for (int i = 0; i < result.length; i++) {
result[i] = HashSetFactory.make();
}
try {
ClassLoaderReference reference = getDeclaringClass().getClassLoader().getReference();
AnnotationsReader r = getAnnotationsReader(AnnotationType.RuntimeInvisibleParameterAnnotations);
Collection<Annotation>[] paramAnnots = Annotation.getParameterAnnotationsFromReader(r, reference);
if (paramAnnots != null) {
assert paramAnnots.length == result.length : paramAnnots.length + " != " + result.length;
for (int i = 0; i < result.length; i++) {
result[i].addAll(paramAnnots[i]);
}
}
r = getAnnotationsReader(AnnotationType.RuntimeVisibleParameterAnnotations);
paramAnnots = Annotation.getParameterAnnotationsFromReader(r, reference);
if (paramAnnots != null) {
assert paramAnnots.length == result.length;
for (int i = 0; i < result.length; i++) {
result[i].addAll(paramAnnots[i]);
}
}
} catch (InvalidClassFileException e) {
e.printStackTrace();
}
return result;
}
private static final IndirectionData NO_INDIRECTIONS = new IndirectionData() {
private final int[] NOTHING = new int[0];

View File

@ -18,13 +18,12 @@ import java.util.List;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.shrikeBT.Constants;
import com.ibm.wala.shrikeCT.AnnotationsReader;
import com.ibm.wala.shrikeCT.AnnotationsReader.AnnotationType;
import com.ibm.wala.shrikeCT.ClassConstants;
import com.ibm.wala.shrikeCT.ClassReader;
import com.ibm.wala.shrikeCT.ClassReader.AttrIterator;
import com.ibm.wala.shrikeCT.InnerClassesReader;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.shrikeCT.RuntimeInvisibleAnnotationsReader;
import com.ibm.wala.shrikeCT.RuntimeVisibleAnnotationsReader;
import com.ibm.wala.shrikeCT.SignatureReader;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.TypeReference;
@ -47,9 +46,10 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
* The Shrike object that knows how to read the class file
*/
private final ShrikeClassReaderHandle reader;
/**
* @throws IllegalArgumentException if reader is null
* @throws IllegalArgumentException
* if reader is null
*/
public ShrikeClass(ShrikeClassReaderHandle reader, IClassLoader loader, IClassHierarchy cha) throws InvalidClassFileException {
super(loader, cha);
@ -70,7 +70,8 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
/**
* Compute the fields declared by this class
*
* @throws InvalidClassFileException iff Shrike fails to read the class file correctly
* @throws InvalidClassFileException
* iff Shrike fails to read the class file correctly
*/
private void computeFields() throws InvalidClassFileException {
ClassReader cr = reader.get();
@ -82,7 +83,7 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
int accessFlags = cr.getFieldAccessFlags(i);
Atom name = Atom.findOrCreateUnicodeAtom(cr.getFieldName(i));
ImmutableByteArray b = ImmutableByteArray.make(cr.getFieldType(i));
Collection<Annotation> annotations = HashSetFactory.make();
Collection<Annotation> annotations = HashSetFactory.make();
annotations.addAll(getRuntimeInvisibleAnnotations(i));
annotations.addAll(getRuntimeVisibleAnnotations(i));
annotations = annotations.isEmpty() ? null : annotations;
@ -111,9 +112,11 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
modifiers = reader.get().getAccessFlags();
}
/**
* Note that this is called from the constructor, at which point this class is not yet ready to actually load the superclass.
* Instead, we pull out the name of the superclass and cache it here, to avoid hitting the reader later.
/**
* Note that this is called from the constructor, at which point this class is
* not yet ready to actually load the superclass. Instead, we pull out the
* name of the superclass and cache it here, to avoid hitting the reader
* later.
*/
private void computeSuperName() {
try {
@ -127,8 +130,10 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
}
/**
* Note that this is called from the constructor, at which point this class is not yet ready to actually load the interfaces.
* Instead, we pull out the name of the interfaces and cache it here, to avoid hitting the reader later.
* Note that this is called from the constructor, at which point this class is
* not yet ready to actually load the interfaces. Instead, we pull out the
* name of the interfaces and cache it here, to avoid hitting the reader
* later.
*/
private void computeInterfaceNames() {
try {
@ -161,11 +166,11 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
return result;
}
/**
* initialize the TypeReference field for this instance
*
* @throws InvalidClassFileException iff Shrike can't read this class
* @throws InvalidClassFileException
* iff Shrike can't read this class
*/
private void computeTypeReference() throws InvalidClassFileException {
String className = "L" + reader.get().getName();
@ -174,7 +179,6 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
typeReference = TypeReference.findOrCreate(getClassLoader().getReference(), TypeName.findOrCreate(name));
}
/**
* @see java.lang.Object#equals(Object)
*/
@ -198,7 +202,7 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
return null;
}
}
/**
* Clear all optional cached data associated with this class
*/
@ -227,7 +231,7 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
public Collection<Annotation> getRuntimeVisibleAnnotations() throws InvalidClassFileException {
return getAnnotations(false);
}
@Override
public Collection<Annotation> getAnnotations() {
Collection<Annotation> result = HashSetFactory.make();
@ -235,7 +239,7 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
result.addAll(getAnnotations(true));
result.addAll(getAnnotations(false));
} catch (InvalidClassFileException e) {
}
return result;
}
@ -250,29 +254,10 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
ClassReader.AttrIterator attrs = new ClassReader.AttrIterator();
r.initClassAttributeIterator(attrs);
// search for the desired attribute
AnnotationsReader result = null;
try {
for (; attrs.isValid(); attrs.advance()) {
if (runtimeInvisable){
if (attrs.getName().equals(RuntimeInvisibleAnnotationsReader.attrName)) {
result = new RuntimeInvisibleAnnotationsReader(attrs);
break;
}
} else {
if (attrs.getName().equals(RuntimeVisibleAnnotationsReader.attrName)) {
result = new RuntimeVisibleAnnotationsReader(attrs);
break;
}
}
}
} catch (InvalidClassFileException e) {
Assertions.UNREACHABLE();
}
return result;
return AnnotationsReader.getReaderForAnnotation(runtimeInvisable ? AnnotationType.RuntimeInvisibleAnnotations
: AnnotationType.RuntimeVisibleAnnotations, attrs);
}
private InnerClassesReader getInnerClassesReader() throws InvalidClassFileException {
ClassReader r = reader.get();
ClassReader.AttrIterator attrs = new ClassReader.AttrIterator();
@ -297,26 +282,8 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
ClassReader.AttrIterator iter = new AttrIterator();
reader.get().initFieldAttributeIterator(fieldIndex, iter);
// search for the desired attribute
AnnotationsReader result = null;
try {
for (; iter.isValid(); iter.advance()) {
if (runtimeInvisible) {
if (iter.getName().equals(RuntimeInvisibleAnnotationsReader.attrName)) {
result = new RuntimeInvisibleAnnotationsReader(iter);
break;
}
} else {
if (iter.getName().equals(RuntimeVisibleAnnotationsReader.attrName)) {
result = new RuntimeVisibleAnnotationsReader(iter);
break;
}
}
}
} catch (InvalidClassFileException e) {
Assertions.UNREACHABLE();
}
return result;
return AnnotationsReader.getReaderForAnnotation(runtimeInvisible ? AnnotationType.RuntimeInvisibleAnnotations
: AnnotationType.RuntimeVisibleAnnotations, iter);
}
/**
@ -332,7 +299,7 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
public Collection<Annotation> getRuntimeVisibleAnnotations(int fieldIndex) throws InvalidClassFileException {
return getFieldAnnotations(fieldIndex, false);
}
protected Collection<Annotation> getFieldAnnotations(int fieldIndex, boolean runtimeInvisible) throws InvalidClassFileException {
AnnotationsReader r = getFieldAnnotationsReader(runtimeInvisible, fieldIndex);
return Annotation.getAnnotationsFromReader(r, getClassLoader().getReference());
@ -373,7 +340,8 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
}
/**
* Does the class file indicate that this class is a member of some other class?
* Does the class file indicate that this class is a member of some other
* class?
*
* @throws InvalidClassFileException
*/
@ -411,10 +379,11 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
}
return false;
}
/**
* If this is an inner class, return the outer class. Else return null.
* @throws InvalidClassFileException
* If this is an inner class, return the outer class. Else return null.
*
* @throws InvalidClassFileException
*/
public TypeReference getOuterClass() throws InvalidClassFileException {
if (!isInnerClass()) {
@ -431,7 +400,8 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
}
return null;
}
@Override
public Module getContainer() {
return reader.getModuleEntry().getContainer();
}

View File

@ -73,13 +73,7 @@ public class Annotation {
public static Collection<Annotation> getAnnotationsFromReader(AnnotationsReader r, ClassLoaderReference clRef) throws InvalidClassFileException {
if (r != null) {
AnnotationAttribute[] allAnnotations = r.getAllAnnotations();
Collection<Annotation> result = HashSetFactory.make();
for (AnnotationAttribute annot : allAnnotations) {
String type = annot.type;
type = type.replaceAll(";", "");
TypeReference t = TypeReference.findOrCreate(clRef, type);
result.add(makeWithNamed(t, annot.elementValues));
}
Collection<Annotation> result = convertToAnnotations(clRef, allAnnotations);
return result;
} else {
return Collections.emptySet();
@ -87,6 +81,35 @@ public class Annotation {
}
/**
* If r != null, return parameter annotations as an array with length equal to
* number of annotatable parameters. Otherwise, return null.
*/
@SuppressWarnings("unchecked")
public static Collection<Annotation>[] getParameterAnnotationsFromReader(AnnotationsReader r, ClassLoaderReference clRef) throws InvalidClassFileException {
if (r != null) {
AnnotationAttribute[][] allAnnots = r.getAllParameterAnnotations();
Collection<Annotation>[] result = new Collection[allAnnots.length];
for (int i = 0; i < result.length; i++) {
result[i] = convertToAnnotations(clRef, allAnnots[i]);
}
return result;
} else {
return null;
}
}
protected static Collection<Annotation> convertToAnnotations(ClassLoaderReference clRef, AnnotationAttribute[] allAnnotations) {
Collection<Annotation> result = HashSetFactory.make();
for (AnnotationAttribute annot : allAnnotations) {
String type = annot.type;
type = type.replaceAll(";", "");
TypeReference t = TypeReference.findOrCreate(clRef, type);
result.add(makeWithNamed(t, annot.elementValues));
}
return result;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer("Annotation type " + type);

View File

@ -32,8 +32,6 @@ import com.ibm.wala.shrikeCT.ConstantValueReader;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.shrikeCT.LineNumberTableReader;
import com.ibm.wala.shrikeCT.LocalVariableTableReader;
import com.ibm.wala.shrikeCT.RuntimeInvisibleAnnotationsReader;
import com.ibm.wala.shrikeCT.RuntimeVisibleAnnotationsReader;
import com.ibm.wala.shrikeCT.SignatureReader;
import com.ibm.wala.shrikeCT.SourceFileReader;
@ -266,11 +264,8 @@ public class ClassPrinter {
} else if (name.equals("Signature")) {
SignatureReader sr = new SignatureReader(attrs);
w.write(" signature: " + cr.getCP().getCPUtf8(sr.getSignatureCPIndex()) + "\n");
} else if (name.equals(RuntimeInvisibleAnnotationsReader.attrName)) {
AnnotationsReader r = new RuntimeInvisibleAnnotationsReader(attrs);
printAnnotations(cr, attrs, r);
} else if (name.equals(RuntimeVisibleAnnotationsReader.attrName)) {
AnnotationsReader r = new RuntimeVisibleAnnotationsReader(attrs);
} else if (AnnotationsReader.isKnownAnnotation(name)) {
AnnotationsReader r = new AnnotationsReader(attrs, name);
printAnnotations(cr, attrs, r);
} else {
int len = attrs.getDataSize();

View File

@ -15,6 +15,7 @@ import java.util.Map;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.collections.Pair;
import com.ibm.wala.util.debug.Assertions;
/**
* This class reads Annotations attributes, e.g., RuntimeInvisibleAnnotations.
@ -74,6 +75,7 @@ public class AnnotationsReader extends AttributeReader {
* @see AnnotationsReader#readElementValueAndSize(int)
*
*/
@SuppressWarnings("javadoc")
public static interface ElementValue {
}
@ -104,12 +106,12 @@ public class AnnotationsReader extends AttributeReader {
* Represents enum constant annotation arguments.
*/
public static class EnumElementValue implements ElementValue {
/**
* the name of the enum type
*/
public final String enumType;
/**
* the enum value
*/
@ -151,7 +153,7 @@ public class AnnotationsReader extends AttributeReader {
}
/**
* get all the annotations declared in this attribute.
* get all the annotations declared in this attribute.
*
* @throws InvalidClassFileException
*/
@ -167,6 +169,37 @@ public class AnnotationsReader extends AttributeReader {
return result;
}
/**
* <pre>
* param_annotations {
* u2 attribute_name_index;
* u4 attribute_length;
* u1 num_parameters;
* {
* u2 num_annotations;
* annotation annotations[num_annotations];
* } parameter_annotations[num_parameters];
* </pre>
*/
public AnnotationAttribute[][] getAllParameterAnnotations() throws InvalidClassFileException {
int numParamOffset = beginOffset + 6;
checkSize(numParamOffset, 1);
int paramCount = cr.getByte(numParamOffset);
AnnotationAttribute[][] result = new AnnotationAttribute[paramCount][];
// skip attribute_name_index, attribute_length, and num_parameters
int offset = beginOffset + 7;
for (int i = 0; i < result.length; i++) {
checkSize(offset, 2);
result[i] = new AnnotationAttribute[cr.getUShort(offset)];
offset += 2;
for (int j = 0; j < result[i].length; j++) {
Pair<AnnotationAttribute, Integer> attributeAndSize = getAttributeAndSize(offset);
result[i][j] = attributeAndSize.fst;
offset += attributeAndSize.snd;
}
}
return result;
}
/**
* <pre>
* annotation {
@ -302,7 +335,7 @@ public class AnnotationsReader extends AttributeReader {
}
return Pair.<ElementValue, Integer> make(new ArrayElementValue(vals), numArrayBytes);
case '@': // annotation
Pair<AnnotationAttribute,Integer> attributeAndSize = getAttributeAndSize(offset+1);
Pair<AnnotationAttribute, Integer> attributeAndSize = getAttributeAndSize(offset + 1);
// add 1 to size for the tag
return Pair.<ElementValue, Integer> make(attributeAndSize.fst, attributeAndSize.snd + 1);
default:
@ -311,4 +344,35 @@ public class AnnotationsReader extends AttributeReader {
}
}
// //////////////
// utility methods for reading well-known annotation types
// //////////////
public static enum AnnotationType {
RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations,RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations
}
public static boolean isKnownAnnotation(String name) {
for (AnnotationType t : AnnotationType.values()) {
if (t.name().equals(name)) {
return true;
}
}
return false;
}
public static AnnotationsReader getReaderForAnnotation(AnnotationType type, ClassReader.AttrIterator iter) {
// search for the desired attribute
final String attrName = type.toString();
try {
for (; iter.isValid(); iter.advance()) {
if (iter.getName().equals(attrName)) {
return new AnnotationsReader(iter, attrName);
}
}
} catch (InvalidClassFileException e) {
Assertions.UNREACHABLE();
}
return null;
}
}

View File

@ -1,25 +0,0 @@
/*******************************************************************************
* Copyright (c) 2002,2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.shrikeCT;
/**
* This class reads RuntimeInvisibleAnnotations attributes.
*
* @author sjfink
*/
public final class RuntimeInvisibleAnnotationsReader extends AnnotationsReader {
public static final String attrName = "RuntimeInvisibleAnnotations";
public RuntimeInvisibleAnnotationsReader(ClassReader.AttrIterator iter) throws InvalidClassFileException {
super(iter, attrName);
}
}

View File

@ -1,25 +0,0 @@
/*******************************************************************************
* Copyright (c) 2002,2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.shrikeCT;
/**
* This class reads RuntimeVisibleAnnotations attributes.
*
* @author sjfink
*/
public final class RuntimeVisibleAnnotationsReader extends AnnotationsReader {
public final static String attrName = "RuntimeVisibleAnnotations";
public RuntimeVisibleAnnotationsReader(ClassReader.AttrIterator iter) throws InvalidClassFileException {
super(iter, attrName);
}
}