Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java
38899 views
/*1* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.tools.doclint;2627import java.io.File;28import java.io.IOException;29import java.io.PrintWriter;30import java.util.ArrayList;31import java.util.HashSet;32import java.util.LinkedList;33import java.util.List;34import java.util.Queue;35import java.util.Set;3637import javax.lang.model.element.Name;38import javax.tools.JavaFileObject;39import javax.tools.StandardLocation;4041import com.sun.source.doctree.DocCommentTree;42import com.sun.source.tree.ClassTree;43import com.sun.source.tree.CompilationUnitTree;44import com.sun.source.tree.MethodTree;45import com.sun.source.tree.Tree;46import com.sun.source.tree.VariableTree;47import com.sun.source.util.JavacTask;48import com.sun.source.util.Plugin;49import com.sun.source.util.TaskEvent;50import com.sun.source.util.TaskListener;51import com.sun.source.util.TreePath;52import com.sun.source.util.TreePathScanner;53import com.sun.tools.javac.api.JavacTaskImpl;54import com.sun.tools.javac.api.JavacTool;55import com.sun.tools.javac.file.JavacFileManager;56import com.sun.tools.javac.main.JavaCompiler;57import com.sun.tools.javac.util.Context;5859/**60* Multi-function entry point for the doc check utility.61*62* This class can be invoked in the following ways:63* <ul>64* <li>From the command line65* <li>From javac, as a plugin66* <li>Directly, via a simple API67* </ul>68*69* <p><b>This is NOT part of any supported API.70* If you write code that depends on this, you do so at your own71* risk. This code and its internal interfaces are subject to change72* or deletion without notice.</b></p>73*/74public class DocLint implements Plugin {7576public static final String XMSGS_OPTION = "-Xmsgs";77public static final String XMSGS_CUSTOM_PREFIX = "-Xmsgs:";78private static final String STATS = "-stats";79public static final String XIMPLICIT_HEADERS = "-XimplicitHeaders:";80public static final String XCUSTOM_TAGS_PREFIX = "-XcustomTags:";81public static final String TAGS_SEPARATOR = ",";8283// <editor-fold defaultstate="collapsed" desc="Command-line entry point">84public static void main(String... args) {85DocLint dl = new DocLint();86try {87dl.run(args);88} catch (BadArgs e) {89System.err.println(e.getMessage());90System.exit(1);91} catch (IOException e) {92System.err.println(dl.localize("dc.main.ioerror", e.getLocalizedMessage()));93System.exit(2);94}95}9697// </editor-fold>9899// <editor-fold defaultstate="collapsed" desc="Simple API">100101public class BadArgs extends Exception {102private static final long serialVersionUID = 0;103BadArgs(String code, Object... args) {104super(localize(code, args));105this.code = code;106this.args = args;107}108109final String code;110final Object[] args;111}112113/**114* Simple API entry point.115*/116public void run(String... args) throws BadArgs, IOException {117PrintWriter out = new PrintWriter(System.out);118try {119run(out, args);120} finally {121out.flush();122}123}124125public void run(PrintWriter out, String... args) throws BadArgs, IOException {126env = new Env();127processArgs(args);128129if (needHelp)130showHelp(out);131132if (javacFiles.isEmpty()) {133if (!needHelp)134out.println(localize("dc.main.no.files.given"));135}136137JavacTool tool = JavacTool.create();138139JavacFileManager fm = new JavacFileManager(new Context(), false, null);140fm.setSymbolFileEnabled(false);141fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, javacBootClassPath);142fm.setLocation(StandardLocation.CLASS_PATH, javacClassPath);143fm.setLocation(StandardLocation.SOURCE_PATH, javacSourcePath);144145JavacTask task = tool.getTask(out, fm, null, javacOpts, null,146fm.getJavaFileObjectsFromFiles(javacFiles));147Iterable<? extends CompilationUnitTree> units = task.parse();148((JavacTaskImpl) task).enter();149150env.init(task);151checker = new Checker(env);152153DeclScanner ds = new DeclScanner() {154@Override155void visitDecl(Tree tree, Name name) {156TreePath p = getCurrentPath();157DocCommentTree dc = env.trees.getDocCommentTree(p);158159checker.scan(dc, p);160}161};162163ds.scan(units, null);164165reportStats(out);166167Context ctx = ((JavacTaskImpl) task).getContext();168JavaCompiler c = JavaCompiler.instance(ctx);169c.printCount("error", c.errorCount());170c.printCount("warn", c.warningCount());171}172173void processArgs(String... args) throws BadArgs {174javacOpts = new ArrayList<>();175javacFiles = new ArrayList<>();176177if (args.length == 0)178needHelp = true;179180for (int i = 0; i < args.length; i++) {181String arg = args[i];182if (arg.matches("-Xmax(errs|warns)") && i + 1 < args.length) {183if (args[++i].matches("[0-9]+")) {184javacOpts.add(arg);185javacOpts.add(args[i]);186} else {187throw new BadArgs("dc.bad.value.for.option", arg, args[i]);188}189} else if (arg.equals(STATS)) {190env.messages.setStatsEnabled(true);191} else if (arg.equals("-bootclasspath") && i + 1 < args.length) {192javacBootClassPath = splitPath(args[++i]);193} else if (arg.equals("-classpath") && i + 1 < args.length) {194javacClassPath = splitPath(args[++i]);195} else if (arg.equals("-cp") && i + 1 < args.length) {196javacClassPath = splitPath(args[++i]);197} else if (arg.equals("-sourcepath") && i + 1 < args.length) {198javacSourcePath = splitPath(args[++i]);199} else if (arg.equals(XMSGS_OPTION)) {200env.messages.setOptions(null);201} else if (arg.startsWith(XMSGS_CUSTOM_PREFIX)) {202env.messages.setOptions(arg.substring(arg.indexOf(":") + 1));203} else if (arg.startsWith(XCUSTOM_TAGS_PREFIX)) {204env.setCustomTags(arg.substring(arg.indexOf(":") + 1));205} else if (arg.equals("-h") || arg.equals("-help") || arg.equals("--help")206|| arg.equals("-?") || arg.equals("-usage")) {207needHelp = true;208} else if (arg.startsWith("-")) {209throw new BadArgs("dc.bad.option", arg);210} else {211while (i < args.length)212javacFiles.add(new File(args[i++]));213}214}215}216217void showHelp(PrintWriter out) {218String msg = localize("dc.main.usage");219for (String line: msg.split("\n"))220out.println(line);221}222223List<File> splitPath(String path) {224List<File> files = new ArrayList<>();225for (String f: path.split(File.pathSeparator)) {226if (f.length() > 0)227files.add(new File(f));228}229return files;230}231232List<File> javacBootClassPath;233List<File> javacClassPath;234List<File> javacSourcePath;235List<String> javacOpts;236List<File> javacFiles;237boolean needHelp = false;238239// </editor-fold>240241// <editor-fold defaultstate="collapsed" desc="javac Plugin">242243@Override244public String getName() {245return "doclint";246}247248@Override249public void init(JavacTask task, String... args) {250init(task, args, true);251}252253// </editor-fold>254255// <editor-fold defaultstate="collapsed" desc="Embedding API">256257public void init(JavacTask task, String[] args, boolean addTaskListener) {258env = new Env();259for (int i = 0; i < args.length; i++) {260String arg = args[i];261if (arg.equals(XMSGS_OPTION)) {262env.messages.setOptions(null);263} else if (arg.startsWith(XMSGS_CUSTOM_PREFIX)) {264env.messages.setOptions(arg.substring(arg.indexOf(":") + 1));265} else if (arg.matches(XIMPLICIT_HEADERS + "[1-6]")) {266char ch = arg.charAt(arg.length() - 1);267env.setImplicitHeaders(Character.digit(ch, 10));268} else if (arg.startsWith(XCUSTOM_TAGS_PREFIX)) {269env.setCustomTags(arg.substring(arg.indexOf(":") + 1));270} else271throw new IllegalArgumentException(arg);272}273env.init(task);274275checker = new Checker(env);276277if (addTaskListener) {278final DeclScanner ds = new DeclScanner() {279@Override280void visitDecl(Tree tree, Name name) {281TreePath p = getCurrentPath();282DocCommentTree dc = env.trees.getDocCommentTree(p);283284checker.scan(dc, p);285}286};287288TaskListener tl = new TaskListener() {289@Override290public void started(TaskEvent e) {291switch (e.getKind()) {292case ANALYZE:293CompilationUnitTree tree;294while ((tree = todo.poll()) != null)295ds.scan(tree, null);296break;297}298}299300@Override301public void finished(TaskEvent e) {302switch (e.getKind()) {303case PARSE:304todo.add(e.getCompilationUnit());305break;306}307}308309Queue<CompilationUnitTree> todo = new LinkedList<CompilationUnitTree>();310};311312task.addTaskListener(tl);313}314}315316public void scan(TreePath p) {317DocCommentTree dc = env.trees.getDocCommentTree(p);318checker.scan(dc, p);319}320321public void reportStats(PrintWriter out) {322env.messages.reportStats(out);323}324325// </editor-fold>326327Env env;328Checker checker;329330public static boolean isValidOption(String opt) {331if (opt.equals(XMSGS_OPTION))332return true;333if (opt.startsWith(XMSGS_CUSTOM_PREFIX))334return Messages.Options.isValidOptions(opt.substring(XMSGS_CUSTOM_PREFIX.length()));335return false;336}337338private String localize(String code, Object... args) {339Messages m = (env != null) ? env.messages : new Messages(null);340return m.localize(code, args);341}342343// <editor-fold defaultstate="collapsed" desc="DeclScanner">344345static abstract class DeclScanner extends TreePathScanner<Void, Void> {346abstract void visitDecl(Tree tree, Name name);347348@Override349public Void visitCompilationUnit(CompilationUnitTree tree, Void ignore) {350if (tree.getPackageName() != null) {351visitDecl(tree, null);352}353return super.visitCompilationUnit(tree, ignore);354}355356@Override357public Void visitClass(ClassTree tree, Void ignore) {358visitDecl(tree, tree.getSimpleName());359return super.visitClass(tree, ignore);360}361362@Override363public Void visitMethod(MethodTree tree, Void ignore) {364visitDecl(tree, tree.getName());365//return super.visitMethod(tree, ignore);366return null;367}368369@Override370public Void visitVariable(VariableTree tree, Void ignore) {371visitDecl(tree, tree.getName());372return super.visitVariable(tree, ignore);373}374}375376// </editor-fold>377378}379380381