| package org.checkerframework.javacutil; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.Arrays; |
| import java.util.Map; |
| |
| import javax.annotation.processing.ProcessingEnvironment; |
| import javax.lang.model.SourceVersion; |
| import javax.lang.model.element.AnnotationMirror; |
| import javax.lang.model.element.AnnotationValue; |
| import javax.lang.model.element.AnnotationValueVisitor; |
| import javax.lang.model.element.ElementKind; |
| import javax.lang.model.element.ExecutableElement; |
| import javax.lang.model.element.VariableElement; |
| import javax.lang.model.type.ArrayType; |
| import javax.lang.model.type.TypeKind; |
| import javax.lang.model.type.TypeMirror; |
| import javax.lang.model.util.Elements; |
| import javax.lang.model.util.Types; |
| |
| import com.sun.tools.javac.code.Attribute; |
| import com.sun.tools.javac.code.Attribute.TypeCompound; |
| import com.sun.tools.javac.code.Symbol; |
| import com.sun.tools.javac.code.TargetType; |
| import com.sun.tools.javac.code.Type; |
| import com.sun.tools.javac.code.TypeAnnotationPosition; |
| import com.sun.tools.javac.processing.JavacProcessingEnvironment; |
| import com.sun.tools.javac.tree.JCTree.JCLambda; |
| import com.sun.tools.javac.util.Context; |
| import com.sun.tools.javac.util.List; |
| import com.sun.tools.javac.util.Pair; |
| |
| /** |
| * A collection of helper methods related to type annotation handling. |
| * |
| * @see AnnotationUtils |
| */ |
| public class TypeAnnotationUtils { |
| |
| // Class cannot be instantiated. |
| private TypeAnnotationUtils() { throw new AssertionError("Class TypeAnnotationUtils cannot be instantiated."); } |
| |
| /** |
| * Check whether a TypeCompound is contained in a list of TypeCompounds. |
| * |
| * @param list The input list of TypeCompounds. |
| * @param tc The TypeCompound to find. |
| * @return true, iff a TypeCompound equal to tc is contained in list. |
| */ |
| public static boolean isTypeCompoundContained(Types types, List<TypeCompound> list, TypeCompound tc) { |
| for (Attribute.TypeCompound rawat : list) { |
| if (rawat.type.tsym.name.contentEquals(tc.type.tsym.name) && |
| // TODO: in previous line, it would be nicer to use reference equality: |
| // rawat.type == tc.type && |
| // or at least "isSameType": |
| // types.isSameType(rawat.type, tc.type) && |
| // but each fails in some cases. |
| rawat.values.equals(tc.values) && |
| isSameTAPosition(rawat.position, tc.position)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Compare two TypeAnnotationPositions for equality. |
| * |
| * @param p1 The first position. |
| * @param p2 The second position. |
| * @return true, iff the two positions are equal. |
| */ |
| public static boolean isSameTAPosition(TypeAnnotationPosition p1, |
| TypeAnnotationPosition p2) { |
| if (p1.isValidOffset == p2.isValidOffset && |
| p1.bound_index == p2.bound_index && |
| p1.exception_index == p2.exception_index && |
| p1.location.equals(p2.location) && |
| Arrays.equals(p1.lvarIndex, p2.lvarIndex) && |
| Arrays.equals(p1.lvarLength, p2.lvarLength) && |
| Arrays.equals(p1.lvarOffset, p2.lvarOffset) && |
| p1.offset == p2.offset && |
| p1.onLambda == p2.onLambda && |
| p1.parameter_index == p2.parameter_index && |
| p1.pos == p2.pos && |
| p1.type == p2.type && |
| p1.type_index == p2.type_index) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Returns a newly created Attribute.Compound corresponding to an |
| * argument AnnotationMirror. |
| * |
| * @param am an AnnotationMirror, which may be part of an AST or an internally |
| * created subclass. |
| * @return a new Attribute.Compound corresponding to the AnnotationMirror |
| */ |
| public static Attribute.Compound createCompoundFromAnnotationMirror(ProcessingEnvironment env, |
| AnnotationMirror am) { |
| // Create a new Attribute to match the AnnotationMirror. |
| List<Pair<Symbol.MethodSymbol, Attribute>> values = List.nil(); |
| for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : |
| am.getElementValues().entrySet()) { |
| Attribute attribute = attributeFromAnnotationValue(env, entry.getKey(), entry.getValue()); |
| values = values.append(new Pair<>((Symbol.MethodSymbol)entry.getKey(), |
| attribute)); |
| } |
| return new Attribute.Compound((Type.ClassType)am.getAnnotationType(), values); |
| } |
| |
| /** |
| * Returns a newly created Attribute.TypeCompound corresponding to an |
| * argument AnnotationMirror. |
| * |
| * @param am an AnnotationMirror, which may be part of an AST or an internally |
| * created subclass. |
| * @param tapos the type annotation position to use. |
| * @return a new Attribute.TypeCompound corresponding to the AnnotationMirror |
| */ |
| public static Attribute.TypeCompound createTypeCompoundFromAnnotationMirror(ProcessingEnvironment env, |
| AnnotationMirror am, TypeAnnotationPosition tapos) { |
| // Create a new Attribute to match the AnnotationMirror. |
| List<Pair<Symbol.MethodSymbol, Attribute>> values = List.nil(); |
| for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : |
| am.getElementValues().entrySet()) { |
| Attribute attribute = attributeFromAnnotationValue(env, entry.getKey(), entry.getValue()); |
| values = values.append(new Pair<>((Symbol.MethodSymbol)entry.getKey(), |
| attribute)); |
| } |
| return new Attribute.TypeCompound((Type.ClassType)am.getAnnotationType(), values, tapos); |
| } |
| |
| /** |
| * Returns a newly created Attribute corresponding to an argument |
| * AnnotationValue. |
| * |
| * @param meth the ExecutableElement that is assigned the value, needed for empty arrays. |
| * @param av an AnnotationValue, which may be part of an AST or an internally |
| * created subclass. |
| * @return a new Attribute corresponding to the AnnotationValue |
| */ |
| public static Attribute attributeFromAnnotationValue(ProcessingEnvironment env, ExecutableElement meth, AnnotationValue av) { |
| return av.accept(new AttributeCreator(env, meth), null); |
| } |
| |
| private static class AttributeCreator implements AnnotationValueVisitor<Attribute, Void> { |
| private final ProcessingEnvironment processingEnv; |
| private final Types modelTypes; |
| private final Elements elements; |
| private final com.sun.tools.javac.code.Types javacTypes; |
| |
| private final ExecutableElement meth; |
| |
| public AttributeCreator(ProcessingEnvironment env, ExecutableElement meth) { |
| this.processingEnv = env; |
| Context context = ((JavacProcessingEnvironment)env).getContext(); |
| this.elements = env.getElementUtils(); |
| this.modelTypes = env.getTypeUtils(); |
| this.javacTypes = com.sun.tools.javac.code.Types.instance(context); |
| |
| this.meth = meth; |
| } |
| |
| @Override |
| public Attribute visit(AnnotationValue av, Void p) { |
| return av.accept(this, p); |
| } |
| |
| @Override |
| public Attribute visit(AnnotationValue av) { |
| return visit(av, null); |
| } |
| |
| @Override |
| public Attribute visitBoolean(boolean b, Void p) { |
| TypeMirror booleanType = modelTypes.getPrimitiveType(TypeKind.BOOLEAN); |
| return new Attribute.Constant((Type) booleanType, b ? 1 : 0); |
| } |
| |
| @Override |
| public Attribute visitByte(byte b, Void p) { |
| TypeMirror byteType = modelTypes.getPrimitiveType(TypeKind.BYTE); |
| return new Attribute.Constant((Type)byteType, b); |
| } |
| |
| @Override |
| public Attribute visitChar(char c, Void p) { |
| TypeMirror charType = modelTypes.getPrimitiveType(TypeKind.CHAR); |
| return new Attribute.Constant((Type)charType, c); |
| } |
| |
| @Override |
| public Attribute visitDouble(double d, Void p) { |
| TypeMirror doubleType = modelTypes.getPrimitiveType(TypeKind.DOUBLE); |
| return new Attribute.Constant((Type)doubleType, d); |
| } |
| |
| @Override |
| public Attribute visitFloat(float f, Void p) { |
| TypeMirror floatType = modelTypes.getPrimitiveType(TypeKind.FLOAT); |
| return new Attribute.Constant((Type)floatType, f); |
| } |
| |
| @Override |
| public Attribute visitInt(int i, Void p) { |
| TypeMirror intType = modelTypes.getPrimitiveType(TypeKind.INT); |
| return new Attribute.Constant((Type)intType, i); |
| } |
| |
| @Override |
| public Attribute visitLong(long i, Void p) { |
| TypeMirror longType = modelTypes.getPrimitiveType(TypeKind.LONG); |
| return new Attribute.Constant((Type)longType, i); |
| } |
| |
| @Override |
| public Attribute visitShort(short s, Void p) { |
| TypeMirror shortType = modelTypes.getPrimitiveType(TypeKind.SHORT); |
| return new Attribute.Constant((Type)shortType, s); |
| } |
| |
| @Override |
| public Attribute visitString(String s, Void p) { |
| TypeMirror stringType = elements.getTypeElement("java.lang.String").asType(); |
| return new Attribute.Constant((Type)stringType, s); |
| } |
| |
| @Override |
| public Attribute visitType(TypeMirror t, Void p) { |
| if (t instanceof Type) { |
| return new Attribute.Class(javacTypes, (Type)t); |
| } |
| |
| assert false : "Unexpected type of TypeMirror: " + t.getClass(); |
| return null; |
| } |
| |
| @Override |
| public Attribute visitEnumConstant(VariableElement c, Void p) { |
| if (c instanceof Symbol.VarSymbol) { |
| Symbol.VarSymbol sym = (Symbol.VarSymbol) c; |
| if (sym.getKind() == ElementKind.ENUM_CONSTANT) { |
| return new Attribute.Enum(sym.type, sym); |
| } |
| } |
| |
| assert false : "Unexpected type of VariableElement: " + c.getClass(); |
| return null; |
| } |
| |
| @Override |
| public Attribute visitAnnotation(AnnotationMirror a, Void p) { |
| return createCompoundFromAnnotationMirror(processingEnv, a); |
| } |
| |
| @Override |
| public Attribute visitArray(java.util.List<? extends AnnotationValue> vals, Void p) { |
| if (!vals.isEmpty()) { |
| List<Attribute> valAttrs = List.nil(); |
| for (AnnotationValue av : vals) { |
| valAttrs = valAttrs.append(av.accept(this, p)); |
| } |
| ArrayType arrayType = modelTypes.getArrayType(valAttrs.get(0).type); |
| return new Attribute.Array((Type)arrayType, valAttrs); |
| } else { |
| return new Attribute.Array((Type) meth.getReturnType(), List.<Attribute>nil()); |
| } |
| } |
| |
| @Override |
| public Attribute visitUnknown(AnnotationValue av, Void p) { |
| assert false : "Unexpected type of AnnotationValue: " + av.getClass(); |
| return null; |
| } |
| } |
| |
| /** |
| * An interface to abstract a Java 8 and a Java 9 version of how |
| * to get a RET reference. |
| * These methods must then be implemented using reflection in order to |
| * compile in either setting. |
| * Note that we cannot use lambda for this as long as we want to |
| * support Java 7. |
| */ |
| interface Call8or9<RET> { |
| RET call8() throws Throwable; |
| RET call9() throws Throwable; |
| } |
| |
| /** |
| * Use the SourceVersion to decide whether to call the Java 8 or Java 9 version. |
| * Catch all exceptions and abort if one occurs - the reflection code should |
| * never break once fully debugged. |
| * |
| * @param ver The SourceVersion to decide what API to use. |
| * @param tc The TAPCall abstraction to encapsulate two methods. |
| * @return The created TypeAnnotationPosition. |
| */ |
| private static <RET> RET call8or9(Call8or9<RET> tc) { |
| try { |
| boolean hasNine; |
| try { |
| hasNine = SourceVersion.valueOf("RELEASE_9") != null; |
| } catch(IllegalArgumentException iae) { |
| hasNine = false; |
| } |
| if (hasNine) { |
| return tc.call9(); |
| } else { |
| boolean hasEight; |
| try { |
| hasEight = SourceVersion.valueOf("RELEASE_8") != null; |
| } catch(IllegalArgumentException iae) { |
| hasEight = false; |
| } |
| if (hasEight) { |
| return tc.call8(); |
| } else { |
| assert false : "Checker Framework needs a Java 8 or 9 javac."; |
| return null; |
| } |
| } |
| } catch (Throwable t) { |
| assert false : "Checker Framework internal error: " + t; |
| t.printStackTrace(); |
| return null; |
| } |
| } |
| |
| public static TypeAnnotationPosition unknownTAPosition() { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException { |
| return TypeAnnotationPosition.class.newInstance(); |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getField("unknown") |
| .get(null); |
| } |
| } |
| ); |
| } |
| |
| public static TypeAnnotationPosition methodReturnTAPosition(final int pos) { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| TypeAnnotationPosition tapos = TypeAnnotationPosition.class.newInstance(); |
| TypeAnnotationPosition.class.getField("type").set(tapos, TargetType.METHOD_RETURN); |
| TypeAnnotationPosition.class.getField("pos").set(tapos, pos); |
| return tapos; |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getMethod("methodReturn", int.class) |
| .invoke(null, pos); |
| } |
| } |
| ); |
| } |
| |
| public static TypeAnnotationPosition methodReceiverTAPosition(final int pos) { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| TypeAnnotationPosition tapos = TypeAnnotationPosition.class.newInstance(); |
| TypeAnnotationPosition.class.getField("type").set(tapos, TargetType.METHOD_RECEIVER); |
| TypeAnnotationPosition.class.getField("pos").set(tapos, pos); |
| return tapos; |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getMethod("methodReceiver", int.class) |
| .invoke(null, pos); |
| } |
| } |
| ); |
| } |
| |
| public static TypeAnnotationPosition methodParameterTAPosition(final int pidx, final int pos) { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| TypeAnnotationPosition tapos = TypeAnnotationPosition.class.newInstance(); |
| TypeAnnotationPosition.class.getField("type").set(tapos, TargetType.METHOD_FORMAL_PARAMETER); |
| TypeAnnotationPosition.class.getField("parameter_index").set(tapos, pidx); |
| TypeAnnotationPosition.class.getField("pos").set(tapos, pos); |
| return tapos; |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getMethod("methodParameter", int.class, int.class) |
| .invoke(null, pidx, pos); |
| } |
| } |
| ); |
| } |
| |
| public static TypeAnnotationPosition methodThrowsTAPosition(final int tidx, final int pos) { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| TypeAnnotationPosition tapos = TypeAnnotationPosition.class.newInstance(); |
| TypeAnnotationPosition.class.getField("type").set(tapos, TargetType.THROWS); |
| TypeAnnotationPosition.class.getField("type_index").set(tapos, tidx); |
| TypeAnnotationPosition.class.getField("pos").set(tapos, pos); |
| return tapos; |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchFieldException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getMethod("methodThrows", List.class, JCLambda.class, int.class, int.class) |
| .invoke(null, TypeAnnotationPosition.class.getField("emptyPath").get(null), null, tidx, pos); |
| } |
| } |
| ); |
| } |
| |
| public static TypeAnnotationPosition fieldTAPosition(final int pos) { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| TypeAnnotationPosition tapos = TypeAnnotationPosition.class.newInstance(); |
| TypeAnnotationPosition.class.getField("type").set(tapos, TargetType.FIELD); |
| TypeAnnotationPosition.class.getField("pos").set(tapos, pos); |
| return tapos; |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getMethod("field", int.class) |
| .invoke(null, pos); |
| } |
| } |
| ); |
| } |
| |
| public static TypeAnnotationPosition classExtendsTAPosition(final int implidx, final int pos) { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| TypeAnnotationPosition tapos = TypeAnnotationPosition.class.newInstance(); |
| TypeAnnotationPosition.class.getField("type").set(tapos, TargetType.CLASS_EXTENDS); |
| TypeAnnotationPosition.class.getField("type_index").set(tapos, implidx); |
| TypeAnnotationPosition.class.getField("pos").set(tapos, pos); |
| return tapos; |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getMethod("classExtends", int.class, int.class) |
| .invoke(null, implidx, pos); |
| } |
| } |
| ); |
| } |
| |
| public static TypeAnnotationPosition typeParameterTAPosition(final int tpidx, final int pos) { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| TypeAnnotationPosition tapos = TypeAnnotationPosition.class.newInstance(); |
| TypeAnnotationPosition.class.getField("type").set(tapos, TargetType.CLASS_TYPE_PARAMETER); |
| TypeAnnotationPosition.class.getField("parameter_index").set(tapos, tpidx); |
| TypeAnnotationPosition.class.getField("pos").set(tapos, pos); |
| return tapos; |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchFieldException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getMethod("typeParameter", List.class, JCLambda.class, int.class, int.class) |
| .invoke(null, TypeAnnotationPosition.class.getField("emptyPath").get(null), null, tpidx, pos); |
| } |
| } |
| ); |
| } |
| |
| public static TypeAnnotationPosition methodTypeParameterTAPosition(final int tpidx, final int pos) { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| TypeAnnotationPosition tapos = TypeAnnotationPosition.class.newInstance(); |
| TypeAnnotationPosition.class.getField("type").set(tapos, TargetType.METHOD_TYPE_PARAMETER); |
| TypeAnnotationPosition.class.getField("parameter_index").set(tapos, tpidx); |
| TypeAnnotationPosition.class.getField("pos").set(tapos, pos); |
| return tapos; |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchFieldException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getMethod("methodTypeParameter", List.class, JCLambda.class, int.class, int.class) |
| .invoke(null, TypeAnnotationPosition.class.getField("emptyPath").get(null), null, tpidx, pos); |
| } |
| } |
| ); |
| } |
| |
| public static TypeAnnotationPosition typeParameterBoundTAPosition(final int tpidx, final int bndidx, final int pos) { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| TypeAnnotationPosition tapos = TypeAnnotationPosition.class.newInstance(); |
| TypeAnnotationPosition.class.getField("type").set(tapos, TargetType.CLASS_TYPE_PARAMETER_BOUND); |
| TypeAnnotationPosition.class.getField("parameter_index").set(tapos, tpidx); |
| TypeAnnotationPosition.class.getField("bound_index").set(tapos, bndidx); |
| TypeAnnotationPosition.class.getField("pos").set(tapos, pos); |
| return tapos; |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchFieldException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getMethod("typeParameterBound", List.class, JCLambda.class, int.class, int.class, int.class) |
| .invoke(null, TypeAnnotationPosition.class.getField("emptyPath").get(null), null, tpidx, bndidx, pos); |
| } |
| } |
| ); |
| } |
| |
| public static TypeAnnotationPosition methodTypeParameterBoundTAPosition(final int tpidx, final int bndidx, final int pos) { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| TypeAnnotationPosition tapos = TypeAnnotationPosition.class.newInstance(); |
| TypeAnnotationPosition.class.getField("type").set(tapos, TargetType.METHOD_TYPE_PARAMETER_BOUND); |
| TypeAnnotationPosition.class.getField("parameter_index").set(tapos, tpidx); |
| TypeAnnotationPosition.class.getField("bound_index").set(tapos, bndidx); |
| TypeAnnotationPosition.class.getField("pos").set(tapos, pos); |
| return tapos; |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchFieldException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getMethod("methodTypeParameterBound", List.class, JCLambda.class, int.class, int.class, int.class) |
| .invoke(null, TypeAnnotationPosition.class.getField("emptyPath").get(null), null, tpidx, bndidx, pos); |
| } |
| } |
| ); |
| } |
| |
| public static TypeAnnotationPosition copyTAPosition(final TypeAnnotationPosition tapos) { |
| return call8or9( |
| new Call8or9<TypeAnnotationPosition>() { |
| @Override |
| public TypeAnnotationPosition call8() throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| return copyTAPosition8(tapos); |
| } |
| @Override |
| public TypeAnnotationPosition call9() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, InvocationTargetException, NoSuchMethodException { |
| return (TypeAnnotationPosition) TypeAnnotationPosition.class |
| .getMethod("copy", TypeAnnotationPosition.class) |
| .invoke(null, tapos); |
| } |
| } |
| ); |
| } |
| |
| private static TypeAnnotationPosition copyTAPosition8(TypeAnnotationPosition tapos) throws InstantiationException, IllegalAccessException, IllegalArgumentException, NoSuchFieldException, SecurityException { |
| TypeAnnotationPosition res = TypeAnnotationPosition.class.newInstance(); |
| res.isValidOffset = tapos.isValidOffset; |
| TypeAnnotationPosition.class.getField("bound_index").set(res, tapos.bound_index); |
| res.exception_index = tapos.exception_index; |
| res.location = List.from(tapos.location); |
| if (tapos.lvarIndex != null) |
| res.lvarIndex = Arrays.copyOf(tapos.lvarIndex, tapos.lvarIndex.length); |
| if (tapos.lvarLength != null) |
| res.lvarLength = Arrays.copyOf(tapos.lvarLength, tapos.lvarLength.length); |
| if (tapos.lvarOffset != null) |
| res.lvarOffset = Arrays.copyOf(tapos.lvarOffset, tapos.lvarOffset.length); |
| res.offset = tapos.offset; |
| TypeAnnotationPosition.class.getField("onLambda").set(res, tapos.onLambda); |
| TypeAnnotationPosition.class.getField("parameter_index").set(res, tapos.parameter_index); |
| TypeAnnotationPosition.class.getField("pos").set(res, tapos.pos); |
| TypeAnnotationPosition.class.getField("type").set(res, tapos.type); |
| TypeAnnotationPosition.class.getField("type_index").set(res, tapos.type_index); |
| return res; |
| } |
| |
| public static Type unannotatedType(final Type in) { |
| return call8or9( |
| new Call8or9<Type>() { |
| @Override |
| public Type call8() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { |
| return (Type) Type.class |
| .getMethod("unannotatedType") |
| .invoke(in); |
| } |
| @Override |
| public Type call9() { |
| return in; |
| } |
| } |
| ); |
| } |
| |
| } |