WALA/com.ibm.wala.core/src/com/ibm/wala/types/annotations/TypeAnnotation.java

1041 lines
36 KiB
Java

/*******************************************************************************
* Copyright (c) 2016 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:
* Martin Hecker, KIT - initial implementation
*******************************************************************************/
package com.ibm.wala.types.annotations;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import com.ibm.wala.classLoader.FieldImpl;
import com.ibm.wala.classLoader.IBytecodeMethod;
import com.ibm.wala.classLoader.ShrikeCTMethod;
import com.ibm.wala.classLoader.ShrikeClass;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.shrikeCT.TypeAnnotationsReader;
import com.ibm.wala.shrikeCT.AnnotationsReader.AnnotationAttribute;
import com.ibm.wala.shrikeCT.TypeAnnotationsReader.TargetInfo;
import com.ibm.wala.shrikeCT.TypeAnnotationsReader.TargetType;
import com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeAnnotationAttribute;
import com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeAnnotationLocation;
import com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeAnnotationTargetVisitor;
import com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypePathKind;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.collections.Pair;
/**
* A {@link TypeAnnotation} represents a JSR 308 Java Type Annotation.
*
* @author Martin Hecker martin.hecker@kit.edu
*
* @see Annotation
* @see TypeAnnotationTarget
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.20">JLS (SE8), 4.7.20</a>
* @see <a href="https://jcp.org/en/jsr/detail?id=308">JSR 308: Annotations on Java Types</a>
* @see <a href="http://types.cs.washington.edu/jsr308/">Type Annotations (JSR 308) and the Checker Framework</a>
*
*/
public class TypeAnnotation {
private final Annotation annotation;
private final List<Pair<TypePathKind, Integer>> typePath;
private final TypeAnnotationTarget typeAnnotationTarget;
private final TargetType targetType;
private TypeAnnotation(Annotation annotation, List<Pair<TypePathKind, Integer>> typePath,
TypeAnnotationTarget typeAnnotationTarget, TargetType targetType) {
this.annotation = annotation;
this.typePath = Collections.unmodifiableList(typePath);
this.typeAnnotationTarget = typeAnnotationTarget;
this.targetType = targetType;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer("TypeAnnotation");
sb.append("{ annotation = ");
sb.append(annotation);
sb.append(", path = ");
sb.append(typePath);
sb.append(", target = ");
sb.append(typeAnnotationTarget);
sb.append("}");
return sb.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((annotation == null) ? 0 : annotation.hashCode());
result = prime * result + ((typeAnnotationTarget == null) ? 0 : typeAnnotationTarget.hashCode());
result = prime * result + ((typePath == null) ? 0 : typePath.hashCode());
result = prime * result + ((targetType == null) ? 0 : targetType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TypeAnnotation other = (TypeAnnotation) obj;
if (annotation == null) {
if (other.annotation != null)
return false;
} else if (!annotation.equals(other.annotation))
return false;
if (typeAnnotationTarget == null) {
if (other.typeAnnotationTarget != null)
return false;
} else if (!typeAnnotationTarget.equals(other.typeAnnotationTarget))
return false;
if (typePath == null) {
if (other.typePath != null)
return false;
} else if (!typePath.equals(other.typePath))
return false;
if (targetType == null) {
if (other.targetType != null)
return false;
} else if (!targetType.equals(other.targetType))
return false;
return true;
}
public static Collection<TypeAnnotation> getTypeAnnotationsFromReader(TypeAnnotationsReader r, TypeAnnotationTargetConverter converter, ClassLoaderReference clRef) throws InvalidClassFileException {
if (r != null) {
TypeAnnotationAttribute[] allTypeAnnotations = r.getAllTypeAnnotations();
Collection<TypeAnnotation> result = new ArrayList<>(allTypeAnnotations.length);
for (TypeAnnotationAttribute tatt : allTypeAnnotations) {
final Collection<Annotation> annotations =
Annotation.convertToAnnotations(clRef, new AnnotationAttribute[] { tatt.annotationAttribute});
assert annotations.size() == 1;
final Annotation annotation = annotations.iterator().next();
result.add(
new TypeAnnotation(
annotation,
tatt.typePath,
tatt.annotationTarget.acceptVisitor(converter),
tatt.targetType
)
);
}
return result;
} else {
return Collections.emptySet();
}
}
/**
* This method is intended to be used in testing only.
*
* Otherwise, obtain TypeAnnotations from
* <ul>
* <li> {@link ShrikeCTMethod#getTypeAnnotationsAtCode(boolean)} </li>
* <li> {@link ShrikeCTMethod#getTypeAnnotationsAtMethodInfo(boolean)} </li>
* <li> {@link FieldImpl#getTypeAnnotations()}
* <li> {@link ShrikeClass#getTypeAnnotations(boolean)}
* </ul>
*
* @return A {@link TypeAnnotation} comprised of annotation, typePath and targetType
*/
public static TypeAnnotation make(Annotation annotation, List<Pair<TypePathKind, Integer>> typePath,
TypeAnnotationTarget typeAnnotationTarget, TargetType targetType) {
return new TypeAnnotation(annotation, typePath, typeAnnotationTarget, targetType);
}
/**
* This method is intended to be used in testing only.
*
* Otherwise, obtain TypeAnnotations from
* <ul>
* <li> {@link ShrikeCTMethod#getTypeAnnotationsAtCode(boolean)} </li>
* <li> {@link ShrikeCTMethod#getTypeAnnotationsAtMethodInfo(boolean)} </li>
* <li> {@link FieldImpl#getTypeAnnotations()}
* <li> {@link ShrikeClass#getTypeAnnotations(boolean)}
* </ul>
*
* @return A {@link TypeAnnotation} comprised of annotation, an empty typePath, and targetType
*/
public static TypeAnnotation make(Annotation annotation,
TypeAnnotationTarget typeAnnotationTarget, TargetType targetType) {
return new TypeAnnotation(annotation, TypeAnnotationsReader.TYPEPATH_EMPTY, typeAnnotationTarget, targetType);
}
/**
* A {@link TypeAnnotationTarget} represents the "target" of a Type Annotation.
*
* In contrast to {@link com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeAnnotationTarget},
* subclasses of {@link TypeAnnotationTarget} usually have already resolved bytecode-specific data
* (such as bcIndices) to their WALA counterparts.
*
* @author Martin Hecker martin.hecker@kit.edu
*
*/
public static abstract class TypeAnnotationTarget {
public static final int INSTRUCTION_INDEX_UNAVAILABLE = -1;
}
public static class TypeParameterTarget extends TypeAnnotationTarget {
private final int type_parameter_index;
public TypeParameterTarget(int type_parameter_index) {
this.type_parameter_index = type_parameter_index;
}
public int getIndex() {
return type_parameter_index;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("TypeParameterTarget");
sb.append("{ type_parameter_index = ");
sb.append(type_parameter_index);
sb.append("}");
return sb.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + type_parameter_index;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TypeParameterTarget other = (TypeParameterTarget) obj;
if (type_parameter_index != other.type_parameter_index)
return false;
return true;
}
}
public static class SuperTypeTarget extends TypeAnnotationTarget {
private final TypeReference superType;
public SuperTypeTarget(TypeReference superType) {
this.superType = superType;
}
public TypeReference getSuperType() {
return superType;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("SuperTypeTarget");
sb.append("{ superType = ");
sb.append(superType);
sb.append("}");
return sb.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((superType == null) ? 0 : superType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SuperTypeTarget other = (SuperTypeTarget) obj;
if (superType == null) {
if (other.superType != null)
return false;
} else if (!superType.equals(other.superType))
return false;
return true;
}
}
public static class TypeParameterBoundTarget extends TypeAnnotationTarget {
private final int type_parameter_index;
private final int bound_index;
public TypeParameterBoundTarget(int type_parameter_index, int bound_index) {
this.type_parameter_index = type_parameter_index;
this.bound_index = bound_index;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("TypeParameterBoundTarget");
sb.append("{ type_parameter_index = ");
sb.append(type_parameter_index);
sb.append(", bound_index = ");
sb.append(bound_index);
sb.append("}");
return sb.toString();
}
public int getParameterIndex() {
return type_parameter_index;
}
public int getBoundIndex() {
return bound_index;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + bound_index;
result = prime * result + type_parameter_index;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TypeParameterBoundTarget other = (TypeParameterBoundTarget) obj;
if (bound_index != other.bound_index)
return false;
if (type_parameter_index != other.type_parameter_index)
return false;
return true;
}
}
public static class EmptyTarget extends TypeAnnotationTarget {
public EmptyTarget() {
}
@Override
public String toString() {
return "EmptyTarget";
}
@Override
public int hashCode() {
return 1;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
return true;
}
}
public static class FormalParameterTarget extends TypeAnnotationTarget {
private final int formal_parameter_index;
public FormalParameterTarget(int index) {
this.formal_parameter_index = index;
}
public int getIndex() {
return formal_parameter_index;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("FormalParameterTarget");
sb.append("{ formal_parameter_index = ");
sb.append(formal_parameter_index);
sb.append("}");
return sb.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + formal_parameter_index;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FormalParameterTarget other = (FormalParameterTarget) obj;
if (formal_parameter_index != other.formal_parameter_index)
return false;
return true;
}
}
public static class ThrowsTarget extends TypeAnnotationTarget {
private final TypeReference throwType;
public ThrowsTarget(TypeReference throwType) {
this.throwType = throwType;
}
public TypeReference getThrowType() {
return throwType;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("ThrowsTarget");
sb.append("{ throwType = ");
sb.append(throwType);
sb.append("}");
return sb.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((throwType == null) ? 0 : throwType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ThrowsTarget other = (ThrowsTarget) obj;
if (throwType == null) {
if (other.throwType != null)
return false;
} else if (!throwType.equals(other.throwType))
return false;
return true;
}
}
public static class LocalVarTarget extends TypeAnnotationTarget {
// TODO: we might want to relate bytecode-ranges to ranges in the
// IInstruction[] array returned by IBytecodeMethod.getInstructions(),
// but is this even meaningful?
private final int varIindex;
private final String name;
public LocalVarTarget(int varIindex, String name) {
this.varIindex = varIindex;
this.name = name;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("LocalVarTarget");
sb.append("{ varIindex = ");
sb.append(varIindex);
sb.append(", name = ");
sb.append(name);
sb.append("}");
return sb.toString();
}
public int getIndex() {
return varIindex;
}
/**
*
* @return the name of the local Variable, or null if it could not be determined
* (for example, if the LocalVariableTable in the corresponding class file is missing).
*/
public String getName() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + varIindex;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LocalVarTarget other = (LocalVarTarget) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (varIindex != other.varIindex)
return false;
return true;
}
}
public static class CatchTarget extends TypeAnnotationTarget {
// TODO: as per LocalVarTarget, can we record a meaningful range in terms
// of IInstriction[] or SSAInstruction[] indices?!?! this is currently missing..
private final int catchIIndex;
private final TypeReference catchType;
// TODO: or should this be TypeReference.JavaLangThrowable?
public static final TypeReference ALL_EXCEPTIONS = null;
public CatchTarget(int catchIIndex, TypeReference catchType) {
this.catchIIndex = catchIIndex;
this.catchType = catchType;
}
/**
* @return the handlers type, or {@link CatchTarget#ALL_EXCEPTIONS}
*/
public TypeReference getCatchType() {
return catchType;
}
/**
* @return the handlers instruction index (if available),
* or {@link TypeAnnotationTarget#INSTRUCTION_INDEX_UNAVAILABLE} otherwise.
*/
public int getCatchIIndex() {
return catchIIndex;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("CatchTarget");
sb.append("{ catchIIndex = ");
sb.append(catchIIndex);
sb.append(", catchType = ");
sb.append(catchType);
sb.append("}");
return sb.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + catchIIndex;
result = prime * result + ((catchType == null) ? 0 : catchType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CatchTarget other = (CatchTarget) obj;
if (catchIIndex != other.catchIIndex)
return false;
if (catchType == null) {
if (other.catchType != null)
return false;
} else if (!catchType.equals(other.catchType))
return false;
return true;
}
}
public static class OffsetTarget extends TypeAnnotationTarget {
private final int iindex;
public OffsetTarget(int iindex) {
this.iindex = iindex;
}
/**
* @return the targets instruction index (if available),
* or {@link TypeAnnotationTarget#INSTRUCTION_INDEX_UNAVAILABLE} otherwise.
*/
public int getIIndex() {
return iindex;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("OffsetTarget");
sb.append("{ iindex = ");
sb.append(iindex);
sb.append("}");
return sb.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + iindex;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
OffsetTarget other = (OffsetTarget) obj;
if (iindex != other.iindex)
return false;
return true;
}
}
public static class TypeArgumentTarget extends TypeAnnotationTarget {
private final int iindex;
private final int type_argument_index;
public TypeArgumentTarget(int iindex, int type_argument_index) {
this.iindex = iindex;
this.type_argument_index = type_argument_index;
}
public int getOffset() {
return iindex;
}
public int getTypeArgumentIndex() {
return type_argument_index;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("TypeArgumentTarget");
sb.append("{ iindex = ");
sb.append(iindex);
sb.append(", type_argument_index = ");
sb.append(type_argument_index);
sb.append("}");
return sb.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + iindex;
result = prime * result + type_argument_index;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TypeArgumentTarget other = (TypeArgumentTarget) obj;
if (iindex != other.iindex)
return false;
if (type_argument_index != other.type_argument_index)
return false;
return true;
}
}
private static TypeReference fromString(ClassLoaderReference clRef, String typeName) {
// TODO: should we not use some lookup that try to (recursively) find a TypeReference in clRefs parents,
// and only create a new TypeReference in clRef if this fails? I can't find a such a utility method, though..?!?!
return TypeReference.findOrCreate(clRef, "L"+typeName.replaceAll(";", ""));
}
private static boolean mayAppearIn(TargetInfo info, TypeAnnotationLocation location) {
for (TargetType targetType : TargetType.values()) {
if (targetType.target_info == info && targetType.location == location) return true;
}
return false;
}
/**
* A @{TypeAnnotationTargetConverter} takes "unresolved" instances of
* {@link com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeAnnotationTarget}, resolves some byte-code specific data,
* and returns instances of the corresponding {@link TypeAnnotationTarget} subclass.
*
* @author Martin Hecker martin.hecker@kit.edu
*
*/
public static interface TypeAnnotationTargetConverter extends TypeAnnotationTargetVisitor<TypeAnnotationTarget> {}
public static TypeAnnotationTargetConverter targetConverterAtCode(final ClassLoaderReference clRef, final IBytecodeMethod method) {
return new TypeAnnotationTargetConverter() {
@Override
public TypeAnnotationTarget visitTypeParameterTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeParameterTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.Code);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitSuperTypeTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.SuperTypeTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.Code);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitTypeParameterBoundTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeParameterBoundTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.Code);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitEmptyTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.EmptyTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.Code);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitFormalParameterTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.FormalParameterTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.Code);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitThrowsTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.ThrowsTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.Code);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitLocalVarTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.LocalVarTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.Code);
// TODO: is this even allowed? Should we have thrown an exception earlier?
if (target.getNrOfRanges() == 0) return new LocalVarTarget(-1, null);
final int varIndex = target.getIndex(0);
final String name = method.getLocalVariableName(target.getStartPc(0), target.getIndex(0));
if (name == null ) {
return new LocalVarTarget(varIndex, null);
}
for (int i = 0; i < target.getNrOfRanges(); i++) {
if ( target.getIndex(i) != varIndex) throw new IllegalArgumentException();
if (!method.getLocalVariableName(target.getStartPc(0), target.getIndex(0)).equals(name)) {
throw new IllegalArgumentException();
}
}
return new LocalVarTarget(varIndex, name);
}
@Override
public TypeAnnotationTarget visitCatchTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.CatchTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.Code);
final TypeReference catchType;
if (target.getCatchType() == com.ibm.wala.shrikeCT.TypeAnnotationsReader.CatchTarget.ALL_EXCEPTIONS) {
catchType = CatchTarget.ALL_EXCEPTIONS;
} else {
catchType = fromString(clRef, target.getCatchType());
}
// well this is awkward..
try {
final int catchIIndex = method.getInstructionIndex(target.getCatchPC());
return new CatchTarget(catchIIndex, catchType);
} catch (InvalidClassFileException e) {
return new CatchTarget(TypeAnnotationTarget.INSTRUCTION_INDEX_UNAVAILABLE, catchType);
}
}
@Override
public TypeAnnotationTarget visitOffsetTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.OffsetTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.Code);
try {
final int iindex = method.getInstructionIndex(target.getOffset());
return new OffsetTarget(iindex);
} catch (InvalidClassFileException e) {
return new OffsetTarget(TypeAnnotationTarget.INSTRUCTION_INDEX_UNAVAILABLE);
}
}
@Override
public TypeAnnotationTarget visitTypeArgumentTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeArgumentTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.Code);
try {
final int iindex = method.getInstructionIndex(target.getOffset());
return new TypeArgumentTarget(iindex, target.getTypeArgumentIndex());
} catch (InvalidClassFileException e) {
return new TypeArgumentTarget(TypeAnnotationTarget.INSTRUCTION_INDEX_UNAVAILABLE, target.getTypeArgumentIndex());
}
}
};
}
// TODO: method is currently unused, but we may want to use it if we decide to resolve generic signature indices here
public static TypeAnnotationTargetConverter targetConverterAtMethodInfo(final ClassLoaderReference clRef, final IBytecodeMethod method) {
return new TypeAnnotationTargetConverter() {
@Override
public TypeAnnotationTarget visitTypeParameterTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeParameterTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.method_info);
return new TypeParameterTarget(target.getIndex());
}
@Override
public TypeAnnotationTarget visitSuperTypeTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.SuperTypeTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.method_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitTypeParameterBoundTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeParameterBoundTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.method_info);
return new TypeParameterBoundTarget(target.getParameterIndex(), target.getBoundIndex());
}
@Override
public TypeAnnotationTarget visitEmptyTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.EmptyTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.method_info);
return new EmptyTarget();
}
@Override
public TypeAnnotationTarget visitFormalParameterTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.FormalParameterTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.method_info);
return new FormalParameterTarget(target.getIndex());
}
@Override
public TypeAnnotationTarget visitThrowsTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.ThrowsTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.method_info);
return new ThrowsTarget(fromString(clRef, target.getThrowType()));
}
@Override
public TypeAnnotationTarget visitLocalVarTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.LocalVarTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.method_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitCatchTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.CatchTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.method_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitOffsetTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.OffsetTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.method_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitTypeArgumentTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeArgumentTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.method_info);
throw new UnsupportedOperationException();
}
};
}
public static TypeAnnotationTargetConverter targetConverterAtClassFile(final ClassLoaderReference clRef) {
return new TypeAnnotationTargetConverter() {
@Override
public TypeAnnotationTarget visitTypeParameterTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeParameterTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.ClassFile);
return new TypeParameterTarget(target.getIndex());
}
@Override
public TypeAnnotationTarget visitSuperTypeTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.SuperTypeTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.ClassFile);
return new SuperTypeTarget(fromString(clRef, target.getSuperType()));
}
@Override
public TypeAnnotationTarget visitTypeParameterBoundTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeParameterBoundTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.ClassFile);
return new TypeParameterBoundTarget(target.getParameterIndex(), target.getBoundIndex());
}
@Override
public TypeAnnotationTarget visitEmptyTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.EmptyTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.ClassFile);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitFormalParameterTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.FormalParameterTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.ClassFile);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitThrowsTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.ThrowsTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.ClassFile);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitLocalVarTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.LocalVarTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.ClassFile);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitCatchTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.CatchTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.ClassFile);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitOffsetTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.OffsetTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.ClassFile);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitTypeArgumentTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeArgumentTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.ClassFile);
throw new UnsupportedOperationException();
}
};
}
public static TypeAnnotationTargetConverter targetConverterAtFieldInfo(final ClassLoaderReference clRef) {
return new TypeAnnotationTargetConverter() {
@Override
public TypeAnnotationTarget visitTypeParameterTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeParameterTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.field_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitSuperTypeTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.SuperTypeTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.field_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitTypeParameterBoundTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeParameterBoundTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.field_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitEmptyTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.EmptyTarget target) {
assert mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.field_info);
return new EmptyTarget();
}
@Override
public TypeAnnotationTarget visitFormalParameterTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.FormalParameterTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.field_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitThrowsTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.ThrowsTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.field_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitLocalVarTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.LocalVarTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.field_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitCatchTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.CatchTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.field_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitOffsetTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.OffsetTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.field_info);
throw new UnsupportedOperationException();
}
@Override
public TypeAnnotationTarget visitTypeArgumentTarget(com.ibm.wala.shrikeCT.TypeAnnotationsReader.TypeArgumentTarget target) {
assert !mayAppearIn(target.getTargetInfo(), TypeAnnotationLocation.field_info);
throw new UnsupportedOperationException();
}
};
}
/**
* @return the {@link Annotation} of this {@link TypeAnnotation}
*/
public Annotation getAnnotation() {
return annotation;
}
/**
* @return the typePath of this {@link TypeAnnotation}
*
* @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.20.2"> JLS (SE8), 4.7.20.2</a>
*/
public List<Pair<TypePathKind, Integer>> getTypePath() {
return typePath;
}
/**
* @return the {@link TypeAnnotationTarget} of this {@link TypeAnnotation}
*/
public TypeAnnotationTarget getTypeAnnotationTarget() {
return typeAnnotationTarget;
}
/**
* @return the {@link TargetType} of this {@link TypeAnnotation}
*/
public TargetType getTargetType() {
return targetType;
}
}