mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 02:54:35 +02:00
8014230: Compilation incorrectly succeeds with inner class constructor with 254 parameters
The compiler does not account fr extra parameters due to inner this parameters Reviewed-by: jjg
This commit is contained in:
parent
b2c41f305e
commit
a2c99b7e5c
13 changed files with 541 additions and 1692 deletions
269
langtools/test/tools/javac/limits/NumArgsTest.java
Normal file
269
langtools/test/tools/javac/limits/NumArgsTest.java
Normal file
|
@ -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<? extends JavaFileObject> 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<? extends JavaFileObject> 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<T> implements DiagnosticListener<T> {
|
||||
public boolean sawError;
|
||||
public final String target;
|
||||
|
||||
public TestDiagnosticHandler(final String target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public void report(final Diagnostic<? extends T> diag) {
|
||||
if (diag.getCode().equals(target))
|
||||
sawError = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue