8008077: update reference impl for type-annotations
Reviewed-by: jjg
This commit is contained in:
parent
1ec5dfafe0
commit
464abcb4fa
@ -727,12 +727,13 @@ public class ClassWriter {
|
|||||||
private void write(TypeAnnotation.Position p, ClassOutputStream out) {
|
private void write(TypeAnnotation.Position p, ClassOutputStream out) {
|
||||||
out.writeByte(p.type.targetTypeValue());
|
out.writeByte(p.type.targetTypeValue());
|
||||||
switch (p.type) {
|
switch (p.type) {
|
||||||
// type cast
|
|
||||||
case CAST:
|
|
||||||
// instanceof
|
// instanceof
|
||||||
case INSTANCEOF:
|
case INSTANCEOF:
|
||||||
// new expression
|
// new expression
|
||||||
case NEW:
|
case NEW:
|
||||||
|
// constructor/method reference receiver
|
||||||
|
case CONSTRUCTOR_REFERENCE:
|
||||||
|
case METHOD_REFERENCE:
|
||||||
out.writeShort(p.offset);
|
out.writeShort(p.offset);
|
||||||
break;
|
break;
|
||||||
// local variable
|
// local variable
|
||||||
@ -779,9 +780,12 @@ public class ClassWriter {
|
|||||||
case METHOD_FORMAL_PARAMETER:
|
case METHOD_FORMAL_PARAMETER:
|
||||||
out.writeByte(p.parameter_index);
|
out.writeByte(p.parameter_index);
|
||||||
break;
|
break;
|
||||||
|
// type cast
|
||||||
|
case CAST:
|
||||||
// method/constructor/reference type argument
|
// method/constructor/reference type argument
|
||||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||||
|
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
|
||||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||||
out.writeShort(p.offset);
|
out.writeShort(p.offset);
|
||||||
out.writeByte(p.type_index);
|
out.writeByte(p.type_index);
|
||||||
@ -790,10 +794,6 @@ public class ClassWriter {
|
|||||||
case METHOD_RETURN:
|
case METHOD_RETURN:
|
||||||
case FIELD:
|
case FIELD:
|
||||||
break;
|
break;
|
||||||
// lambda formal parameter
|
|
||||||
case LAMBDA_FORMAL_PARAMETER:
|
|
||||||
out.writeByte(p.parameter_index);
|
|
||||||
break;
|
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
throw new AssertionError("ClassWriter: UNKNOWN target type should never occur!");
|
throw new AssertionError("ClassWriter: UNKNOWN target type should never occur!");
|
||||||
default:
|
default:
|
||||||
|
@ -86,12 +86,13 @@ public class TypeAnnotation {
|
|||||||
position.type = type;
|
position.type = type;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// type cast
|
|
||||||
case CAST:
|
|
||||||
// instanceof
|
// instanceof
|
||||||
case INSTANCEOF:
|
case INSTANCEOF:
|
||||||
// new expression
|
// new expression
|
||||||
case NEW:
|
case NEW:
|
||||||
|
// constructor/method reference receiver
|
||||||
|
case CONSTRUCTOR_REFERENCE:
|
||||||
|
case METHOD_REFERENCE:
|
||||||
position.offset = cr.readUnsignedShort();
|
position.offset = cr.readUnsignedShort();
|
||||||
break;
|
break;
|
||||||
// local variable
|
// local variable
|
||||||
@ -142,9 +143,12 @@ public class TypeAnnotation {
|
|||||||
case METHOD_FORMAL_PARAMETER:
|
case METHOD_FORMAL_PARAMETER:
|
||||||
position.parameter_index = cr.readUnsignedByte();
|
position.parameter_index = cr.readUnsignedByte();
|
||||||
break;
|
break;
|
||||||
|
// type cast
|
||||||
|
case CAST:
|
||||||
// method/constructor/reference type argument
|
// method/constructor/reference type argument
|
||||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||||
|
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
|
||||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||||
position.offset = cr.readUnsignedShort();
|
position.offset = cr.readUnsignedShort();
|
||||||
position.type_index = cr.readUnsignedByte();
|
position.type_index = cr.readUnsignedByte();
|
||||||
@ -153,10 +157,6 @@ public class TypeAnnotation {
|
|||||||
case METHOD_RETURN:
|
case METHOD_RETURN:
|
||||||
case FIELD:
|
case FIELD:
|
||||||
break;
|
break;
|
||||||
// lambda formal parameter
|
|
||||||
case LAMBDA_FORMAL_PARAMETER:
|
|
||||||
position.parameter_index = cr.readUnsignedByte();
|
|
||||||
break;
|
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
|
throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
|
||||||
default:
|
default:
|
||||||
@ -177,13 +177,14 @@ public class TypeAnnotation {
|
|||||||
int n = 0;
|
int n = 0;
|
||||||
n += 1; // TargetType tag is a byte
|
n += 1; // TargetType tag is a byte
|
||||||
switch (pos.type) {
|
switch (pos.type) {
|
||||||
// type cast
|
|
||||||
case CAST:
|
|
||||||
// instanceof
|
// instanceof
|
||||||
case INSTANCEOF:
|
case INSTANCEOF:
|
||||||
// new expression
|
// new expression
|
||||||
case NEW:
|
case NEW:
|
||||||
n += 2;
|
// constructor/method reference receiver
|
||||||
|
case CONSTRUCTOR_REFERENCE:
|
||||||
|
case METHOD_REFERENCE:
|
||||||
|
n += 2; // offset
|
||||||
break;
|
break;
|
||||||
// local variable
|
// local variable
|
||||||
case LOCAL_VARIABLE:
|
case LOCAL_VARIABLE:
|
||||||
@ -192,7 +193,7 @@ public class TypeAnnotation {
|
|||||||
n += 2; // table_length;
|
n += 2; // table_length;
|
||||||
int table_length = pos.lvarOffset.length;
|
int table_length = pos.lvarOffset.length;
|
||||||
n += 2 * table_length; // offset
|
n += 2 * table_length; // offset
|
||||||
n += 2 * table_length; // length;
|
n += 2 * table_length; // length
|
||||||
n += 2 * table_length; // index
|
n += 2 * table_length; // index
|
||||||
break;
|
break;
|
||||||
// exception parameter
|
// exception parameter
|
||||||
@ -206,7 +207,7 @@ public class TypeAnnotation {
|
|||||||
// type parameter
|
// type parameter
|
||||||
case CLASS_TYPE_PARAMETER:
|
case CLASS_TYPE_PARAMETER:
|
||||||
case METHOD_TYPE_PARAMETER:
|
case METHOD_TYPE_PARAMETER:
|
||||||
n += 1; // parameter_index;
|
n += 1; // parameter_index
|
||||||
break;
|
break;
|
||||||
// type parameter bound
|
// type parameter bound
|
||||||
case CLASS_TYPE_PARAMETER_BOUND:
|
case CLASS_TYPE_PARAMETER_BOUND:
|
||||||
@ -226,9 +227,12 @@ public class TypeAnnotation {
|
|||||||
case METHOD_FORMAL_PARAMETER:
|
case METHOD_FORMAL_PARAMETER:
|
||||||
n += 1; // parameter_index
|
n += 1; // parameter_index
|
||||||
break;
|
break;
|
||||||
|
// type cast
|
||||||
|
case CAST:
|
||||||
// method/constructor/reference type argument
|
// method/constructor/reference type argument
|
||||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||||
|
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
|
||||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||||
n += 2; // offset
|
n += 2; // offset
|
||||||
n += 1; // type index
|
n += 1; // type index
|
||||||
@ -237,10 +241,6 @@ public class TypeAnnotation {
|
|||||||
case METHOD_RETURN:
|
case METHOD_RETURN:
|
||||||
case FIELD:
|
case FIELD:
|
||||||
break;
|
break;
|
||||||
// lambda formal parameter
|
|
||||||
case LAMBDA_FORMAL_PARAMETER:
|
|
||||||
n += 1; // parameter_index
|
|
||||||
break;
|
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
|
throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
|
||||||
default:
|
default:
|
||||||
@ -377,12 +377,13 @@ public class TypeAnnotation {
|
|||||||
sb.append(type);
|
sb.append(type);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// type cast
|
|
||||||
case CAST:
|
|
||||||
// instanceof
|
// instanceof
|
||||||
case INSTANCEOF:
|
case INSTANCEOF:
|
||||||
// new expression
|
// new expression
|
||||||
case NEW:
|
case NEW:
|
||||||
|
// constructor/method reference receiver
|
||||||
|
case CONSTRUCTOR_REFERENCE:
|
||||||
|
case METHOD_REFERENCE:
|
||||||
sb.append(", offset = ");
|
sb.append(", offset = ");
|
||||||
sb.append(offset);
|
sb.append(offset);
|
||||||
break;
|
break;
|
||||||
@ -444,9 +445,12 @@ public class TypeAnnotation {
|
|||||||
sb.append(", param_index = ");
|
sb.append(", param_index = ");
|
||||||
sb.append(parameter_index);
|
sb.append(parameter_index);
|
||||||
break;
|
break;
|
||||||
|
// type cast
|
||||||
|
case CAST:
|
||||||
// method/constructor/reference type argument
|
// method/constructor/reference type argument
|
||||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||||
|
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
|
||||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||||
sb.append(", offset = ");
|
sb.append(", offset = ");
|
||||||
sb.append(offset);
|
sb.append(offset);
|
||||||
@ -457,12 +461,6 @@ public class TypeAnnotation {
|
|||||||
case METHOD_RETURN:
|
case METHOD_RETURN:
|
||||||
case FIELD:
|
case FIELD:
|
||||||
break;
|
break;
|
||||||
// lambda formal parameter
|
|
||||||
case LAMBDA_FORMAL_PARAMETER:
|
|
||||||
// TODO: also needs an offset?
|
|
||||||
sb.append(", param_index = ");
|
|
||||||
sb.append(parameter_index);
|
|
||||||
break;
|
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
sb.append(", position UNKNOWN!");
|
sb.append(", position UNKNOWN!");
|
||||||
break;
|
break;
|
||||||
@ -564,34 +562,37 @@ public class TypeAnnotation {
|
|||||||
/** For annotations on an exception parameter. */
|
/** For annotations on an exception parameter. */
|
||||||
EXCEPTION_PARAMETER(0x42, true),
|
EXCEPTION_PARAMETER(0x42, true),
|
||||||
|
|
||||||
/** For annotations on a typecast. */
|
|
||||||
CAST(0x43, true),
|
|
||||||
|
|
||||||
/** For annotations on a type test. */
|
/** For annotations on a type test. */
|
||||||
INSTANCEOF(0x44, true),
|
INSTANCEOF(0x43, true),
|
||||||
|
|
||||||
/** For annotations on an object creation expression. */
|
/** For annotations on an object creation expression. */
|
||||||
NEW(0x45, true),
|
NEW(0x44, true),
|
||||||
|
|
||||||
|
/** For annotations on a constructor reference receiver. */
|
||||||
|
CONSTRUCTOR_REFERENCE(0x45, true),
|
||||||
|
|
||||||
|
/** For annotations on a method reference receiver. */
|
||||||
|
METHOD_REFERENCE(0x46, true),
|
||||||
|
|
||||||
|
/** For annotations on a typecast. */
|
||||||
|
CAST(0x47, true),
|
||||||
|
|
||||||
/** For annotations on a type argument of an object creation expression. */
|
/** For annotations on a type argument of an object creation expression. */
|
||||||
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
|
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x48, true),
|
||||||
|
|
||||||
/** For annotations on a type argument of a method call. */
|
/** For annotations on a type argument of a method call. */
|
||||||
METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true),
|
METHOD_INVOCATION_TYPE_ARGUMENT(0x49, true),
|
||||||
|
|
||||||
/** For annotations on a lambda parameter type. */
|
/** For annotations on a type argument of a constructor reference. */
|
||||||
LAMBDA_FORMAL_PARAMETER(0x48, true),
|
CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true),
|
||||||
|
|
||||||
/** For annotations on a method reference. */
|
|
||||||
METHOD_REFERENCE(0x49, true),
|
|
||||||
|
|
||||||
/** For annotations on a type argument of a method reference. */
|
/** For annotations on a type argument of a method reference. */
|
||||||
METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true),
|
METHOD_REFERENCE_TYPE_ARGUMENT(0x4B, true),
|
||||||
|
|
||||||
/** For annotations with an unknown target. */
|
/** For annotations with an unknown target. */
|
||||||
UNKNOWN(0xFF);
|
UNKNOWN(0xFF);
|
||||||
|
|
||||||
private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x50;
|
private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x4B;
|
||||||
|
|
||||||
private final int targetTypeValue;
|
private final int targetTypeValue;
|
||||||
private final boolean isLocal;
|
private final boolean isLocal;
|
||||||
|
@ -82,34 +82,37 @@ public enum TargetType {
|
|||||||
/** For annotations on an exception parameter. */
|
/** For annotations on an exception parameter. */
|
||||||
EXCEPTION_PARAMETER(0x42, true),
|
EXCEPTION_PARAMETER(0x42, true),
|
||||||
|
|
||||||
/** For annotations on a typecast. */
|
|
||||||
CAST(0x43, true),
|
|
||||||
|
|
||||||
/** For annotations on a type test. */
|
/** For annotations on a type test. */
|
||||||
INSTANCEOF(0x44, true),
|
INSTANCEOF(0x43, true),
|
||||||
|
|
||||||
/** For annotations on an object creation expression. */
|
/** For annotations on an object creation expression. */
|
||||||
NEW(0x45, true),
|
NEW(0x44, true),
|
||||||
|
|
||||||
|
/** For annotations on a constructor reference receiver. */
|
||||||
|
CONSTRUCTOR_REFERENCE(0x45, true),
|
||||||
|
|
||||||
|
/** For annotations on a method reference receiver. */
|
||||||
|
METHOD_REFERENCE(0x46, true),
|
||||||
|
|
||||||
|
/** For annotations on a typecast. */
|
||||||
|
CAST(0x47, true),
|
||||||
|
|
||||||
/** For annotations on a type argument of an object creation expression. */
|
/** For annotations on a type argument of an object creation expression. */
|
||||||
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
|
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x48, true),
|
||||||
|
|
||||||
/** For annotations on a type argument of a method call. */
|
/** For annotations on a type argument of a method call. */
|
||||||
METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true),
|
METHOD_INVOCATION_TYPE_ARGUMENT(0x49, true),
|
||||||
|
|
||||||
/** For annotations on a lambda parameter type. */
|
/** For annotations on a type argument of a constructor reference. */
|
||||||
LAMBDA_FORMAL_PARAMETER(0x48, true),
|
CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true),
|
||||||
|
|
||||||
/** For annotations on a method reference. */
|
|
||||||
METHOD_REFERENCE(0x49, true),
|
|
||||||
|
|
||||||
/** For annotations on a type argument of a method reference. */
|
/** For annotations on a type argument of a method reference. */
|
||||||
METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true),
|
METHOD_REFERENCE_TYPE_ARGUMENT(0x4B, true),
|
||||||
|
|
||||||
/** For annotations with an unknown target. */
|
/** For annotations with an unknown target. */
|
||||||
UNKNOWN(0xFF);
|
UNKNOWN(0xFF);
|
||||||
|
|
||||||
private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x92;
|
private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x4B;
|
||||||
|
|
||||||
private final int targetTypeValue;
|
private final int targetTypeValue;
|
||||||
private final boolean isLocal;
|
private final boolean isLocal;
|
||||||
|
@ -126,7 +126,8 @@ public class TypeAnnotationPosition {
|
|||||||
// Tree position.
|
// Tree position.
|
||||||
public int pos = -1;
|
public int pos = -1;
|
||||||
|
|
||||||
// For typecasts, type tests, new (and locals, as start_pc).
|
// For type casts, type tests, new, locals (as start_pc),
|
||||||
|
// and method and constructor reference type arguments.
|
||||||
public boolean isValidOffset = false;
|
public boolean isValidOffset = false;
|
||||||
public int offset = -1;
|
public int offset = -1;
|
||||||
|
|
||||||
@ -156,12 +157,13 @@ public class TypeAnnotationPosition {
|
|||||||
sb.append(type);
|
sb.append(type);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// type cast
|
|
||||||
case CAST:
|
|
||||||
// instanceof
|
// instanceof
|
||||||
case INSTANCEOF:
|
case INSTANCEOF:
|
||||||
// new expression
|
// new expression
|
||||||
case NEW:
|
case NEW:
|
||||||
|
// constructor/method reference receiver
|
||||||
|
case CONSTRUCTOR_REFERENCE:
|
||||||
|
case METHOD_REFERENCE:
|
||||||
sb.append(", offset = ");
|
sb.append(", offset = ");
|
||||||
sb.append(offset);
|
sb.append(offset);
|
||||||
break;
|
break;
|
||||||
@ -223,9 +225,12 @@ public class TypeAnnotationPosition {
|
|||||||
sb.append(", param_index = ");
|
sb.append(", param_index = ");
|
||||||
sb.append(parameter_index);
|
sb.append(parameter_index);
|
||||||
break;
|
break;
|
||||||
|
// type cast
|
||||||
|
case CAST:
|
||||||
// method/constructor/reference type argument
|
// method/constructor/reference type argument
|
||||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||||
|
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
|
||||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||||
sb.append(", offset = ");
|
sb.append(", offset = ");
|
||||||
sb.append(offset);
|
sb.append(offset);
|
||||||
@ -236,12 +241,6 @@ public class TypeAnnotationPosition {
|
|||||||
case METHOD_RETURN:
|
case METHOD_RETURN:
|
||||||
case FIELD:
|
case FIELD:
|
||||||
break;
|
break;
|
||||||
// lambda formal parameter
|
|
||||||
case LAMBDA_FORMAL_PARAMETER:
|
|
||||||
// TODO: also needs an offset?
|
|
||||||
sb.append(", param_index = ");
|
|
||||||
sb.append(parameter_index);
|
|
||||||
break;
|
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
sb.append(", position UNKNOWN!");
|
sb.append(", position UNKNOWN!");
|
||||||
break;
|
break;
|
||||||
|
@ -217,6 +217,9 @@ public class TypeAnnotations {
|
|||||||
// Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore
|
// Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore
|
||||||
// need to set its position explicitly.
|
// need to set its position explicitly.
|
||||||
// The method returns a copy of type that contains these annotations.
|
// The method returns a copy of type that contains these annotations.
|
||||||
|
//
|
||||||
|
// As a side effect the method sets the type annotation position of "annotations".
|
||||||
|
// Note that it is assumed that all annotations share the same position.
|
||||||
private static Type typeWithAnnotations(final JCTree typetree, final Type type,
|
private static Type typeWithAnnotations(final JCTree typetree, final Type type,
|
||||||
final List<Attribute.TypeCompound> annotations, Log log) {
|
final List<Attribute.TypeCompound> annotations, Log log) {
|
||||||
// System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n",
|
// System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n",
|
||||||
@ -267,7 +270,9 @@ public class TypeAnnotations {
|
|||||||
}
|
}
|
||||||
Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, log);
|
Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, log);
|
||||||
tomodify.elemtype = arelemType;
|
tomodify.elemtype = arelemType;
|
||||||
for (Attribute.TypeCompound a : annotations) {
|
{
|
||||||
|
// All annotations share the same position; modify the first one.
|
||||||
|
Attribute.TypeCompound a = annotations.get(0);
|
||||||
TypeAnnotationPosition p = a.position;
|
TypeAnnotationPosition p = a.position;
|
||||||
p.location = p.location.prependList(depth.toList());
|
p.location = p.location.prependList(depth.toList());
|
||||||
}
|
}
|
||||||
@ -345,10 +350,10 @@ public class TypeAnnotations {
|
|||||||
if (depth.nonEmpty()) {
|
if (depth.nonEmpty()) {
|
||||||
// Only need to change the annotation positions
|
// Only need to change the annotation positions
|
||||||
// if they are on an enclosed type.
|
// if they are on an enclosed type.
|
||||||
for (Attribute.TypeCompound a : annotations) {
|
// All annotations share the same position; modify the first one.
|
||||||
TypeAnnotationPosition p = a.position;
|
Attribute.TypeCompound a = annotations.get(0);
|
||||||
p.location = p.location.appendList(depth.toList());
|
TypeAnnotationPosition p = a.position;
|
||||||
}
|
p.location = p.location.appendList(depth.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
Type ret = typeWithAnnotations(type, enclTy, annotations);
|
Type ret = typeWithAnnotations(type, enclTy, annotations);
|
||||||
@ -463,8 +468,7 @@ public class TypeAnnotations {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type visitType(Type t, List<TypeCompound> s) {
|
public Type visitType(Type t, List<TypeCompound> s) {
|
||||||
// Error?
|
return new AnnotatedType(s, t);
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -575,6 +579,10 @@ public class TypeAnnotations {
|
|||||||
System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind());
|
System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind());
|
||||||
System.out.println(" Framing tree: " + frame + " kind: " + frame.getKind());
|
System.out.println(" Framing tree: " + frame + " kind: " + frame.getKind());
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Note that p.offset is set in
|
||||||
|
// com.sun.tools.javac.jvm.Gen.setTypeAnnotationPositions(int)
|
||||||
|
|
||||||
switch (frame.getKind()) {
|
switch (frame.getKind()) {
|
||||||
case TYPE_CAST:
|
case TYPE_CAST:
|
||||||
p.type = TargetType.CAST;
|
p.type = TargetType.CAST;
|
||||||
@ -659,6 +667,45 @@ public class TypeAnnotations {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MEMBER_REFERENCE: {
|
||||||
|
JCMemberReference mrframe = (JCMemberReference) frame;
|
||||||
|
|
||||||
|
if (mrframe.expr == tree) {
|
||||||
|
switch (mrframe.mode) {
|
||||||
|
case INVOKE:
|
||||||
|
p.type = TargetType.METHOD_REFERENCE;
|
||||||
|
break;
|
||||||
|
case NEW:
|
||||||
|
p.type = TargetType.CONSTRUCTOR_REFERENCE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Assert.error("Unknown method reference mode " + mrframe.mode +
|
||||||
|
" for tree " + tree + " within frame " + frame);
|
||||||
|
}
|
||||||
|
p.pos = frame.pos;
|
||||||
|
} else if (mrframe.typeargs != null &&
|
||||||
|
mrframe.typeargs.contains(tree)) {
|
||||||
|
int arg = mrframe.typeargs.indexOf(tree);
|
||||||
|
p.type_index = arg;
|
||||||
|
switch (mrframe.mode) {
|
||||||
|
case INVOKE:
|
||||||
|
p.type = TargetType.METHOD_REFERENCE_TYPE_ARGUMENT;
|
||||||
|
break;
|
||||||
|
case NEW:
|
||||||
|
p.type = TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Assert.error("Unknown method reference mode " + mrframe.mode +
|
||||||
|
" for tree " + tree + " within frame " + frame);
|
||||||
|
}
|
||||||
|
p.pos = frame.pos;
|
||||||
|
} else {
|
||||||
|
Assert.error("Could not determine type argument position of tree " + tree +
|
||||||
|
" within frame " + frame);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case ARRAY_TYPE: {
|
case ARRAY_TYPE: {
|
||||||
ListBuffer<TypePathEntry> index = ListBuffer.lb();
|
ListBuffer<TypePathEntry> index = ListBuffer.lb();
|
||||||
index = index.append(TypePathEntry.ARRAY);
|
index = index.append(TypePathEntry.ARRAY);
|
||||||
@ -766,6 +813,14 @@ public class TypeAnnotations {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case INTERSECTION_TYPE: {
|
||||||
|
JCTypeIntersection isect = (JCTypeIntersection)frame;
|
||||||
|
p.type_index = isect.bounds.indexOf(tree);
|
||||||
|
List<JCTree> newPath = path.tail;
|
||||||
|
resolveFrame(newPath.head, newPath.tail.head, newPath, p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case METHOD_INVOCATION: {
|
case METHOD_INVOCATION: {
|
||||||
JCMethodInvocation invocation = (JCMethodInvocation)frame;
|
JCMethodInvocation invocation = (JCMethodInvocation)frame;
|
||||||
if (!invocation.typeargs.contains(tree)) {
|
if (!invocation.typeargs.contains(tree)) {
|
||||||
@ -911,6 +966,8 @@ public class TypeAnnotations {
|
|||||||
public void visitVarDef(final JCVariableDecl tree) {
|
public void visitVarDef(final JCVariableDecl tree) {
|
||||||
if (tree.sym == null) {
|
if (tree.sym == null) {
|
||||||
// Something is wrong already. Quietly ignore.
|
// Something is wrong already. Quietly ignore.
|
||||||
|
} else if (tree.sym.getKind() == ElementKind.PARAMETER) {
|
||||||
|
// Parameters are handled in visitMethodDef above.
|
||||||
} else if (tree.sym.getKind() == ElementKind.FIELD) {
|
} else if (tree.sym.getKind() == ElementKind.FIELD) {
|
||||||
if (sigOnly) {
|
if (sigOnly) {
|
||||||
TypeAnnotationPosition pos = new TypeAnnotationPosition();
|
TypeAnnotationPosition pos = new TypeAnnotationPosition();
|
||||||
@ -924,7 +981,6 @@ public class TypeAnnotations {
|
|||||||
pos.pos = tree.pos;
|
pos.pos = tree.pos;
|
||||||
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
|
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
|
||||||
} else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
|
} else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
|
||||||
// System.out.println("Found exception param: " + tree);
|
|
||||||
TypeAnnotationPosition pos = new TypeAnnotationPosition();
|
TypeAnnotationPosition pos = new TypeAnnotationPosition();
|
||||||
pos.type = TargetType.EXCEPTION_PARAMETER;
|
pos.type = TargetType.EXCEPTION_PARAMETER;
|
||||||
pos.pos = tree.pos;
|
pos.pos = tree.pos;
|
||||||
@ -934,9 +990,11 @@ public class TypeAnnotations {
|
|||||||
pos.type = TargetType.RESOURCE_VARIABLE;
|
pos.type = TargetType.RESOURCE_VARIABLE;
|
||||||
pos.pos = tree.pos;
|
pos.pos = tree.pos;
|
||||||
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
|
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
|
||||||
|
} else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
|
||||||
|
// No type annotations can occur here.
|
||||||
} else {
|
} else {
|
||||||
// There is nothing else in a variable declaration that needs separation.
|
// There is nothing else in a variable declaration that needs separation.
|
||||||
// System.out.println("We found a: " + tree);
|
Assert.error("Unhandled variable kind: " + tree + " of kind: " + tree.sym.getKind());
|
||||||
}
|
}
|
||||||
|
|
||||||
push(tree);
|
push(tree);
|
||||||
|
@ -2068,7 +2068,15 @@ public class Types {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) {
|
public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) {
|
||||||
return new AnnotatedType(t.typeAnnotations, erasure(t.underlyingType, recurse));
|
Type erased = erasure(t.underlyingType, recurse);
|
||||||
|
if (erased.getKind() == TypeKind.ANNOTATED) {
|
||||||
|
// This can only happen when the underlying type is a
|
||||||
|
// type variable and the upper bound of it is annotated.
|
||||||
|
// The annotation on the type variable overrides the one
|
||||||
|
// on the bound.
|
||||||
|
erased = ((AnnotatedType)erased).underlyingType;
|
||||||
|
}
|
||||||
|
return new AnnotatedType(t.typeAnnotations, erased);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -766,6 +766,8 @@ public class Attr extends JCTree.Visitor {
|
|||||||
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
memberEnter.typeAnnotate(initializer, env, env.info.enclVar);
|
||||||
|
annotate.flush();
|
||||||
Type itype = attribExpr(initializer, env, type);
|
Type itype = attribExpr(initializer, env, type);
|
||||||
if (itype.constValue() != null)
|
if (itype.constValue() != null)
|
||||||
return coerce(itype, type).constValue();
|
return coerce(itype, type).constValue();
|
||||||
@ -2539,7 +2541,7 @@ public class Attr extends JCTree.Visitor {
|
|||||||
|
|
||||||
if (exprType.isErroneous()) {
|
if (exprType.isErroneous()) {
|
||||||
//if the qualifier expression contains problems,
|
//if the qualifier expression contains problems,
|
||||||
//give up atttribution of method reference
|
//give up attribution of method reference
|
||||||
result = that.type = exprType;
|
result = that.type = exprType;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1470,12 +1470,13 @@ public class ClassReader implements Completer {
|
|||||||
position.type = type;
|
position.type = type;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// type cast
|
|
||||||
case CAST:
|
|
||||||
// instanceof
|
// instanceof
|
||||||
case INSTANCEOF:
|
case INSTANCEOF:
|
||||||
// new expression
|
// new expression
|
||||||
case NEW:
|
case NEW:
|
||||||
|
// constructor/method reference receiver
|
||||||
|
case CONSTRUCTOR_REFERENCE:
|
||||||
|
case METHOD_REFERENCE:
|
||||||
position.offset = nextChar();
|
position.offset = nextChar();
|
||||||
break;
|
break;
|
||||||
// local variable
|
// local variable
|
||||||
@ -1524,9 +1525,12 @@ public class ClassReader implements Completer {
|
|||||||
case METHOD_FORMAL_PARAMETER:
|
case METHOD_FORMAL_PARAMETER:
|
||||||
position.parameter_index = nextByte();
|
position.parameter_index = nextByte();
|
||||||
break;
|
break;
|
||||||
|
// type cast
|
||||||
|
case CAST:
|
||||||
// method/constructor/reference type argument
|
// method/constructor/reference type argument
|
||||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||||
|
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
|
||||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||||
position.offset = nextChar();
|
position.offset = nextChar();
|
||||||
position.type_index = nextByte();
|
position.type_index = nextByte();
|
||||||
@ -1535,10 +1539,6 @@ public class ClassReader implements Completer {
|
|||||||
case METHOD_RETURN:
|
case METHOD_RETURN:
|
||||||
case FIELD:
|
case FIELD:
|
||||||
break;
|
break;
|
||||||
// lambda formal parameter
|
|
||||||
case LAMBDA_FORMAL_PARAMETER:
|
|
||||||
position.parameter_index = nextByte();
|
|
||||||
break;
|
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!");
|
throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!");
|
||||||
default:
|
default:
|
||||||
|
@ -992,12 +992,13 @@ public class ClassWriter extends ClassFile {
|
|||||||
void writePosition(TypeAnnotationPosition p) {
|
void writePosition(TypeAnnotationPosition p) {
|
||||||
databuf.appendByte(p.type.targetTypeValue()); // TargetType tag is a byte
|
databuf.appendByte(p.type.targetTypeValue()); // TargetType tag is a byte
|
||||||
switch (p.type) {
|
switch (p.type) {
|
||||||
// type cast
|
|
||||||
case CAST:
|
|
||||||
// instanceof
|
// instanceof
|
||||||
case INSTANCEOF:
|
case INSTANCEOF:
|
||||||
// new expression
|
// new expression
|
||||||
case NEW:
|
case NEW:
|
||||||
|
// constructor/method reference receiver
|
||||||
|
case CONSTRUCTOR_REFERENCE:
|
||||||
|
case METHOD_REFERENCE:
|
||||||
databuf.appendChar(p.offset);
|
databuf.appendChar(p.offset);
|
||||||
break;
|
break;
|
||||||
// local variable
|
// local variable
|
||||||
@ -1042,9 +1043,12 @@ public class ClassWriter extends ClassFile {
|
|||||||
case METHOD_FORMAL_PARAMETER:
|
case METHOD_FORMAL_PARAMETER:
|
||||||
databuf.appendByte(p.parameter_index);
|
databuf.appendByte(p.parameter_index);
|
||||||
break;
|
break;
|
||||||
|
// type cast
|
||||||
|
case CAST:
|
||||||
// method/constructor/reference type argument
|
// method/constructor/reference type argument
|
||||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||||
|
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
|
||||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||||
databuf.appendChar(p.offset);
|
databuf.appendChar(p.offset);
|
||||||
databuf.appendByte(p.type_index);
|
databuf.appendByte(p.type_index);
|
||||||
@ -1053,10 +1057,6 @@ public class ClassWriter extends ClassFile {
|
|||||||
case METHOD_RETURN:
|
case METHOD_RETURN:
|
||||||
case FIELD:
|
case FIELD:
|
||||||
break;
|
break;
|
||||||
// lambda formal parameter
|
|
||||||
case LAMBDA_FORMAL_PARAMETER:
|
|
||||||
databuf.appendByte(p.parameter_index);
|
|
||||||
break;
|
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!");
|
throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!");
|
||||||
default:
|
default:
|
||||||
|
@ -1164,7 +1164,7 @@ public class JavacParser implements Parser {
|
|||||||
} else return illegal();
|
} else return illegal();
|
||||||
break;
|
break;
|
||||||
case MONKEYS_AT:
|
case MONKEYS_AT:
|
||||||
// Only annotated cast types are valid
|
// Only annotated cast types and method references are valid
|
||||||
List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
|
List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
|
||||||
if (typeAnnos.isEmpty()) {
|
if (typeAnnos.isEmpty()) {
|
||||||
// else there would be no '@'
|
// else there would be no '@'
|
||||||
@ -1175,17 +1175,27 @@ public class JavacParser implements Parser {
|
|||||||
|
|
||||||
if ((mode & TYPE) == 0) {
|
if ((mode & TYPE) == 0) {
|
||||||
// Type annotations on class literals no longer legal
|
// Type annotations on class literals no longer legal
|
||||||
if (!expr.hasTag(Tag.SELECT)) {
|
switch (expr.getTag()) {
|
||||||
|
case REFERENCE: {
|
||||||
|
JCMemberReference mref = (JCMemberReference) expr;
|
||||||
|
mref.expr = toP(F.at(pos).AnnotatedType(typeAnnos, mref.expr));
|
||||||
|
t = mref;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SELECT: {
|
||||||
|
JCFieldAccess sel = (JCFieldAccess) expr;
|
||||||
|
|
||||||
|
if (sel.name != names._class) {
|
||||||
|
return illegal();
|
||||||
|
} else {
|
||||||
|
log.error(token.pos, "no.annotations.on.dot.class");
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
return illegal(typeAnnos.head.pos);
|
return illegal(typeAnnos.head.pos);
|
||||||
}
|
}
|
||||||
JCFieldAccess sel = (JCFieldAccess)expr;
|
|
||||||
|
|
||||||
if (sel.name != names._class) {
|
|
||||||
return illegal();
|
|
||||||
} else {
|
|
||||||
log.error(token.pos, "no.annotations.on.dot.class");
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Type annotations targeting a cast
|
// Type annotations targeting a cast
|
||||||
t = insertAnnotationsToMostInner(expr, typeAnnos, false);
|
t = insertAnnotationsToMostInner(expr, typeAnnos, false);
|
||||||
@ -1457,18 +1467,40 @@ public class JavacParser implements Parser {
|
|||||||
/**
|
/**
|
||||||
* If we see an identifier followed by a '<' it could be an unbound
|
* If we see an identifier followed by a '<' it could be an unbound
|
||||||
* method reference or a binary expression. To disambiguate, look for a
|
* method reference or a binary expression. To disambiguate, look for a
|
||||||
* matching '>' and see if the subsequent terminal is either '.' or '#'.
|
* matching '>' and see if the subsequent terminal is either '.' or '::'.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("fallthrough")
|
@SuppressWarnings("fallthrough")
|
||||||
boolean isUnboundMemberRef() {
|
boolean isUnboundMemberRef() {
|
||||||
int pos = 0, depth = 0;
|
int pos = 0, depth = 0;
|
||||||
for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
|
outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
|
||||||
switch (t.kind) {
|
switch (t.kind) {
|
||||||
case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
|
case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
|
||||||
case DOT: case RBRACKET: case LBRACKET: case COMMA:
|
case DOT: case RBRACKET: case LBRACKET: case COMMA:
|
||||||
case BYTE: case SHORT: case INT: case LONG: case FLOAT:
|
case BYTE: case SHORT: case INT: case LONG: case FLOAT:
|
||||||
case DOUBLE: case BOOLEAN: case CHAR:
|
case DOUBLE: case BOOLEAN: case CHAR:
|
||||||
|
case MONKEYS_AT:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LPAREN:
|
||||||
|
// skip annotation values
|
||||||
|
int nesting = 0;
|
||||||
|
for (; ; pos++) {
|
||||||
|
TokenKind tk2 = S.token(pos).kind;
|
||||||
|
switch (tk2) {
|
||||||
|
case EOF:
|
||||||
|
return false;
|
||||||
|
case LPAREN:
|
||||||
|
nesting++;
|
||||||
|
break;
|
||||||
|
case RPAREN:
|
||||||
|
nesting--;
|
||||||
|
if (nesting == 0) {
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case LT:
|
case LT:
|
||||||
depth++; break;
|
depth++; break;
|
||||||
case GTGTGT:
|
case GTGTGT:
|
||||||
@ -1494,7 +1526,7 @@ public class JavacParser implements Parser {
|
|||||||
/**
|
/**
|
||||||
* If we see an identifier followed by a '<' it could be an unbound
|
* If we see an identifier followed by a '<' it could be an unbound
|
||||||
* method reference or a binary expression. To disambiguate, look for a
|
* method reference or a binary expression. To disambiguate, look for a
|
||||||
* matching '>' and see if the subsequent terminal is either '.' or '#'.
|
* matching '>' and see if the subsequent terminal is either '.' or '::'.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("fallthrough")
|
@SuppressWarnings("fallthrough")
|
||||||
ParensResult analyzeParens() {
|
ParensResult analyzeParens() {
|
||||||
|
@ -235,6 +235,7 @@ public class TreeInfo {
|
|||||||
switch(tree.getTag()) {
|
switch(tree.getTag()) {
|
||||||
case TYPEAPPLY: return ((JCTypeApply)tree).getTypeArguments().isEmpty();
|
case TYPEAPPLY: return ((JCTypeApply)tree).getTypeArguments().isEmpty();
|
||||||
case NEWCLASS: return isDiamond(((JCNewClass)tree).clazz);
|
case NEWCLASS: return isDiamond(((JCNewClass)tree).clazz);
|
||||||
|
case ANNOTATED_TYPE: return isDiamond(((JCAnnotatedType)tree).underlyingType);
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,6 +336,8 @@ public class TreeInfo {
|
|||||||
case TYPEAPPLY:
|
case TYPEAPPLY:
|
||||||
case TYPEARRAY:
|
case TYPEARRAY:
|
||||||
return true;
|
return true;
|
||||||
|
case ANNOTATED_TYPE:
|
||||||
|
return isStaticSelector(((JCAnnotatedType)base).underlyingType, names);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -91,12 +91,13 @@ public class AnnotationWriter extends BasicWriter {
|
|||||||
print(pos.type);
|
print(pos.type);
|
||||||
|
|
||||||
switch (pos.type) {
|
switch (pos.type) {
|
||||||
// type cast
|
|
||||||
case CAST:
|
|
||||||
// instanceof
|
// instanceof
|
||||||
case INSTANCEOF:
|
case INSTANCEOF:
|
||||||
// new expression
|
// new expression
|
||||||
case NEW:
|
case NEW:
|
||||||
|
// constructor/method reference receiver
|
||||||
|
case CONSTRUCTOR_REFERENCE:
|
||||||
|
case METHOD_REFERENCE:
|
||||||
if (showOffsets) {
|
if (showOffsets) {
|
||||||
print(", offset=");
|
print(", offset=");
|
||||||
print(pos.offset);
|
print(pos.offset);
|
||||||
@ -162,9 +163,12 @@ public class AnnotationWriter extends BasicWriter {
|
|||||||
print(", param_index=");
|
print(", param_index=");
|
||||||
print(pos.parameter_index);
|
print(pos.parameter_index);
|
||||||
break;
|
break;
|
||||||
|
// type cast
|
||||||
|
case CAST:
|
||||||
// method/constructor/reference type argument
|
// method/constructor/reference type argument
|
||||||
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
|
||||||
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
case METHOD_INVOCATION_TYPE_ARGUMENT:
|
||||||
|
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
|
||||||
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
case METHOD_REFERENCE_TYPE_ARGUMENT:
|
||||||
if (showOffsets) {
|
if (showOffsets) {
|
||||||
print(", offset=");
|
print(", offset=");
|
||||||
@ -177,11 +181,6 @@ public class AnnotationWriter extends BasicWriter {
|
|||||||
case METHOD_RETURN:
|
case METHOD_RETURN:
|
||||||
case FIELD:
|
case FIELD:
|
||||||
break;
|
break;
|
||||||
// lambda formal parameter
|
|
||||||
case LAMBDA_FORMAL_PARAMETER:
|
|
||||||
print(", param_index=");
|
|
||||||
print(pos.parameter_index);
|
|
||||||
break;
|
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
throw new AssertionError("AnnotationWriter: UNKNOWN target type should never occur!");
|
throw new AssertionError("AnnotationWriter: UNKNOWN target type should never occur!");
|
||||||
default:
|
default:
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8008077
|
||||||
|
* @summary Type annotations in a lazy constant need to be attributed
|
||||||
|
* in the correct order.
|
||||||
|
* @author Werner Dietl
|
||||||
|
* @compile LazyConstantValue.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
class ClassA {
|
||||||
|
Object o = ClassB.lcv;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassB {
|
||||||
|
static final String[] lcv = new @TA String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
|
||||||
|
@interface TA {}
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8008077
|
||||||
|
* @summary Type annotations on a type variable, where the bound of
|
||||||
|
* the type variable is also annotated, need to be processed correctly.
|
||||||
|
* @author Werner Dietl
|
||||||
|
* @compile TypeVariable.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
class TypeVariable {
|
||||||
|
<TV extends @TA Object> TV cast(TV p) {
|
||||||
|
return (@TA TV) p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
|
||||||
|
@interface TA {}
|
||||||
|
|
@ -21,6 +21,8 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 6843077 8006775
|
* @bug 6843077 8006775
|
||||||
@ -29,7 +31,8 @@
|
|||||||
* @compile/fail VoidGenericMethod.java
|
* @compile/fail VoidGenericMethod.java
|
||||||
*/
|
*/
|
||||||
class VoidGenericMethod {
|
class VoidGenericMethod {
|
||||||
public <T> @A void method() { }
|
public @A <T> void method() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Target(ElementType.TYPE_USE)
|
||||||
@interface A { }
|
@interface A { }
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8008077
|
||||||
|
* @summary new type annotation location: lambda expressions
|
||||||
|
* @compile Lambda.java
|
||||||
|
* @author Werner Dietl
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
public class Lambda {
|
||||||
|
|
||||||
|
interface LambdaInt {
|
||||||
|
<S, T> void generic(S p1, T p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class LambdaImpl implements LambdaInt {
|
||||||
|
<S, T> LambdaImpl(S p1, T p2) {}
|
||||||
|
public <S, T> void generic(S p1, T p2) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
LambdaInt getMethodRefTA(LambdaImpl r) {
|
||||||
|
return r::<@TA Object, @TB Object>generic;
|
||||||
|
}
|
||||||
|
|
||||||
|
LambdaInt getConstructorRefTA() {
|
||||||
|
return LambdaImpl::<@TA Object, @TB Object>new;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
|
||||||
|
@interface TA { }
|
||||||
|
|
||||||
|
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
|
||||||
|
@interface TB { }
|
@ -0,0 +1,262 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8008077
|
||||||
|
* @summary Test population of reference info for lambda expressions
|
||||||
|
* @compile -g Driver.java ReferenceInfoUtil.java Lambda.java
|
||||||
|
* @run main Driver Lambda
|
||||||
|
* @author Werner Dietl
|
||||||
|
*/
|
||||||
|
|
||||||
|
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
|
||||||
|
|
||||||
|
public class Lambda {
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "TA", type = METHOD_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE),
|
||||||
|
@TADescription(annotation = "TB", type = METHOD_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE)
|
||||||
|
})
|
||||||
|
public String returnMethodRef1() {
|
||||||
|
return
|
||||||
|
"class Lambda {" +
|
||||||
|
" public String getName() { return \"Lambda!\"; }" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"class Test {" +
|
||||||
|
" java.util.function.Function<Lambda, String> lambda() {" +
|
||||||
|
" return @TA @TB Lambda::getName;" +
|
||||||
|
" }" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "TA", type = METHOD_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE),
|
||||||
|
@TADescription(annotation = "TB", type = METHOD_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 0 }),
|
||||||
|
@TADescription(annotation = "TC", type = METHOD_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 0 }),
|
||||||
|
@TADescription(annotation = "TD", type = METHOD_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 1 }),
|
||||||
|
@TADescription(annotation = "TE", type = METHOD_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 1 })
|
||||||
|
})
|
||||||
|
public String returnMethodRef2() {
|
||||||
|
return
|
||||||
|
"class Lambda<S, T> {" +
|
||||||
|
" public String getName() { return \"Lambda!\"; }" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"class Test {" +
|
||||||
|
" java.util.function.Function<Lambda<Integer, Float>, String> lambda() {" +
|
||||||
|
" return @TA Lambda<@TB @TC Integer, @TD @TE Float>::getName;" +
|
||||||
|
" }" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "CTA", type = METHOD_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE),
|
||||||
|
@TADescription(annotation = "CTB", type = METHOD_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 0 }),
|
||||||
|
@TADescription(annotation = "CTC", type = METHOD_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 1 })
|
||||||
|
})
|
||||||
|
public String returnMethodRef3() {
|
||||||
|
return
|
||||||
|
"class Lambda<S, T> {" +
|
||||||
|
" public String getName() { return \"Lambda!\"; }" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"@Target(ElementType.TYPE_USE)" +
|
||||||
|
"@interface CTA {" +
|
||||||
|
" String value();" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"@Target(ElementType.TYPE_USE)" +
|
||||||
|
"@interface CTB {" +
|
||||||
|
" int age();" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"@Target(ElementType.TYPE_USE)" +
|
||||||
|
"@interface CTC {" +
|
||||||
|
" String name();" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"class Test {" +
|
||||||
|
" java.util.function.Function<Lambda<Integer, Float>, String> lambda() {" +
|
||||||
|
" return @CTA(\"x\") Lambda<@CTB(age = 5) Integer, @CTC(name = \"y\") Float>::getName;" +
|
||||||
|
" }" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE),
|
||||||
|
@TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE)
|
||||||
|
})
|
||||||
|
public String returnConstructorRef1() {
|
||||||
|
return
|
||||||
|
"class Lambda {" +
|
||||||
|
" Lambda() { }" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"class Test {" +
|
||||||
|
" Runnable lambda() {" +
|
||||||
|
" return @TA @TB Lambda::new;" +
|
||||||
|
" }" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE),
|
||||||
|
@TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 0 }),
|
||||||
|
@TADescription(annotation = "TC", type = CONSTRUCTOR_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 0 }),
|
||||||
|
@TADescription(annotation = "TD", type = CONSTRUCTOR_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 1 }),
|
||||||
|
@TADescription(annotation = "TE", type = CONSTRUCTOR_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 1 })
|
||||||
|
})
|
||||||
|
public String returnConstructorRef2() {
|
||||||
|
return
|
||||||
|
"class Lambda<S, T> {" +
|
||||||
|
" Lambda() { }" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"class Test {" +
|
||||||
|
" Runnable lambda() {" +
|
||||||
|
" return @TA Lambda<@TB @TC Integer, @TD @TE Float>::new;" +
|
||||||
|
" }" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "CTA", type = CONSTRUCTOR_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE),
|
||||||
|
@TADescription(annotation = "CTB", type = CONSTRUCTOR_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 0 }),
|
||||||
|
@TADescription(annotation = "CTC", type = CONSTRUCTOR_REFERENCE,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
genericLocation = { 3, 1 })
|
||||||
|
})
|
||||||
|
public String returnConstructorRef3() {
|
||||||
|
return
|
||||||
|
"class Lambda<S, T> {" +
|
||||||
|
" Lambda() { }" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"@Target(ElementType.TYPE_USE)" +
|
||||||
|
"@interface CTA {" +
|
||||||
|
" String value();" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"@Target(ElementType.TYPE_USE)" +
|
||||||
|
"@interface CTB {" +
|
||||||
|
" int age();" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"@Target(ElementType.TYPE_USE)" +
|
||||||
|
"@interface CTC {" +
|
||||||
|
" String name();" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"class Test {" +
|
||||||
|
" Runnable lambda() {" +
|
||||||
|
" return @CTA(\"x\") Lambda<@CTB(age = 5) Integer, @CTC(name = \"y\") Float>::new;" +
|
||||||
|
" }" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "TA", type = METHOD_REFERENCE_TYPE_ARGUMENT,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
|
@TADescription(annotation = "TB", type = METHOD_REFERENCE_TYPE_ARGUMENT,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 1)
|
||||||
|
})
|
||||||
|
public String returnMethodRefTA1() {
|
||||||
|
return
|
||||||
|
"interface Lambda {" +
|
||||||
|
" <S, T> void generic(S p1, T p2);" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"class LambdaImpl implements Lambda {" +
|
||||||
|
" public <S, T> void generic(S p1, T p2) {}" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"class Test {" +
|
||||||
|
" Lambda lambda(LambdaImpl r) {" +
|
||||||
|
" return r::<@TA Object, @TB Object>generic;" +
|
||||||
|
" }" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
|
@TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 1)
|
||||||
|
})
|
||||||
|
public String returnConstructorRefTA2() {
|
||||||
|
return
|
||||||
|
"interface Lambda {" +
|
||||||
|
" <S, T> void generic(S p1, T p2);" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"class LambdaImpl implements Lambda {" +
|
||||||
|
" <S, T> LambdaImpl(S p1, T p2) {}" +
|
||||||
|
" public <S, T> void generic(S p1, T p2) {}" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"class Test {" +
|
||||||
|
" Lambda lambda() {" +
|
||||||
|
" return LambdaImpl::<@TA Object, @TB Object>new;" +
|
||||||
|
" }" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -92,6 +92,28 @@ public class MethodParameters {
|
|||||||
return "void test(Object b, @TC String @TA [] @TB [] a) { }";
|
return "void test(Object b, @TC String @TA [] @TB [] a) { }";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
|
||||||
|
genericLocation = { 0, 0 }, paramIndex = 1),
|
||||||
|
@TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
|
||||||
|
genericLocation = { 0, 0 }, paramIndex = 1)
|
||||||
|
})
|
||||||
|
public String methodParamAsArray2() {
|
||||||
|
return "void test(Object b, @TA @TB String [] a) { }";
|
||||||
|
}
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
|
||||||
|
genericLocation = { 0, 0 }, paramIndex = 1),
|
||||||
|
@TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
|
||||||
|
genericLocation = { 0, 0 }, paramIndex = 1),
|
||||||
|
@TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER,
|
||||||
|
genericLocation = { 0, 0 }, paramIndex = 1)
|
||||||
|
})
|
||||||
|
public String methodParamAsArray3() {
|
||||||
|
return "void test(Object b, @TA @TB @TC String [] a) { }";
|
||||||
|
}
|
||||||
|
|
||||||
@TADescriptions({
|
@TADescriptions({
|
||||||
@TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1),
|
@TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1),
|
||||||
@TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
|
@TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
|
||||||
|
@ -31,118 +31,170 @@ import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
|
|||||||
*/
|
*/
|
||||||
public class TypeCasts {
|
public class TypeCasts {
|
||||||
|
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
public String returnObject() {
|
public String returnObject() {
|
||||||
return "Object returnObject() { return (@TA String)null; }";
|
return "Object returnObject() { return (@TA String)null; }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescriptions({
|
@TADescriptions({
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
@TADescription(annotation = "TB", type = CAST,
|
@TADescription(annotation = "TB", type = CAST,
|
||||||
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE),
|
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
@TADescription(annotation = "TC", type = CAST,
|
@TADescription(annotation = "TC", type = CAST,
|
||||||
genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
})
|
})
|
||||||
public String returnObjectArray() {
|
public String returnObjectArray() {
|
||||||
return "Object returnObjectArray() { return (@TC String @TA [] @TB [])null; }";
|
return "Object returnObjectArray() { return (@TC String @TA [] @TB [])null; }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescriptions({
|
@TADescriptions({
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
@TADescription(annotation = "TB", type = CAST,
|
@TADescription(annotation = "TB", type = CAST,
|
||||||
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
})
|
})
|
||||||
public String returnObjectGeneric() {
|
public String returnObjectGeneric() {
|
||||||
return "Object returnObjectGeneric() { return (@TA List<@TB String>)null; }";
|
return "Object returnObjectGeneric() { return (@TA List<@TB String>)null; }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
public String returnPrim() {
|
public String returnPrim() {
|
||||||
return "Object returnPrim() { return (@TA int)0; }";
|
return "Object returnPrim() { return (@TA int)0; }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescriptions({
|
@TADescriptions({
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
@TADescription(annotation = "TB", type = CAST,
|
@TADescription(annotation = "TB", type = CAST,
|
||||||
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
})
|
})
|
||||||
public String returnPrimArray() {
|
public String returnPrimArray() {
|
||||||
return "Object returnPrimArray() { return (@TB int @TA [])null; }";
|
return "Object returnPrimArray() { return (@TB int @TA [])null; }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
public String initObject() {
|
public String initObject() {
|
||||||
return "void initObject() { Object a = (@TA String)null; }";
|
return "void initObject() { Object a = (@TA String)null; }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescriptions({
|
@TADescriptions({
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
@TADescription(annotation = "TB", type = CAST,
|
@TADescription(annotation = "TB", type = CAST,
|
||||||
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
})
|
})
|
||||||
public String initObjectArray() {
|
public String initObjectArray() {
|
||||||
return "void initObjectArray() { Object a = (@TB String @TA [])null; }";
|
return "void initObjectArray() { Object a = (@TB String @TA [])null; }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescriptions({
|
@TADescriptions({
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
@TADescription(annotation = "TB", type = CAST,
|
@TADescription(annotation = "TB", type = CAST,
|
||||||
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
})
|
})
|
||||||
public String initObjectGeneric() {
|
public String initObjectGeneric() {
|
||||||
return "void initObjectGeneric() { Object a = (@TA List<@TB String>)null; }";
|
return "void initObjectGeneric() { Object a = (@TA List<@TB String>)null; }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
public String initPrim() {
|
public String initPrim() {
|
||||||
return "void initPrim() { Object a = (@TA int)0; }";
|
return "void initPrim() { Object a = (@TA int)0; }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescriptions({
|
@TADescriptions({
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
@TADescription(annotation = "TB", type = CAST,
|
@TADescription(annotation = "TB", type = CAST,
|
||||||
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
})
|
})
|
||||||
public String initPrimArray() {
|
public String initPrimArray() {
|
||||||
return "void initPrimArray() { Object a = (@TB int @TA [])null; }";
|
return "void initPrimArray() { Object a = (@TB int @TA [])null; }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
public String eqtestObject() {
|
public String eqtestObject() {
|
||||||
return "void eqtestObject() { if (null == (@TA String)null); }";
|
return "void eqtestObject() { if (null == (@TA String)null); }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescriptions({
|
@TADescriptions({
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
@TADescription(annotation = "TB", type = CAST,
|
@TADescription(annotation = "TB", type = CAST,
|
||||||
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
})
|
})
|
||||||
public String eqtestObjectArray() {
|
public String eqtestObjectArray() {
|
||||||
return "void eqtestObjectArray() { if (null == (@TB String @TA [])null); }";
|
return "void eqtestObjectArray() { if (null == (@TB String @TA [])null); }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescriptions({
|
@TADescriptions({
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
@TADescription(annotation = "TB", type = CAST,
|
@TADescription(annotation = "TB", type = CAST,
|
||||||
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
})
|
})
|
||||||
public String eqtestObjectGeneric() {
|
public String eqtestObjectGeneric() {
|
||||||
return "void eqtestObjectGeneric() { if (null == (@TA List<@TB String >)null); }";
|
return "void eqtestObjectGeneric() { if (null == (@TA List<@TB String >)null); }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
// compiler optimizes away compile time constants casts
|
// compiler optimizes away compile time constants casts
|
||||||
public String eqtestPrim() {
|
public String eqtestPrim() {
|
||||||
return "void eqtestPrim(int a) { if (0 == (@TA int)a); }";
|
return "void eqtestPrim(int a) { if (0 == (@TA int)a); }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@TADescriptions({
|
@TADescriptions({
|
||||||
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
|
@TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0),
|
||||||
@TADescription(annotation = "TB", type = CAST,
|
@TADescription(annotation = "TB", type = CAST,
|
||||||
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
|
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
|
||||||
|
typeIndex = 0)
|
||||||
})
|
})
|
||||||
public String eqtestPrimArray() {
|
public String eqtestPrimArray() {
|
||||||
return "void eqtestPrimArray() { if (null == (@TB int @TA [])null); }";
|
return "void eqtestPrimArray() { if (null == (@TB int @TA [])null); }";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "TA", type = CAST,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 0),
|
||||||
|
@TADescription(annotation = "TB", type = CAST,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1),
|
||||||
|
@TADescription(annotation = "TC", type = CAST,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1,
|
||||||
|
genericLocation = {3, 0})
|
||||||
|
})
|
||||||
|
public String intersection1() {
|
||||||
|
return "void intersection() { Object o = (@TA String & @TB Comparable<@TC String>) null; }";
|
||||||
|
}
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "TA", type = CAST,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 0),
|
||||||
|
@TADescription(annotation = "TB", type = CAST,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1),
|
||||||
|
@TADescription(annotation = "TC", type = CAST,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1,
|
||||||
|
genericLocation = {3, 0}),
|
||||||
|
@TADescription(annotation = "TD", type = CAST,
|
||||||
|
offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 2),
|
||||||
|
})
|
||||||
|
public String intersection2() {
|
||||||
|
return "void intersection() { Object o = (@TA String & @TB Comparable<@TC String> & @TD CharSequence) null; }";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user