提交 ee93ddcf 编写于 作者: J jjg

8023515: import type-annotations updates

Reviewed-by: jjg
Contributed-by: wdietl@gmail.com
上级 37401f9d
......@@ -53,7 +53,15 @@ public interface MethodTree extends Tree {
Tree getReturnType();
List<? extends TypeParameterTree> getTypeParameters();
List<? extends VariableTree> getParameters();
/**
* Return an explicit receiver parameter ("this" parameter).
*
* @return an explicit receiver parameter ("this" parameter)
* @since 1.8
*/
VariableTree getReceiverParameter();
List<? extends ExpressionTree> getThrows();
BlockTree getBody();
Tree getDefaultValue(); // for annotation types
......
......@@ -36,6 +36,8 @@ import javax.lang.model.element.Name;
* <em>name</em>
*
* <em>name</em> extends <em>bounds</em>
*
* <em>annotations</em> <em>name</em>
* </pre>
*
* @jls section 4.4
......@@ -48,5 +50,17 @@ import javax.lang.model.element.Name;
public interface TypeParameterTree extends Tree {
Name getName();
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();
}
......@@ -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<String, Locale>, 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<String, Locale>, 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<String, Locale>, 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<String, Locale>, 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(' ');
......
......@@ -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<AttrContext> 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;
......
......@@ -249,7 +249,7 @@ public class LambdaToMethod extends TreeTranslator {
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> lambdaTypeAnnos = new ListBuffer<Attribute.TypeCompound>();
......
......@@ -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);
}
}
......
......@@ -89,7 +89,7 @@ import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
* deletion without notice.</b>
*/
public class JavacProcessingEnvironment implements ProcessingEnvironment, Closeable {
Options options;
private final Options options;
private final boolean printProcessorInfo;
private final boolean printRounds;
......
......@@ -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=\
......
......@@ -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<List<JCAnnotation>> da = tree.dimAnnotations;
for (List<JCExpression> 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);
......
......@@ -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;
}
......
/*
* 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;
}
}
/*
* 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); } }";
}
}
/*
* 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;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册