aoqi@0: /* aoqi@0: * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: /* aoqi@0: * @test aoqi@0: * @bug 8004833 aoqi@0: * @summary Integrate doclint support into javac aoqi@0: */ aoqi@0: aoqi@0: import java.io.File; aoqi@0: import java.io.PrintWriter; aoqi@0: import java.io.StringWriter; aoqi@0: import java.net.URI; aoqi@0: import java.util.Arrays; aoqi@0: import java.util.Collections; aoqi@0: import java.util.List; aoqi@0: aoqi@0: import javax.tools.Diagnostic; aoqi@0: import javax.tools.JavaCompiler; aoqi@0: import javax.tools.JavaFileObject; aoqi@0: import javax.tools.SimpleJavaFileObject; aoqi@0: import javax.tools.StandardJavaFileManager; aoqi@0: import javax.tools.StandardLocation; aoqi@0: import javax.tools.ToolProvider; aoqi@0: import static javax.tools.Diagnostic.Kind.*; aoqi@0: aoqi@0: import com.sun.source.util.JavacTask; aoqi@0: import com.sun.tools.javac.main.Main; aoqi@0: import java.util.EnumSet; aoqi@0: import java.util.Set; aoqi@0: import java.util.regex.Matcher; aoqi@0: import java.util.regex.Pattern; aoqi@0: aoqi@0: public class DocLintTest { aoqi@0: public static void main(String... args) throws Exception { aoqi@0: new DocLintTest().run(); aoqi@0: } aoqi@0: aoqi@0: JavaCompiler javac; aoqi@0: StandardJavaFileManager fm; aoqi@0: JavaFileObject file; aoqi@0: aoqi@0: final String code = aoqi@0: /* 01 */ "/** Class comment. */\n" + aoqi@0: /* 02 */ "public class Test {\n" + aoqi@0: /* 03 */ " /** Method comment. */\n" + aoqi@0: /* 04 */ " public void method() { }\n" + aoqi@0: /* 05 */ "\n" + aoqi@0: /* 06 */ " /** Syntax < error. */\n" + aoqi@0: /* 07 */ " private void syntaxError() { }\n" + aoqi@0: /* 08 */ "\n" + aoqi@0: /* 09 */ " /** @see DoesNotExist */\n" + aoqi@0: /* 10 */ " protected void referenceError() { }\n" + aoqi@0: /* 08 */ "\n" + aoqi@0: /* 09 */ " /** @return */\n" + aoqi@0: /* 10 */ " public int emptyReturn() { return 0; }\n" + aoqi@0: /* 11 */ "}\n"; aoqi@0: aoqi@0: final String rawDiags = "-XDrawDiagnostics"; aoqi@0: private enum Message { aoqi@0: // doclint messages aoqi@0: DL_ERR6(ERROR, "Test.java:6:16: compiler.err.proc.messager: malformed HTML"), aoqi@0: DL_ERR9(ERROR, "Test.java:9:14: compiler.err.proc.messager: reference not found"), aoqi@0: DL_WRN12(WARNING, "Test.java:12:9: compiler.warn.proc.messager: no description for @return"), aoqi@0: aoqi@0: OPT_BADARG(ERROR, "invalid flag: -Xdoclint:badarg"); aoqi@0: aoqi@0: final Diagnostic.Kind kind; aoqi@0: final String text; aoqi@0: aoqi@0: static Message get(String text) { aoqi@0: for (Message m: values()) { aoqi@0: if (m.text.equals(text)) aoqi@0: return m; aoqi@0: } aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: Message(Diagnostic.Kind kind, String text) { aoqi@0: this.kind = kind; aoqi@0: this.text = text; aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public String toString() { aoqi@0: return "[" + kind + ",\"" + text + "\"]"; aoqi@0: } aoqi@0: } aoqi@0: void run() throws Exception { aoqi@0: javac = ToolProvider.getSystemJavaCompiler(); aoqi@0: fm = javac.getStandardFileManager(null, null, null); aoqi@0: fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); aoqi@0: file = new SimpleJavaFileObject(URI.create("Test.java"), JavaFileObject.Kind.SOURCE) { aoqi@0: @Override aoqi@0: public CharSequence getCharContent(boolean ignoreEncoding) { aoqi@0: return code; aoqi@0: } aoqi@0: }; aoqi@0: aoqi@0: test(Collections.emptyList(), aoqi@0: Main.Result.OK, aoqi@0: EnumSet.noneOf(Message.class)); aoqi@0: aoqi@0: test(Arrays.asList("-Xdoclint:none"), aoqi@0: Main.Result.OK, aoqi@0: EnumSet.noneOf(Message.class)); aoqi@0: aoqi@0: test(Arrays.asList(rawDiags, "-Xdoclint"), aoqi@0: Main.Result.ERROR, aoqi@0: EnumSet.of(Message.DL_ERR6, Message.DL_ERR9, Message.DL_WRN12)); aoqi@0: aoqi@0: test(Arrays.asList(rawDiags, "-Xdoclint:all/public"), aoqi@0: Main.Result.OK, aoqi@0: EnumSet.of(Message.DL_WRN12)); aoqi@0: aoqi@0: test(Arrays.asList(rawDiags, "-Xdoclint:syntax"), aoqi@0: Main.Result.ERROR, aoqi@0: EnumSet.of(Message.DL_ERR6, Message.DL_WRN12)); aoqi@0: aoqi@0: test(Arrays.asList(rawDiags, "-Xdoclint:reference"), aoqi@0: Main.Result.ERROR, aoqi@0: EnumSet.of(Message.DL_ERR9)); aoqi@0: aoqi@0: test(Arrays.asList(rawDiags, "-Xdoclint:badarg"), aoqi@0: Main.Result.CMDERR, aoqi@0: EnumSet.of(Message.OPT_BADARG)); aoqi@0: aoqi@0: if (errors > 0) aoqi@0: throw new Exception(errors + " errors occurred"); aoqi@0: } aoqi@0: aoqi@0: void test(List opts, Main.Result expectResult, Set expectMessages) { aoqi@0: System.err.println("test: " + opts); aoqi@0: StringWriter sw = new StringWriter(); aoqi@0: PrintWriter pw = new PrintWriter(sw); aoqi@0: List files = Arrays.asList(file); aoqi@0: try { aoqi@0: JavacTask t = (JavacTask) javac.getTask(pw, fm, null, opts, null, files); aoqi@0: boolean ok = t.call(); aoqi@0: pw.close(); aoqi@0: String out = sw.toString().replaceAll("[\r\n]+", "\n"); aoqi@0: if (!out.isEmpty()) aoqi@0: System.err.println(out); aoqi@0: if (ok && expectResult != Main.Result.OK) { aoqi@0: error("Compilation succeeded unexpectedly"); aoqi@0: } else if (!ok && expectResult != Main.Result.ERROR) { aoqi@0: error("Compilation failed unexpectedly"); aoqi@0: } else aoqi@0: check(out, expectMessages); aoqi@0: } catch (IllegalArgumentException e) { aoqi@0: System.err.println(e); aoqi@0: String expectOut = expectMessages.iterator().next().text; aoqi@0: if (expectResult != Main.Result.CMDERR) aoqi@0: error("unexpected exception caught"); aoqi@0: else if (!e.getMessage().equals(expectOut)) { aoqi@0: error("unexpected exception message: " aoqi@0: + e.getMessage() aoqi@0: + " expected: " + expectOut); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: // if (errors > 0) aoqi@0: // throw new Error("stop"); aoqi@0: } aoqi@0: aoqi@0: private void check(String out, Set expect) { aoqi@0: Pattern stats = Pattern.compile("^([1-9]+) (error|warning)(s?)"); aoqi@0: Set found = EnumSet.noneOf(Message.class); aoqi@0: int e = 0, w = 0; aoqi@0: if (!out.isEmpty()) { aoqi@0: for (String line: out.split("[\r\n]+")) { aoqi@0: Matcher s = stats.matcher(line); aoqi@0: if (s.matches()) { aoqi@0: int i = Integer.valueOf(s.group(1)); aoqi@0: if (s.group(2).equals("error")) aoqi@0: e++; aoqi@0: else aoqi@0: w++; aoqi@0: continue; aoqi@0: } aoqi@0: aoqi@0: Message m = Message.get(line); aoqi@0: if (m == null) aoqi@0: error("Unexpected line: " + line); aoqi@0: else aoqi@0: found.add(m); aoqi@0: } aoqi@0: } aoqi@0: for (Message m: expect) { aoqi@0: if (!found.contains(m)) aoqi@0: error("expected message not found: " + m.text); aoqi@0: } aoqi@0: for (Message m: found) { aoqi@0: if (!expect.contains(m)) aoqi@0: error("unexpected message found: " + m.text); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void error(String msg) { aoqi@0: System.err.println("Error: " + msg); aoqi@0: errors++; aoqi@0: } aoqi@0: aoqi@0: int errors; aoqi@0: }