From ee93ddcf2ce506b17253288a9f8542ea5decdb76 Mon Sep 17 00:00:00 2001 From: jjg Date: Wed, 21 Aug 2013 16:13:50 -0700 Subject: [PATCH] 8023515: import type-annotations updates Reviewed-by: jjg Contributed-by: wdietl@gmail.com --- .../com/sun/source/tree/MethodTree.java | 8 + .../sun/source/tree/TypeParameterTree.java | 14 ++ .../com/sun/tools/javac/code/Printer.java | 12 +- .../sun/tools/javac/code/TypeAnnotations.java | 25 ++- .../sun/tools/javac/comp/LambdaToMethod.java | 2 +- .../com/sun/tools/javac/comp/MemberEnter.java | 2 +- .../JavacProcessingEnvironment.java | 2 +- .../tools/javac/resources/compiler.properties | 2 +- .../com/sun/tools/javac/tree/Pretty.java | 58 +++--- .../classfile/CombinationsTargetTest2.java | 84 +++++++-- .../failures/DummyProcessor.java | 43 +++++ .../typeAnnotations/failures/T8020715.java | 49 +++++ .../referenceinfos/Constructors.java | 20 +++ .../javac/tree/TypeAnnotationsPretty.java | 170 ++++++++++++++++++ 14 files changed, 429 insertions(+), 62 deletions(-) create mode 100644 test/tools/javac/annotations/typeAnnotations/failures/DummyProcessor.java create mode 100644 test/tools/javac/annotations/typeAnnotations/failures/T8020715.java create mode 100644 test/tools/javac/tree/TypeAnnotationsPretty.java diff --git a/src/share/classes/com/sun/source/tree/MethodTree.java b/src/share/classes/com/sun/source/tree/MethodTree.java index 8d9820ba..987c3742 100644 --- a/src/share/classes/com/sun/source/tree/MethodTree.java +++ b/src/share/classes/com/sun/source/tree/MethodTree.java @@ -53,7 +53,15 @@ public interface MethodTree extends Tree { Tree getReturnType(); List getTypeParameters(); List getParameters(); + + /** + * Return an explicit receiver parameter ("this" parameter). + * + * @return an explicit receiver parameter ("this" parameter) + * @since 1.8 + */ VariableTree getReceiverParameter(); + List getThrows(); BlockTree getBody(); Tree getDefaultValue(); // for annotation types diff --git a/src/share/classes/com/sun/source/tree/TypeParameterTree.java b/src/share/classes/com/sun/source/tree/TypeParameterTree.java index 293a38b3..6dd469a7 100644 --- a/src/share/classes/com/sun/source/tree/TypeParameterTree.java +++ b/src/share/classes/com/sun/source/tree/TypeParameterTree.java @@ -36,6 +36,8 @@ import javax.lang.model.element.Name; * name * * name extends bounds + * + * annotations name * * * @jls section 4.4 @@ -48,5 +50,17 @@ import javax.lang.model.element.Name; public interface TypeParameterTree extends Tree { Name getName(); List getBounds(); + + /** + * Return annotations on the type parameter declaration. + * + * Annotations need Target meta-annotations of + * {@link java.lang.annotation.ElementType#TYPE_PARAMETER} or + * {@link java.lang.annotation.ElementType#TYPE_USE} + * to appear in this position. + * + * @return annotations on the type parameter declaration + * @since 1.8 + */ List getAnnotations(); } diff --git a/src/share/classes/com/sun/tools/javac/code/Printer.java b/src/share/classes/com/sun/tools/javac/code/Printer.java index be0b5038..aa05cc29 100644 --- a/src/share/classes/com/sun/tools/javac/code/Printer.java +++ b/src/share/classes/com/sun/tools/javac/code/Printer.java @@ -27,8 +27,6 @@ package com.sun.tools.javac.code; import java.util.Locale; -import javax.lang.model.type.TypeKind; - import com.sun.tools.javac.api.Messages; import com.sun.tools.javac.code.Type.AnnotatedType; import com.sun.tools.javac.code.Type.ArrayType; @@ -191,7 +189,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi void printBaseElementType(Type t, StringBuilder sb, Locale locale) { Type arrel = t; - while (arrel.getKind() == TypeKind.ARRAY) { + while (arrel.hasTag(TypeTag.ARRAY)) { arrel = arrel.unannotatedType(); arrel = ((ArrayType) arrel).elemtype; } @@ -200,7 +198,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi void printBrackets(Type t, StringBuilder sb, Locale locale) { Type arrel = t; - while (arrel.getKind() == TypeKind.ARRAY) { + while (arrel.hasTag(TypeTag.ARRAY)) { if (arrel.isAnnotated()) { sb.append(' '); sb.append(arrel.getAnnotationMirrors()); @@ -264,12 +262,12 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi public String visitAnnotatedType(AnnotatedType t, Locale locale) { if (t.typeAnnotations != null && t.typeAnnotations.nonEmpty()) { - if (t.underlyingType.getKind() == TypeKind.ARRAY) { + if (t.underlyingType.hasTag(TypeTag.ARRAY)) { StringBuilder res = new StringBuilder(); printBaseElementType(t, res, locale); printBrackets(t, res, locale); return res.toString(); - } else if (t.underlyingType.getKind() == TypeKind.DECLARED && + } else if (t.underlyingType.hasTag(TypeTag.CLASS) && t.underlyingType.getEnclosingType() != Type.noType) { return visit(t.underlyingType.getEnclosingType(), locale) + ". " + @@ -348,7 +346,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi args = args.tail; buf.append(','); } - if (args.head.unannotatedType().getKind() == TypeKind.ARRAY) { + if (args.head.unannotatedType().hasTag(TypeTag.ARRAY)) { buf.append(visit(((ArrayType) args.head.unannotatedType()).elemtype, locale)); if (args.head.getAnnotationMirrors().nonEmpty()) { buf.append(' '); diff --git a/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index 260715df..642de5d4 100644 --- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -29,6 +29,8 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.type.TypeKind; +import javax.tools.JavaFileObject; + import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Attribute.TypeCompound; import com.sun.tools.javac.code.Flags; @@ -52,12 +54,16 @@ import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.comp.Annotate; import com.sun.tools.javac.comp.Annotate.Annotator; +import com.sun.tools.javac.comp.AttrContext; +import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCLambda; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; import com.sun.tools.javac.tree.JCTree.JCNewClass; import com.sun.tools.javac.tree.JCTree.JCTypeApply; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; @@ -90,11 +96,17 @@ public class TypeAnnotations { * later processing. */ public static void organizeTypeAnnotationsSignatures(final Symtab syms, final Names names, - final Log log, final JCClassDecl tree, Annotate annotate) { + final Log log, final Env env, final JCClassDecl tree, final Annotate annotate) { annotate.afterRepeated( new Annotator() { @Override public void enterAnnotation() { - new TypeAnnotationPositions(syms, names, log, true).scan(tree); + JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); + + try { + new TypeAnnotationPositions(syms, names, log, true).scan(tree); + } finally { + log.useSource(oldSource); + } } } ); } @@ -906,7 +918,14 @@ public class TypeAnnotations { if (!invocation.typeargs.contains(tree)) { Assert.error("{" + tree + "} is not an argument in the invocation: " + invocation); } - p.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT; + MethodSymbol exsym = (MethodSymbol) TreeInfo.symbol(invocation.getMethodSelect()); + if (exsym == null) { + Assert.error("could not determine symbol for {" + invocation + "}"); + } else if (exsym.isConstructor()) { + p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT; + } else { + p.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT; + } p.pos = invocation.pos; p.type_index = invocation.typeargs.indexOf(tree); return; diff --git a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index 577d7cc3..7633f96d 100644 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -249,7 +249,7 @@ public class LambdaToMethod extends TreeTranslator { MethodType lambdaType = (MethodType) sym.type; { - MethodSymbol owner = (MethodSymbol) localContext.owner; + Symbol owner = localContext.owner; ListBuffer ownerTypeAnnos = new ListBuffer(); ListBuffer lambdaTypeAnnos = new ListBuffer(); diff --git a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 4f23e8d8..cdd3db2b 100644 --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -1089,7 +1089,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } } if (allowTypeAnnos) { - TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate); + TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, env, tree, annotate); } } diff --git a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index 4e966f9b..7aca9f55 100644 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -89,7 +89,7 @@ import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; * deletion without notice. */ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closeable { - Options options; + private final Options options; private final boolean printProcessorInfo; private final boolean printRounds; diff --git a/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 572478f1..5d1a22b8 100644 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -2248,7 +2248,7 @@ compiler.err.cant.annotate.static.class=\ # TODO 308: make a better error message # 0: unused compiler.err.cant.annotate.nested.type=\ - nested type cannot be annotated + scoping construct for static nested type cannot be annotated # 0: type, 1: type compiler.err.incorrect.receiver.name=\ diff --git a/src/share/classes/com/sun/tools/javac/tree/Pretty.java b/src/share/classes/com/sun/tools/javac/tree/Pretty.java index e7c1e12b..653d9e54 100644 --- a/src/share/classes/com/sun/tools/javac/tree/Pretty.java +++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java @@ -944,10 +944,17 @@ public class Pretty extends JCTree.Visitor { try { if (tree.elemtype != null) { print("new "); - printTypeAnnotations(tree.annotations); JCTree elem = tree.elemtype; printBaseElementType(elem); - boolean isElemAnnoType = elem instanceof JCAnnotatedType; + + if (!tree.annotations.isEmpty()) { + print(' '); + printTypeAnnotations(tree.annotations); + } + if (tree.elems != null) { + print("[]"); + } + int i = 0; List> da = tree.dimAnnotations; for (List l = tree.dims; l.nonEmpty(); l = l.tail) { @@ -960,17 +967,7 @@ public class Pretty extends JCTree.Visitor { printExpr(l.head); print("]"); } - if (tree.elems != null) { - if (isElemAnnoType) { - print(' '); - printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations); - } - print("[]"); - } - if (isElemAnnoType) - elem = ((JCAnnotatedType)elem).underlyingType; - if (elem instanceof JCArrayTypeTree) - printBrackets((JCArrayTypeTree) elem); + printBrackets(elem); } if (tree.elems != null) { print("{"); @@ -1260,20 +1257,24 @@ public class Pretty extends JCTree.Visitor { } // prints the brackets of a nested array in reverse order - private void printBrackets(JCArrayTypeTree tree) throws IOException { - JCTree elem; + // tree is either JCArrayTypeTree or JCAnnotatedTypeTree + private void printBrackets(JCTree tree) throws IOException { + JCTree elem = tree; while (true) { - elem = tree.elemtype; if (elem.hasTag(ANNOTATED_TYPE)) { JCAnnotatedType atype = (JCAnnotatedType) elem; elem = atype.underlyingType; - if (!elem.hasTag(TYPEARRAY)) break; - print(' '); - printTypeAnnotations(atype.annotations); + if (elem.hasTag(TYPEARRAY)) { + print(' '); + printTypeAnnotations(atype.annotations); + } + } + if (elem.hasTag(TYPEARRAY)) { + print("[]"); + elem = ((JCArrayTypeTree)elem).elemtype; + } else { + break; } - print("[]"); - if (!elem.hasTag(TYPEARRAY)) break; - tree = (JCArrayTypeTree) elem; } } @@ -1378,22 +1379,15 @@ public class Pretty extends JCTree.Visitor { public void visitAnnotatedType(JCAnnotatedType tree) { try { - if (tree.underlyingType.getKind() == JCTree.Kind.MEMBER_SELECT) { + if (tree.underlyingType.hasTag(SELECT)) { JCFieldAccess access = (JCFieldAccess) tree.underlyingType; printExpr(access.selected, TreeInfo.postfixPrec); print("."); printTypeAnnotations(tree.annotations); print(access.name); - } else if (tree.underlyingType.getKind() == JCTree.Kind.ARRAY_TYPE) { - JCArrayTypeTree array = (JCArrayTypeTree) tree.underlyingType; + } else if (tree.underlyingType.hasTag(TYPEARRAY)) { printBaseElementType(tree); - print(' '); - printTypeAnnotations(tree.annotations); - print("[]"); - JCExpression elem = array.elemtype; - if (elem.hasTag(TYPEARRAY)) { - printBrackets((JCArrayTypeTree) elem); - } + printBrackets(tree); } else { printTypeAnnotations(tree.annotations); printExpr(tree.underlyingType); diff --git a/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java b/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java index b660855a..644b6847 100644 --- a/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java +++ b/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java @@ -35,13 +35,16 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper { // Test count helps identify test case in event of failure. int testcount = 0; - // Base test case template descriptions + // Base test case template descriptions;true==annotations in code attribute. enum srce { src1("(repeating) type annotations on on field in method body",true), src2("(repeating) type annotations on type parameters, bounds and type arguments", true), src3("(repeating) type annotations on type parameters of class, method return value in method", true), src4("(repeating) type annotations on field in anonymous class", false), - src5("(repeating) type annotations on field in anonymous class", false); + src5("(repeating) type annotations on field in anonymous class", false), + src6("(repeating) type annotations on void method declaration", false), + src7("(repeating) type annotations in use of instanceof", true), + src8("(repeating) type annotations in use of instanceof in method", true); String description; Boolean local; @@ -84,6 +87,12 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper { test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1); test( 2, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src5); test( 0, 2, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5); + test( 0, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src6); + test( 0, 0, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src6); + test( 2, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src7); + test( 0, 2, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src7); + test( 4, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src8); + test( 0, 4, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src8); break; case "FIELD": test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src1); @@ -121,18 +130,6 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper { ", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " + et2 + ", src=" + source + "\n " + source.description; - if( -// 8005681 - src1,2,3 - skip cases with repeated annotations on new, array, cast. - (( source.equals(srce.src1) || source.equals(srce.src2) || - source.equals(srce.src3)) && (ABmix || (Arepeats && BDrepeats))) - // 8008928 - src4,5 - this change cause crash with t-a on anon class) - || (source.equals(srce.src4) || source.equals(srce.src5)) - ) { - System.out.println(testDef + - "\n 8005681-skip repeated annotations on new,array,cast"); - return; - } - println(testDef); // Create test source and File. String sourceString = sourceString(tname, rtn, et2, Arepeats, @@ -178,9 +175,7 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper { println("Pass"); } - // // Source for test cases - // String sourceString(String testname, String retentn, String annot2, Boolean Arepeats, Boolean BDrepeats, Boolean ABmix, srce src) { @@ -359,6 +354,63 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper { hasInnerClass=true; innerClassname="$1"; break; + case src6: // (repeating)annotations on void method declaration + /* + * class Test95{ + * @A @A @B @B public void test() { }; + * } + */ + source = new String( source + + "// " + src.description + "\n" + + "class "+ testname + "{\n" + + " _As_ _Bs_ public void test() { }\n" + + "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + + "\n\n"; + hasInnerClass=false; + break; + case src7: // (repeating) type annotations in use of instanceof + /* + * class Test10{ + * String data = "test"; + * boolean dataIsString = ( data instanceof @A @B @A @B String); + * } + */ + source = new String( source + + "// " + src.description + "\n" + + "class "+ testname + "{\n" + + " String data = \"test\";\n" + + " boolean dataIsString = ( data instanceof _As_ _Bs_ String);\n" + + "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + + "\n\n"; + hasInnerClass=false; + break; + case src8: // (repeating) type annotations in use of instanceof + /* + * class Test20{ + * String data = "test"; + * Boolean isString() { + * if( data instanceof @A @B @A @B String ) + * return true; + * else + * return( data instanceof @A @B @A @B String ); + * } + * } + */ + source = new String( source + + "// " + src.description + "\n" + + "class "+ testname + "{\n" + + " String data = \"test\";\n" + + " Boolean isString() { \n" + + " if( data instanceof _As_ _Bs_ String )\n" + + " return true;\n" + + " else\n" + + " return( data instanceof _As_ _Bs_ String );\n" + + " }\n" + + "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + + "\n\n"; + hasInnerClass=false; + break; + } return imports + source; } diff --git a/test/tools/javac/annotations/typeAnnotations/failures/DummyProcessor.java b/test/tools/javac/annotations/typeAnnotations/failures/DummyProcessor.java new file mode 100644 index 00000000..26bd4d28 --- /dev/null +++ b/test/tools/javac/annotations/typeAnnotations/failures/DummyProcessor.java @@ -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. + */ + +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.TypeElement; + +import java.util.Set; + +/* A simple annotation processor. */ +@SupportedAnnotationTypes("*") +public class DummyProcessor extends AbstractProcessor { + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + @Override + public final boolean process(Set annotations, + RoundEnvironment roundEnv) { + return false; + } +} diff --git a/test/tools/javac/annotations/typeAnnotations/failures/T8020715.java b/test/tools/javac/annotations/typeAnnotations/failures/T8020715.java new file mode 100644 index 00000000..89670f3e --- /dev/null +++ b/test/tools/javac/annotations/typeAnnotations/failures/T8020715.java @@ -0,0 +1,49 @@ +/* + * 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 + * @summary Regression: compiling program with lambda crashed compiler + * @bug 8020715 + * @compile T8020715.java + */ +class T8020715 { + // This crashed. + private static void makeTask1() { + class LocalClass { + private Runnable r = () -> {}; + } + } + + // This crashed, too. + private void makeTask2() { + class LocalClass { + private Runnable r = () -> {}; + } + } + + // This is fine. + private class InnerClass { + private Runnable r = () -> {}; + } +} diff --git a/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java b/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java index 38e46159..a8d1311e 100644 --- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java +++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java @@ -85,4 +85,24 @@ public class Constructors { " } } }"; } + @TADescriptions({ + @TADescription(annotation = "TA", type = CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT, + typeIndex = 0, offset = 4), + @TADescription(annotation = "TB", type = CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT, + typeIndex = 0, offset = 0) + }) + public String generic1() { + return "class Test { Test(int i) { new <@TA T>Test(); }" + + " Test() { <@TB String>this(0); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT, + typeIndex = 0, offset = 0) + }) + public String generic2() { + return "class Super { Super(int i) { } } " + + "class Test extends Super { Test() { <@TA String>super(0); } }"; + } + } diff --git a/test/tools/javac/tree/TypeAnnotationsPretty.java b/test/tools/javac/tree/TypeAnnotationsPretty.java new file mode 100644 index 00000000..0ca021c9 --- /dev/null +++ b/test/tools/javac/tree/TypeAnnotationsPretty.java @@ -0,0 +1,170 @@ +/* + * 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 test Pretty print of type annotations + * @author wmdietl + */ + +import com.sun.source.tree.ClassTree; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.tools.javac.api.JavacTaskImpl; +import com.sun.tools.javac.tree.JCTree; + +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import java.util.LinkedList; + +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; + +public class TypeAnnotationsPretty { + private final JavaCompiler tool; + + TypeAnnotationsPretty() { + tool = ToolProvider.getSystemJavaCompiler(); + } + + private List matches = new LinkedList(); + private List mismatches = new LinkedList(); + + public static void main(String... args) throws Exception { + TypeAnnotationsPretty tap = new TypeAnnotationsPretty(); + + tap.runField("@TA()\nObject cls = null"); + tap.runField("@TA()\nObject cls = new @TA() Object()"); + + tap.runField("@TA()\nList<@TB() Object> cls = null"); + tap.runField("@TA()\nList<@TB() Object> cls = new @TA() LinkedList<@TB() Object>()"); + + tap.runField("Class[] cls = null"); + tap.runField("@TA()\nClass[] cls = null"); + tap.runField("Class @TA() [] cls = null"); + tap.runField("@TA()\nClass @TB() [] cls = null"); + + tap.runField("Class[] cls = new Class[]{Object.class}"); + tap.runField("@TA()\nClass[] cls = new @TA() Class[]{Object.class}"); + tap.runField("Class @TB() [] cls = new Class @TB() []{Object.class}"); + tap.runField("@TA()\nClass @TB() [] cls = new @TA() Class @TB() []{Object.class}"); + tap.runField("@TA()\nClass @TB() [] @TC() [] cls = new @TA() Class @TB() [10] @TC() []"); + tap.runField("Class @TB() [] @TC() [] cls = new Class @TB() [10] @TC() []"); + tap.runField("@TA()\nClass @TB() [] @TC() [] @TD() [] cls = new @TA() Class @TB() [10] @TC() [] @TD() []"); + + tap.runMethod("\n@TA()\nObject test(@TB()\nList<@TC() String> p) {\n" + + " return null;\n" + + "}"); + + + if (!tap.matches.isEmpty()) { + for (String m : tap.matches) + System.out.println(m); + } + if (!tap.mismatches.isEmpty()) { + for (String mm : tap.mismatches) + System.err.println(mm + "\n"); + throw new RuntimeException("Tests failed!"); + } + } + + private static final String prefix = + "import java.lang.annotation.*;" + + "import java.util.*;" + + "public class Test {"; + + private static final String postfix = + "@Target(ElementType.TYPE_USE)" + + "@interface TA {}" + + "@Target(ElementType.TYPE_USE)" + + "@interface TB {}" + + "@Target(ElementType.TYPE_USE)" + + "@interface TC {}" + + "@Target(ElementType.TYPE_USE)" + + "@interface TD {}"; + + + private void runField(String code) throws IOException { + String src = prefix + + code + "; }" + + postfix; + + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, + null, Arrays.asList(new MyFileObject(src))); + + + for (CompilationUnitTree cut : ct.parse()) { + JCTree.JCVariableDecl var = + (JCTree.JCVariableDecl) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0); + + if (!code.equals(var.toString())) { + mismatches.add("Expected: " + code + + "\nObtained: " + var.toString()); + } else { + matches.add("Passed: " + code); + } + } + } + + private void runMethod(String code) throws IOException { + String src = prefix + + code + "}" + + postfix; + + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, + null, Arrays.asList(new MyFileObject(src))); + + + for (CompilationUnitTree cut : ct.parse()) { + JCTree.JCMethodDecl var = + (JCTree.JCMethodDecl) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0); + + if (!code.equals(var.toString())) { + mismatches.add("Expected: " + code + + "\nObtained: " + var.toString()); + } else { + matches.add("Passed: " + code); + } + } + } +} + + +class MyFileObject extends SimpleJavaFileObject { + + private String text; + + public MyFileObject(String text) { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + this.text = text; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return text; + } +} -- GitLab