1 /* 2 * Copyright (c) 2019, 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 * @bug 8223967 27 * @bug 8232681 28 * @summary Unit tests for Text Block language changes 29 * @library /tools/lib 30 * @modules jdk.compiler/com.sun.tools.javac.api 31 * jdk.compiler/com.sun.tools.javac.main 32 * @build toolbox.ToolBox toolbox.JavacTask 33 * @run main TextBlockAPI 34 */ 35 36 import toolbox.JavacTask; 37 import toolbox.JavaTask; 38 import toolbox.Task; 39 import toolbox.ToolBox; 40 41 public class TextBlockAPI { 42 private static ToolBox TOOLBOX = new ToolBox(); 43 private final static String JDK_VERSION = Integer.toString(Runtime.version().feature()); 44 main(String... args)45 public static void main(String... args) { 46 test1(); 47 test2(); 48 test3(); 49 test4(); 50 test5(); 51 test6(); 52 test7(); 53 test8(); 54 } 55 56 /* 57 * Check that correct/incorrect syntax is properly detected 58 */ test1()59 static void test1() { 60 for (String lineterminators : new String[] { "\n", "\r", "\r\n" }) 61 for (String whitespace : new String[] { "", " ", "\t", "\f" }) 62 for (String content : new String[] { "a", "ab", "abc", "\u2022", "*".repeat(1000), "*".repeat(10000) }) { 63 String code = 64 "public class CorrectTest {\n" + 65 " public static void main(String... args) {\n" + 66 " String xxx = " + 67 "\"\"\"" + whitespace + lineterminators + 68 content + 69 "\"\"\";\n" + 70 " }\n" + 71 "}\n"; 72 compPass(code); 73 } 74 } 75 76 /* 77 * Check that use of \u0022 is properly detected 78 */ test2()79 static void test2() { 80 compPass("public class UnicodeDelimiterTest {", 81 " public static void main(String... args) {", 82 " String xxx = \\u0022\\u0022\\u0022\nabc\n\\u0022\\u0022\\u0022;", 83 " }", 84 "}"); 85 } 86 87 /* 88 * Check edge cases of text blocks as last token 89 */ test3()90 static void test3() { 91 compFail("public class EndTest {", 92 " public static void main(String... args) {", 93 " String xxx = \"\"\"\nabc\"\"\""); 94 compFail("public class TwoQuoteClose {", 95 " public static void main(String... args) {", 96 " String xxx = \"\"\"\nabc\"\""); 97 compFail("public class OneQuoteClose {", 98 " public static void main(String... args) {", 99 " String xxx = \"\"\"\nabc\""); 100 compFail("public class NoClose {", 101 " public static void main(String... args) {", 102 " String xxx = \"\"\"\nabc"); 103 compFail("public class ZeroTerminator {", 104 " public static void main(String... args) {", 105 " String xxx = \"\"\"\nabc\\u0000"); 106 compFail("public class NonBreakingSpace {", 107 " public static void main(String... args) {", 108 " String xxx = \"\"\"\nabc\\u001A"); 109 } 110 111 /* 112 * Check line terminator translation 113 */ test4()114 static void test4() { 115 String[] terminators = new String[] { "\n", "\r\n", "\r" }; 116 for (String terminator : terminators) { 117 String code = "public class LineTerminatorTest {" + terminator + 118 " public static void main(String... args) {" + terminator + 119 " String s =" + terminator + 120 "\"\"\"" + terminator + 121 "abc" + terminator + 122 "\"\"\";" + terminator + 123 " System.out.println(s.equals(\"abc\\n\"));" + terminator + 124 " }" + terminator + 125 "}" + terminator; 126 new JavacTask(TOOLBOX) 127 .sources(code) 128 .classpath(".") 129 .options("-encoding", "utf8") 130 .run(); 131 String output = new JavaTask(TOOLBOX) 132 .classpath(".") 133 .classArgs("LineTerminatorTest") 134 .run() 135 .writeAll() 136 .getOutput(Task.OutputKind.STDOUT); 137 138 if (!output.contains("true")) { 139 throw new RuntimeException("Error detected"); 140 } 141 } 142 } 143 144 /* 145 * Check escape space 146 */ test5()147 static void test5() { 148 compPass("public class EscapeSChar {", 149 " public static void main(String... args) {", 150 " char xxx = '\\s';", 151 " }", 152 "}"); 153 compPass("public class EscapeSString {", 154 " public static void main(String... args) {", 155 " String xxx = \"\\s\";", 156 " }", 157 "}"); 158 compPass("public class EscapeSTextBlock {", 159 " public static void main(String... args) {", 160 " String xxx = \"\"\"", 161 " \\s", 162 " \"\"\";", 163 " }", 164 "}"); 165 } 166 167 /* 168 * Check escape line terminator 169 */ test6()170 static void test6() { 171 String[] terminators = new String[] { "\n", "\r\n", "\r" }; 172 for (String terminator : terminators) { 173 compPass("public class EscapeLineTerminator {", 174 " public static void main(String... args) {", 175 " String xxx = \"\"\"", 176 " \\" + terminator + 177 " \"\"\";", 178 " }", 179 "}"); 180 } 181 } 182 183 /* 184 * Check incorrect escape line terminator cases 185 */ test7()186 static void test7() { 187 compFail("public class EscapeLineTerminatorChar {", 188 " public static void main(String... args) {", 189 " char xxx = '\\\n';", 190 " }", 191 "}"); 192 compFail("public class EscapeLineTerminatorString {", 193 " public static void main(String... args) {", 194 " String xxx = \"\\\n\";", 195 " }", 196 "}"); 197 } 198 test8()199 static void test8() { 200 String code = "class C {\n" + 201 "\n" + 202 " void x() {\n" + 203 " String s = \"\"\"\n" + 204 "\n" + 205 "\"\"\";\n" + 206 " }\n" + 207 "}\n"; 208 209 new JavacTask(TOOLBOX) 210 .sources(code) 211 .classpath(".") 212 .options("-encoding", "utf8", "-Xlint") 213 .run(); 214 } 215 216 /* 217 * Test source for successful compile. 218 */ compPass(String source)219 static void compPass(String source) { 220 String output = new JavacTask(TOOLBOX) 221 .sources(source) 222 .classpath(".") 223 .options("-encoding", "utf8") 224 .run() 225 .writeAll() 226 .getOutput(Task.OutputKind.DIRECT); 227 228 if (output.contains("compiler.err")) { 229 throw new RuntimeException("Error detected"); 230 } 231 } 232 compPass(String... lines)233 static void compPass(String... lines) { 234 compPass(String.join("\n", lines) + "\n"); 235 } 236 237 /* 238 * Test source for unsuccessful compile and specific error. 239 */ compFail(String source)240 static void compFail(String source) { 241 String errors = new JavacTask(TOOLBOX) 242 .sources(source) 243 .classpath(".") 244 .options("-XDrawDiagnostics", "-encoding", "utf8") 245 .run(Task.Expect.FAIL) 246 .writeAll() 247 .getOutput(Task.OutputKind.DIRECT); 248 249 if (!errors.contains("compiler.err")) { 250 throw new RuntimeException("No error detected"); 251 } 252 } 253 compFail(String... lines)254 static void compFail(String... lines) { 255 compFail(String.join("\n", lines) + "\n"); 256 } 257 } 258