1 /*
   2  * Copyright (c) 2018, 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 Unit tests for Raw String Literal language changes
  27  * @library /tools/lib
  28  * @modules jdk.compiler/com.sun.tools.javac.api
  29  *          jdk.compiler/com.sun.tools.javac.main
  30  * @build toolbox.ToolBox toolbox.JavacTask
  31  * @run main RawStringLiteralLangAPI
  32  */
  33 
  34 import toolbox.JavacTask;
  35 import toolbox.JavaTask;
  36 import toolbox.Task;
  37 import toolbox.ToolBox;
  38 
  39 public class RawStringLiteralLangAPI {
  40     private static ToolBox TOOLBOX = new ToolBox();
  41 
  42     public static void main(String... args) {
  43         test1();
  44         test2();
  45         test3();
  46         test4();
  47     }
  48 
  49     /*
  50      * Check that correct/incorrect syntax is properly detected
  51      */
  52     enum Test {
  53         t0(false, "`*`*`"),
  54         t1(false, "`\\u2022`\\u2022`"),
  55         t2(false, "``*`*`"),
  56         t3(false, "``\\u2022`\\u2022`"),
  57         t4(false, "`*`*``"),
  58         t5(false, "`\\u2022`\\u2022``"),
  59         t6(true, "``*`*``"),
  60         t7(true, "``\\u2022`\\u2022``"),
  61         t8(true, "`*``*`"),
  62         t9(true, "`\\u2022``\\u2022`"),
  63         ;
  64 
  65         Test(boolean pass, String string) {
  66             this.pass = pass;
  67             this.string = string;
  68         }
  69 
  70         boolean pass;
  71         String string;
  72     }
  73     static void test1() {
  74         for (Test t : Test.values()) {
  75             String code =
  76                     "public class RawStringLiteralTest {\n" +
  77                             "    public static void main(String... args) {\n" +
  78                             "        String xxx = " + t.string + ";\n" +
  79                             "    }\n" +
  80                             "}\n";
  81             if (t.pass) {
  82                 compPass(code);
  83             } else {
  84                 compFail(code);
  85             }
  86         }
  87     }
  88 
  89     /*
  90      * Check that misuse of \u0060 is properly detected
  91      */
  92     static void test2() {
  93         compFail("public class BadDelimiter {\n" +
  94                 "    public static void main(String... args) {\n" +
  95                 "        String xxx = \\u0060`abc`;\n" +
  96                 "    }\n" +
  97                 "}\n");
  98     }
  99 
 100     /*
 101      * Check edge cases of raw string literal as last token
 102      */
 103     static void test3() {
 104         compFail("public class RawStringLiteralTest {\n" +
 105                 "    public static void main(String... args) {\n" +
 106                 "        String xxx = `abc`");
 107         compFail("public class RawStringLiteralTest {\n" +
 108                 "    public static void main(String... args) {\n" +
 109                 "        String xxx = `abc");
 110         compFail("public class RawStringLiteralTest {\n" +
 111                 "    public static void main(String... args) {\n" +
 112                 "        String xxx = `abc\u0000");
 113     }
 114 
 115     /*
 116      * Check line terminator translation
 117      */
 118     static void test4() {
 119         String[] terminators = new String[] { "\n", "\r\n", "\r" };
 120         for (String terminator : terminators) {
 121             String code = "public class LineTerminatorTest {" + terminator +
 122                           "    public static void main(String... args) {" + terminator +
 123                           "        String s =" + terminator +
 124                           "`" + terminator +
 125                           "abc" + terminator +
 126                           "`;" + terminator +
 127                           "        System.out.println(s.equals(\"\\nabc\\n\"));" + terminator +
 128                           "    }" + terminator +
 129                           "}" + terminator;
 130             new JavacTask(TOOLBOX)
 131                     .sources(code)
 132                     .classpath(".")
 133                     .options("--enable-preview", "-source", "12")
 134                     .run();
 135             String output = new JavaTask(TOOLBOX)
 136                     .vmOptions("--enable-preview")
 137                     .classpath(".")
 138                     .classArgs("LineTerminatorTest")
 139                     .run()
 140                     .writeAll()
 141                     .getOutput(Task.OutputKind.STDOUT);
 142 
 143             if (!output.contains("true")) {
 144                 throw new RuntimeException("Error detected");
 145             }
 146         }
 147     }
 148 
 149     /*
 150      * Test source for successful compile.
 151      */
 152     static void compPass(String source) {
 153         String output = new JavacTask(TOOLBOX)
 154                 .sources(source)
 155                 .classpath(".")
 156                 .options("--enable-preview", "-source", "12", "-encoding", "utf8")
 157                 .run()
 158                 .writeAll()
 159                 .getOutput(Task.OutputKind.DIRECT);
 160 
 161         if (output.contains("compiler.err")) {
 162             throw new RuntimeException("Error detected");
 163         }
 164     }
 165 
 166     /*
 167      * Test source for unsuccessful compile and specific error.
 168      */
 169     static void compFail(String source)  {
 170         String errors = new JavacTask(TOOLBOX)
 171                 .sources(source)
 172                 .classpath(".")
 173                 .options("-XDrawDiagnostics", "--enable-preview", "-source", "12", "-encoding", "utf8")
 174                 .run(Task.Expect.FAIL)
 175                 .writeAll()
 176                 .getOutput(Task.OutputKind.DIRECT);
 177 
 178         if (!errors.contains("compiler.err")) {
 179             throw new RuntimeException("No error detected");
 180         }
 181     }
 182 }