All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gw.gosudoc.com.sun.tools.javadoc.main.Start Maven / Gradle / Ivy

There is a newer version: 1.18.2
Show newest version
/*
 * This file is a shadowed version of the older javadoc codebase on which gosudoc is based; borrowed from jdk 9.
 */

package gw.gosudoc.com.sun.tools.javadoc.main;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Path;
import java.util.*;

import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;

import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.main.CommandLine;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.main.Arguments;
import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
import com.sun.tools.javac.platform.PlatformDescription;
import com.sun.tools.javac.platform.PlatformUtils;
import com.sun.tools.javac.util.ClientCodeException;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Options;
import gw.gosudoc.com.sun.javadoc.LanguageVersion;
import manifold.util.JreUtil;
import manifold.util.ReflectUtil;

import static com.sun.tools.javac.code.Flags.*;

/**
 * Main program of Javadoc.
 * Previously named "Main".
 *
 *  

This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or * deletion without notice. * * @since 1.2 * @author Robert Field * @author Neal Gafter (rewrite) */ @Deprecated public class Start extends gw.gosudoc.com.sun.tools.javadoc.main.ToolOption.Helper { /** Context for this invocation. */ private final Context context; private final String defaultDocletClassName; private final ClassLoader docletParentClassLoader; private static final String javadocName = "javadoc"; private static final String standardDocletClassName = "gw.gosudoc.com.sun.tools.doclets.standard.Standard"; private final long defaultFilter = PUBLIC | PROTECTED; private final gw.gosudoc.com.sun.tools.javadoc.main.Messager messager; private gw.gosudoc.com.sun.tools.javadoc.main.DocletInvoker docletInvoker; /** * In API mode, exceptions thrown while calling the doclet are * propagated using ClientCodeException. */ private boolean apiMode; private JavaFileManager fileManager; public Start(String programName, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter, String defaultDocletClassName) { this(programName, errWriter, warnWriter, noticeWriter, defaultDocletClassName, null); } public Start(PrintWriter pw) { this(javadocName, pw, pw, pw, standardDocletClassName); } public Start(String programName, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter, String defaultDocletClassName, ClassLoader docletParentClassLoader) { context = new Context(); messager = new gw.gosudoc.com.sun.tools.javadoc.main.Messager(context, programName, errWriter, warnWriter, noticeWriter); this.defaultDocletClassName = defaultDocletClassName; this.docletParentClassLoader = docletParentClassLoader; } public Start(String programName, String defaultDocletClassName) { this(programName, defaultDocletClassName, null); } public Start(String programName, String defaultDocletClassName, ClassLoader docletParentClassLoader) { context = new Context(); messager = new gw.gosudoc.com.sun.tools.javadoc.main.Messager(context, programName); this.defaultDocletClassName = defaultDocletClassName; this.docletParentClassLoader = docletParentClassLoader; } public Start(String programName, ClassLoader docletParentClassLoader) { this(programName, standardDocletClassName, docletParentClassLoader); } public Start(String programName) { this(programName, standardDocletClassName); } public Start(ClassLoader docletParentClassLoader) { this(javadocName, docletParentClassLoader); } public Start() { this(javadocName); } public Start(Context context) { this.context = Objects.requireNonNull(context); apiMode = true; defaultDocletClassName = standardDocletClassName; docletParentClassLoader = null; Log log = context.get(Log.logKey); if (log instanceof gw.gosudoc.com.sun.tools.javadoc.main.Messager ) messager = (gw.gosudoc.com.sun.tools.javadoc.main.Messager) log; else { PrintWriter out = context.get(Log.errKey); messager = (out == null) ? new gw.gosudoc.com.sun.tools.javadoc.main.Messager(context, javadocName) : new gw.gosudoc.com.sun.tools.javadoc.main.Messager(context, javadocName, out, out, out); } } /** * Usage */ @Override void usage() { usage(true); } void usage(boolean exit) { usage("main.usage", "-help", "main.usage.foot", exit); } @Override void Xusage() { Xusage(true); } void Xusage(boolean exit) { usage("main.Xusage", "-X", "main.Xusage.foot", exit); } private void usage(String main, String doclet, String foot, boolean exit) { // RFE: it would be better to replace the following with code to // write a header, then help for each option, then a footer. messager.notice(main); // let doclet print usage information (does nothing on error) if (docletInvoker != null) { // RFE: this is a pretty bad way to get the doclet to show // help info. Moreover, the output appears on stdout, // and not on any of the standard streams passed // to javadoc, and in particular, not to the noticeWriter // But, to fix this, we need to fix the Doclet API. docletInvoker.optionLength(doclet); } if (foot != null) messager.notice(foot); if (exit) exit(); } /** * Exit */ private void exit() { messager.exit(); } /** * Main program - external wrapper */ public int begin(String... argv) { boolean ok = begin(null, argv, Collections.emptySet()); return ok ? 0 : 1; } public boolean begin(Class docletClass, Iterable options, Iterable fileObjects) { Collection opts = new ArrayList<>(); for (String opt: options) opts.add(opt); return begin(docletClass, opts.toArray(new String[opts.size()]), fileObjects); } private boolean begin(Class docletClass, String[] options, Iterable fileObjects) { boolean failed = false; try { failed = !parseAndExecute(docletClass, options, fileObjects); } catch ( gw.gosudoc.com.sun.tools.javadoc.main.Messager.ExitJavadoc exc) { // ignore, we just exit this way } catch (OutOfMemoryError ee) { messager.error( gw.gosudoc.com.sun.tools.javadoc.main.Messager.NOPOS, "main.out.of.memory"); failed = true; } catch (ClientCodeException e) { // simply rethrow these exceptions, to be caught and handled by JavadocTaskImpl throw e; } catch (Error ee) { ee.printStackTrace(System.err); messager.error( gw.gosudoc.com.sun.tools.javadoc.main.Messager.NOPOS, "main.fatal.error"); failed = true; } catch (Exception ee) { ee.printStackTrace(System.err); messager.error( gw.gosudoc.com.sun.tools.javadoc.main.Messager.NOPOS, "main.fatal.exception"); failed = true; } finally { if (fileManager != null && fileManager instanceof BaseFileManager && ((BaseFileManager) fileManager).autoClose) { try { fileManager.close(); } catch (IOException ignore) { } } messager.exitNotice(); messager.flush(); } failed |= messager.nerrors() > 0; failed |= rejectWarnings && messager.nwarnings() > 0; return !failed; } /** * Main program - internal */ private boolean parseAndExecute( Class docletClass, String[] argv, Iterable fileObjects) throws IOException { long tm = System.currentTimeMillis(); ListBuffer javaNames = new ListBuffer<>(); // Preprocess @file arguments try { if( JreUtil.isJava17orLater() ) { List args = (List)ReflectUtil.method( CommandLine.class, "parse", List.class ) .invokeStatic( Arrays.asList(argv) ); argv = args.toArray(new String[0]); } else { // Java 11 argv = CommandLine.parse(argv); } } catch (FileNotFoundException e) { messager.error( Messager.NOPOS, "main.cant.read", e.getMessage()); exit(); } catch (IOException e) { e.printStackTrace(System.err); exit(); } fileManager = context.get(JavaFileManager.class); setDocletInvoker(docletClass, fileManager, argv); compOpts = Options.instance(context); // Make sure no obsolete source/target messages are reported compOpts.put("-Xlint:-options", "-Xlint:-options"); // Parse arguments for (int i = 0 ; i < argv.length ; i++) { String arg = argv[i]; gw.gosudoc.com.sun.tools.javadoc.main.ToolOption o = gw.gosudoc.com.sun.tools.javadoc.main.ToolOption.get(arg); if (o != null) { // hack: this restriction should be removed if (o == gw.gosudoc.com.sun.tools.javadoc.main.ToolOption.LOCALE && i > 0) usageError("main.locale_first"); try { if (o.hasArg) { oneArg(argv, i++); o.process(this, argv[i]); } else { setOption(arg); o.process(this); } } catch (Option.InvalidValueException e) { usageError("main.option.invalid.value", e.getMessage()); } } else if (arg.equals("-XDaccessInternalAPI")) { // pass this hidden option down to the doclet, if it wants it if (docletInvoker.optionLength("-XDaccessInternalAPI") == 1) { setOption(arg); } } else if (arg.startsWith("-XD")) { // hidden javac options String s = arg.substring("-XD".length()); int eq = s.indexOf('='); String key = (eq < 0) ? s : s.substring(0, eq); String value = (eq < 0) ? s : s.substring(eq+1); compOpts.put(key, value); } // call doclet for its options // other arg starts with - is invalid else if (arg.startsWith("-")) { int optionLength; optionLength = docletInvoker.optionLength(arg); if (optionLength < 0) { // error already displayed exit(); } else if (optionLength == 0) { // option not found usageError("main.invalid_flag", arg); } else { // doclet added option if ((i + optionLength) > argv.length) { usageError("main.requires_argument", arg); } ListBuffer args = new ListBuffer<>(); for (int j = 0; j < optionLength-1; ++j) { args.append(argv[++i]); } setOption(arg, args.toList()); } } else { javaNames.append(arg); } } if (fileManager == null) { JavacFileManager.preRegister(context); fileManager = context.get(JavaFileManager.class); if (fileManager instanceof BaseFileManager) { ((BaseFileManager) fileManager).autoClose = true; } } if (fileManager instanceof BaseFileManager) { ((BaseFileManager) fileManager).handleOptions(fileManagerOpts); } Arguments arguments = Arguments.instance(context); arguments.init(messager.programName); arguments.allowEmpty(); arguments.validate(); String platformString = compOpts.get("--release"); if (platformString != null) { if (compOpts.isSet("-source")) { usageError("main.release.bootclasspath.conflict", "-source"); } if (fileManagerOpts.containsKey(Option.BOOT_CLASS_PATH)) { usageError("main.release.bootclasspath.conflict", Option.BOOT_CLASS_PATH.getPrimaryName()); } PlatformDescription platformDescription = PlatformUtils.lookupPlatformDescription(platformString); if (platformDescription == null) { usageError("main.unsupported.release.version", platformString); } compOpts.put(Option.SOURCE, platformDescription.getSourceVersion()); context.put(PlatformDescription.class, platformDescription); //todo: enable this somehow? // Collection platformCP = platformDescription.getPlatformPath(); // // if (platformCP != null) { // if (fileManager instanceof StandardJavaFileManager) { // StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager; // // sfm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, platformCP); // } else { // usageError("main.release.not.standard.file.manager", platformString); // } // } } compOpts.notifyListeners(); if (javaNames.isEmpty() && subPackages.isEmpty() && isEmpty(fileObjects)) { usageError("main.No_packages_or_classes_specified"); } if (!docletInvoker.validOptions(options.toList())) { // error message already displayed exit(); } JavadocTool comp = JavadocTool.make0(context); if (comp == null) return false; if (showAccess == null) { setFilter(defaultFilter); } gw.gosudoc.com.sun.javadoc.LanguageVersion languageVersion = docletInvoker.languageVersion(); RootDocImpl root = comp.getRootDocImpl( docLocale, encoding, showAccess, javaNames.toList(), options.toList(), fileObjects, breakiterator, subPackages.toList(), excludedPackages.toList(), docClasses, // legacy? languageVersion == null || languageVersion == LanguageVersion.JAVA_1_1, quiet); // release resources comp = null; // pass off control to the doclet boolean ok = root != null; if (ok) ok = docletInvoker.start(root); // We're done. if (compOpts.get("-verbose") != null) { tm = System.currentTimeMillis() - tm; messager.notice("main.done_in", Long.toString(tm)); } return ok; } private boolean isEmpty(Iterable iter) { return !iter.iterator().hasNext(); } /** * Init the doclet invoker. * The doclet class may be given explicitly, or via the -doclet option in * argv. * If the doclet class is not given explicitly, it will be loaded from * the file manager's DOCLET_PATH location, if available, or via the * -doclet path option in argv. * @param docletClass The doclet class. May be null. * @param fileManager The file manager used to get the class loader to load * the doclet class if required. May be null. * @param argv Args containing -doclet and -docletpath, in case they are required. */ private void setDocletInvoker(Class docletClass, JavaFileManager fileManager, String[] argv) { boolean exportInternalAPI = false; String docletClassName = null; String docletPath = null; // Parse doclet specifying arguments for (int i = 0 ; i < argv.length ; i++) { String arg = argv[i]; if (arg.equals( ToolOption.DOCLET.opt)) { oneArg(argv, i++); if (docletClassName != null) { usageError("main.more_than_one_doclet_specified_0_and_1", docletClassName, argv[i]); } docletClassName = argv[i]; } else if (arg.equals( ToolOption.DOCLETPATH.opt)) { oneArg(argv, i++); if (docletPath == null) { docletPath = argv[i]; } else { docletPath += File.pathSeparator + argv[i]; } } else if (arg.equals("-XDaccessInternalAPI")) { exportInternalAPI = true; } } if (docletClass != null) { // TODO, check no -doclet, -docletpath docletInvoker = new DocletInvoker(messager, docletClass, apiMode, exportInternalAPI); } else { if (docletClassName == null) { docletClassName = defaultDocletClassName; } // attempt to find doclet docletInvoker = new DocletInvoker(messager, fileManager, docletClassName, docletPath, docletParentClassLoader, apiMode, exportInternalAPI); } } /** * Set one arg option. * Error and exit if one argument is not provided. */ private void oneArg(String[] args, int index) { if ((index + 1) < args.length) { setOption(args[index], args[index+1]); } else { usageError("main.requires_argument", args[index]); } } @Override void usageError(String key, Object... args) { messager.error( Messager.NOPOS, key, args); usage(true); } /** * indicate an option with no arguments was given. */ private void setOption(String opt) { String[] option = { opt }; options.append(option); } /** * indicate an option with one argument was given. */ private void setOption(String opt, String argument) { String[] option = { opt, argument }; options.append(option); } /** * indicate an option with the specified list of arguments was given. */ private void setOption(String opt, List arguments) { String[] args = new String[arguments.length() + 1]; int k = 0; args[k++] = opt; for (List i = arguments; i.nonEmpty(); i=i.tail) { args[k++] = i.head; } options.append(args); } @Override OptionHelper getOptionHelper() { return new GrumpyHelper(messager) { @Override public String get( Option option) { return compOpts.get(option); } @Override public void put(String name, String value) { compOpts.put(name, value); } }; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy