1/* 2 * Copyright (c) 2012, 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 * @bug 8004833 27 * @summary Integrate doclint support into javac 28 * @modules jdk.compiler/com.sun.tools.javac.main 29 */ 30 31import java.io.File; 32import java.io.PrintWriter; 33import java.io.StringWriter; 34import java.net.URI; 35import java.util.Arrays; 36import java.util.Collections; 37import java.util.List; 38 39import javax.tools.Diagnostic; 40import javax.tools.JavaCompiler; 41import javax.tools.JavaFileObject; 42import javax.tools.SimpleJavaFileObject; 43import javax.tools.StandardJavaFileManager; 44import javax.tools.StandardLocation; 45import javax.tools.ToolProvider; 46import static javax.tools.Diagnostic.Kind.*; 47 48import com.sun.source.util.JavacTask; 49import com.sun.tools.javac.main.Main; 50import java.util.EnumSet; 51import java.util.Set; 52import java.util.regex.Matcher; 53import java.util.regex.Pattern; 54 55public class DocLintTest { 56 public static void main(String... args) throws Exception { 57 new DocLintTest().run(); 58 } 59 60 JavaCompiler javac; 61 StandardJavaFileManager fm; 62 JavaFileObject file; 63 64 final String code = 65 /* 01 */ "/** Class comment. */\n" + 66 /* 02 */ "public class Test {\n" + 67 /* 03 */ " /** Method comment. */\n" + 68 /* 04 */ " public void method() { }\n" + 69 /* 05 */ "\n" + 70 /* 06 */ " /** Syntax < error. */\n" + 71 /* 07 */ " private void syntaxError() { }\n" + 72 /* 08 */ "\n" + 73 /* 09 */ " /** @see DoesNotExist */\n" + 74 /* 10 */ " protected void referenceError() { }\n" + 75 /* 08 */ "\n" + 76 /* 09 */ " /** @return */\n" + 77 /* 10 */ " public int emptyReturn() { return 0; }\n" + 78 /* 11 */ "}\n"; 79 80 final String rawDiags = "-XDrawDiagnostics"; 81 private enum Message { 82 // doclint messages 83 DL_ERR6(ERROR, "Test.java:6:16: compiler.err.proc.messager: malformed HTML"), 84 DL_ERR9(ERROR, "Test.java:9:14: compiler.err.proc.messager: reference not found"), 85 DL_WRN12(WARNING, "Test.java:12:9: compiler.warn.proc.messager: no description for @return"), 86 87 OPT_BADARG(ERROR, "invalid flag: -Xdoclint:badarg"); 88 89 final Diagnostic.Kind kind; 90 final String text; 91 92 static Message get(String text) { 93 for (Message m: values()) { 94 if (m.text.equals(text)) 95 return m; 96 } 97 return null; 98 } 99 100 Message(Diagnostic.Kind kind, String text) { 101 this.kind = kind; 102 this.text = text; 103 } 104 105 @Override 106 public String toString() { 107 return "[" + kind + ",\"" + text + "\"]"; 108 } 109 } 110 void run() throws Exception { 111 javac = ToolProvider.getSystemJavaCompiler(); 112 fm = javac.getStandardFileManager(null, null, null); 113 try { 114 fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); 115 file = new SimpleJavaFileObject(URI.create("Test.java"), JavaFileObject.Kind.SOURCE) { 116 @Override 117 public CharSequence getCharContent(boolean ignoreEncoding) { 118 return code; 119 } 120 }; 121 122 test(Collections.<String>emptyList(), 123 Main.Result.OK, 124 EnumSet.noneOf(Message.class)); 125 126 test(Arrays.asList("-Xdoclint:none"), 127 Main.Result.OK, 128 EnumSet.noneOf(Message.class)); 129 130 test(Arrays.asList(rawDiags, "-Xdoclint"), 131 Main.Result.ERROR, 132 EnumSet.of(Message.DL_ERR6, Message.DL_ERR9, Message.DL_WRN12)); 133 134 test(Arrays.asList(rawDiags, "-Xdoclint:all/public"), 135 Main.Result.OK, 136 EnumSet.of(Message.DL_WRN12)); 137 138 test(Arrays.asList(rawDiags, "-Xdoclint:syntax"), 139 Main.Result.ERROR, 140 EnumSet.of(Message.DL_ERR6, Message.DL_WRN12)); 141 142 test(Arrays.asList(rawDiags, "-Xdoclint:reference"), 143 Main.Result.ERROR, 144 EnumSet.of(Message.DL_ERR9)); 145 146 test(Arrays.asList(rawDiags, "-Xdoclint:badarg"), 147 Main.Result.CMDERR, 148 EnumSet.of(Message.OPT_BADARG)); 149 150 if (errors > 0) 151 throw new Exception(errors + " errors occurred"); 152 } finally { 153 fm.close(); 154 } 155 } 156 157 void test(List<String> opts, Main.Result expectResult, Set<Message> expectMessages) { 158 System.err.println("test: " + opts); 159 StringWriter sw = new StringWriter(); 160 PrintWriter pw = new PrintWriter(sw); 161 List<JavaFileObject> files = Arrays.asList(file); 162 try { 163 JavacTask t = (JavacTask) javac.getTask(pw, fm, null, opts, null, files); 164 boolean ok = t.call(); 165 pw.close(); 166 String out = sw.toString().replaceAll("[\r\n]+", "\n"); 167 if (!out.isEmpty()) 168 System.err.println(out); 169 if (ok && expectResult != Main.Result.OK) { 170 error("Compilation succeeded unexpectedly"); 171 } else if (!ok && expectResult != Main.Result.ERROR) { 172 error("Compilation failed unexpectedly"); 173 } else 174 check(out, expectMessages); 175 } catch (IllegalArgumentException e) { 176 System.err.println(e); 177 String expectOut = expectMessages.iterator().next().text; 178 if (expectResult != Main.Result.CMDERR) 179 error("unexpected exception caught"); 180 else if (!e.getMessage().equals(expectOut)) { 181 error("unexpected exception message: " 182 + e.getMessage() 183 + " expected: " + expectOut); 184 } 185 } 186 187// if (errors > 0) 188// throw new Error("stop"); 189 } 190 191 private void check(String out, Set<Message> expect) { 192 Pattern stats = Pattern.compile("^([1-9]+) (error|warning)(s?)"); 193 Set<Message> found = EnumSet.noneOf(Message.class); 194 int e = 0, w = 0; 195 if (!out.isEmpty()) { 196 for (String line: out.split("[\r\n]+")) { 197 Matcher s = stats.matcher(line); 198 if (s.matches()) { 199 int i = Integer.valueOf(s.group(1)); 200 if (s.group(2).equals("error")) 201 e++; 202 else 203 w++; 204 continue; 205 } 206 207 Message m = Message.get(line); 208 if (m == null) 209 error("Unexpected line: " + line); 210 else 211 found.add(m); 212 } 213 } 214 for (Message m: expect) { 215 if (!found.contains(m)) 216 error("expected message not found: " + m.text); 217 } 218 for (Message m: found) { 219 if (!expect.contains(m)) 220 error("unexpected message found: " + m.text); 221 } 222 } 223 224 void error(String msg) { 225 System.err.println("Error: " + msg); 226 errors++; 227 } 228 229 int errors; 230} 231