--- old/src/share/classes/com/sun/tools/classfile/ClassWriter.java 2013-02-12 16:39:45.877542221 -0800 +++ new/src/share/classes/com/sun/tools/classfile/ClassWriter.java 2013-02-12 16:39:45.785544197 -0800 @@ -727,12 +727,13 @@ 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 @@ 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 @@ 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: --- old/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java 2013-02-12 16:39:46.185535614 -0800 +++ new/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java 2013-02-12 16:39:46.097537501 -0800 @@ -86,12 +86,13 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /** 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), - - /** For annotations on a lambda parameter type. */ - LAMBDA_FORMAL_PARAMETER(0x48, true), + METHOD_INVOCATION_TYPE_ARGUMENT(0x49, 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; --- old/src/share/classes/com/sun/tools/javac/code/TargetType.java 2013-02-12 16:39:46.497528918 -0800 +++ new/src/share/classes/com/sun/tools/javac/code/TargetType.java 2013-02-12 16:39:46.405530893 -0800 @@ -82,34 +82,37 @@ /** 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), - - /** For annotations on a lambda parameter type. */ - LAMBDA_FORMAL_PARAMETER(0x48, true), + METHOD_INVOCATION_TYPE_ARGUMENT(0x49, 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; --- old/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java 2013-02-12 16:39:46.793522567 -0800 +++ new/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java 2013-02-12 16:39:46.705524455 -0800 @@ -126,7 +126,8 @@ // 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 @@ 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 @@ 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 @@ 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; --- old/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java 2013-02-12 16:39:47.105515351 -0800 +++ new/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java 2013-02-12 16:39:47.013517731 -0800 @@ -217,6 +217,9 @@ // 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 annotations, Log log) { // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n", @@ -267,7 +270,9 @@ } 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 @@ 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 @@ @Override public Type visitType(Type t, List s) { - // Error? - return t; + return new AnnotatedType(s, t); } }; @@ -575,6 +579,10 @@ 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 @@ 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 index = ListBuffer.lb(); index = index.append(TypePathEntry.ARRAY); @@ -766,6 +813,14 @@ return; } + case INTERSECTION_TYPE: { + JCTypeIntersection isect = (JCTypeIntersection)frame; + p.type_index = isect.bounds.indexOf(tree); + List 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 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 @@ 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 @@ 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); --- old/src/share/classes/com/sun/tools/javac/code/Types.java 2013-02-12 16:39:47.417507289 -0800 +++ new/src/share/classes/com/sun/tools/javac/code/Types.java 2013-02-12 16:39:47.329509564 -0800 @@ -2068,7 +2068,15 @@ @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); } }; --- old/src/share/classes/com/sun/tools/javac/comp/Attr.java 2013-02-12 16:39:47.785497780 -0800 +++ new/src/share/classes/com/sun/tools/javac/comp/Attr.java 2013-02-12 16:39:47.685500365 -0800 @@ -766,6 +766,8 @@ 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 @@ 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; } --- old/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java 2013-02-12 16:39:48.149488521 -0800 +++ new/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java 2013-02-12 16:39:48.061490708 -0800 @@ -1470,12 +1470,13 @@ 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 @@ 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 @@ 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: --- old/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java 2013-02-12 16:39:48.481480266 -0800 +++ new/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java 2013-02-12 16:39:48.393482453 -0800 @@ -992,12 +992,13 @@ 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 @@ 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 @@ 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: --- old/src/share/classes/com/sun/tools/javac/parser/JavacParser.java 2013-02-12 16:39:48.813472011 -0800 +++ new/src/share/classes/com/sun/tools/javac/parser/JavacParser.java 2013-02-12 16:39:48.721474298 -0800 @@ -1164,7 +1164,7 @@ } else return illegal(); break; case MONKEYS_AT: - // Only annotated cast types are valid + // Only annotated cast types and method references are valid List typeAnnos = typeAnnotationsOpt(); if (typeAnnos.isEmpty()) { // else there would be no '@' @@ -1175,17 +1175,27 @@ if ((mode & TYPE) == 0) { // Type annotations on class literals no longer legal - if (!expr.hasTag(Tag.SELECT)) { - return illegal(typeAnnos.head.pos); + switch (expr.getTag()) { + case REFERENCE: { + JCMemberReference mref = (JCMemberReference) expr; + mref.expr = toP(F.at(pos).AnnotatedType(typeAnnos, mref.expr)); + t = mref; + break; } - JCFieldAccess sel = (JCFieldAccess)expr; + 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; + 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); } + } else { // Type annotations targeting a cast t = insertAnnotationsToMostInner(expr, typeAnnos, false); @@ -1457,18 +1467,40 @@ /** * If we see an identifier followed by a '<' it could be an unbound * 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") 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 @@ /** * If we see an identifier followed by a '<' it could be an unbound * 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") ParensResult analyzeParens() { --- old/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java 2013-02-12 16:39:49.161463474 -0800 +++ new/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java 2013-02-12 16:39:49.077465501 -0800 @@ -235,6 +235,7 @@ 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 @@ case TYPEAPPLY: case TYPEARRAY: return true; + case ANNOTATED_TYPE: + return isStaticSelector(((JCAnnotatedType)base).underlyingType, names); default: return false; } --- old/src/share/classes/com/sun/tools/javap/AnnotationWriter.java 2013-02-12 16:39:49.477455846 -0800 +++ new/src/share/classes/com/sun/tools/javap/AnnotationWriter.java 2013-02-12 16:39:49.389457971 -0800 @@ -91,12 +91,13 @@ 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 @@ 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 @@ 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: --- old/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java 2013-02-12 16:39:49.777448606 -0800 +++ new/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java 2013-02-12 16:39:49.685450827 -0800 @@ -21,6 +21,8 @@ * questions. */ +import java.lang.annotation.*; + /* * @test * @bug 6843077 8006775 @@ -29,7 +31,8 @@ * @compile/fail VoidGenericMethod.java */ class VoidGenericMethod { - public @A void method() { } + public @A void method() { } } +@Target(ElementType.TYPE_USE) @interface A { } --- old/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java 2013-02-12 16:39:50.069441597 -0800 +++ new/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java 2013-02-12 16:39:49.981443683 -0800 @@ -93,6 +93,28 @@ } @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, genericLocation = { 0, 0 }, paramIndex = 1), --- old/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java 2013-02-12 16:39:50.361434708 -0800 +++ new/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java 2013-02-12 16:39:50.273436785 -0800 @@ -31,118 +31,170 @@ */ 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; }"; + } } --- /dev/null 2013-02-03 10:19:03.336104554 -0800 +++ new/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.java 2013-02-12 16:39:50.581429518 -0800 @@ -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 1234567 + * @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 {} --- /dev/null 2013-02-03 10:19:03.336104554 -0800 +++ new/test/tools/javac/annotations/typeAnnotations/failures/TypeVariable.java 2013-02-12 16:39:50.853423103 -0800 @@ -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 1234567 + * @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 cast(TV p) { + return (@TA TV) p; + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA {} + --- /dev/null 2013-02-03 10:19:03.336104554 -0800 +++ new/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java 2013-02-12 16:39:51.129416646 -0800 @@ -0,0 +1,57 @@ +/* + * 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @summary new type annotation location: lambda expressions + * @compile Lambda.java + * @author Werner Dietl + */ +public class Lambda { + + interface LambdaInt { + void generic(S p1, T p2); + } + + static class LambdaImpl implements LambdaInt { + LambdaImpl(S p1, T p2) {} + public 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 { } --- /dev/null 2013-02-03 10:19:03.336104554 -0800 +++ new/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java 2013-02-12 16:39:51.385410712 -0800 @@ -0,0 +1,260 @@ +/* + * 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for lambda expressions + * @compile -g Driver.java ReferenceInfoUtil.java Lambda.java + * @run main Driver Lambda + * @author Werner Dietl + */ +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() {" + + " 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 {" + + " public String getName() { return \"Lambda!\"; }" + + "}" + + + "class Test {" + + " java.util.function.Function, 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 {" + + " 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, 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 {" + + " 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 {" + + " 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 {" + + " void generic(S p1, T p2);" + + "}" + + + "class LambdaImpl implements Lambda {" + + " public 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 {" + + " void generic(S p1, T p2);" + + "}" + + + "class LambdaImpl implements Lambda {" + + " LambdaImpl(S p1, T p2) {}" + + " public void generic(S p1, T p2) {}" + + "}" + + + "class Test {" + + " Lambda lambda() {" + + " return LambdaImpl::<@TA Object, @TB Object>new;" + + " }" + + "}"; + } + +}