1 /*
   2  * Copyright (c) 2015, 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  */
  23 
  24 /*
  25  * @test
  26  * @summary Tests for EvaluationState.methods
  27  * @build KullaTesting TestingInputStream ExpectedDiagnostic
  28  * @run testng MethodsTest
  29  */
  30 
  31 import javax.tools.Diagnostic;
  32 
  33 import jdk.jshell.Snippet;
  34 import jdk.jshell.MethodSnippet;
  35 import jdk.jshell.Snippet.Status;
  36 import org.testng.annotations.Test;
  37 
  38 import static jdk.jshell.Snippet.Status.*;
  39 import static jdk.jshell.Snippet.SubKind.*;
  40 
  41 @Test
  42 public class MethodsTest extends KullaTesting {
  43 
  44     public void noMethods() {
  45         assertNumberOfActiveMethods(0);
  46     }
  47 
  48     public void testSignature1() {
  49         MethodSnippet m1 = methodKey(assertEval("void f() { g(); }", added(RECOVERABLE_DEFINED)));
  50         assertMethodDeclSnippet(m1, "f", "()void", RECOVERABLE_DEFINED, 1, 0);
  51         MethodSnippet m2 = methodKey(assertEval("void g() { }",
  52                 added(VALID),
  53                 ste(m1, RECOVERABLE_DEFINED, VALID, false, null)));
  54         assertMethodDeclSnippet(m2, "g", "()void", VALID, 0, 0);
  55     }
  56 
  57     public void testSignature2() {
  58         MethodSnippet m1 = (MethodSnippet) assertDeclareFail("void f() { return g(); }", "compiler.err.prob.found.req");
  59         assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
  60         MethodSnippet m2 = methodKey(assertEval("int f() { return g(); }",
  61                 ste(m1, REJECTED, RECOVERABLE_DEFINED, true, null)));
  62         assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
  63         assertMethodDeclSnippet(m2, "f", "()int", RECOVERABLE_DEFINED, 1, 0);
  64     }
  65 
  66     @Test(enabled = false) // TODO 8081690
  67     public void testSignature3() {
  68         MethodSnippet m1 = methodKey(assertEval("void f(Bar b) { }", added(RECOVERABLE_NOT_DEFINED)));
  69         assertMethodDeclSnippet(m1, "f", "(Bar)void", RECOVERABLE_NOT_DEFINED, 1, 0);
  70         MethodSnippet m2 = methodKey(assertEval("void f(A.Bar b) { }", added(RECOVERABLE_NOT_DEFINED)));
  71         assertMethodDeclSnippet(m1, "f", "(Bar)void", RECOVERABLE_NOT_DEFINED, 1, 0);
  72         assertMethodDeclSnippet(m2, "f", "(A.Bar)void", RECOVERABLE_NOT_DEFINED, 1, 0);
  73         assertDrop(m1, ste(m1, RECOVERABLE_NOT_DEFINED, DROPPED, false, null));
  74         assertMethodDeclSnippet(m1, "f", "(Bar)void", DROPPED, 1, 0);
  75     }
  76 
  77     public void methods() {
  78         assertEval("int x() { return 10; }");
  79         assertEval("String y() { return null; }");
  80         assertEval("long z() { return 0; }");
  81         assertMethods(method("()int", "x"), method("()String", "y"), method("()long", "z"));
  82         assertActiveKeys();
  83     }
  84 
  85     public void methodOverload() {
  86         assertEval("int m() { return 1; }");
  87         assertEval("int m(int x) { return 2; }");
  88         assertEval("int m(String s) { return 3; }");
  89         assertEval("int m(int x, int y) { return 4; }");
  90         assertEval("int m(int x, String z) { return 5; }");
  91         assertEval("int m(int x, String z, long g) { return 6; }");
  92         assertMethods(
  93                 method("()int", "m"),
  94                 method("(int)int", "m"),
  95                 method("(String)int", "m"),
  96                 method("(int,int)int", "m"),
  97                 method("(int,String)int", "m"),
  98                 method("(int,String,long)int", "m")
  99         );
 100         assertEval("m();", "1");
 101         assertEval("m(3);", "2");
 102         assertEval("m(\"hi\");", "3");
 103         assertEval("m(7, 8);", "4");
 104         assertEval("m(7, \"eight\");", "5");
 105         assertEval("m(7, \"eight\", 9L);", "6");
 106         assertActiveKeys();
 107     }
 108 
 109     public void methodsRedeclaration1() {
 110         Snippet x = methodKey(assertEval("int x() { return 10; }"));
 111         Snippet y = methodKey(assertEval("String y() { return \"\"; }"));
 112         assertMethods(method("()int", "x"), method("()String", "y"));
 113         assertActiveKeys();
 114 
 115         assertEval("long x() { return 0; }",
 116                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
 117                 ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
 118         assertMethods(method("()long", "x"), method("()String", "y"));
 119         assertActiveKeys();
 120 
 121         assertEval("String y() { return null; }",
 122                 ste(MAIN_SNIPPET, VALID, VALID, false, null),
 123                 ste(y, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
 124         assertMethods(method("()long", "x"), method("()String", "y"));
 125         assertActiveKeys();
 126     }
 127 
 128     public void methodsRedeclaration2() {
 129         assertEval("int a() { return 1; }");
 130         assertMethods(method("()int", "a"));
 131         assertActiveKeys();
 132 
 133         Snippet b = methodKey(assertEval("Integer b() { return a(); }"));
 134         assertMethods(method("()int", "a"), method("()Integer", "b"));
 135         assertActiveKeys();
 136 
 137         Snippet c = methodKey(assertEval("double c() { return b(); }"));
 138         assertMethods(method("()int", "a"), method("()Integer", "b"), method("()double", "c"));
 139         assertActiveKeys();
 140 
 141         assertEval("double b() { return 3.14159; }",
 142                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
 143                 ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
 144                 ste(c, VALID, VALID, false, MAIN_SNIPPET));
 145         assertMethods(method("()int", "a"), method("()double", "b"), method("()double", "c"));
 146         assertEval("c();", "3.14159");
 147         assertActiveKeys();
 148     }
 149 
 150     public void methodsRedeclaration3() {
 151         Snippet x = methodKey(assertEval("int x(Object...a) { return 10; }"));
 152         assertMethods(method("(Object...)int", "x"));
 153         assertActiveKeys();
 154 
 155         assertEval("int x(Object[]a) { return 10; }",
 156                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
 157                 ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
 158         assertMethods(method("(Object[])int", "x"));
 159         assertActiveKeys();
 160     }
 161 
 162 
 163     public void methodsRedeclaration4() {
 164         Snippet a = methodKey(assertEval("int foo(int a) { return a; }"));
 165         assertEval("int x = foo(10);");
 166         assertActiveKeys();
 167         assertMethods(method("(int)int", "foo"));
 168         assertEval("int foo(int a) { return a * a; }",
 169                 ste(MAIN_SNIPPET, VALID, VALID, false, null),
 170                 ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
 171         assertActiveKeys();
 172     }
 173 
 174     public void methodsErrors() {
 175         assertDeclareFail("String f();",
 176                 new ExpectedDiagnostic("compiler.err.missing.meth.body.or.decl.abstract", 0, 11, 7, -1, -1, Diagnostic.Kind.ERROR));
 177         assertNumberOfActiveMethods(0);
 178         assertActiveKeys();
 179 
 180         assertDeclareFail("abstract String f();",
 181                 new ExpectedDiagnostic("jdk.eval.error.illegal.modifiers", 0, 8, 0, -1, -1, Diagnostic.Kind.ERROR));
 182         assertNumberOfActiveMethods(0);
 183         assertActiveKeys();
 184 
 185         assertDeclareFail("native String f();",
 186                 new ExpectedDiagnostic("jdk.eval.error.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.ERROR));
 187         assertNumberOfActiveMethods(0);
 188         assertActiveKeys();
 189 
 190         assertDeclareFail("synchronized String f() {return null;}",
 191                 new ExpectedDiagnostic("jdk.eval.error.illegal.modifiers", 0, 12, 0, -1, -1, Diagnostic.Kind.ERROR));
 192         assertNumberOfActiveMethods(0);
 193         assertActiveKeys();
 194 
 195         assertDeclareFail("int f() {}", "compiler.err.missing.ret.stmt",
 196                 ste(MAIN_SNIPPET, REJECTED, REJECTED, false, null));
 197         assertNumberOfActiveMethods(0);
 198         assertActiveKeys();
 199 
 200         assertEval("String x() { return \"\"; };");
 201         assertMethods(method("()String", "x"));
 202         assertActiveKeys();
 203     }
 204 
 205     public void methodsWarn() {
 206         Snippet f = assertDeclareWarn1("public String f() {return null;}",
 207                 new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING),
 208                 added(VALID));
 209         assertNumberOfActiveMethods(1);
 210         assertActiveKeys();
 211 
 212         f = assertDeclareWarn1("protected String f() {return null;}",
 213                 new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 9, 0, -1, -1, Diagnostic.Kind.WARNING),
 214                 ste(MAIN_SNIPPET, VALID, VALID, false, null),
 215                 ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
 216         assertNumberOfActiveMethods(1);
 217         assertActiveKeys();
 218 
 219         f = assertDeclareWarn1("private String f() {return null;}",
 220                 new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 7, 0, -1, -1, Diagnostic.Kind.WARNING),
 221                 ste(MAIN_SNIPPET, VALID, VALID, false, null),
 222                 ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
 223         assertNumberOfActiveMethods(1);
 224         assertActiveKeys();
 225 
 226         f = assertDeclareWarn1("static String f() {return null;}",
 227                 new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING),
 228                 ste(MAIN_SNIPPET, VALID, VALID, false, null),
 229                 ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
 230         assertNumberOfActiveMethods(1);
 231         assertActiveKeys();
 232 
 233         assertDeclareWarn1("final String f() {return null;}",
 234                 new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 5, 0, -1, -1, Diagnostic.Kind.WARNING),
 235                 ste(MAIN_SNIPPET, VALID, VALID, false, null),
 236                 ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
 237         assertNumberOfActiveMethods(1);
 238         assertActiveKeys();
 239     }
 240 
 241     public void methodSignatureUnresolved() {
 242         MethodSnippet key = (MethodSnippet) methodKey(assertEval("und m() { return new und(); }", added(RECOVERABLE_NOT_DEFINED)));
 243         assertMethodDeclSnippet(key, "m", "()und", RECOVERABLE_NOT_DEFINED, 1, 0);
 244         assertUnresolvedDependencies1(key, Status.RECOVERABLE_NOT_DEFINED, "class und");
 245         assertEval("class und {}",
 246                 added(VALID),
 247                 ste(key, RECOVERABLE_NOT_DEFINED, VALID, true, null));
 248         assertMethodDeclSnippet(key, "m", "()und", Status.VALID, 0, 0);
 249         assertNumberOfActiveMethods(1);
 250         assertActiveKeys();
 251     }
 252 
 253     @Test(enabled = false) // TODO 8081689
 254     public void classMethodsAreNotVisible() {
 255         assertEval(
 256             "class A {" +
 257                 "int foo() {" +
 258                     "int x = 10;" +
 259                     "int y = 2 * x;" +
 260                     "return x * y;" +
 261                 "}" +
 262             "}");
 263         assertNumberOfActiveMethods(0);
 264         assertEval("int x = 10;", "10");
 265         assertEval("int foo() {" +
 266                         "int y = 2 * x;" +
 267                         "return x * y;" +
 268                         "}");
 269         assertMethods(method("()int", "foo"));
 270         assertEval("foo();", "200");
 271         assertActiveKeys();
 272     }
 273 
 274     public void lambdas() {
 275         assertEval("class Inner1 implements Runnable {" +
 276                 "public Runnable lambda1 = () -> {};" +
 277                 "public void function() {}" +
 278                 "public void run() {}" +
 279                 "}");
 280 
 281         assertEval("class Inner2 {" +
 282                 "private Runnable lambda1 = () -> {};" +
 283                 "private static void staticFunction() {}" +
 284                 "}");
 285 
 286         // the following method references and lambda functions
 287         // generate synthetic methods
 288         assertEval("Runnable run = () -> {};");
 289         assertEval("Inner1 inner = new Inner1();");
 290         assertEval("Runnable l1 = inner::function;");
 291         assertEval("Runnable l2 = Inner1::new;");
 292         assertEval("inner.lambda1 = inner::function;");
 293         assertEval("java.util.stream.IntStream.of(2).mapToObj(int[]::new);");
 294         assertNumberOfActiveMethods(0);
 295         assertActiveKeys();
 296     }
 297 }