mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
8023515: import type-annotations updates
Reviewed-by: jjg
This commit is contained in:
parent
c7b90c0ca4
commit
1dc32a077e
14 changed files with 429 additions and 62 deletions
|
@ -53,7 +53,15 @@ public interface MethodTree extends Tree {
|
||||||
Tree getReturnType();
|
Tree getReturnType();
|
||||||
List<? extends TypeParameterTree> getTypeParameters();
|
List<? extends TypeParameterTree> getTypeParameters();
|
||||||
List<? extends VariableTree> getParameters();
|
List<? extends VariableTree> getParameters();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an explicit receiver parameter ("this" parameter).
|
||||||
|
*
|
||||||
|
* @return an explicit receiver parameter ("this" parameter)
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
VariableTree getReceiverParameter();
|
VariableTree getReceiverParameter();
|
||||||
|
|
||||||
List<? extends ExpressionTree> getThrows();
|
List<? extends ExpressionTree> getThrows();
|
||||||
BlockTree getBody();
|
BlockTree getBody();
|
||||||
Tree getDefaultValue(); // for annotation types
|
Tree getDefaultValue(); // for annotation types
|
||||||
|
|
|
@ -36,6 +36,8 @@ import javax.lang.model.element.Name;
|
||||||
* <em>name</em>
|
* <em>name</em>
|
||||||
*
|
*
|
||||||
* <em>name</em> extends <em>bounds</em>
|
* <em>name</em> extends <em>bounds</em>
|
||||||
|
*
|
||||||
|
* <em>annotations</em> <em>name</em>
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @jls section 4.4
|
* @jls section 4.4
|
||||||
|
@ -48,5 +50,17 @@ import javax.lang.model.element.Name;
|
||||||
public interface TypeParameterTree extends Tree {
|
public interface TypeParameterTree extends Tree {
|
||||||
Name getName();
|
Name getName();
|
||||||
List<? extends Tree> getBounds();
|
List<? extends Tree> 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<? extends AnnotationTree> getAnnotations();
|
List<? extends AnnotationTree> getAnnotations();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,6 @@ package com.sun.tools.javac.code;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import javax.lang.model.type.TypeKind;
|
|
||||||
|
|
||||||
import com.sun.tools.javac.api.Messages;
|
import com.sun.tools.javac.api.Messages;
|
||||||
import com.sun.tools.javac.code.Type.AnnotatedType;
|
import com.sun.tools.javac.code.Type.AnnotatedType;
|
||||||
import com.sun.tools.javac.code.Type.ArrayType;
|
import com.sun.tools.javac.code.Type.ArrayType;
|
||||||
|
@ -191,7 +189,7 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||||
|
|
||||||
void printBaseElementType(Type t, StringBuilder sb, Locale locale) {
|
void printBaseElementType(Type t, StringBuilder sb, Locale locale) {
|
||||||
Type arrel = t;
|
Type arrel = t;
|
||||||
while (arrel.getKind() == TypeKind.ARRAY) {
|
while (arrel.hasTag(TypeTag.ARRAY)) {
|
||||||
arrel = arrel.unannotatedType();
|
arrel = arrel.unannotatedType();
|
||||||
arrel = ((ArrayType) arrel).elemtype;
|
arrel = ((ArrayType) arrel).elemtype;
|
||||||
}
|
}
|
||||||
|
@ -200,7 +198,7 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||||
|
|
||||||
void printBrackets(Type t, StringBuilder sb, Locale locale) {
|
void printBrackets(Type t, StringBuilder sb, Locale locale) {
|
||||||
Type arrel = t;
|
Type arrel = t;
|
||||||
while (arrel.getKind() == TypeKind.ARRAY) {
|
while (arrel.hasTag(TypeTag.ARRAY)) {
|
||||||
if (arrel.isAnnotated()) {
|
if (arrel.isAnnotated()) {
|
||||||
sb.append(' ');
|
sb.append(' ');
|
||||||
sb.append(arrel.getAnnotationMirrors());
|
sb.append(arrel.getAnnotationMirrors());
|
||||||
|
@ -264,12 +262,12 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||||
public String visitAnnotatedType(AnnotatedType t, Locale locale) {
|
public String visitAnnotatedType(AnnotatedType t, Locale locale) {
|
||||||
if (t.typeAnnotations != null &&
|
if (t.typeAnnotations != null &&
|
||||||
t.typeAnnotations.nonEmpty()) {
|
t.typeAnnotations.nonEmpty()) {
|
||||||
if (t.underlyingType.getKind() == TypeKind.ARRAY) {
|
if (t.underlyingType.hasTag(TypeTag.ARRAY)) {
|
||||||
StringBuilder res = new StringBuilder();
|
StringBuilder res = new StringBuilder();
|
||||||
printBaseElementType(t, res, locale);
|
printBaseElementType(t, res, locale);
|
||||||
printBrackets(t, res, locale);
|
printBrackets(t, res, locale);
|
||||||
return res.toString();
|
return res.toString();
|
||||||
} else if (t.underlyingType.getKind() == TypeKind.DECLARED &&
|
} else if (t.underlyingType.hasTag(TypeTag.CLASS) &&
|
||||||
t.underlyingType.getEnclosingType() != Type.noType) {
|
t.underlyingType.getEnclosingType() != Type.noType) {
|
||||||
return visit(t.underlyingType.getEnclosingType(), locale) +
|
return visit(t.underlyingType.getEnclosingType(), locale) +
|
||||||
". " +
|
". " +
|
||||||
|
@ -348,7 +346,7 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||||
args = args.tail;
|
args = args.tail;
|
||||||
buf.append(',');
|
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));
|
buf.append(visit(((ArrayType) args.head.unannotatedType()).elemtype, locale));
|
||||||
if (args.head.getAnnotationMirrors().nonEmpty()) {
|
if (args.head.getAnnotationMirrors().nonEmpty()) {
|
||||||
buf.append(' ');
|
buf.append(' ');
|
||||||
|
|
|
@ -29,6 +29,8 @@ import javax.lang.model.element.Element;
|
||||||
import javax.lang.model.element.ElementKind;
|
import javax.lang.model.element.ElementKind;
|
||||||
import javax.lang.model.type.TypeKind;
|
import javax.lang.model.type.TypeKind;
|
||||||
|
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
|
||||||
import com.sun.tools.javac.code.Attribute;
|
import com.sun.tools.javac.code.Attribute;
|
||||||
import com.sun.tools.javac.code.Attribute.TypeCompound;
|
import com.sun.tools.javac.code.Attribute.TypeCompound;
|
||||||
import com.sun.tools.javac.code.Flags;
|
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.code.Symbol.MethodSymbol;
|
||||||
import com.sun.tools.javac.comp.Annotate;
|
import com.sun.tools.javac.comp.Annotate;
|
||||||
import com.sun.tools.javac.comp.Annotate.Annotator;
|
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.JCTree;
|
||||||
|
import com.sun.tools.javac.tree.TreeInfo;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCBlock;
|
import com.sun.tools.javac.tree.JCTree.JCBlock;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
|
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCExpression;
|
import com.sun.tools.javac.tree.JCTree.JCExpression;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCLambda;
|
import com.sun.tools.javac.tree.JCTree.JCLambda;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
|
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.JCNewClass;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCTypeApply;
|
import com.sun.tools.javac.tree.JCTree.JCTypeApply;
|
||||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||||
|
@ -90,11 +96,17 @@ public class TypeAnnotations {
|
||||||
* later processing.
|
* later processing.
|
||||||
*/
|
*/
|
||||||
public static void organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
|
public static void organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
|
||||||
final Log log, final JCClassDecl tree, Annotate annotate) {
|
final Log log, final Env<AttrContext> env, final JCClassDecl tree, final Annotate annotate) {
|
||||||
annotate.afterRepeated( new Annotator() {
|
annotate.afterRepeated( new Annotator() {
|
||||||
@Override
|
@Override
|
||||||
public void enterAnnotation() {
|
public void enterAnnotation() {
|
||||||
|
JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
|
||||||
|
|
||||||
|
try {
|
||||||
new TypeAnnotationPositions(syms, names, log, true).scan(tree);
|
new TypeAnnotationPositions(syms, names, log, true).scan(tree);
|
||||||
|
} finally {
|
||||||
|
log.useSource(oldSource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
@ -906,7 +918,14 @@ public class TypeAnnotations {
|
||||||
if (!invocation.typeargs.contains(tree)) {
|
if (!invocation.typeargs.contains(tree)) {
|
||||||
Assert.error("{" + tree + "} is not an argument in the invocation: " + invocation);
|
Assert.error("{" + tree + "} is not an argument in the invocation: " + invocation);
|
||||||
}
|
}
|
||||||
|
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.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT;
|
||||||
|
}
|
||||||
p.pos = invocation.pos;
|
p.pos = invocation.pos;
|
||||||
p.type_index = invocation.typeargs.indexOf(tree);
|
p.type_index = invocation.typeargs.indexOf(tree);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -249,7 +249,7 @@ public class LambdaToMethod extends TreeTranslator {
|
||||||
MethodType lambdaType = (MethodType) sym.type;
|
MethodType lambdaType = (MethodType) sym.type;
|
||||||
|
|
||||||
{
|
{
|
||||||
MethodSymbol owner = (MethodSymbol) localContext.owner;
|
Symbol owner = localContext.owner;
|
||||||
ListBuffer<Attribute.TypeCompound> ownerTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
|
ListBuffer<Attribute.TypeCompound> ownerTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
|
||||||
ListBuffer<Attribute.TypeCompound> lambdaTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
|
ListBuffer<Attribute.TypeCompound> lambdaTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
|
||||||
|
|
||||||
|
|
|
@ -1089,7 +1089,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (allowTypeAnnos) {
|
if (allowTypeAnnos) {
|
||||||
TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate);
|
TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, env, tree, annotate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
|
||||||
* deletion without notice.</b>
|
* deletion without notice.</b>
|
||||||
*/
|
*/
|
||||||
public class JavacProcessingEnvironment implements ProcessingEnvironment, Closeable {
|
public class JavacProcessingEnvironment implements ProcessingEnvironment, Closeable {
|
||||||
Options options;
|
private final Options options;
|
||||||
|
|
||||||
private final boolean printProcessorInfo;
|
private final boolean printProcessorInfo;
|
||||||
private final boolean printRounds;
|
private final boolean printRounds;
|
||||||
|
|
|
@ -2248,7 +2248,7 @@ compiler.err.cant.annotate.static.class=\
|
||||||
# TODO 308: make a better error message
|
# TODO 308: make a better error message
|
||||||
# 0: unused
|
# 0: unused
|
||||||
compiler.err.cant.annotate.nested.type=\
|
compiler.err.cant.annotate.nested.type=\
|
||||||
nested type cannot be annotated
|
scoping construct for static nested type cannot be annotated
|
||||||
|
|
||||||
# 0: type, 1: type
|
# 0: type, 1: type
|
||||||
compiler.err.incorrect.receiver.name=\
|
compiler.err.incorrect.receiver.name=\
|
||||||
|
|
|
@ -944,10 +944,17 @@ public class Pretty extends JCTree.Visitor {
|
||||||
try {
|
try {
|
||||||
if (tree.elemtype != null) {
|
if (tree.elemtype != null) {
|
||||||
print("new ");
|
print("new ");
|
||||||
printTypeAnnotations(tree.annotations);
|
|
||||||
JCTree elem = tree.elemtype;
|
JCTree elem = tree.elemtype;
|
||||||
printBaseElementType(elem);
|
printBaseElementType(elem);
|
||||||
boolean isElemAnnoType = elem instanceof JCAnnotatedType;
|
|
||||||
|
if (!tree.annotations.isEmpty()) {
|
||||||
|
print(' ');
|
||||||
|
printTypeAnnotations(tree.annotations);
|
||||||
|
}
|
||||||
|
if (tree.elems != null) {
|
||||||
|
print("[]");
|
||||||
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
List<List<JCAnnotation>> da = tree.dimAnnotations;
|
List<List<JCAnnotation>> da = tree.dimAnnotations;
|
||||||
for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
|
for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
|
||||||
|
@ -960,17 +967,7 @@ public class Pretty extends JCTree.Visitor {
|
||||||
printExpr(l.head);
|
printExpr(l.head);
|
||||||
print("]");
|
print("]");
|
||||||
}
|
}
|
||||||
if (tree.elems != null) {
|
printBrackets(elem);
|
||||||
if (isElemAnnoType) {
|
|
||||||
print(' ');
|
|
||||||
printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations);
|
|
||||||
}
|
|
||||||
print("[]");
|
|
||||||
}
|
|
||||||
if (isElemAnnoType)
|
|
||||||
elem = ((JCAnnotatedType)elem).underlyingType;
|
|
||||||
if (elem instanceof JCArrayTypeTree)
|
|
||||||
printBrackets((JCArrayTypeTree) elem);
|
|
||||||
}
|
}
|
||||||
if (tree.elems != null) {
|
if (tree.elems != null) {
|
||||||
print("{");
|
print("{");
|
||||||
|
@ -1260,20 +1257,24 @@ public class Pretty extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// prints the brackets of a nested array in reverse order
|
// prints the brackets of a nested array in reverse order
|
||||||
private void printBrackets(JCArrayTypeTree tree) throws IOException {
|
// tree is either JCArrayTypeTree or JCAnnotatedTypeTree
|
||||||
JCTree elem;
|
private void printBrackets(JCTree tree) throws IOException {
|
||||||
|
JCTree elem = tree;
|
||||||
while (true) {
|
while (true) {
|
||||||
elem = tree.elemtype;
|
|
||||||
if (elem.hasTag(ANNOTATED_TYPE)) {
|
if (elem.hasTag(ANNOTATED_TYPE)) {
|
||||||
JCAnnotatedType atype = (JCAnnotatedType) elem;
|
JCAnnotatedType atype = (JCAnnotatedType) elem;
|
||||||
elem = atype.underlyingType;
|
elem = atype.underlyingType;
|
||||||
if (!elem.hasTag(TYPEARRAY)) break;
|
if (elem.hasTag(TYPEARRAY)) {
|
||||||
print(' ');
|
print(' ');
|
||||||
printTypeAnnotations(atype.annotations);
|
printTypeAnnotations(atype.annotations);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (elem.hasTag(TYPEARRAY)) {
|
||||||
print("[]");
|
print("[]");
|
||||||
if (!elem.hasTag(TYPEARRAY)) break;
|
elem = ((JCArrayTypeTree)elem).elemtype;
|
||||||
tree = (JCArrayTypeTree) elem;
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1378,22 +1379,15 @@ public class Pretty extends JCTree.Visitor {
|
||||||
|
|
||||||
public void visitAnnotatedType(JCAnnotatedType tree) {
|
public void visitAnnotatedType(JCAnnotatedType tree) {
|
||||||
try {
|
try {
|
||||||
if (tree.underlyingType.getKind() == JCTree.Kind.MEMBER_SELECT) {
|
if (tree.underlyingType.hasTag(SELECT)) {
|
||||||
JCFieldAccess access = (JCFieldAccess) tree.underlyingType;
|
JCFieldAccess access = (JCFieldAccess) tree.underlyingType;
|
||||||
printExpr(access.selected, TreeInfo.postfixPrec);
|
printExpr(access.selected, TreeInfo.postfixPrec);
|
||||||
print(".");
|
print(".");
|
||||||
printTypeAnnotations(tree.annotations);
|
printTypeAnnotations(tree.annotations);
|
||||||
print(access.name);
|
print(access.name);
|
||||||
} else if (tree.underlyingType.getKind() == JCTree.Kind.ARRAY_TYPE) {
|
} else if (tree.underlyingType.hasTag(TYPEARRAY)) {
|
||||||
JCArrayTypeTree array = (JCArrayTypeTree) tree.underlyingType;
|
|
||||||
printBaseElementType(tree);
|
printBaseElementType(tree);
|
||||||
print(' ');
|
printBrackets(tree);
|
||||||
printTypeAnnotations(tree.annotations);
|
|
||||||
print("[]");
|
|
||||||
JCExpression elem = array.elemtype;
|
|
||||||
if (elem.hasTag(TYPEARRAY)) {
|
|
||||||
printBrackets((JCArrayTypeTree) elem);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
printTypeAnnotations(tree.annotations);
|
printTypeAnnotations(tree.annotations);
|
||||||
printExpr(tree.underlyingType);
|
printExpr(tree.underlyingType);
|
||||||
|
|
|
@ -35,13 +35,16 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper {
|
||||||
// Test count helps identify test case in event of failure.
|
// Test count helps identify test case in event of failure.
|
||||||
int testcount = 0;
|
int testcount = 0;
|
||||||
|
|
||||||
// Base test case template descriptions
|
// Base test case template descriptions;true==annotations in code attribute.
|
||||||
enum srce {
|
enum srce {
|
||||||
src1("(repeating) type annotations on on field in method body",true),
|
src1("(repeating) type annotations on on field in method body",true),
|
||||||
src2("(repeating) type annotations on type parameters, bounds and type arguments", 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),
|
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),
|
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;
|
String description;
|
||||||
Boolean local;
|
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( 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( 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, 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;
|
break;
|
||||||
case "FIELD":
|
case "FIELD":
|
||||||
test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src1);
|
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: " +
|
", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " +
|
||||||
et2 + ", src=" + source + "\n " + source.description;
|
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);
|
println(testDef);
|
||||||
// Create test source and File.
|
// Create test source and File.
|
||||||
String sourceString = sourceString(tname, rtn, et2, Arepeats,
|
String sourceString = sourceString(tname, rtn, et2, Arepeats,
|
||||||
|
@ -178,9 +175,7 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper {
|
||||||
println("Pass");
|
println("Pass");
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Source for test cases
|
// Source for test cases
|
||||||
//
|
|
||||||
String sourceString(String testname, String retentn, String annot2,
|
String sourceString(String testname, String retentn, String annot2,
|
||||||
Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
|
Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
|
||||||
srce src) {
|
srce src) {
|
||||||
|
@ -359,6 +354,63 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper {
|
||||||
hasInnerClass=true;
|
hasInnerClass=true;
|
||||||
innerClassname="$1";
|
innerClassname="$1";
|
||||||
break;
|
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;
|
return imports + source;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<? extends TypeElement> annotations,
|
||||||
|
RoundEnvironment roundEnv) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 = () -> {};
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 { <T> Test(int i) { new <@TA T>Test(); }" +
|
||||||
|
" <T> Test() { <@TB String>this(0); } }";
|
||||||
|
}
|
||||||
|
|
||||||
|
@TADescriptions({
|
||||||
|
@TADescription(annotation = "TA", type = CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT,
|
||||||
|
typeIndex = 0, offset = 0)
|
||||||
|
})
|
||||||
|
public String generic2() {
|
||||||
|
return "class Super { <T> Super(int i) { } } " +
|
||||||
|
"class Test extends Super { <T> Test() { <@TA String>super(0); } }";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
170
langtools/test/tools/javac/tree/TypeAnnotationsPretty.java
Normal file
170
langtools/test/tools/javac/tree/TypeAnnotationsPretty.java
Normal file
|
@ -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<String> matches = new LinkedList<String>();
|
||||||
|
private List<String> mismatches = new LinkedList<String>();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue