提交 9070b968 编写于 作者: M mnunez

8015372: Update tests for Method Parameter Reflection API to check whether a parameter is final

Reviewed-by: jjg, jfranck
上级 e83eefef
......@@ -27,7 +27,7 @@
* @summary javac should generate method parameters correctly.
* @build Tester
* @compile -parameters AnnotationTest.java
* @run main Tester AnnotationTest
* @run main Tester AnnotationTest AnnotationTest.out
*/
import java.lang.annotation.*;
......
static interface AnnotationTest$Annos -- inner
AnnotationTest$Annos.foo()
AnnotationTest$Annos.value()
class AnnotationTest --
AnnotationTest.<init>(i, ji)
AnnotationTest.foo(i, ji)
static interface AnnotationTest$I -- inner
AnnotationTest$I.m(i, ji)
static interface AnnotationTest$Anno -- inner
AnnotationTest$Anno.f()
\ No newline at end of file
......@@ -27,7 +27,7 @@
* @summary javac should generate method parameters correctly.
* @build Tester
* @compile -parameters AnonymousClass.java
* @run main Tester AnonymousClass
* @run main Tester AnonymousClass AnonymousClass.out
*/
class AnonymousClass {
......
static public class AnonymousClass$Sinner -- inner
AnonymousClass$Sinner.<init>()
AnonymousClass$Sinner.<init>(arg, barg)
AnonymousClass$Sinner.m(s/*synthetic*/, ts/*synthetic*/)/*synthetic*/
AnonymousClass$Sinner.m()/*synthetic*/
AnonymousClass$Sinner.m(s, ts)
AnonymousClass$Sinner.m()
class AnonymousClass$9 -- anon
AnonymousClass$9.<init>(final this$0/*implicit*/)
AnonymousClass$9.m()/*synthetic*/
AnonymousClass$9.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/
AnonymousClass$9.m(i, ji)
AnonymousClass$9.m()
class AnonymousClass$Inner -- inner
AnonymousClass$Inner.<init>(final this$0/*synthetic*/)
AnonymousClass$Inner.<init>(final this$0/*synthetic*/, arg, barg)
AnonymousClass$Inner.m(s/*synthetic*/, ts/*synthetic*/)/*synthetic*/
AnonymousClass$Inner.m()/*synthetic*/
AnonymousClass$Inner.m(s, ts)
AnonymousClass$Inner.m()
class AnonymousClass$3 -- anon
AnonymousClass$3.<init>(final this$0/*implicit*/, arg, barg)
AnonymousClass$3.m()/*synthetic*/
AnonymousClass$3.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/
AnonymousClass$3.m(i, ji)
AnonymousClass$3.m()
class AnonymousClass$2 -- anon
AnonymousClass$2.<init>(final this$0/*implicit*/)
AnonymousClass$2.m()/*synthetic*/
AnonymousClass$2.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/
AnonymousClass$2.m(i, ji)
AnonymousClass$2.m()
class AnonymousClass --
AnonymousClass.<init>(final a, ba)
AnonymousClass.foo(final a, ba)
class AnonymousClass$5 -- anon
AnonymousClass$5.<init>(final this$0/*implicit*/, arg, barg)
AnonymousClass$5.m()/*synthetic*/
AnonymousClass$5.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/
AnonymousClass$5.m(i, ji)
AnonymousClass$5.m()
static interface AnonymousClass$I -- inner
AnonymousClass$I.m()
AnonymousClass$I.m(x, yx)
class AnonymousClass$10 -- anon
AnonymousClass$10.<init>(final this$0/*implicit*/, arg, barg)
AnonymousClass$10.m()/*synthetic*/
AnonymousClass$10.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/
AnonymousClass$10.m(i, ji)
AnonymousClass$10.m()
class AnonymousClass$8 -- anon
AnonymousClass$8.<init>(final this$0/*implicit*/, arg, barg)
AnonymousClass$8.m()/*synthetic*/
AnonymousClass$8.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/
AnonymousClass$8.m(i, ji)
AnonymousClass$8.m()
class AnonymousClass$6 -- anon
AnonymousClass$6.<init>(final this$0/*implicit*/)
AnonymousClass$6.m()/*synthetic*/
AnonymousClass$6.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/
AnonymousClass$6.m(i, ji)
AnonymousClass$6.m()
class AnonymousClass$7 -- anon
AnonymousClass$7.<init>(final this$0/*implicit*/)
AnonymousClass$7.m()/*synthetic*/
AnonymousClass$7.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/
AnonymousClass$7.m(i, ji)
AnonymousClass$7.m()
class AnonymousClass$4 -- anon
AnonymousClass$4.<init>(final this$0/*implicit*/)
AnonymousClass$4.m()/*synthetic*/
AnonymousClass$4.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/
AnonymousClass$4.m(i, ji)
AnonymousClass$4.m()
class AnonymousClass$1 -- anon
AnonymousClass$1.<init>(final this$0/*implicit*/)
AnonymousClass$1.m()/*synthetic*/
AnonymousClass$1.m(i/*synthetic*/, ji/*synthetic*/)/*synthetic*/
AnonymousClass$1.m(i, ji)
AnonymousClass$1.m()
\ No newline at end of file
......@@ -82,15 +82,14 @@ class ClassFileVisitor extends Tester.Visitor {
* Read the class and determine some key characteristics, like if it's
* an enum, or inner class, etc.
*/
void visitClass(final String cname, final File cfile, final StringBuilder sb)
throws Exception {
void visitClass(final String cname, final File cfile, final StringBuilder sb) throws Exception {
this.cname = cname;
classFile = ClassFile.read(cfile);
isEnum = classFile.access_flags.is(AccessFlags.ACC_ENUM);
isInterface = classFile.access_flags.is(AccessFlags.ACC_INTERFACE);
isPublic = classFile.access_flags.is(AccessFlags.ACC_PUBLIC);
isInner = false;
isStatic = true;
isStatic = false;
isAnon = false;
Attribute attr = classFile.getAttribute("InnerClasses");
......@@ -100,10 +99,11 @@ class ClassFileVisitor extends Tester.Visitor {
sb.append(isStatic ? "static " : "")
.append(isPublic ? "public " : "")
.append(isEnum ? "enum " : isInterface ? "interface " : "class ")
.append(cname).append(" -- ")
.append(isInner? "inner " : "" )
.append(isAnon ? "anon" : "")
.append("\n");;
.append(cname).append(" -- ");
if (isInner) {
sb.append(isAnon ? "anon" : "inner");
}
sb.append("\n");
for (Method method : classFile.methods) {
new MethodVisitor().visitMethod(method, sb);
......@@ -148,7 +148,9 @@ class ClassFileVisitor extends Tester.Visitor {
public int mNumParams;
public boolean mSynthetic;
public boolean mIsConstructor;
public boolean mIsClinit;
public boolean mIsBridge;
public boolean isFinal;
public String prefix;
void visitMethod(Method method, StringBuilder sb) throws Exception {
......@@ -160,9 +162,13 @@ class ClassFileVisitor extends Tester.Visitor {
mNumParams = -1; // no MethodParameters attribute found
mSynthetic = method.access_flags.is(AccessFlags.ACC_SYNTHETIC);
mIsConstructor = mName.equals("<init>");
mIsClinit = mName.equals("<clinit>");
prefix = cname + "." + mName + "() - ";
mIsBridge = method.access_flags.is(AccessFlags.ACC_BRIDGE);
if (mIsClinit) {
sb = new StringBuilder(); // Discard output
}
sb.append(cname).append(".").append(mName).append("(");
for (Attribute a : method.attributes) {
......@@ -170,9 +176,18 @@ class ClassFileVisitor extends Tester.Visitor {
}
if (mNumParams == -1) {
if (mSynthetic) {
sb.append("<none>)!!");
// We don't generate MethodParameters attribute for synthetic
// methods, so we are creating a parameter pattern to match
// ReflectionVisitor API output.
for (int i = 0; i < mParams; i++) {
if (i == 0)
sb.append("arg").append(i);
else
sb.append(", arg").append(i);
}
sb.append(")/*synthetic*/");
} else {
sb.append("<none>)");
sb.append(")");
}
}
sb.append("\n");
......@@ -217,7 +232,7 @@ class ClassFileVisitor extends Tester.Visitor {
String sep = "";
String userParam = null;
for (int x = 0; x < mNumParams; x++) {
isFinal = (mp.method_parameter_table[x].flags & AccessFlags.ACC_FINAL) != 0;
// IMPL: Assume all parameters are named, something.
int cpi = mp.method_parameter_table[x].name_index;
if (cpi == 0) {
......@@ -229,6 +244,8 @@ class ClassFileVisitor extends Tester.Visitor {
String param = null;
try {
param = classFile.constant_pool.getUTF8Value(cpi);
if (isFinal)
param = "final " + param;
sb.append(sep).append(param);
sep = ", ";
} catch(ConstantPoolException e) {
......@@ -239,7 +256,7 @@ class ClassFileVisitor extends Tester.Visitor {
// Check availability, flags and special names
int check = checkParam(mp, param, x, sb);
int check = checkParam(mp, param, x, sb, isFinal);
if (check < 0) {
return null;
}
......@@ -253,9 +270,15 @@ class ClassFileVisitor extends Tester.Visitor {
char c = userParam.charAt(0);
expect = (++c) + userParam;
}
if(isFinal && expect != null)
expect = "final " + expect;
if (check > 0) {
if(isFinal) {
userParam = param.substring(6);
} else {
userParam = param;
}
}
if (expect != null && !param.equals(expect)) {
error(prefix + "param[" + x + "]='"
+ param + "' expected '" + expect + "'");
......@@ -263,7 +286,7 @@ class ClassFileVisitor extends Tester.Visitor {
}
}
if (mSynthetic) {
sb.append(")!!");
sb.append(")/*synthetic*/");
} else {
sb.append(")");
}
......@@ -278,7 +301,7 @@ class ClassFileVisitor extends Tester.Visitor {
* explicitly declared parameter.
*/
int checkParam(MethodParameters_attribute mp, String param, int index,
StringBuilder sb) {
StringBuilder sb, boolean isFinal) {
boolean synthetic = (mp.method_parameter_table[index].flags
& AccessFlags.ACC_SYNTHETIC) != 0;
......@@ -304,9 +327,13 @@ class ClassFileVisitor extends Tester.Visitor {
}
} else if (index == 0) {
if (isAnon) {
expect = "this\\$[0-9]+";
allowMandated = true;
expect = "this\\$[0-n]*";
if (isFinal) {
expect = "final this\\$[0-9]+";
}
} else if (isInner && !isStatic) {
expect = "this\\$[0-9]+";
allowMandated = true;
if (!isPublic) {
// some but not all non-public inner classes
......@@ -314,7 +341,9 @@ class ClassFileVisitor extends Tester.Visitor {
// the test a bit of slack and allow either.
allowSynthetic = true;
}
expect = "this\\$[0-n]*";
if (isFinal) {
expect = "final this\\$[0-9]+";
}
}
}
} else if (isEnum && mNumParams == 1 && index == 0 && mName.equals("valueOf")) {
......@@ -327,8 +356,8 @@ class ClassFileVisitor extends Tester.Visitor {
*/
expect = null;
}
if (mandated) sb.append("!");
if (synthetic) sb.append("!!");
if (mandated) sb.append("/*implicit*/");
if (synthetic) sb.append("/*synthetic*/");
// IMPL: our rules a somewhat fuzzy, sometimes allowing both mandated
// and synthetic. However, a parameters cannot be both.
......
......@@ -27,7 +27,7 @@
* @summary javac should generate method parameters correctly.
* @build Tester
* @compile -parameters Constructors.java
* @run main Tester Constructors
* @run main Tester Constructors Constructors.out
*/
public class Constructors {
......
public class Constructors --
Constructors.<init>()
Constructors.<init>(final a, final ba)
Constructors.<init>(a, final ba, final cba)
Constructors.<init>(a, ba, final cba, final dcba)
\ No newline at end of file
......@@ -27,7 +27,7 @@
* @summary javac should generate method parameters correctly.
* @build Tester
* @compile -parameters EnumTest.java
* @run main Tester EnumTest
* @run main Tester EnumTest EnumTest.out
*/
/** Test that parameter names are recorded for enum methods */
......
enum EnumTest --
EnumTest.<init>($enum$name/*synthetic*/, $enum$ordinal/*synthetic*/)
EnumTest.<init>($enum$name/*synthetic*/, $enum$ordinal/*synthetic*/, a, ba)
EnumTest.ok(c, dc)
EnumTest.values()
EnumTest.valueOf(A, BA)
EnumTest.valueOf(name/*implicit*/)
\ No newline at end of file
......@@ -27,7 +27,7 @@
* @summary javac should generate method parameters correctly.
* @build Tester
* @compile -parameters InstanceMethods.java
* @run main Tester InstanceMethods
* @run main Tester InstanceMethods InstanceMethods.out
*/
public class InstanceMethods {
......
public class InstanceMethods --
InstanceMethods.<init>()
InstanceMethods.empty()
InstanceMethods.def(a, final ba, final cba)
InstanceMethods.pub(d, final ed, final fed)
InstanceMethods.prot(g, final hg, final ihg)
InstanceMethods.priv(j, final kj, final lkj)
InstanceMethods.def(A, BA, final CBA, final DCBA)
InstanceMethods.pub(B, CB, final DCB, final EDCB)
InstanceMethods.prot(C, DC, final EDC, final FEDC)
InstanceMethods.priv(D, ED, final FED, final GFED)
\ No newline at end of file
......@@ -27,7 +27,7 @@
* @summary javac should generate method parameters correctly.
* @build Tester
* @compile -parameters LambdaTest.java
* @run main Tester LambdaTest
* @run main Tester LambdaTest LambdaTest.out
*/
/**
......
class LambdaTest --
LambdaTest.<init>()
LambdaTest.foo(i)
LambdaTest.lambda$1(arg0, arg1)/*synthetic*/
LambdaTest.lambda$0(arg0)/*synthetic*/
static interface LambdaTest$I -- inner
LambdaTest$I.m(x)
\ No newline at end of file
......@@ -27,7 +27,7 @@
* @summary javac should generate method parameters correctly.
* @build Tester
* @compile -parameters LocalClassTest.java
* @run main Tester LocalClassTest
* @run main Tester LocalClassTest LocalClassTest.out
*/
class LocalClassTest {
......
class LocalClassTest$1Local_has_constructor -- inner
LocalClassTest$1Local_has_constructor.<init>(final this$0/*implicit*/, a, ba)
LocalClassTest$1Local_has_constructor.<init>(final this$0/*implicit*/)
LocalClassTest$1Local_has_constructor.foo(m, nm)
LocalClassTest$1Local_has_constructor.foo()
class LocalClassTest$1Local_default_constructor -- inner
LocalClassTest$1Local_default_constructor.<init>(final this$0/*implicit*/)
LocalClassTest$1Local_default_constructor.foo()
LocalClassTest$1Local_default_constructor.foo(m, nm)
class LocalClassTest --
LocalClassTest.<init>()
LocalClassTest.foo()
\ No newline at end of file
......@@ -27,7 +27,7 @@
* @summary javac should generate method parameters correctly.
* @build Tester
* @compile -parameters MemberClassTest.java
* @run main Tester MemberClassTest
* @run main Tester MemberClassTest MemberClassTest.out
*/
class MemberClassTest {
......
static class MemberClassTest$Static_Member -- inner
MemberClassTest$Static_Member.<init>()
MemberClassTest$Static_Member.<init>(arg, barg)
MemberClassTest$Static_Member.m(s, ts)
MemberClassTest$Static_Member.m()
public class MemberClassTest$Member -- inner
MemberClassTest$Member.<init>(final this$0/*implicit*/)
MemberClassTest$Member.<init>(final this$0/*implicit*/, a, ba)
MemberClassTest$Member.m(s, ts)
MemberClassTest$Member.m()
public class MemberClassTest$Member$Member_Member -- inner
MemberClassTest$Member$Member_Member.<init>(final this$1/*implicit*/)
MemberClassTest$Member$Member_Member.<init>(final this$1/*implicit*/, x, yx)
class MemberClassTest$1 -- anon
MemberClassTest$1.<init>(final this$0/*implicit*/)
MemberClassTest$1.m()
MemberClassTest$1.m(s, ts)
static public class MemberClassTest$Static_Member$Static_Member_Static_Member -- inner
MemberClassTest$Static_Member$Static_Member_Static_Member.<init>()
MemberClassTest$Static_Member$Static_Member_Static_Member.<init>(x, yx)
public class MemberClassTest$Static_Member$Static_Member_Member -- inner
MemberClassTest$Static_Member$Static_Member_Member.<init>(final this$0/*implicit*/)
MemberClassTest$Static_Member$Static_Member_Member.<init>(final this$0/*implicit*/, x, yx)
class MemberClassTest --
MemberClassTest.<init>(final a, ba)
MemberClassTest.<init>()
MemberClassTest.foo()
static interface MemberClassTest$I -- inner
MemberClassTest$I.m()
MemberClassTest$I.m(x, yx)
class MemberClassTest$1$Anonymous_Member -- inner
MemberClassTest$1$Anonymous_Member.<init>(final this$1/*implicit*/)
MemberClassTest$1$Anonymous_Member.<init>(final this$1/*implicit*/, x, yx)
\ No newline at end of file
......@@ -48,6 +48,7 @@ public class ReflectionVisitor extends Tester.Visitor {
boolean isMember;
boolean isStatic;
boolean isPublic;
boolean isFinal;
Class clazz;
StringBuilder sb;
......@@ -72,8 +73,8 @@ public class ReflectionVisitor extends Tester.Visitor {
.append(isPublic ? "public " : "")
.append(isEnum ? "enum " : isInterface ? "interface " : "class ")
.append(cl).append(" -- ")
.append(isMember? "member " : "" )
.append(isLocal? "local " : "" )
.append(isMember? "inner" : "" )
.append(isLocal? "inner" : "" )
.append(isAnon ? "anon" : "")
.append("\n");
......@@ -82,7 +83,6 @@ public class ReflectionVisitor extends Tester.Visitor {
}
for (Method m :clazz.getDeclaredMethods()) {
testMethod(m);
}
}
......@@ -116,9 +116,15 @@ public class ReflectionVisitor extends Tester.Visitor {
for (Parameter p : c.getParameters()) {
i++;
String pname = p.getName();
int pmodifier = p.getModifiers();
isFinal = false;
if (Modifier.isFinal(pmodifier)) {
isFinal = true;
pname = "final " + pname;
}
sb.append(sep).append(pname);
if (p.isImplicit()) sb.append("!");
if (p.isSynthetic()) sb.append("!!");
if (p.isImplicit()) sb.append("/*implicit*/");
if (p.isSynthetic()) sb.append("/*synthetic*/");
sep = ", ";
// Set expectations
......@@ -135,11 +141,17 @@ public class ReflectionVisitor extends Tester.Visitor {
}
} else if (i == 0) {
if (isAnon) {
expect = "this\\$[0-9]+";
allowImplicit = true;
if (isFinal)
expect = "final this\\$[0-9]+";
} else if (isLocal) {
expect = "this\\$[0-9]+";
allowImplicit = true;
expect = "this\\$[0-n]*";
if (isFinal)
expect = "final this\\$[0-9]+";
} else if ((isMember && !isStatic)) {
expect = "this\\$[0-9]+";
allowImplicit = true;
if (!isPublic) {
// some but not all non-public inner classes
......@@ -147,7 +159,8 @@ public class ReflectionVisitor extends Tester.Visitor {
// the test a bit of slack and allow either.
allowSynthetic = true;
}
expect = "this\\$[0-n]*";
if (isFinal)
expect = "final this\\$[0-9]+";
}
}
......@@ -201,11 +214,16 @@ public class ReflectionVisitor extends Tester.Visitor {
char ch = param.charAt(0);
expect = (++ch) + param;
}
if (isFinal && expect != null) {
expect = "final " + expect;
}
if (pname != null && fidelity) {
if (isFinal) {
param = pname.substring(6);
} else {
param = pname;
}
}
if (expect != null && !expect.equals(pname)) {
error(prefix + "param[" + i + "]='" + pname +
"' expected '" + expect + "'");
......@@ -213,7 +231,7 @@ public class ReflectionVisitor extends Tester.Visitor {
}
}
if (c.isSynthetic()) {
sb.append(")!!\n");
sb.append(")/*synthetic*/\n");
} else {
sb.append(")\n");
}
......@@ -240,13 +258,24 @@ public class ReflectionVisitor extends Tester.Visitor {
// the test-case design pattern, except synthetic methods.
for (Parameter p : m.getParameters()) {
i++;
isFinal = false;
int pmodifier = p.getModifiers();
if (param == null) {
param = p.getName();
if (Modifier.isFinal(pmodifier)) {
isFinal = true;
param = "final " + param;
}
sb.append(sep).append(param);
} else {
char c = param.charAt(0);
String expect = m.isSynthetic() ? ("arg" + i) : ((++c) + param);
param = p.getName();
if (Modifier.isFinal(pmodifier)) {
isFinal = true;
expect = "final " + expect;
param = "final " + param;
}
sb.append(sep).append(param);
if (!m.isBridge() && !expect.equals(param)) {
error(prefix + "param[" + i + "]='"
......@@ -254,10 +283,18 @@ public class ReflectionVisitor extends Tester.Visitor {
break;
}
}
if(isFinal)
param = param.substring(6);
if (p.isImplicit()) {
sb.append("/*implicit*/");
}
if (p.isSynthetic()) {
sb.append("/*synthetic*/");
}
sep = ", ";
}
if (m.isSynthetic()) {
sb.append(")!!\n");
sb.append(")/*synthetic*/\n");
} else {
sb.append(")\n");
}
......
......@@ -27,7 +27,7 @@
* @summary javac should generate method parameters correctly.
* @build Tester
* @compile -parameters StaticMethods.java
* @run main Tester StaticMethods
* @run main Tester StaticMethods StaticMethods.out
*/
public class StaticMethods {
......
public class StaticMethods --
StaticMethods.<init>()
StaticMethods.def(a, ba, final cba, final dcba)
StaticMethods.def(a, final ba, final cba)
StaticMethods.pub(d, final ed, final fed)
StaticMethods.pub(a, ba, final cba, final dcba)
StaticMethods.prot(g, final hg, final ihg)
StaticMethods.prot(aa, baa, final cbaa, final dcbaa)
StaticMethods.priv(j, final kj, final lkj)
StaticMethods.priv(abc, babc, final cbabc, final dcbabc)
StaticMethods.empty()
\ No newline at end of file
......@@ -23,6 +23,12 @@
import java.io.*;
import java.lang.reflect.Constructor;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Test driver for MethodParameters testing.
......@@ -44,6 +50,13 @@ public class Tester {
final static File classesdir = new File(System.getProperty("test.classes", "."));
private String classname;
private File[] files;
private File refFile;
private int errors;
private int warnings;
private int diffGolden;
/**
* The visitor classes that does the actual checking are referenced
* statically, to force compilations, without having to reference
......@@ -62,32 +75,38 @@ public class Tester {
* Test-driver expect a single classname as argument.
*/
public static void main(String... args) throws Exception {
if (args.length != 1) {
throw new Error("A single class name is expected as argument");
if (args.length != 2) {
throw new Error("A single class name and a golden file are expected as argument");
}
final String pattern = args[0] + ".*\\.class";
File files[] = classesdir.listFiles(new FileFilter() {
String testSrc = System.getProperty("test.src");
String testName = args[0];
String testGoldenFile = args[1];
final String pattern = testName + ".*\\.class";
File refFile = new File(testSrc, testGoldenFile);
File[] files = classesdir.listFiles(new FileFilter() {
public boolean accept(File f) {
return f.getName().matches(pattern);
}
});
if (files.length == 0) {
File file = new File(classesdir, args[0] + ".class");
File file = new File(classesdir, testName + ".class");
throw new Error(file.getPath() + " not found");
}
new Tester(args[0], files).run();
new Tester(testName, files, refFile).run();
}
public Tester(String name, File files[]) {
public Tester(String name, File[] files, File refFile) {
this.classname = name;
this.files = files;
this.refFile = refFile;
}
void run() throws Exception {
// Test with each visitor
for (Class<Visitor> vclass : visitors) {
boolean compResult = false;
try {
String vname = vclass.getName();
Constructor c = vclass.getConstructor(Tester.class);
......@@ -105,13 +124,22 @@ public class Tester {
e.printStackTrace();
}
}
info(sb.toString());
String output = sb.toString();
info(output);
compResult = compareOutput(refFile, output);
} catch(ReflectiveOperationException e) {
warn("Class " + vclass.getName() + " ignored, not a Visitor");
continue;
}
if (!compResult) {
diffGolden++;
error("The output from " + vclass.getName() + " did not match golden file.");
}
}
if (0 != diffGolden)
throw new Exception("Test output is not equal with golden file.");
if(0 != warnings)
System.err.println("Test generated " + warnings + " warnings");
......@@ -119,6 +147,25 @@ public class Tester {
throw new Exception("Tester test failed with " +
errors + " errors");
}
// Check if test output matches the golden file.
boolean compareOutput(File refFile, String sb)
throws FileNotFoundException, IOException {
List<String> refFileList = Files.readAllLines(refFile.toPath(), StandardCharsets.UTF_8);
List<String> sbList = Arrays.asList(sb.split(System.getProperty("line.separator")));
// Check if test output contains unexpected lines or is missing expected lines.
List<String> sbOnly = new ArrayList<String>(sbList);
sbOnly.removeAll(refFileList);
for (String line: sbOnly)
error("unexpected line found: " + line);
List<String> refOnly = new ArrayList<String>(refFileList);
refOnly.removeAll(sbList);
for (String line: refOnly)
error("expected line not found: " + line);
return sbOnly.isEmpty() && refOnly.isEmpty();
}
abstract static class Visitor {
Tester tester;
......@@ -153,9 +200,4 @@ public class Tester {
void info(String msg) {
System.out.println(msg);
}
int errors;
int warnings;
String classname;
File files[];
}
......@@ -27,7 +27,7 @@
* @summary javac should generate method parameters correctly.
* @build Tester
* @compile -parameters UncommonParamNames.java
* @run main Tester UncommonParamNames
* @run main Tester UncommonParamNames UncommonParamNames.out
*/
/** Test uncommon parameter names */
......
class UncommonParamNames --
UncommonParamNames.<init>(zerozero)
UncommonParamNames.<init>(a)
UncommonParamNames.<init>($1)
UncommonParamNames.<init>(_x)
UncommonParamNames.<init>(a, ba, cba, dcba, edcba, fedcba, gfedcba, hgfedcba, ihgfedcba, jihgfedcba, kjihgfedcba, lkjihgfedcba, mlkjihgfedcba, nmlkjihgfedcba, onmlkjihgfedcba, ponmlkjihgfedcba, qponmlkjihgfedcba, rqponmlkjihgfedcba, srqponmlkjihgfedcba, tsrqponmlkjihgfedcba, utsrqponmlkjihgfedcba, vutsrqponmlkjihgfedcba, wvutsrqponmlkjihgfedcba, xwvutsrqponmlkjihgfedcba, yxwvutsrqponmlkjihgfedcba, zyxwvutsrqponmlkjihgfedcba)
UncommonParamNames.<init>(aLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName, baLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName, cbaLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName)
UncommonParamNames.<init>(zerozeroeight)
UncommonParamNames.<init>(zerozeroseven)
UncommonParamNames.foo(zerozero)
UncommonParamNames.foo(a)
UncommonParamNames.foo($1)
UncommonParamNames.foo(a, ba, cba, dcba, edcba, fedcba, gfedcba, hgfedcba, ihgfedcba, jihgfedcba, kjihgfedcba, lkjihgfedcba, mlkjihgfedcba, nmlkjihgfedcba, onmlkjihgfedcba, ponmlkjihgfedcba, qponmlkjihgfedcba, rqponmlkjihgfedcba, srqponmlkjihgfedcba, tsrqponmlkjihgfedcba, utsrqponmlkjihgfedcba, vutsrqponmlkjihgfedcba, wvutsrqponmlkjihgfedcba, xwvutsrqponmlkjihgfedcba, yxwvutsrqponmlkjihgfedcba, zyxwvutsrqponmlkjihgfedcba)
UncommonParamNames.foo(zerozeroseven)
UncommonParamNames.foo(zerozeroeight)
UncommonParamNames.foo(aLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName, baLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName, cbaLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName)
UncommonParamNames.foo(_x)
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册