test/tools/javac/lambda/TestSelfRef.java

Tue, 12 Mar 2013 16:02:43 +0000

author
mcimadamore
date
Tue, 12 Mar 2013 16:02:43 +0000
changeset 1628
5ddecb91d843
parent 1415
01c9d4161882
child 2148
c4292590fc70
permissions
-rw-r--r--

8009545: Graph inference: dependencies between inference variables should be set during incorporation
Summary: Move all transitivity checks into the incorporation round
Reviewed-by: jjg

     1 /*
     2  * Copyright (c) 2012, 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 8003280
    27  * @summary Add lambda tests
    28  *  Check that self/forward references from lambda expressions behave
    29  *          consistently w.r.t. local inner classes
    30  */
    32 import com.sun.source.util.JavacTask;
    33 import java.net.URI;
    34 import java.util.Arrays;
    35 import javax.tools.Diagnostic;
    36 import javax.tools.JavaCompiler;
    37 import javax.tools.JavaFileObject;
    38 import javax.tools.SimpleJavaFileObject;
    39 import javax.tools.StandardJavaFileManager;
    40 import javax.tools.ToolProvider;
    42 public class TestSelfRef {
    44     static int checkCount = 0;
    46     enum RefKind {
    47         SELF_LAMBDA("SAM s = x->{ System.out.println(s); };", true, false),
    48         FORWARD_LAMBDA("SAM s = x->{ System.out.println(f); };\nObject f = null;", false, true),
    49         SELF_ANON("Object s = new Object() { void test() { System.out.println(s); } };", true, false),
    50         FORWARD_ANON("Object s = new Object() { void test() { System.out.println(f); } }; Object f = null;", false, true);
    52         String refStr;
    53         boolean selfRef;
    54         boolean forwardRef;
    56         private RefKind(String refStr, boolean selfRef, boolean forwardRef) {
    57             this.refStr = refStr;
    58             this.selfRef = selfRef;
    59             this.forwardRef = forwardRef;
    60         }
    61     }
    63     enum EnclosingKind {
    64         TOPLEVEL("class C { #S }"),
    65         MEMBER_INNER("class Outer { class C { #S } }"),
    66         NESTED_INNER("class Outer { static class C { #S } }");
    68         String enclStr;
    70         private EnclosingKind(String enclStr) {
    71             this.enclStr = enclStr;
    72         }
    73     }
    75     enum InnerKind {
    76         NONE("#R"),
    77         LOCAL_NONE("class Local { #R }"),
    78         LOCAL_MTH("class Local { void test() { #R } }"),
    79         ANON_NONE("new Object() { #R };"),
    80         ANON_MTH("new Object() { void test() { #R } };");
    82         String innerStr;
    84         private InnerKind(String innerStr) {
    85             this.innerStr = innerStr;
    86         }
    88         boolean inMethodContext(SiteKind sk) {
    89             switch (this) {
    90                 case LOCAL_MTH:
    91                 case ANON_MTH: return true;
    92                 case NONE: return sk != SiteKind.NONE;
    93                 default:
    94                     return false;
    95             }
    96         }
    97     }
    99     enum SiteKind {
   100         NONE("#I"),
   101         STATIC_INIT("static { #I }"),
   102         INSTANCE_INIT("{ #I }"),
   103         CONSTRUCTOR("C() { #I }"),
   104         METHOD("void test() { #I }");
   106         String siteStr;
   108         private SiteKind(String siteStr) {
   109             this.siteStr = siteStr;
   110         }
   111     }
   113     public static void main(String... args) throws Exception {
   115         //create default shared JavaCompiler - reused across multiple compilations
   116         JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
   117         StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
   119         for (EnclosingKind ek : EnclosingKind.values()) {
   120             for (SiteKind sk : SiteKind.values()) {
   121                 if (sk == SiteKind.STATIC_INIT && ek == EnclosingKind.MEMBER_INNER)
   122                     continue;
   123                 for (InnerKind ik : InnerKind.values()) {
   124                     if (ik != InnerKind.NONE && sk == SiteKind.NONE)
   125                         break;
   126                     for (RefKind rk : RefKind.values()) {
   127                         new TestSelfRef(ek, sk, ik, rk).run(comp, fm);
   128                     }
   129                 }
   130             }
   131         }
   132         System.out.println("Total check executed: " + checkCount);
   133     }
   135     EnclosingKind ek;
   136     SiteKind sk;
   137     InnerKind ik;
   138     RefKind rk;
   139     JavaSource source;
   140     DiagnosticChecker diagChecker;
   142     TestSelfRef(EnclosingKind ek, SiteKind sk, InnerKind ik, RefKind rk) {
   143         this.ek = ek;
   144         this.sk = sk;
   145         this.ik = ik;
   146         this.rk = rk;
   147         this.source = new JavaSource();
   148         this.diagChecker = new DiagnosticChecker();
   149     }
   151     class JavaSource extends SimpleJavaFileObject {
   153         String bodyTemplate = "interface SAM { void test(Object o); }\n#B";
   154         String source;
   156         public JavaSource() {
   157             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
   158             source = bodyTemplate.replace("#B",
   159                     ek.enclStr.replace("#S", sk.siteStr.replace("#I", ik.innerStr.replace("#R", rk.refStr))));
   160         }
   162         @Override
   163         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   164             return source;
   165         }
   166     }
   168     void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
   169         JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
   170                 null, null, Arrays.asList(source));
   171         try {
   172             ct.analyze();
   173         } catch (Throwable ex) {
   174             throw new AssertionError("Error thron when compiling the following code:\n" + source.getCharContent(true));
   175         }
   176         check();
   177     }
   179     void check() {
   180         //illegal forward ref
   181         boolean errorExpected = ik.inMethodContext(sk) &&
   182                 (rk.selfRef || rk.forwardRef);
   183         if (diagChecker.errorFound != errorExpected) {
   184             throw new Error("invalid diagnostics for source:\n" +
   185                 source.getCharContent(true) +
   186                 "\nFound error: " + diagChecker.errorFound +
   187                 "\nExpected error: " + errorExpected);
   188         }
   189     }
   191     static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
   193         boolean errorFound;
   195         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
   196             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
   197                 errorFound = true;
   198             }
   199         }
   200     }
   201 }

mercurial