8008077: update reference impl for type-annotations

Reviewed-by: jjg
This commit is contained in:
Werner Dietl 2013-02-12 17:15:29 -08:00 committed by Jonathan Gibbons
parent 1ec5dfafe0
commit 464abcb4fa
19 changed files with 724 additions and 134 deletions

View File

@ -727,12 +727,13 @@ public class ClassWriter {
private void write(TypeAnnotation.Position p, ClassOutputStream out) {
out.writeByte(p.type.targetTypeValue());
switch (p.type) {
// type cast
case CAST:
// instanceof
case INSTANCEOF:
// new expression
case NEW:
// constructor/method reference receiver
case CONSTRUCTOR_REFERENCE:
case METHOD_REFERENCE:
out.writeShort(p.offset);
break;
// local variable
@ -779,9 +780,12 @@ public class ClassWriter {
case METHOD_FORMAL_PARAMETER:
out.writeByte(p.parameter_index);
break;
// type cast
case CAST:
// method/constructor/reference type argument
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case METHOD_INVOCATION_TYPE_ARGUMENT:
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case METHOD_REFERENCE_TYPE_ARGUMENT:
out.writeShort(p.offset);
out.writeByte(p.type_index);
@ -790,10 +794,6 @@ public class ClassWriter {
case METHOD_RETURN:
case FIELD:
break;
// lambda formal parameter
case LAMBDA_FORMAL_PARAMETER:
out.writeByte(p.parameter_index);
break;
case UNKNOWN:
throw new AssertionError("ClassWriter: UNKNOWN target type should never occur!");
default:

View File

@ -86,12 +86,13 @@ public class TypeAnnotation {
position.type = type;
switch (type) {
// type cast
case CAST:
// instanceof
case INSTANCEOF:
// new expression
case NEW:
// constructor/method reference receiver
case CONSTRUCTOR_REFERENCE:
case METHOD_REFERENCE:
position.offset = cr.readUnsignedShort();
break;
// local variable
@ -142,9 +143,12 @@ public class TypeAnnotation {
case METHOD_FORMAL_PARAMETER:
position.parameter_index = cr.readUnsignedByte();
break;
// type cast
case CAST:
// method/constructor/reference type argument
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case METHOD_INVOCATION_TYPE_ARGUMENT:
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case METHOD_REFERENCE_TYPE_ARGUMENT:
position.offset = cr.readUnsignedShort();
position.type_index = cr.readUnsignedByte();
@ -153,10 +157,6 @@ public class TypeAnnotation {
case METHOD_RETURN:
case FIELD:
break;
// lambda formal parameter
case LAMBDA_FORMAL_PARAMETER:
position.parameter_index = cr.readUnsignedByte();
break;
case UNKNOWN:
throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
default:
@ -177,13 +177,14 @@ public class TypeAnnotation {
int n = 0;
n += 1; // TargetType tag is a byte
switch (pos.type) {
// type cast
case CAST:
// instanceof
case INSTANCEOF:
// new expression
case NEW:
n += 2;
// constructor/method reference receiver
case CONSTRUCTOR_REFERENCE:
case METHOD_REFERENCE:
n += 2; // offset
break;
// local variable
case LOCAL_VARIABLE:
@ -192,7 +193,7 @@ public class TypeAnnotation {
n += 2; // table_length;
int table_length = pos.lvarOffset.length;
n += 2 * table_length; // offset
n += 2 * table_length; // length;
n += 2 * table_length; // length
n += 2 * table_length; // index
break;
// exception parameter
@ -206,7 +207,7 @@ public class TypeAnnotation {
// type parameter
case CLASS_TYPE_PARAMETER:
case METHOD_TYPE_PARAMETER:
n += 1; // parameter_index;
n += 1; // parameter_index
break;
// type parameter bound
case CLASS_TYPE_PARAMETER_BOUND:
@ -226,9 +227,12 @@ public class TypeAnnotation {
case METHOD_FORMAL_PARAMETER:
n += 1; // parameter_index
break;
// type cast
case CAST:
// method/constructor/reference type argument
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case METHOD_INVOCATION_TYPE_ARGUMENT:
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case METHOD_REFERENCE_TYPE_ARGUMENT:
n += 2; // offset
n += 1; // type index
@ -237,10 +241,6 @@ public class TypeAnnotation {
case METHOD_RETURN:
case FIELD:
break;
// lambda formal parameter
case LAMBDA_FORMAL_PARAMETER:
n += 1; // parameter_index
break;
case UNKNOWN:
throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
default:
@ -377,12 +377,13 @@ public class TypeAnnotation {
sb.append(type);
switch (type) {
// type cast
case CAST:
// instanceof
case INSTANCEOF:
// new expression
case NEW:
// constructor/method reference receiver
case CONSTRUCTOR_REFERENCE:
case METHOD_REFERENCE:
sb.append(", offset = ");
sb.append(offset);
break;
@ -444,9 +445,12 @@ public class TypeAnnotation {
sb.append(", param_index = ");
sb.append(parameter_index);
break;
// type cast
case CAST:
// method/constructor/reference type argument
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case METHOD_INVOCATION_TYPE_ARGUMENT:
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case METHOD_REFERENCE_TYPE_ARGUMENT:
sb.append(", offset = ");
sb.append(offset);
@ -457,12 +461,6 @@ public class TypeAnnotation {
case METHOD_RETURN:
case FIELD:
break;
// lambda formal parameter
case LAMBDA_FORMAL_PARAMETER:
// TODO: also needs an offset?
sb.append(", param_index = ");
sb.append(parameter_index);
break;
case UNKNOWN:
sb.append(", position UNKNOWN!");
break;
@ -564,34 +562,37 @@ public class TypeAnnotation {
/** For annotations on an exception parameter. */
EXCEPTION_PARAMETER(0x42, true),
/** For annotations on a typecast. */
CAST(0x43, true),
/** For annotations on a type test. */
INSTANCEOF(0x44, true),
INSTANCEOF(0x43, true),
/** 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. */
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x48, true),
/** 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. */
LAMBDA_FORMAL_PARAMETER(0x48, true),
/** For annotations on a method reference. */
METHOD_REFERENCE(0x49, true),
/** For annotations on a type argument of a constructor reference. */
CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true),
/** 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. */
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 boolean isLocal;

View File

@ -82,34 +82,37 @@ public enum TargetType {
/** For annotations on an exception parameter. */
EXCEPTION_PARAMETER(0x42, true),
/** For annotations on a typecast. */
CAST(0x43, true),
/** For annotations on a type test. */
INSTANCEOF(0x44, true),
INSTANCEOF(0x43, true),
/** 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. */
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x48, true),
/** 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. */
LAMBDA_FORMAL_PARAMETER(0x48, true),
/** For annotations on a method reference. */
METHOD_REFERENCE(0x49, true),
/** For annotations on a type argument of a constructor reference. */
CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true),
/** 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. */
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 boolean isLocal;

View File

@ -126,7 +126,8 @@ public class TypeAnnotationPosition {
// Tree position.
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 int offset = -1;
@ -156,12 +157,13 @@ public class TypeAnnotationPosition {
sb.append(type);
switch (type) {
// type cast
case CAST:
// instanceof
case INSTANCEOF:
// new expression
case NEW:
// constructor/method reference receiver
case CONSTRUCTOR_REFERENCE:
case METHOD_REFERENCE:
sb.append(", offset = ");
sb.append(offset);
break;
@ -223,9 +225,12 @@ public class TypeAnnotationPosition {
sb.append(", param_index = ");
sb.append(parameter_index);
break;
// type cast
case CAST:
// method/constructor/reference type argument
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case METHOD_INVOCATION_TYPE_ARGUMENT:
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case METHOD_REFERENCE_TYPE_ARGUMENT:
sb.append(", offset = ");
sb.append(offset);
@ -236,12 +241,6 @@ public class TypeAnnotationPosition {
case METHOD_RETURN:
case FIELD:
break;
// lambda formal parameter
case LAMBDA_FORMAL_PARAMETER:
// TODO: also needs an offset?
sb.append(", param_index = ");
sb.append(parameter_index);
break;
case UNKNOWN:
sb.append(", position UNKNOWN!");
break;

View File

@ -217,6 +217,9 @@ public class TypeAnnotations {
// Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore
// need to set its position explicitly.
// 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,
final List<Attribute.TypeCompound> annotations, Log log) {
// 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);
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;
p.location = p.location.prependList(depth.toList());
}
@ -345,10 +350,10 @@ public class TypeAnnotations {
if (depth.nonEmpty()) {
// Only need to change the annotation positions
// if they are on an enclosed type.
for (Attribute.TypeCompound a : annotations) {
TypeAnnotationPosition p = a.position;
p.location = p.location.appendList(depth.toList());
}
// All annotations share the same position; modify the first one.
Attribute.TypeCompound a = annotations.get(0);
TypeAnnotationPosition p = a.position;
p.location = p.location.appendList(depth.toList());
}
Type ret = typeWithAnnotations(type, enclTy, annotations);
@ -463,8 +468,7 @@ public class TypeAnnotations {
@Override
public Type visitType(Type t, List<TypeCompound> s) {
// Error?
return t;
return new AnnotatedType(s, t);
}
};
@ -575,6 +579,10 @@ public class TypeAnnotations {
System.out.println("Resolving tree: " + tree + " kind: " + tree.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()) {
case TYPE_CAST:
p.type = TargetType.CAST;
@ -659,6 +667,45 @@ public class TypeAnnotations {
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: {
ListBuffer<TypePathEntry> index = ListBuffer.lb();
index = index.append(TypePathEntry.ARRAY);
@ -766,6 +813,14 @@ public class TypeAnnotations {
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: {
JCMethodInvocation invocation = (JCMethodInvocation)frame;
if (!invocation.typeargs.contains(tree)) {
@ -911,6 +966,8 @@ public class TypeAnnotations {
public void visitVarDef(final JCVariableDecl tree) {
if (tree.sym == null) {
// 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) {
if (sigOnly) {
TypeAnnotationPosition pos = new TypeAnnotationPosition();
@ -924,7 +981,6 @@ public class TypeAnnotations {
pos.pos = tree.pos;
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
} else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
// System.out.println("Found exception param: " + tree);
TypeAnnotationPosition pos = new TypeAnnotationPosition();
pos.type = TargetType.EXCEPTION_PARAMETER;
pos.pos = tree.pos;
@ -934,9 +990,11 @@ public class TypeAnnotations {
pos.type = TargetType.RESOURCE_VARIABLE;
pos.pos = tree.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 {
// 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);

View File

@ -2068,7 +2068,15 @@ public class Types {
@Override
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);
}
};

View File

@ -766,6 +766,8 @@ public class Attr extends JCTree.Visitor {
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
try {
memberEnter.typeAnnotate(initializer, env, env.info.enclVar);
annotate.flush();
Type itype = attribExpr(initializer, env, type);
if (itype.constValue() != null)
return coerce(itype, type).constValue();
@ -2539,7 +2541,7 @@ public class Attr extends JCTree.Visitor {
if (exprType.isErroneous()) {
//if the qualifier expression contains problems,
//give up atttribution of method reference
//give up attribution of method reference
result = that.type = exprType;
return;
}

View File

@ -1470,12 +1470,13 @@ public class ClassReader implements Completer {
position.type = type;
switch (type) {
// type cast
case CAST:
// instanceof
case INSTANCEOF:
// new expression
case NEW:
// constructor/method reference receiver
case CONSTRUCTOR_REFERENCE:
case METHOD_REFERENCE:
position.offset = nextChar();
break;
// local variable
@ -1524,9 +1525,12 @@ public class ClassReader implements Completer {
case METHOD_FORMAL_PARAMETER:
position.parameter_index = nextByte();
break;
// type cast
case CAST:
// method/constructor/reference type argument
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case METHOD_INVOCATION_TYPE_ARGUMENT:
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case METHOD_REFERENCE_TYPE_ARGUMENT:
position.offset = nextChar();
position.type_index = nextByte();
@ -1535,10 +1539,6 @@ public class ClassReader implements Completer {
case METHOD_RETURN:
case FIELD:
break;
// lambda formal parameter
case LAMBDA_FORMAL_PARAMETER:
position.parameter_index = nextByte();
break;
case UNKNOWN:
throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!");
default:

View File

@ -992,12 +992,13 @@ public class ClassWriter extends ClassFile {
void writePosition(TypeAnnotationPosition p) {
databuf.appendByte(p.type.targetTypeValue()); // TargetType tag is a byte
switch (p.type) {
// type cast
case CAST:
// instanceof
case INSTANCEOF:
// new expression
case NEW:
// constructor/method reference receiver
case CONSTRUCTOR_REFERENCE:
case METHOD_REFERENCE:
databuf.appendChar(p.offset);
break;
// local variable
@ -1042,9 +1043,12 @@ public class ClassWriter extends ClassFile {
case METHOD_FORMAL_PARAMETER:
databuf.appendByte(p.parameter_index);
break;
// type cast
case CAST:
// method/constructor/reference type argument
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case METHOD_INVOCATION_TYPE_ARGUMENT:
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case METHOD_REFERENCE_TYPE_ARGUMENT:
databuf.appendChar(p.offset);
databuf.appendByte(p.type_index);
@ -1053,10 +1057,6 @@ public class ClassWriter extends ClassFile {
case METHOD_RETURN:
case FIELD:
break;
// lambda formal parameter
case LAMBDA_FORMAL_PARAMETER:
databuf.appendByte(p.parameter_index);
break;
case UNKNOWN:
throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!");
default:

View File

@ -1164,7 +1164,7 @@ public class JavacParser implements Parser {
} else return illegal();
break;
case MONKEYS_AT:
// Only annotated cast types are valid
// Only annotated cast types and method references are valid
List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
if (typeAnnos.isEmpty()) {
// else there would be no '@'
@ -1175,17 +1175,27 @@ public class JavacParser implements Parser {
if ((mode & TYPE) == 0) {
// 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);
}
JCFieldAccess sel = (JCFieldAccess)expr;
if (sel.name != names._class) {
return illegal();
} else {
log.error(token.pos, "no.annotations.on.dot.class");
return expr;
}
} else {
// Type annotations targeting a cast
t = insertAnnotationsToMostInner(expr, typeAnnos, false);
@ -1457,18 +1467,40 @@ public class JavacParser implements Parser {
/**
* If we see an identifier followed by a '&lt;' it could be an unbound
* method reference or a binary expression. To disambiguate, look for a
* matching '&gt;' and see if the subsequent terminal is either '.' or '#'.
* matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
*/
@SuppressWarnings("fallthrough")
boolean isUnboundMemberRef() {
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) {
case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
case DOT: case RBRACKET: case LBRACKET: case COMMA:
case BYTE: case SHORT: case INT: case LONG: case FLOAT:
case DOUBLE: case BOOLEAN: case CHAR:
case MONKEYS_AT:
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:
depth++; break;
case GTGTGT:
@ -1494,7 +1526,7 @@ public class JavacParser implements Parser {
/**
* If we see an identifier followed by a '&lt;' it could be an unbound
* method reference or a binary expression. To disambiguate, look for a
* matching '&gt;' and see if the subsequent terminal is either '.' or '#'.
* matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
*/
@SuppressWarnings("fallthrough")
ParensResult analyzeParens() {

View File

@ -235,6 +235,7 @@ public class TreeInfo {
switch(tree.getTag()) {
case TYPEAPPLY: return ((JCTypeApply)tree).getTypeArguments().isEmpty();
case NEWCLASS: return isDiamond(((JCNewClass)tree).clazz);
case ANNOTATED_TYPE: return isDiamond(((JCAnnotatedType)tree).underlyingType);
default: return false;
}
}
@ -335,6 +336,8 @@ public class TreeInfo {
case TYPEAPPLY:
case TYPEARRAY:
return true;
case ANNOTATED_TYPE:
return isStaticSelector(((JCAnnotatedType)base).underlyingType, names);
default:
return false;
}

View File

@ -91,12 +91,13 @@ public class AnnotationWriter extends BasicWriter {
print(pos.type);
switch (pos.type) {
// type cast
case CAST:
// instanceof
case INSTANCEOF:
// new expression
case NEW:
// constructor/method reference receiver
case CONSTRUCTOR_REFERENCE:
case METHOD_REFERENCE:
if (showOffsets) {
print(", offset=");
print(pos.offset);
@ -162,9 +163,12 @@ public class AnnotationWriter extends BasicWriter {
print(", param_index=");
print(pos.parameter_index);
break;
// type cast
case CAST:
// method/constructor/reference type argument
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case METHOD_INVOCATION_TYPE_ARGUMENT:
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case METHOD_REFERENCE_TYPE_ARGUMENT:
if (showOffsets) {
print(", offset=");
@ -177,11 +181,6 @@ public class AnnotationWriter extends BasicWriter {
case METHOD_RETURN:
case FIELD:
break;
// lambda formal parameter
case LAMBDA_FORMAL_PARAMETER:
print(", param_index=");
print(pos.parameter_index);
break;
case UNKNOWN:
throw new AssertionError("AnnotationWriter: UNKNOWN target type should never occur!");
default:

View File

@ -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 {}

View File

@ -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 {}

View File

@ -21,6 +21,8 @@
* questions.
*/
import java.lang.annotation.*;
/*
* @test
* @bug 6843077 8006775
@ -29,7 +31,8 @@
* @compile/fail VoidGenericMethod.java
*/
class VoidGenericMethod {
public <T> @A void method() { }
public @A <T> void method() { }
}
@Target(ElementType.TYPE_USE)
@interface A { }

View File

@ -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 { }

View File

@ -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;" +
" }" +
"}";
}
}

View File

@ -92,6 +92,28 @@ public class MethodParameters {
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({
@TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1),
@TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,

View File

@ -31,118 +31,170 @@ import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
*/
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() {
return "Object returnObject() { return (@TA String)null; }";
}
@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,
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE),
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
typeIndex = 0),
@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() {
return "Object returnObjectArray() { return (@TC String @TA [] @TB [])null; }";
}
@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,
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
typeIndex = 0)
})
public String returnObjectGeneric() {
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() {
return "Object returnPrim() { return (@TA int)0; }";
}
@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,
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
typeIndex = 0)
})
public String returnPrimArray() {
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() {
return "void initObject() { Object a = (@TA String)null; }";
}
@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,
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
typeIndex = 0)
})
public String initObjectArray() {
return "void initObjectArray() { Object a = (@TB String @TA [])null; }";
}
@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,
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
typeIndex = 0)
})
public String initObjectGeneric() {
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() {
return "void initPrim() { Object a = (@TA int)0; }";
}
@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,
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
typeIndex = 0)
})
public String initPrimArray() {
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() {
return "void eqtestObject() { if (null == (@TA String)null); }";
}
@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,
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
typeIndex = 0)
})
public String eqtestObjectArray() {
return "void eqtestObjectArray() { if (null == (@TB String @TA [])null); }";
}
@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,
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
typeIndex = 0)
})
public String eqtestObjectGeneric() {
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
public String eqtestPrim() {
return "void eqtestPrim(int a) { if (0 == (@TA int)a); }";
}
@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,
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
typeIndex = 0)
})
public String eqtestPrimArray() {
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; }";
}
}