test/tools/javac/varargs/7043922/T7043922.java

Mon, 16 May 2011 09:38:04 +0100

author
mcimadamore
date
Mon, 16 May 2011 09:38:04 +0100
changeset 1010
5faa9eedc44e
parent 0
959103a6100f
permissions
-rw-r--r--

7043922: Regression: internal compiler error for nested anonymous inner class featuring varargs constructor
Summary: Attributing a constructor call does not clean up the compiler's attribution context
Reviewed-by: jjg

     1 /*
     2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  */
    24 /*
    25  * @test
    26  * @bug 7043922
    27  * @summary Regression: internal compiler error for nested anonymous inner class featuring varargs constructor
    28  */
    30 import com.sun.source.util.JavacTask;
    31 import com.sun.tools.javac.api.JavacTool;
    32 import com.sun.tools.javac.util.List;
    34 import java.net.URI;
    35 import java.util.Arrays;
    36 import java.util.Locale;
    37 import javax.tools.Diagnostic;
    38 import javax.tools.JavaCompiler;
    39 import javax.tools.JavaFileObject;
    40 import javax.tools.SimpleJavaFileObject;
    41 import javax.tools.StandardJavaFileManager;
    42 import javax.tools.ToolProvider;
    44 public class T7043922 {
    46     ClassKind[] classKinds;
    47     ConstructorKind[] constructorKinds;
    49     T7043922(ClassKind[] classKinds, ConstructorKind[] constructorKinds) {
    50         this.classKinds = classKinds;
    51         this.constructorKinds = constructorKinds;
    52     }
    54     void compileAndCheck() throws Exception {
    55         JavaSource source = new JavaSource();
    56         ErrorChecker ec = new ErrorChecker();
    57         JavacTask ct = (JavacTask)tool.getTask(null, fm, ec,
    58                 null, null, Arrays.asList(source));
    59         ct.analyze();
    60         if (ec.errorFound) {
    61             throw new Error("invalid diagnostics for source:\n" +
    62                     source.getCharContent(true) +
    63                     "\nCompiler diagnostics:\n" + ec.printDiags());
    64         }
    65     }
    67     class JavaSource extends SimpleJavaFileObject {
    69         static final String source_template = "#C0 A0 { #K0 }\n" +
    70                                               "#C1 A1 { #K1 }\n" +
    71                                               "#C2 A2 { #K2 }\n" +
    72                                               "class D {\n" +
    73                                               "   void test() {\n" +
    74                                               "      new A0(#V0) {\n" +
    75                                               "         void test() {\n" +
    76                                               "            new A1(#V1) {\n" +
    77                                               "               void test() {\n" +
    78                                               "                   new A2(#V2) {};\n" +
    79                                               "               }\n" +
    80                                               "            };\n" +
    81                                               "         }\n" +
    82                                               "      };\n" +
    83                                               "   }\n" +
    84                                               "}\n";
    86         String source;
    88         public JavaSource() {
    89             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
    90             source = source_template;
    91             for (int i = 0; i < 3; i++) {
    92                 source = source.replaceAll("#C" + i, classKinds[i].classKind).
    93                     replaceAll("#K" + i, classKinds[i].getConstructor("A" + i, constructorKinds[i])).
    94                     replaceAll("#V" + i, constructorKinds[i].constrArgs);
    95             }
    96         }
    98         @Override
    99         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   100             return source;
   101         }
   102     }
   104     /** global decls ***/
   106     enum ConstructorKind {
   107         DEFAULT("", ""),
   108         FIXED_ARITY("String s", "\"\""),
   109         VARIABLE_ARITY("String... ss", "\"\",\"\"");
   111         String constrParam;
   112         String constrArgs;
   114         private ConstructorKind(String constrParam, String constrArgs) {
   115             this.constrParam = constrParam;
   116             this.constrArgs = constrArgs;
   117         }
   118     }
   120     enum ClassKind {
   121         ABSTRACT("abstract class"),
   122         CLASS("class"),
   123         INTERFACE("interface");
   125         String classKind;
   127         private ClassKind(String classKind) {
   128             this.classKind = classKind;
   129         }
   131         boolean isConstructorOk(ConstructorKind ck) {
   132             return this != INTERFACE ||
   133                     ck == ConstructorKind.DEFAULT;
   134         }
   136         String getConstructor(String className, ConstructorKind ck) {
   137             return this == INTERFACE ?
   138                 "" :
   139                 (className + "(" + ck.constrParam + ") {}");
   140         }
   141     }
   143     // Create a single file manager and JavaCompiler tool
   144     // and reuse them for each compile to save time.
   145     static final StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
   146     static final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
   148     public static void main(String... args) throws Exception {
   149         for (ClassKind classKind1 : ClassKind.values()) {
   150             for (ConstructorKind constrKind1 : ConstructorKind.values()) {
   151                 if (!classKind1.isConstructorOk(constrKind1)) continue;
   152                 for (ClassKind classKind2 : ClassKind.values()) {
   153                     for (ConstructorKind constrKind2 : ConstructorKind.values()) {
   154                         if (!classKind2.isConstructorOk(constrKind2)) continue;
   155                         for (ClassKind classKind3 : ClassKind.values()) {
   156                             for (ConstructorKind constrKind3 : ConstructorKind.values()) {
   157                                 if (!classKind3.isConstructorOk(constrKind3)) continue;
   158                                 new T7043922(new ClassKind[] { classKind1, classKind2, classKind3 },
   159                                         new ConstructorKind[] { constrKind1, constrKind2, constrKind3 }).compileAndCheck();
   160                             }
   161                         }
   162                     }
   163                 }
   164             }
   165         }
   166     }
   168     static class ErrorChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   170         boolean errorFound;
   171         List<String> errDiags = List.nil();
   173         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   174             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
   175                 errDiags = errDiags.append(diagnostic.getMessage(Locale.getDefault()));
   176                 errorFound = true;
   177             }
   178         }
   180         String printDiags() {
   181             StringBuilder buf = new StringBuilder();
   182             for (String s : errDiags) {
   183                 buf.append(s);
   184                 buf.append("\n");
   185             }
   186             return buf.toString();
   187         }
   188     }
   189 }

mercurial