Arguments.java revision 4171:77a2d6c1f321
1139804Simp/* 21541Srgrimes * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. 31541Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41541Srgrimes * 51541Srgrimes * This code is free software; you can redistribute it and/or modify it 61541Srgrimes * under the terms of the GNU General Public License version 2 only, as 71541Srgrimes * published by the Free Software Foundation. Oracle designates this 81541Srgrimes * particular file as subject to the "Classpath" exception as provided 91541Srgrimes * by Oracle in the LICENSE file that accompanied this code. 101541Srgrimes * 111541Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT 121541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 131541Srgrimes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 141541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that 151541Srgrimes * accompanied this code). 161541Srgrimes * 171541Srgrimes * You should have received a copy of the GNU General Public License version 181541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation, 191541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 201541Srgrimes * 211541Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 221541Srgrimes * or visit www.oracle.com if you need additional information or have any 231541Srgrimes * questions. 241541Srgrimes */ 251541Srgrimes 261541Srgrimespackage com.sun.tools.javac.main; 271541Srgrimes 281541Srgrimesimport java.io.IOException; 291541Srgrimesimport java.nio.file.Files; 301541Srgrimesimport java.nio.file.Path; 311541Srgrimesimport java.nio.file.Paths; 32116182Sobrienimport java.util.Arrays; 33116182Sobrienimport java.util.Collection; 34116182Sobrienimport java.util.Collections; 35101007Srwatsonimport java.util.EnumSet; 3677572Sobrienimport java.util.HashSet; 37113490Ssilbyimport java.util.Iterator; 38101007Srwatsonimport java.util.LinkedHashMap; 391541Srgrimesimport java.util.LinkedHashSet; 401541Srgrimesimport java.util.Map; 4176166Smarkmimport java.util.Set; 42125296Ssilbyimport java.util.function.Predicate; 4376166Smarkmimport java.util.regex.Matcher; 44101173Srwatsonimport java.util.regex.Pattern; 4532036Sbdeimport java.util.stream.Stream; 461541Srgrimes 4723081Swollmanimport javax.lang.model.SourceVersion; 481541Srgrimesimport javax.tools.JavaFileManager; 491541Srgrimesimport javax.tools.JavaFileManager.Location; 50125296Ssilbyimport javax.tools.JavaFileObject; 5176166Smarkmimport javax.tools.JavaFileObject.Kind; 529759Sbdeimport javax.tools.StandardJavaFileManager; 539759Sbdeimport javax.tools.StandardLocation; 549759Sbde 559759Sbdeimport com.sun.tools.doclint.DocLint; 56116455Ssilbyimport com.sun.tools.javac.code.Lint.LintCategory; 57112777Ssilbyimport com.sun.tools.javac.code.Source; 58112777Ssilbyimport com.sun.tools.javac.file.BaseFileManager; 59112777Ssilbyimport com.sun.tools.javac.file.JavacFileManager; 60112777Ssilbyimport com.sun.tools.javac.jvm.Profile; 61113490Ssilbyimport com.sun.tools.javac.jvm.Target; 62113490Ssilbyimport com.sun.tools.javac.main.OptionHelper.GrumpyHelper; 631541Srgrimesimport com.sun.tools.javac.platform.PlatformDescription; 6466475Sbmilekicimport com.sun.tools.javac.platform.PlatformUtils; 6566475Sbmilekicimport com.sun.tools.javac.resources.CompilerProperties.Errors; 6666475Sbmilekicimport com.sun.tools.javac.resources.CompilerProperties.Warnings; 6744078Sdfrimport com.sun.tools.javac.util.Context; 6823081Swollmanimport com.sun.tools.javac.util.JCDiagnostic; 6923081Swollmanimport com.sun.tools.javac.util.List; 7023081Swollmanimport com.sun.tools.javac.util.ListBuffer; 7123081Swollmanimport com.sun.tools.javac.util.Log; 7223081Swollmanimport com.sun.tools.javac.util.Log.PrefixKind; 7323081Swollmanimport com.sun.tools.javac.util.Log.WriterKind; 7423081Swollmanimport com.sun.tools.javac.util.Options; 75116455Ssilbyimport com.sun.tools.javac.util.PropagatedException; 76112777Ssilby 77112777Ssilby/** 78112777Ssilby * Shared option and argument handling for command line and API usage of javac. 79112777Ssilby */ 80112777Ssilbypublic class Arguments { 81112777Ssilby 82112777Ssilby /** 83112777Ssilby * The context key for the arguments. 84113490Ssilby */ 85113490Ssilby public static final Context.Key<Arguments> argsKey = new Context.Key<>(); 86113490Ssilby 8775112Sbmilekic private String ownName; 881541Srgrimes private Set<String> classNames; 89129906Sbmilekic private Set<Path> files; 90129906Sbmilekic private Map<Option, String> deferredFileManagerOptions; 91141616Sphk private Set<JavaFileObject> fileObjects; 92129906Sbmilekic private boolean emptyAllowed; 93129906Sbmilekic private final Options options; 94129906Sbmilekic 95129906Sbmilekic private JavaFileManager fileManager; 96129906Sbmilekic private final Log log; 97129906Sbmilekic private final Context context; 98129906Sbmilekic 99129906Sbmilekic private enum ErrorMode { ILLEGAL_ARGUMENT, ILLEGAL_STATE, LOG }; 100129906Sbmilekic private ErrorMode errorMode; 101129906Sbmilekic private boolean errors; 102129906Sbmilekic 103129906Sbmilekic /** 104129906Sbmilekic * Gets the Arguments instance for this context. 105129906Sbmilekic * 106129906Sbmilekic * @param context the content 107129906Sbmilekic * @return the Arguments instance for this context. 108129906Sbmilekic */ 109129906Sbmilekic public static Arguments instance(Context context) { 110129906Sbmilekic Arguments instance = context.get(argsKey); 111129906Sbmilekic if (instance == null) { 112129906Sbmilekic instance = new Arguments(context); 113129906Sbmilekic } 114129906Sbmilekic return instance; 115129906Sbmilekic } 116129906Sbmilekic 117129906Sbmilekic protected Arguments(Context context) { 118129906Sbmilekic context.put(argsKey, this); 119129906Sbmilekic options = Options.instance(context); 120129906Sbmilekic log = Log.instance(context); 121129906Sbmilekic this.context = context; 122129906Sbmilekic 123129906Sbmilekic // Ideally, we could init this here and update/configure it as 124129906Sbmilekic // needed, but right now, initializing a file manager triggers 125129906Sbmilekic // initialization of other items in the context, such as Lint 126130271Smux // and FSInfo, which should not be initialized until after 127129906Sbmilekic // processArgs 128129906Sbmilekic // fileManager = context.get(JavaFileManager.class); 129129906Sbmilekic } 130129906Sbmilekic 131129906Sbmilekic private final OptionHelper cmdLineHelper = new OptionHelper() { 132129906Sbmilekic @Override 133129906Sbmilekic public String get(Option option) { 134129906Sbmilekic return options.get(option); 135129906Sbmilekic } 136129906Sbmilekic 137129906Sbmilekic @Override 138129906Sbmilekic public void put(String name, String value) { 139129906Sbmilekic options.put(name, value); 140129906Sbmilekic } 141129906Sbmilekic 142129906Sbmilekic @Override 143129906Sbmilekic public void remove(String name) { 144129906Sbmilekic options.remove(name); 145129906Sbmilekic } 146129906Sbmilekic 147129906Sbmilekic @Override 148129906Sbmilekic public boolean handleFileManagerOption(Option option, String value) { 149129906Sbmilekic options.put(option, value); 150129906Sbmilekic deferredFileManagerOptions.put(option, value); 151129906Sbmilekic return true; 152129906Sbmilekic } 153129906Sbmilekic 154129906Sbmilekic @Override 155129906Sbmilekic public Log getLog() { 156129906Sbmilekic return log; 157129906Sbmilekic } 158129906Sbmilekic 159129906Sbmilekic @Override 160129906Sbmilekic public String getOwnName() { 161129906Sbmilekic return ownName; 162129906Sbmilekic } 163129906Sbmilekic 164129906Sbmilekic @Override 165129906Sbmilekic public void addFile(Path p) { 166129906Sbmilekic files.add(p); 167129906Sbmilekic } 168129906Sbmilekic 169129906Sbmilekic @Override 170129906Sbmilekic public void addClassName(String s) { 171129906Sbmilekic classNames.add(s); 172129906Sbmilekic } 173129906Sbmilekic 174129906Sbmilekic }; 175129906Sbmilekic 176129906Sbmilekic /** 177129906Sbmilekic * Initializes this Args instance with a set of command line args. 178129906Sbmilekic * The args will be processed in conjunction with the full set of 179129906Sbmilekic * command line options, including -help, -version etc. 180129906Sbmilekic * The args may also contain class names and filenames. 181129906Sbmilekic * Any errors during this call, and later during validate, will be reported 182129906Sbmilekic * to the log. 183129906Sbmilekic * @param ownName the name of this tool; used to prefix messages 184129906Sbmilekic * @param args the args to be processed 185129906Sbmilekic */ 186129906Sbmilekic public void init(String ownName, String... args) { 187129906Sbmilekic this.ownName = ownName; 188129906Sbmilekic errorMode = ErrorMode.LOG; 189129906Sbmilekic files = new LinkedHashSet<>(); 190129906Sbmilekic deferredFileManagerOptions = new LinkedHashMap<>(); 191129906Sbmilekic fileObjects = null; 192129906Sbmilekic classNames = new LinkedHashSet<>(); 193129906Sbmilekic processArgs(List.from(args), Option.getJavaCompilerOptions(), cmdLineHelper, true, false); 194129906Sbmilekic if (errors) { 195129906Sbmilekic log.printLines(PrefixKind.JAVAC, "msg.usage", ownName); 196129906Sbmilekic } 197129906Sbmilekic } 198129906Sbmilekic 199129906Sbmilekic private final OptionHelper apiHelper = new GrumpyHelper(null) { 200129906Sbmilekic @Override 201129906Sbmilekic public String get(Option option) { 202143188Salc return options.get(option); 203129906Sbmilekic } 204129906Sbmilekic 205129906Sbmilekic @Override 206129906Sbmilekic public void put(String name, String value) { 207129906Sbmilekic options.put(name, value); 208129906Sbmilekic } 209129906Sbmilekic 210129906Sbmilekic @Override 211129906Sbmilekic public void remove(String name) { 212129906Sbmilekic options.remove(name); 213129906Sbmilekic } 214129906Sbmilekic 215129906Sbmilekic @Override 216129906Sbmilekic public Log getLog() { 217129906Sbmilekic return Arguments.this.log; 218129906Sbmilekic } 219129906Sbmilekic }; 220129906Sbmilekic 221129906Sbmilekic /** 222129906Sbmilekic * Initializes this Args instance with the parameters for a JavacTask. 223129906Sbmilekic * The options will be processed in conjunction with the restricted set 224130289Sbmilekic * of tool options, which does not include -help, -version, etc, 225141668Sbmilekic * nor does it include classes and filenames, which should be specified 226129906Sbmilekic * separately. 227141668Sbmilekic * File manager options are handled directly by the file manager. 228141668Sbmilekic * Any errors found while processing individual args will be reported 229141668Sbmilekic * via IllegalArgumentException. 230141668Sbmilekic * Any subsequent errors during validate will be reported via IllegalStateException. 231141668Sbmilekic * @param ownName the name of this tool; used to prefix messages 232141668Sbmilekic * @param options the options to be processed 233130289Sbmilekic * @param classNames the classes to be subject to annotation processing 234130289Sbmilekic * @param files the files to be compiled 235130289Sbmilekic */ 236130289Sbmilekic public void init(String ownName, 237130289Sbmilekic Iterable<String> options, 238141668Sbmilekic Iterable<String> classNames, 239143188Salc Iterable<? extends JavaFileObject> files) { 240130289Sbmilekic this.ownName = ownName; 241141668Sbmilekic this.classNames = toSet(classNames); 242141668Sbmilekic this.fileObjects = toSet(files); 243130289Sbmilekic this.files = null; 244129906Sbmilekic errorMode = ErrorMode.ILLEGAL_ARGUMENT; 245141668Sbmilekic if (options != null) { 246141668Sbmilekic processArgs(toList(options), Option.getJavacToolOptions(), apiHelper, false, true); 247141668Sbmilekic } 248141668Sbmilekic errorMode = ErrorMode.ILLEGAL_STATE; 249141668Sbmilekic } 250141668Sbmilekic 251141668Sbmilekic /** 252141668Sbmilekic * Minimal initialization for tools, like javadoc, 253141668Sbmilekic * to be able to process javac options for themselves, 254141668Sbmilekic * and then call validate. 255141668Sbmilekic * @param ownName the name of this tool; used to prefix messages 256141668Sbmilekic */ 257141668Sbmilekic public void init(String ownName) { 258141668Sbmilekic this.ownName = ownName; 259141668Sbmilekic errorMode = ErrorMode.LOG; 260141668Sbmilekic } 261141668Sbmilekic 262143188Salc /** 263143188Salc * Gets the files to be compiled. 264141668Sbmilekic * @return the files to be compiled 265141668Sbmilekic */ 266141668Sbmilekic public Set<JavaFileObject> getFileObjects() { 267141668Sbmilekic if (fileObjects == null) { 268141668Sbmilekic fileObjects = new LinkedHashSet<>(); 269130357Sbmilekic } 270129906Sbmilekic if (files != null) { 271129906Sbmilekic JavacFileManager jfm = (JavacFileManager) getFileManager(); 272129906Sbmilekic for (JavaFileObject fo: jfm.getJavaFileObjectsFromPaths(files)) 273149598Sandre fileObjects.add(fo); 274149598Sandre } 275149598Sandre return fileObjects; 276149598Sandre } 277149598Sandre 278149598Sandre /** 279149598Sandre * Gets the classes to be subject to annotation processing. 280149598Sandre * @return the classes to be subject to annotation processing 281149598Sandre */ 282149598Sandre public Set<String> getClassNames() { 283149598Sandre return classNames; 284149598Sandre } 285149598Sandre 286149598Sandre /** 287149598Sandre * Handles the {@code --release} option. 288149598Sandre * 289149598Sandre * @param additionalOptions a predicate to handle additional options implied by the 290149598Sandre * {@code --release} option. The predicate should return true if all the additional 291149598Sandre * options were processed successfully. 292149598Sandre * @return true if successful, false otherwise 293149598Sandre */ 294149598Sandre public boolean handleReleaseOptions(Predicate<Iterable<String>> additionalOptions) { 295149598Sandre String platformString = options.get(Option.RELEASE); 296149598Sandre 297149599Sandre checkOptionAllowed(platformString == null, 298149599Sandre option -> error("err.release.bootclasspath.conflict", option.getPrimaryName()), 299149599Sandre Option.BOOT_CLASS_PATH, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND, 300149599Sandre Option.XBOOTCLASSPATH_PREPEND, 301149599Sandre Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS, 302149599Sandre Option.EXTDIRS, Option.DJAVA_EXT_DIRS, 303149599Sandre Option.SOURCE, Option.TARGET, 304149599Sandre Option.SYSTEM, Option.UPGRADE_MODULE_PATH); 305149599Sandre 306149599Sandre if (platformString != null) { 307149599Sandre PlatformDescription platformDescription = PlatformUtils.lookupPlatformDescription(platformString); 308149599Sandre 309149599Sandre if (platformDescription == null) { 310149599Sandre error("err.unsupported.release.version", platformString); 311149599Sandre return false; 312149599Sandre } 313149599Sandre 314149599Sandre options.put(Option.SOURCE, platformDescription.getSourceVersion()); 315149599Sandre options.put(Option.TARGET, platformDescription.getTargetVersion()); 316149599Sandre 317149599Sandre context.put(PlatformDescription.class, platformDescription); 318149599Sandre 319149599Sandre if (!additionalOptions.test(platformDescription.getAdditionalOptions())) 320149599Sandre return false; 321149599Sandre 322149599Sandre Collection<Path> platformCP = platformDescription.getPlatformPath(); 323149599Sandre 324149599Sandre if (platformCP != null) { 325149599Sandre JavaFileManager fm = getFileManager(); 326149599Sandre 327149599Sandre if (!(fm instanceof StandardJavaFileManager)) { 328149599Sandre error("err.release.not.standard.file.manager"); 329149599Sandre return false; 330149599Sandre } 331149599Sandre 332149599Sandre try { 333149599Sandre StandardJavaFileManager sfm = (StandardJavaFileManager) fm; 334149599Sandre 335149599Sandre if (Source.instance(context).allowModules()) { 336149599Sandre sfm.handleOption("--system", Arrays.asList("none").iterator()); 337149599Sandre sfm.setLocationFromPaths(StandardLocation.UPGRADE_MODULE_PATH, platformCP); 338149599Sandre } else { 339149599Sandre sfm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, platformCP); 340149599Sandre } 341149599Sandre } catch (IOException ex) { 342149599Sandre log.printLines(PrefixKind.JAVAC, "msg.io"); 343149599Sandre ex.printStackTrace(log.getWriter(WriterKind.NOTICE)); 344149599Sandre return false; 345149599Sandre } 346149599Sandre } 347149599Sandre } 348149599Sandre 349149599Sandre return true; 350149599Sandre } 351149599Sandre 352149599Sandre /** 353149599Sandre * Processes strings containing options and operands. 354149599Sandre * @param args the strings to be processed 355149599Sandre * @param allowableOpts the set of option declarations that are applicable 356149599Sandre * @param helper a help for use by Option.process 357149599Sandre * @param allowOperands whether or not to check for files and classes 358149599Sandre * @param checkFileManager whether or not to check if the file manager can handle 359149599Sandre * options which are not recognized by any of allowableOpts 360149599Sandre * @return true if all the strings were successfully processed; false otherwise 361149599Sandre * @throws IllegalArgumentException if a problem occurs and errorMode is set to 362149599Sandre * ILLEGAL_ARGUMENT 363149599Sandre */ 364149599Sandre private boolean processArgs(Iterable<String> args, 365149599Sandre Set<Option> allowableOpts, OptionHelper helper, 366149599Sandre boolean allowOperands, boolean checkFileManager) { 367149599Sandre if (!doProcessArgs(args, allowableOpts, helper, allowOperands, checkFileManager)) 368149599Sandre return false; 369149599Sandre 370149599Sandre if (!handleReleaseOptions(extra -> doProcessArgs(extra, allowableOpts, helper, allowOperands, checkFileManager))) 371149599Sandre return false; 372149599Sandre 373149599Sandre options.notifyListeners(); 374149599Sandre 375149599Sandre return true; 376149599Sandre } 377149599Sandre 378149599Sandre private boolean doProcessArgs(Iterable<String> args, 379149599Sandre Set<Option> allowableOpts, OptionHelper helper, 380149599Sandre boolean allowOperands, boolean checkFileManager) { 381149599Sandre JavaFileManager fm = checkFileManager ? getFileManager() : null; 382149599Sandre Iterator<String> argIter = args.iterator(); 383149599Sandre while (argIter.hasNext()) { 384149599Sandre String arg = argIter.next(); 385149599Sandre if (arg.isEmpty()) { 386149599Sandre error("err.invalid.flag", arg); 387149599Sandre return false; 388149599Sandre } 389149599Sandre 390149599Sandre Option option = null; 391149599Sandre 392108466Ssam // first, check the provided set of javac options 393100960Srwatson if (arg.startsWith("-")) { 394100960Srwatson option = Option.lookup(arg, allowableOpts); 395100960Srwatson } else if (allowOperands && Option.SOURCEFILE.matches(arg)) { 396108466Ssam option = Option.SOURCEFILE; 397100960Srwatson } 398100960Srwatson 399100960Srwatson if (option != null) { 400108466Ssam try { 401113255Sdes option.handleOption(helper, arg, argIter); 402113487Srwatson } catch (Option.InvalidValueException e) { 403108466Ssam error(e); 404108466Ssam return false; 405100960Srwatson } 406101007Srwatson continue; 407113487Srwatson } 408113487Srwatson 409113487Srwatson // check file manager option 410101007Srwatson if (fm != null && fm.handleOption(arg, argIter)) { 411113487Srwatson continue; 412101007Srwatson } 413143302Ssam 414143302Ssam // none of the above 415143302Ssam error("err.invalid.flag", arg); 416108466Ssam return false; 417108466Ssam } 418108466Ssam 419108466Ssam return true; 420108466Ssam } 421108466Ssam 422108466Ssam /** 423108466Ssam * Validates the overall consistency of the options and operands 424108466Ssam * processed by processOptions. 425108466Ssam * @return true if all args are successfully validated; false otherwise. 426108466Ssam * @throws IllegalStateException if a problem is found and errorMode is set to 427108466Ssam * ILLEGAL_STATE 428108466Ssam */ 429108466Ssam public boolean validate() { 430108466Ssam JavaFileManager fm = getFileManager(); 431108466Ssam if (options.isSet(Option.MODULE)) { 432108466Ssam if (!fm.hasLocation(StandardLocation.CLASS_OUTPUT)) { 433108466Ssam log.error(Errors.OutputDirMustBeSpecifiedWithDashMOption); 434108466Ssam } else if (!fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) { 435108466Ssam log.error(Errors.ModulesourcepathMustBeSpecifiedWithDashMOption); 436108466Ssam } else { 437108466Ssam java.util.List<String> modules = Arrays.asList(options.get(Option.MODULE).split(",")); 438113255Sdes try { 439113487Srwatson for (String module : modules) { 440108466Ssam Location sourceLoc = fm.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH, module); 441108466Ssam if (sourceLoc == null) { 442132488Salfred log.error(Errors.ModuleNotFoundInModuleSourcePath(module)); 443108466Ssam } else { 444108466Ssam Location classLoc = fm.getLocationForModule(StandardLocation.CLASS_OUTPUT, module); 445113487Srwatson 446108466Ssam for (JavaFileObject file : fm.list(sourceLoc, "", EnumSet.of(JavaFileObject.Kind.SOURCE), true)) { 447112733Ssilby String className = fm.inferBinaryName(sourceLoc, file); 448112733Ssilby JavaFileObject classFile = fm.getJavaFileForInput(classLoc, className, Kind.CLASS); 449112733Ssilby 450100960Srwatson if (classFile == null || classFile.getLastModified() < file.getLastModified()) { 451108466Ssam if (fileObjects == null) 452113480Srwatson fileObjects = new HashSet<>(); 453100960Srwatson fileObjects.add(file); 454100960Srwatson } 455100960Srwatson } 4561541Srgrimes } 4571541Srgrimes } 4581541Srgrimes } catch (IOException ex) { 4591541Srgrimes log.printLines(PrefixKind.JAVAC, "msg.io"); 4601541Srgrimes ex.printStackTrace(log.getWriter(WriterKind.NOTICE)); 46172356Sbmilekic return false; 4621541Srgrimes } 4631541Srgrimes } 4641541Srgrimes } 465117770Ssilby 466117770Ssilby if (isEmpty()) { 467117770Ssilby // It is allowed to compile nothing if just asking for help or version info. 468117770Ssilby // But also note that none of these options are supported in API mode. 46972356Sbmilekic if (options.isSet(Option.HELP) 4701541Srgrimes || options.isSet(Option.X) 47172356Sbmilekic || options.isSet(Option.VERSION) 4721541Srgrimes || options.isSet(Option.FULLVERSION) 473113487Srwatson || options.isSet(Option.MODULE)) { 474108466Ssam return true; 4751541Srgrimes } 4761541Srgrimes 4771541Srgrimes if (!emptyAllowed) { 4781541Srgrimes if (!errors) { 4791541Srgrimes if (JavaCompiler.explicitAnnotationProcessingRequested(options)) { 4801541Srgrimes error("err.no.source.files.classes"); 4811541Srgrimes } else { 4821541Srgrimes error("err.no.source.files"); 4831541Srgrimes } 4841541Srgrimes } 4851541Srgrimes return false; 486111119Simp } 48754002Sarchie } 48854002Sarchie 4891541Srgrimes if (!checkDirectory(Option.D)) { 4901541Srgrimes return false; 49172356Sbmilekic } 4921541Srgrimes if (!checkDirectory(Option.S)) { 49372356Sbmilekic return false; 49472356Sbmilekic } 4951541Srgrimes if (!checkDirectory(Option.H)) { 4961541Srgrimes return false; 4971541Srgrimes } 49852201Salfred 49952201Salfred // The following checks are to help avoid accidental confusion between 500132488Salfred // directories of modules and exploded module directories. 5011541Srgrimes if (fm instanceof StandardJavaFileManager) { 5021541Srgrimes StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager; 5031541Srgrimes if (sfm.hasLocation(StandardLocation.CLASS_OUTPUT)) { 50452201Salfred Path outDir = sfm.getLocationAsPaths(StandardLocation.CLASS_OUTPUT).iterator().next(); 5051541Srgrimes if (sfm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) { 5061541Srgrimes // multi-module mode 5071541Srgrimes if (Files.exists(outDir.resolve("module-info.class"))) { 5081541Srgrimes log.error(Errors.MultiModuleOutdirCannotBeExplodedModule(outDir)); 5091541Srgrimes } 5101541Srgrimes } else { 5111541Srgrimes // single-module or legacy mode 5121541Srgrimes boolean lintPaths = options.isUnset(Option.XLINT_CUSTOM, 51372356Sbmilekic "-" + LintCategory.PATH.option); 51452201Salfred if (lintPaths) { 51552201Salfred Path outDirParent = outDir.getParent(); 5161541Srgrimes if (outDirParent != null && Files.exists(outDirParent.resolve("module-info.class"))) { 5171541Srgrimes log.warning(LintCategory.PATH, Warnings.OutdirIsInExplodedModule(outDir)); 518117770Ssilby } 519117770Ssilby } 520117770Ssilby } 521117770Ssilby } 5221541Srgrimes } 52372356Sbmilekic 5241541Srgrimes 5251541Srgrimes String sourceString = options.get(Option.SOURCE); 526108466Ssam Source source = (sourceString != null) 527108466Ssam ? Source.lookup(sourceString) 5281541Srgrimes : Source.DEFAULT; 5291541Srgrimes String targetString = options.get(Option.TARGET); 5301541Srgrimes Target target = (targetString != null) 5311541Srgrimes ? Target.lookup(targetString) 5321541Srgrimes : Target.DEFAULT; 5331541Srgrimes 5341541Srgrimes // We don't check source/target consistency for CLDC, as J2ME 5351541Srgrimes // profiles are not aligned with J2SE targets; moreover, a 5361541Srgrimes // single CLDC target may have many profiles. In addition, 5371541Srgrimes // this is needed for the continued functioning of the JSR14 5381541Srgrimes // prototype. 53964837Sdwmalone if (Character.isDigit(target.name.charAt(0))) { 540141668Sbmilekic if (target.compareTo(source.requiredTarget()) < 0) { 5411541Srgrimes if (targetString != null) { 5421541Srgrimes if (sourceString == null) { 543103569Sbmilekic error("warn.target.default.source.conflict", 5441541Srgrimes targetString, 5451541Srgrimes source.requiredTarget().name); 5461541Srgrimes } else { 5471541Srgrimes error("warn.source.target.conflict", 5481541Srgrimes sourceString, 5491541Srgrimes source.requiredTarget().name); 55078592Sbmilekic } 55178592Sbmilekic return false; 55278592Sbmilekic } else { 5531541Srgrimes target = source.requiredTarget(); 5541541Srgrimes options.put("-target", target.name); 5551541Srgrimes } 55678592Sbmilekic } 55772356Sbmilekic } 5581541Srgrimes 5591541Srgrimes String profileString = options.get(Option.PROFILE); 5601541Srgrimes if (profileString != null) { 561149602Sandre Profile profile = Profile.lookup(profileString); 562149602Sandre if (!profile.isValid(target)) { 563149602Sandre error("warn.profile.target.conflict", profileString, target.name); 564149602Sandre } 565149602Sandre 566149602Sandre // This check is only effective in command line mode, 567149602Sandre // where the file manager options are added to options 568149602Sandre if (options.get(Option.BOOT_CLASS_PATH) != null) { 569149602Sandre error("err.profile.bootclasspath.conflict"); 570149602Sandre } 571149602Sandre } 572149602Sandre 573149602Sandre if (options.isSet(Option.SOURCE_PATH) && options.isSet(Option.MODULE_SOURCE_PATH)) { 574149602Sandre error("err.sourcepath.modulesourcepath.conflict"); 575149602Sandre } 576149602Sandre 577149602Sandre boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option); 578149602Sandre if (lintOptions && source.compareTo(Source.DEFAULT) < 0 && !options.isSet(Option.RELEASE)) { 579149602Sandre if (fm instanceof BaseFileManager) { 580149602Sandre if (((BaseFileManager) fm).isDefaultBootClassPath()) 581149602Sandre log.warning(LintCategory.OPTIONS, "source.no.bootclasspath", source.name); 582149602Sandre } 583149602Sandre } 584149602Sandre 585149602Sandre boolean obsoleteOptionFound = false; 586149602Sandre 587149602Sandre if (source.compareTo(Source.MIN) < 0) { 588149602Sandre log.error(Errors.OptionRemovedSource(source.name, Source.MIN.name)); 589149602Sandre } else if (source == Source.MIN && lintOptions) { 590149602Sandre log.warning(LintCategory.OPTIONS, Warnings.OptionObsoleteSource(source.name)); 591149602Sandre obsoleteOptionFound = true; 592149602Sandre } 593149602Sandre 594149602Sandre if (target.compareTo(Target.MIN) < 0) { 595149602Sandre log.error(Errors.OptionRemovedTarget(target.name, Target.MIN.name)); 596149602Sandre } else if (target == Target.MIN && lintOptions) { 597149602Sandre log.warning(LintCategory.OPTIONS, Warnings.OptionObsoleteTarget(target.name)); 598149602Sandre obsoleteOptionFound = true; 599149602Sandre } 600149602Sandre 601149602Sandre final Target t = target; 602149602Sandre checkOptionAllowed(t.compareTo(Target.JDK1_8) <= 0, 603149602Sandre option -> error("err.option.not.allowed.with.target", option.getPrimaryName(), t.name), 604149602Sandre Option.BOOT_CLASS_PATH, 605149602Sandre Option.XBOOTCLASSPATH_PREPEND, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND, 606149602Sandre Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS, 607149602Sandre Option.EXTDIRS, Option.DJAVA_EXT_DIRS, 608149602Sandre Option.PROFILE); 609149602Sandre 610149602Sandre checkOptionAllowed(t.compareTo(Target.JDK1_9) >= 0, 611149602Sandre option -> error("err.option.not.allowed.with.target", option.getPrimaryName(), t.name), 612149602Sandre Option.MODULE_SOURCE_PATH, Option.UPGRADE_MODULE_PATH, 613149602Sandre Option.SYSTEM, Option.MODULE_PATH, Option.ADD_MODULES, 614149602Sandre Option.ADD_EXPORTS, Option.ADD_OPENS, Option.ADD_READS, 615149602Sandre Option.LIMIT_MODULES, 616149602Sandre Option.PATCH_MODULE); 617149602Sandre 618149602Sandre if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) { 619149602Sandre if (!options.isSet(Option.PROC, "only") 620149602Sandre && !fm.hasLocation(StandardLocation.CLASS_OUTPUT)) { 621149602Sandre log.error(Errors.NoOutputDir); 622149602Sandre } 623149602Sandre } 624149602Sandre 625149602Sandre if (fm.hasLocation(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH) && 626149602Sandre fm.hasLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH)) { 627149602Sandre log.error(Errors.ProcessorpathNoProcessormodulepath); 628149602Sandre } 629149602Sandre 630149602Sandre if (obsoleteOptionFound && lintOptions) { 631149602Sandre log.warning(LintCategory.OPTIONS, "option.obsolete.suppression"); 632149602Sandre } 633149602Sandre 634149602Sandre SourceVersion sv = Source.toSourceVersion(source); 635149602Sandre validateAddExports(sv); 636149602Sandre validateAddModules(sv); 637149602Sandre validateAddReads(sv); 638149602Sandre validateLimitModules(sv); 639149602Sandre validateDefaultModuleForCreatedFiles(sv); 640149602Sandre 641149602Sandre if (lintOptions && options.isSet(Option.ADD_OPENS)) { 642149602Sandre log.warning(LintCategory.OPTIONS, Warnings.AddopensIgnored); 643149602Sandre } 644149602Sandre 645149602Sandre return !errors && (log.nerrors == 0); 646149602Sandre } 647149602Sandre 648149602Sandre private void validateAddExports(SourceVersion sv) { 649149602Sandre String addExports = options.get(Option.ADD_EXPORTS); 650149602Sandre if (addExports != null) { 651149602Sandre // Each entry must be of the form sourceModule/sourcePackage=target-list where 652149602Sandre // target-list is a comma separated list of module or ALL-UNNAMED. 653149602Sandre // Empty items in the target-list are ignored. 654149602Sandre // There must be at least one item in the list; this is handled in Option.ADD_EXPORTS. 655149602Sandre Pattern p = Option.ADD_EXPORTS.getPattern(); 656149602Sandre for (String e : addExports.split("\0")) { 657149602Sandre Matcher m = p.matcher(e); 658149602Sandre if (m.matches()) { 659149602Sandre String sourceModuleName = m.group(1); 660149602Sandre if (!SourceVersion.isName(sourceModuleName, sv)) { 661149602Sandre // syntactically invalid source name: e.g. --add-exports m!/p1=m2 662149602Sandre log.warning(Warnings.BadNameForOption(Option.ADD_EXPORTS, sourceModuleName)); 663149602Sandre } 664149602Sandre String sourcePackageName = m.group(2); 665149602Sandre if (!SourceVersion.isName(sourcePackageName, sv)) { 666149602Sandre // syntactically invalid source name: e.g. --add-exports m1/p!=m2 667149602Sandre log.warning(Warnings.BadNameForOption(Option.ADD_EXPORTS, sourcePackageName)); 668149602Sandre } 669149602Sandre 670149602Sandre String targetNames = m.group(3); 671149602Sandre for (String targetName : targetNames.split(",")) { 672149602Sandre switch (targetName) { 673149602Sandre case "": 674149602Sandre case "ALL-UNNAMED": 675149602Sandre break; 676149602Sandre 677149602Sandre default: 678149602Sandre if (!SourceVersion.isName(targetName, sv)) { 679149602Sandre // syntactically invalid target name: e.g. --add-exports m1/p1=m! 680149602Sandre log.warning(Warnings.BadNameForOption(Option.ADD_EXPORTS, targetName)); 681149602Sandre } 682149602Sandre break; 683149602Sandre } 684149602Sandre } 685149602Sandre } 686149602Sandre } 687149602Sandre } 688149602Sandre } 689149602Sandre 690149602Sandre private void validateAddReads(SourceVersion sv) { 691149602Sandre String addReads = options.get(Option.ADD_READS); 692149602Sandre if (addReads != null) { 693149602Sandre // Each entry must be of the form source=target-list where target-list is a 694149602Sandre // comma-separated list of module or ALL-UNNAMED. 695149602Sandre // Empty items in the target list are ignored. 696149602Sandre // There must be at least one item in the list; this is handled in Option.ADD_READS. 697149602Sandre Pattern p = Option.ADD_READS.getPattern(); 698149602Sandre for (String e : addReads.split("\0")) { 699149602Sandre Matcher m = p.matcher(e); 700149602Sandre if (m.matches()) { 701149602Sandre String sourceName = m.group(1); 702149602Sandre if (!SourceVersion.isName(sourceName, sv)) { 703149602Sandre // syntactically invalid source name: e.g. --add-reads m!=m2 704149602Sandre log.warning(Warnings.BadNameForOption(Option.ADD_READS, sourceName)); 705149602Sandre } 70615689Swollman 70715689Swollman String targetNames = m.group(2); 70854002Sarchie for (String targetName : targetNames.split(",", -1)) { 70954002Sarchie switch (targetName) { 71072750Sluigi case "": 71172750Sluigi case "ALL-UNNAMED": 71272750Sluigi break; 71315689Swollman 71415689Swollman default: 71572356Sbmilekic if (!SourceVersion.isName(targetName, sv)) { 71615689Swollman // syntactically invalid target name: e.g. --add-reads m1=m! 71715689Swollman log.warning(Warnings.BadNameForOption(Option.ADD_READS, targetName)); 71815689Swollman } 719132488Salfred break; 72015689Swollman } 72115689Swollman } 72272356Sbmilekic } 72315689Swollman } 72415689Swollman } 725108466Ssam } 726108466Ssam 72715689Swollman private void validateAddModules(SourceVersion sv) { 72815689Swollman String addModules = options.get(Option.ADD_MODULES); 72915689Swollman if (addModules != null) { 73015689Swollman // Each entry must be of the form target-list where target-list is a 73115689Swollman // comma separated list of module names, or ALL-DEFAULT, ALL-SYSTEM, 73264837Sdwmalone // or ALL-MODULE_PATH. 733141668Sbmilekic // Empty items in the target list are ignored. 73415689Swollman // There must be at least one item in the list; this is handled in Option.ADD_MODULES. 73572750Sluigi for (String moduleName : addModules.split(",")) { 73615689Swollman switch (moduleName) { 73715689Swollman case "": 73815689Swollman case "ALL-SYSTEM": 73915689Swollman case "ALL-MODULE-PATH": 74015689Swollman break; 74115689Swollman 74272356Sbmilekic default: 74315689Swollman if (!SourceVersion.isName(moduleName, sv)) { 74415689Swollman // syntactically invalid module name: e.g. --add-modules m1,m! 74515689Swollman log.error(Errors.BadNameForOption(Option.ADD_MODULES, moduleName)); 74615689Swollman } 74715689Swollman break; 74815689Swollman } 74915689Swollman } 75015689Swollman } 75115689Swollman } 75215689Swollman 75364837Sdwmalone private void validateLimitModules(SourceVersion sv) { 754141668Sbmilekic String limitModules = options.get(Option.LIMIT_MODULES); 75515689Swollman if (limitModules != null) { 75615689Swollman // Each entry must be of the form target-list where target-list is a 75715689Swollman // comma separated list of module names, or ALL-DEFAULT, ALL-SYSTEM, 75815689Swollman // or ALL-MODULE_PATH. 75915689Swollman // Empty items in the target list are ignored. 76015689Swollman // There must be at least one item in the list; this is handled in Option.LIMIT_EXPORTS. 76115689Swollman for (String moduleName : limitModules.split(",")) { 76215689Swollman switch (moduleName) { 76315689Swollman case "": 76478592Sbmilekic break; 76572356Sbmilekic 76615689Swollman default: 76715689Swollman if (!SourceVersion.isName(moduleName, sv)) { 76815689Swollman // syntactically invalid module name: e.g. --limit-modules m1,m! 7691541Srgrimes log.error(Errors.BadNameForOption(Option.LIMIT_MODULES, moduleName)); 7701541Srgrimes } 7711541Srgrimes break; 7721549Srgrimes } 77381907Sjulian } 7741541Srgrimes } 775103569Sbmilekic } 7761541Srgrimes 77752201Salfred private void validateDefaultModuleForCreatedFiles(SourceVersion sv) { 77852201Salfred String moduleName = options.get(Option.DEFAULT_MODULE_FOR_CREATED_FILES); 7791541Srgrimes if (moduleName != null) { 78052201Salfred if (!SourceVersion.isName(moduleName, sv)) { 7811541Srgrimes // syntactically invalid module name: e.g. --default-module-for-created-files m! 7821541Srgrimes log.error(Errors.BadNameForOption(Option.DEFAULT_MODULE_FOR_CREATED_FILES, 7831541Srgrimes moduleName)); 7841541Srgrimes } 7851541Srgrimes } 7861541Srgrimes } 78752201Salfred 7881541Srgrimes /** 7891541Srgrimes * Returns true if there are no files or classes specified for use. 7901541Srgrimes * @return true if there are no files or classes specified for use 7911541Srgrimes */ 7921541Srgrimes public boolean isEmpty() { 7931541Srgrimes return ((files == null) || files.isEmpty()) 7941541Srgrimes && ((fileObjects == null) || fileObjects.isEmpty()) 7951541Srgrimes && (classNames == null || classNames.isEmpty()); 7961541Srgrimes } 7971541Srgrimes 79854002Sarchie public void allowEmpty() { 79954002Sarchie this.emptyAllowed = true; 80054002Sarchie } 80154002Sarchie 80254002Sarchie /** 80372356Sbmilekic * Gets the file manager options which may have been deferred 80454002Sarchie * during processArgs. 80554002Sarchie * @return the deferred file manager options 80654002Sarchie */ 80754002Sarchie public Map<Option, String> getDeferredFileManagerOptions() { 808132488Salfred return deferredFileManagerOptions; 80954002Sarchie } 81054002Sarchie 81172356Sbmilekic /** 812113255Sdes * Gets any options specifying plugins to be run. 81354002Sarchie * @return options for plugins 81454002Sarchie */ 81554002Sarchie public Set<List<String>> getPluginOpts() { 81654002Sarchie String plugins = options.get(Option.PLUGIN); 81754002Sarchie if (plugins == null) 81854002Sarchie return Collections.emptySet(); 81954002Sarchie 82054002Sarchie Set<List<String>> pluginOpts = new LinkedHashSet<>(); 82154002Sarchie for (String plugin: plugins.split("\\x00")) { 822129906Sbmilekic pluginOpts.add(List.from(plugin.split("\\s+"))); 823129906Sbmilekic } 824129906Sbmilekic return Collections.unmodifiableSet(pluginOpts); 825129906Sbmilekic } 826129906Sbmilekic 827129906Sbmilekic /** 828129906Sbmilekic * Gets any options specifying how doclint should be run. 82954002Sarchie * An empty list is returned if no doclint options are specified 83054002Sarchie * or if the only doclint option is -Xdoclint:none. 831129906Sbmilekic * @return options for doclint 832129906Sbmilekic */ 833129906Sbmilekic public List<String> getDocLintOpts() { 834129906Sbmilekic String xdoclint = options.get(Option.XDOCLINT); 835108466Ssam String xdoclintCustom = options.get(Option.XDOCLINT_CUSTOM); 836129906Sbmilekic if (xdoclint == null && xdoclintCustom == null) 83754002Sarchie return List.nil(); 83854002Sarchie 83954002Sarchie Set<String> doclintOpts = new LinkedHashSet<>(); 84054002Sarchie if (xdoclint != null) 84154002Sarchie doclintOpts.add(DocLint.XMSGS_OPTION); 84254002Sarchie if (xdoclintCustom != null) { 84354002Sarchie for (String s: xdoclintCustom.split("\\s+")) { 84454002Sarchie if (s.isEmpty()) 84554002Sarchie continue; 84654002Sarchie doclintOpts.add(DocLint.XMSGS_CUSTOM_PREFIX + s); 84754002Sarchie } 84854002Sarchie } 84954002Sarchie 85054002Sarchie if (doclintOpts.equals(Collections.singleton(DocLint.XMSGS_CUSTOM_PREFIX + "none"))) 85154002Sarchie return List.nil(); 85254002Sarchie 85354002Sarchie String checkPackages = options.get(Option.XDOCLINT_PACKAGE); 85454002Sarchie if (checkPackages != null) { 85554002Sarchie for (String s : checkPackages.split("\\s+")) { 85654002Sarchie doclintOpts.add(DocLint.XCHECK_PACKAGE + s); 85754002Sarchie } 85854002Sarchie } 85954002Sarchie 86054002Sarchie String format = options.get(Option.DOCLINT_FORMAT); 86187594Sobrien if (format != null) { 86254002Sarchie doclintOpts.add(DocLint.XHTML_VERSION_PREFIX + format); 86354002Sarchie } 86454002Sarchie 86554002Sarchie // standard doclet normally generates H1, H2, 86654002Sarchie // so for now, allow user comments to assume that 86778592Sbmilekic doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2"); 86872356Sbmilekic return List.from(doclintOpts.toArray(new String[doclintOpts.size()])); 86954002Sarchie } 87054002Sarchie 87154002Sarchie private boolean checkDirectory(Option option) { 8721541Srgrimes String value = options.get(option); 8731541Srgrimes if (value == null) { 8741541Srgrimes return true; 8751541Srgrimes } 8761549Srgrimes Path file = Paths.get(value); 87772356Sbmilekic if (Files.exists(file) && !Files.isDirectory(file)) { 8781541Srgrimes error("err.file.not.directory", value); 8791541Srgrimes return false; 8801541Srgrimes } 8811541Srgrimes return true; 8821541Srgrimes } 8831541Srgrimes 8841541Srgrimes private interface ErrorReporter { 8851541Srgrimes void report(Option o); 8861541Srgrimes } 8871541Srgrimes 8881541Srgrimes void checkOptionAllowed(boolean allowed, ErrorReporter r, Option... opts) { 8891541Srgrimes if (!allowed) { 8901541Srgrimes Stream.of(opts) 8911541Srgrimes .filter(options :: isSet) 8921541Srgrimes .forEach(r :: report); 8931541Srgrimes } 8941541Srgrimes } 8951541Srgrimes 8961549Srgrimes void error(JCDiagnostic.Error error) { 89772356Sbmilekic errors = true; 8981541Srgrimes switch (errorMode) { 89972356Sbmilekic case ILLEGAL_ARGUMENT: { 90072356Sbmilekic String msg = log.localize(error); 90172356Sbmilekic throw new PropagatedException(new IllegalArgumentException(msg)); 9021541Srgrimes } 9031541Srgrimes case ILLEGAL_STATE: { 9041541Srgrimes String msg = log.localize(error); 9051541Srgrimes throw new PropagatedException(new IllegalStateException(msg)); 9061541Srgrimes } 9071541Srgrimes case LOG: 9081541Srgrimes report(error); 9091541Srgrimes } 9101541Srgrimes } 9111541Srgrimes 9121541Srgrimes void error(String key, Object... args) { 9131541Srgrimes errors = true; 9141541Srgrimes switch (errorMode) { 9151541Srgrimes case ILLEGAL_ARGUMENT: { 9161541Srgrimes String msg = log.localize(PrefixKind.JAVAC, key, args); 9171541Srgrimes throw new PropagatedException(new IllegalArgumentException(msg)); 9181541Srgrimes } 9191541Srgrimes case ILLEGAL_STATE: { 9201541Srgrimes String msg = log.localize(PrefixKind.JAVAC, key, args); 9211541Srgrimes throw new PropagatedException(new IllegalStateException(msg)); 9221541Srgrimes } 9231541Srgrimes case LOG: 9241541Srgrimes report(key, args); 9251541Srgrimes } 9261541Srgrimes } 9271541Srgrimes 9281541Srgrimes void error(Option.InvalidValueException f) { 9291541Srgrimes String msg = f.getMessage(); 9301541Srgrimes errors = true; 9311541Srgrimes switch (errorMode) { 9321541Srgrimes case ILLEGAL_ARGUMENT: { 9331541Srgrimes throw new PropagatedException(new IllegalArgumentException(msg, f.getCause())); 9341541Srgrimes } 9351541Srgrimes case ILLEGAL_STATE: { 9361541Srgrimes throw new PropagatedException(new IllegalStateException(msg, f.getCause())); 9371541Srgrimes } 9381541Srgrimes case LOG: 9391541Srgrimes log.printRawLines(ownName + ": " + msg); 9401541Srgrimes } 9411541Srgrimes } 9421541Srgrimes 9431541Srgrimes void warning(String key, Object... args) { 9441541Srgrimes report(key, args); 9451541Srgrimes } 9461541Srgrimes 9471541Srgrimes private void report(String key, Object... args) { 9481541Srgrimes // Would be good to have support for -XDrawDiagnostics here 9491541Srgrimes log.printRawLines(ownName + ": " + log.localize(PrefixKind.JAVAC, key, args)); 9501541Srgrimes } 9511541Srgrimes 9521541Srgrimes private void report(JCDiagnostic.Error error) { 9531541Srgrimes // Would be good to have support for -XDrawDiagnostics here 9541541Srgrimes log.printRawLines(ownName + ": " + log.localize(error)); 9551541Srgrimes } 9561541Srgrimes 9571541Srgrimes private JavaFileManager getFileManager() { 9581541Srgrimes if (fileManager == null) 959142350Ssam fileManager = context.get(JavaFileManager.class); 960142350Ssam return fileManager; 961142350Ssam } 962142350Ssam 9631541Srgrimes <T> ListBuffer<T> toList(Iterable<? extends T> items) { 9641541Srgrimes ListBuffer<T> list = new ListBuffer<>(); 9651541Srgrimes if (items != null) { 9661541Srgrimes for (T item : items) { 9671541Srgrimes list.add(item); 9681541Srgrimes } 9691541Srgrimes } 9701541Srgrimes return list; 9711541Srgrimes } 9721541Srgrimes 9731541Srgrimes <T> Set<T> toSet(Iterable<? extends T> items) { 9741541Srgrimes Set<T> set = new LinkedHashSet<>(); 9751541Srgrimes if (items != null) { 9761541Srgrimes for (T item : items) { 9771541Srgrimes set.add(item); 9781541Srgrimes } 97972356Sbmilekic } 9801541Srgrimes return set; 98172356Sbmilekic } 98272356Sbmilekic} 9831541Srgrimes