diff -r 36e8bc1907a2 -r c674b396827c test/tools/javac/limits/NumArgsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/limits/NumArgsTest.java Thu Jun 27 00:37:13 2013 -0400 @@ -0,0 +1,269 @@ +/* + * 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 com.sun.tools.javac.util.*; +import com.sun.tools.javac.api.*; +import com.sun.tools.javac.file.*; +import java.io.*; +import java.util.*; +import javax.tools.*; + +// More general parameter limit testing framework, and designed so +// that it could be expanded into a general limits-testing framework +// in the future. +public class NumArgsTest { + + private static final NumArgsTest.NestingDef[] NO_NESTING = {}; + + // threshold is named as such because "threshold" args is expected + // to pass, and "threshold" + 1 args is expected to fail. + private final int threshold; + private final boolean isStaticMethod; + private final String result; + private final String testName; + private final String methodName; + private final NestingDef[] nesting; + private final File testdir; + private final JavacTool tool = JavacTool.create(); + private final JavacFileManager fm = + tool.getStandardFileManager(null, null, null); + private int errors = 0; + + public NumArgsTest(final int threshold, + final boolean isStaticMethod, + final String result, + final String methodName, + final String testName, + final NestingDef[] nesting) { + this.threshold = threshold; + this.isStaticMethod = isStaticMethod; + this.result = result; + this.methodName = methodName; + this.testName = testName; + this.nesting = nesting; + testdir = new File(testName); + testdir.mkdir(); + } + + public NumArgsTest(final int threshold, + final boolean isStaticMethod, + final String result, + final String methodName, + final String testName) { + this(threshold, isStaticMethod, result, methodName, + testName, NO_NESTING); + } + + public NumArgsTest(final int threshold, + final String result, + final String methodName, + final String testName, + final NestingDef[] nesting) { + this(threshold, false, result, methodName, testName, nesting); + } + + public NumArgsTest(final int threshold, + final String result, + final String methodName, + final String testName) { + this(threshold, false, result, methodName, testName, NO_NESTING); + } + + public NumArgsTest(final int threshold, + final String testName, + final NestingDef[] nesting) { + this(threshold, null, null, testName, nesting); + } + + public NumArgsTest(final int threshold, + final String testName) { + this(threshold, null, null, testName, NO_NESTING); + } + + public NumArgsTest(final int threshold, + final String testName, + final String constructorName, + final NestingDef[] nesting) { + this(threshold, null, constructorName, testName, nesting); + } + + protected void writeArgs(final int num, final PrintWriter stream) + throws IOException { + stream.print("int x1"); + for(int i = 1; i < num; i++) + stream.print(", int x" + (i + 1)); + } + + protected void writeMethod(final int num, + final String name, + final PrintWriter stream) + throws IOException { + stream.write("public "); + if (isStaticMethod) stream.write("static "); + if (result == null) + stream.write(""); + else { + stream.write(result); + stream.write(" "); + } + stream.write(name); + stream.write("("); + writeArgs(num, stream); + stream.write(") {}\n"); + } + + protected void writeJavaFile(final int num, + final boolean pass, + final PrintWriter stream) + throws IOException { + final String fullName = testName + (pass ? "Pass" : "Fail"); + stream.write("public class "); + stream.write(fullName); + stream.write(" {\n"); + for(int i = 0; i < nesting.length; i++) + nesting[i].writeBefore(stream); + if (null == methodName) + writeMethod(num, fullName, stream); + else + writeMethod(num, methodName, stream); + for(int i = nesting.length - 1; i >= 0; i--) + nesting[i].writeAfter(stream); + stream.write("}\n"); + } + + public void runTest() throws Exception { + // Run the pass test + final String passTestName = testName + "Pass.java"; + final StringWriter passBody = new StringWriter(); + final PrintWriter passStream = new PrintWriter(passBody); + final File passFile = new File(testdir, passTestName); + final FileWriter passWriter = new FileWriter(passFile); + + writeJavaFile(threshold, true, passStream); + passStream.close(); + passWriter.write(passBody.toString()); + passWriter.close(); + + final StringWriter passSW = new StringWriter(); + final String[] passArgs = { passFile.toString() }; + final Iterable passFiles = + fm.getJavaFileObjectsFromFiles(Arrays.asList(passFile)); + final JavaCompiler.CompilationTask passTask = + tool.getTask(passSW, fm, null, null, null, passFiles); + + if (!passTask.call()) { + errors++; + System.err.println("Compilation unexpectedly failed. Body:\n" + + passBody); + System.err.println("Output:\n" + passSW.toString()); + } + + // Run the fail test + final String failTestName = testName + "Fail.java"; + final StringWriter failBody = new StringWriter(); + final PrintWriter failStream = new PrintWriter(failBody); + final File failFile = new File(testdir, failTestName); + final FileWriter failWriter = new FileWriter(failFile); + + writeJavaFile(threshold + 1, false, failStream); + failStream.close(); + failWriter.write(failBody.toString()); + failWriter.close(); + + final StringWriter failSW = new StringWriter(); + final TestDiagnosticHandler failDiag = + new TestDiagnosticHandler("compiler.err.limit.parameters"); + final Iterable failFiles = + fm.getJavaFileObjectsFromFiles(Arrays.asList(failFile)); + final JavaCompiler.CompilationTask failTask = + tool.getTask(failSW, + tool.getStandardFileManager(null, null, null), + failDiag, + null, + null, + failFiles); + + if (failTask.call()) { + errors++; + System.err.println("Compilation unexpectedly succeeded."); + System.err.println("Input:\n" + failBody); + } + + if (!failDiag.sawError) { + errors++; + System.err.println("Did not see expected compile error."); + } + + if (errors != 0) + throw new RuntimeException("Test failed with " + + errors + " errors"); + } + + public static NestingDef classNesting(final String name) { + return new NestedClassBuilder(name, false); + } + + public static NestingDef classNesting(final String name, + final boolean isStatic) { + return new NestedClassBuilder(name, isStatic); + } + + protected interface NestingDef { + public abstract void writeBefore(final PrintWriter stream); + public abstract void writeAfter(final PrintWriter stream); + } + + private static class NestedClassBuilder implements NestingDef { + private final String name; + private final boolean isStatic; + public NestedClassBuilder(final String name, final boolean isStatic) { + this.name = name; + this.isStatic = isStatic; + } + public void writeBefore(final PrintWriter stream) { + stream.write("public "); + if (isStatic) stream.write("static"); + stream.write(" class "); + stream.write(name); + stream.write(" {\n"); + } + public void writeAfter(final PrintWriter stream) { + stream.write("}\n"); + } + } + + public class TestDiagnosticHandler implements DiagnosticListener { + public boolean sawError; + public final String target; + + public TestDiagnosticHandler(final String target) { + this.target = target; + } + + public void report(final Diagnostic diag) { + if (diag.getCode().equals(target)) + sawError = true; + } + } + +}