# HG changeset patch # User lana # Date 1487269743 0 # Node ID a12e388192c0506b0df1eac9be488be235241c05 # Parent f402e32dfbf393ba714adf59c45fb0af8535bef1# Parent bfb874896f7e5e450824257a1c1c5b4abb0e68a8 Merge diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java --- a/langtools/src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,7 +92,7 @@ * same set of strings as the annotation. If the class is not so * annotated, an empty set is returned. * - * If the {@link ProcessingEvironment#getSourceVersion source + * If the {@link ProcessingEnvironment#getSourceVersion source * version} does not support modules, in other words if it is less * than or equal to {@link SourceVersion#RELEASE_8 RELEASE_8}, * then any leading {@link Processor#getSupportedAnnotationTypes diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/java.compiler/share/classes/javax/annotation/processing/Processor.java --- a/langtools/src/java.compiler/share/classes/javax/annotation/processing/Processor.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/java.compiler/share/classes/javax/annotation/processing/Processor.java Thu Feb 16 18:29:03 2017 +0000 @@ -291,7 +291,7 @@ * @apiNote When running in an environment which supports modules, * processors are encouraged to include the module prefix when * describing their supported annotation types. The method {@link - * AbstractProcessor.getSupportedAnnotationTypes + * AbstractProcessor#getSupportedAnnotationTypes * AbstractProcessor.getSupportedAnnotationTypes} provides support * for stripping off the module prefix when running in an * environment without modules. diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java --- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java Thu Feb 16 18:29:03 2017 +0000 @@ -25,9 +25,12 @@ package javax.lang.model.util; - +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.LinkedHashSet; import javax.lang.model.AnnotatedConstruct; import javax.lang.model.element.*; @@ -65,6 +68,7 @@ * @param name fully qualified package name, or an empty string for an unnamed package * @param module module relative to which the lookup should happen * @return the specified package, or {@code null} if it cannot be found + * @see #getAllPackageElements * @since 9 */ default PackageElement getPackageElement(ModuleElement module, CharSequence name) { @@ -72,6 +76,49 @@ } /** + * Returns all package elements with the given canonical name. + * + * There may be more than one package element with the same canonical + * name if the package elements are in different modules. + * + * @implSpec The default implementation of this method calls + * {@link #getAllModuleElements() getAllModuleElements} and stores + * the result. If the set of modules is empty, {@link + * #getPackageElement(CharSequence) getPackageElement(name)} is + * called passing through the name argument. If {@code + * getPackageElement(name)} is {@code null}, an empty set of + * package elements is returned; otherwise, a single-element set + * with the found package element is returned. If the set of + * modules is nonempty, the modules are iterated over and any + * non-{@code null} results of {@link + * #getPackageElement(ModuleElement, CharSequence) + * getPackageElement(module, name)} are accumulated into a + * set. The set is then returned. + * + * @param name the canonical name + * @return the package elements, or an empty set if no package with the name can be found + * @see #getPackageElement(ModuleElement, CharSequence) + * @since 9 + */ + default Set getAllPackageElements(CharSequence name) { + Set modules = getAllModuleElements(); + if (modules.isEmpty()) { + PackageElement packageElt = getPackageElement(name); + return (packageElt != null) ? + Collections.singleton(packageElt): + Collections.emptySet(); + } else { + Set result = new LinkedHashSet<>(1); // Usually expect at most 1 result + for (ModuleElement module: modules) { + PackageElement packageElt = getPackageElement(module, name); + if (packageElt != null) + result.add(packageElt); + } + return Collections.unmodifiableSet(result); + } + } + + /** * Returns a type element given its canonical name if the type element is unique in the environment. * If running with modules, all modules in the modules graph are searched for matching * type elements. @@ -90,6 +137,7 @@ * @param name the canonical name * @param module module relative to which the lookup should happen * @return the named type element, or {@code null} if it cannot be found + * @see #getAllTypeElements * @since 9 */ default TypeElement getTypeElement(ModuleElement module, CharSequence name) { @@ -97,11 +145,54 @@ } /** + * Returns all type elements with the given canonical name. + * + * There may be more than one type element with the same canonical + * name if the type elements are in different modules. + * + * @implSpec The default implementation of this method calls + * {@link #getAllModuleElements() getAllModuleElements} and stores + * the result. If the set of modules is empty, {@link + * #getTypeElement(CharSequence) getTypeElement(name)} is called + * passing through the name argument. If {@code + * getTypeElement(name)} is {@code null}, an empty set of type + * elements is returned; otherwise, a single-element set with the + * found type element is returned. If the set of modules is + * nonempty, the modules are iterated over and any non-{@code null} + * results of {@link #getTypeElement(ModuleElement, + * CharSequence) getTypeElement(module, name)} are accumulated + * into a set. The set is then returned. + * + * @param name the canonical name + * @return the type elements, or an empty set if no type with the name can be found + * @see #getTypeElement(ModuleElement, CharSequence) + * @since 9 + */ + default Set getAllTypeElements(CharSequence name) { + Set modules = getAllModuleElements(); + if (modules.isEmpty()) { + TypeElement typeElt = getTypeElement(name); + return (typeElt != null) ? + Collections.singleton(typeElt): + Collections.emptySet(); + } else { + Set result = new LinkedHashSet<>(1); // Usually expect at most 1 result + for (ModuleElement module: modules) { + TypeElement typeElt = getTypeElement(module, name); + if (typeElt != null) + result.add(typeElt); + } + return Collections.unmodifiableSet(result); + } + } + + /** * Returns a module element given its fully qualified name. - * If the named module cannot be found, null is returned. One situation where a module - * cannot be found is if the environment does not include modules, such as - * an annotation processing environment configured for - * a {@linkplain + * + * If the named module cannot be found, {@code null} is + * returned. One situation where a module cannot be found is if + * the environment does not include modules, such as an annotation + * processing environment configured for a {@linkplain * javax.annotation.processing.ProcessingEnvironment#getSourceVersion * source version} without modules. * @@ -110,6 +201,7 @@ * * @param name the name * @return the named module element, or {@code null} if it cannot be found + * @see #getAllModuleElements * @since 9 * @spec JPMS */ @@ -118,6 +210,27 @@ } /** + * Returns all module elements in the current environment. + * + * If no modules are present, an empty set is returned. One + * situation where no modules are present occurs when the + * environment does not include modules, such as an annotation + * processing environment configured for a {@linkplain + * javax.annotation.processing.ProcessingEnvironment#getSourceVersion + * source version} without modules. + * + * @implSpec The default implementation of this method returns + * an empty set. + * + * @return the known module elements, or an empty set if there are no modules + * @see #getModuleElement(CharSequence) + * @since 9 + */ + default Set getAllModuleElements() { + return Collections.emptySet(); + } + + /** * Returns the values of an annotation's elements, including defaults. * * @see AnnotationMirror#getElementValues() diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/java.compiler/share/classes/javax/tools/DocumentationTool.java --- a/langtools/src/java.compiler/share/classes/javax/tools/DocumentationTool.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/java.compiler/share/classes/javax/tools/DocumentationTool.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,7 +121,20 @@ */ interface DocumentationTask extends Callable { /** - * Set the locale to be applied when formatting diagnostics and + * Adds root modules to be taken into account during module + * resolution. + * Invalid module names may cause either + * {@code IllegalArgumentException} to be thrown, + * or diagnostics to be reported when the task is started. + * @param moduleNames the names of the root modules + * @throws IllegalArgumentException may be thrown for some + * invalid module names + * @throws IllegalStateException if the task has started + */ + void addModules(Iterable moduleNames); + + /** + * Sets the locale to be applied when formatting diagnostics and * other localized data. * * @param locale the locale to apply; {@code null} means apply no diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java --- a/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package javax.tools; -import java.io.File; import java.io.Writer; import java.nio.charset.Charset; import java.util.Locale; @@ -296,6 +295,18 @@ * {@linkplain #setProcessors setProcessors} method. */ interface CompilationTask extends Callable { + /** + * Adds root modules to be taken into account during module + * resolution. + * Invalid module names may cause either + * {@code IllegalArgumentException} to be thrown, + * or diagnostics to be reported when the task is started. + * @param moduleNames the names of the root modules + * @throws IllegalArgumentException may be thrown for some + * invalid module names + * @throws IllegalStateException if the task has started + */ + void addModules(Iterable moduleNames); /** * Sets processors (for annotation processing). This will @@ -307,7 +318,7 @@ void setProcessors(Iterable processors); /** - * Set the locale to be applied when formatting diagnostics and + * Sets the locale to be applied when formatting diagnostics and * other localized data. * * @param locale the locale to apply; {@code null} means apply no @@ -330,6 +341,7 @@ * in user code. * @throws IllegalStateException if called more than once */ + @Override Boolean call(); } } diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java --- a/langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java Thu Feb 16 18:29:03 2017 +0000 @@ -130,7 +130,7 @@ * It is not possible to directly list the classes in a module-oriented * location. Instead, you can get a package-oriented location for any specific module * using methods like {@link JavaFileManager#getLocationForModule} or - * {@link JavaFileManager#listLocationsForModule}. + * {@link JavaFileManager#listLocationsForModules}. */ interface Location { /** diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/java.compiler/share/classes/module-info.java --- a/langtools/src/java.compiler/share/classes/module-info.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/java.compiler/share/classes/module-info.java Thu Feb 16 18:29:03 2017 +0000 @@ -29,6 +29,8 @@ * These APIs model declarations and types of the Java programming language, * and define interfaces for tools such as compilers which can be invoked * from a program. + * + * @since 9 */ module java.compiler { exports javax.annotation.processing; diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/BasicJavacTask.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,6 +155,11 @@ } @Override @DefinedBy(Api.COMPILER) + public void addModules(Iterable moduleNames) { + throw new IllegalStateException(); + } + + @Override @DefinedBy(Api.COMPILER) public void setProcessors(Iterable processors) { throw new IllegalStateException(); } diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,17 +33,12 @@ import javax.annotation.processing.Processor; import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; -import javax.lang.model.util.ElementFilter; import javax.tools.*; -import javax.tools.JavaFileObject.Kind; import com.sun.source.tree.*; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.ClassSymbol; -import com.sun.tools.javac.code.Symbol.ModuleSymbol; -import com.sun.tools.javac.code.Symbol.PackageSymbol; import com.sun.tools.javac.comp.*; import com.sun.tools.javac.file.BaseFileManager; import com.sun.tools.javac.main.*; @@ -82,6 +77,7 @@ private ListBuffer> genList; private final AtomicBoolean used = new AtomicBoolean(); private Iterable processors; + private ListBuffer addModules = new ListBuffer<>(); protected JavacTaskImpl(Context context) { super(context, true); @@ -101,7 +97,7 @@ prepareCompiler(false); if (compiler.errorCount() > 0) return Main.Result.ERROR; - compiler.compile(args.getFileObjects(), args.getClassNames(), processors); + compiler.compile(args.getFileObjects(), args.getClassNames(), processors, addModules); return (compiler.errorCount() > 0) ? Main.Result.ERROR : Main.Result.OK; // FIXME? }, Main.Result.SYSERR, Main.Result.ABNORMAL); } finally { @@ -114,6 +110,18 @@ } @Override @DefinedBy(Api.COMPILER) + public void addModules(Iterable moduleNames) { + Objects.requireNonNull(moduleNames); + // not mt-safe + if (used.get()) + throw new IllegalStateException(); + for (String m : moduleNames) { + Objects.requireNonNull(m); + addModules.add(m); + } + } + + @Override @DefinedBy(Api.COMPILER) public void setProcessors(Iterable processors) { Objects.requireNonNull(processors); // not mt-safe diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,6 +79,10 @@ */ boolean isNewClass = false; + /** Indicate if the type being visited is a service implementation + */ + boolean visitingServiceImplementation = false; + /** Are arguments to current function applications boxed into an array for varargs? */ Resolve.MethodResolutionPhase pendingResolutionPhase = null; @@ -127,6 +131,7 @@ info.isAnonymousDiamond = isAnonymousDiamond; info.isNewClass = isNewClass; info.preferredTreeForDiagnostics = preferredTreeForDiagnostics; + info.visitingServiceImplementation = visitingServiceImplementation; return info; } diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Thu Feb 16 18:29:03 2017 +0000 @@ -996,8 +996,18 @@ } ListBuffer impls = new ListBuffer<>(); for (JCExpression implName : tree.implNames) { - Type it = attr.attribType(implName, env, syms.objectType); + Type it; + boolean prevVisitingServiceImplementation = env.info.visitingServiceImplementation; + try { + env.info.visitingServiceImplementation = true; + it = attr.attribType(implName, env, syms.objectType); + } finally { + env.info.visitingServiceImplementation = prevVisitingServiceImplementation; + } ClassSymbol impl = (ClassSymbol) it.tsym; + if ((impl.flags_field & PUBLIC) == 0) { + log.error(implName.pos(), Errors.NotDefPublic(impl, impl.location())); + } //find provider factory: MethodSymbol factory = factoryMethod(impl); if (factory != null) { diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Feb 16 18:29:03 2017 +0000 @@ -307,6 +307,11 @@ if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0) return true; + if (env.info.visitingServiceImplementation && + env.toplevel.modle == c.packge().modle) { + return true; + } + boolean isAccessible = false; switch ((short)(c.flags() & AccessFlags)) { case PRIVATE: @@ -389,6 +394,11 @@ if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0) return true; + if (env.info.visitingServiceImplementation && + env.toplevel.modle == sym.packge().modle) { + return true; + } + switch ((short)(sym.flags() & AccessFlags)) { case PRIVATE: return @@ -2094,7 +2104,7 @@ for (S sym : candidates) { if (validate.test(sym)) - return new InvisibleSymbolError(env, suppressError, sym); + return createInvisibleSymbolError(env, suppressError, sym); } Set recoverableModules = new HashSet<>(syms.getAllModules()); @@ -2113,7 +2123,7 @@ S sym = load.apply(ms, name); if (sym != null && validate.test(sym)) { - return new InvisibleSymbolError(env, suppressError, sym); + return createInvisibleSymbolError(env, suppressError, sym); } } } @@ -2122,6 +2132,21 @@ return defaultResult; } + private Symbol createInvisibleSymbolError(Env env, boolean suppressError, Symbol sym) { + if (symbolPackageVisible(env, sym)) { + return new AccessError(env, null, sym); + } else { + return new InvisibleSymbolError(env, suppressError, sym); + } + } + + private boolean symbolPackageVisible(Env env, Symbol sym) { + ModuleSymbol envMod = env.toplevel.modle; + PackageSymbol symPack = sym.packge(); + return envMod == symPack.modle || + envMod.visiblePackages.containsKey(symPack.fullname); + } + /** * Find a type declared in a scope (not inherited). Return null * if none is found. @@ -4094,8 +4119,7 @@ pos, "not.def.access.package.cant.access", sym, sym.location(), inaccessiblePackageReason(env, sym.packge())); } else if ( sym.packge() != syms.rootPackage - && sym.packge().modle != env.toplevel.modle - && !isAccessible(env, sym.outermostClass())) { + && !symbolPackageVisible(env, sym)) { return diags.create(dkind, log.currentSource(), pos, "not.def.access.class.intf.cant.access.reason", sym, sym.location(), sym.location().packge(), diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/CommandLine.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,9 @@ import java.io.Reader; import java.nio.file.Files; import java.nio.file.Paths; - -import com.sun.tools.javac.util.ListBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * Various utility methods for processing Java tool command line arguments. @@ -55,28 +56,80 @@ * @throws IOException if there is a problem reading any of the @files */ public static String[] parse(String[] args) throws IOException { - ListBuffer newArgs = new ListBuffer<>(); + List newArgs = new ArrayList<>(); + appendParsedCommandArgs(newArgs, Arrays.asList(args)); + return newArgs.toArray(new String[newArgs.size()]); + } + + private static void appendParsedCommandArgs(List newArgs, List args) throws IOException { for (String arg : args) { if (arg.length() > 1 && arg.charAt(0) == '@') { arg = arg.substring(1); if (arg.charAt(0) == '@') { - newArgs.append(arg); + newArgs.add(arg); } else { loadCmdFile(arg, newArgs); } } else { - newArgs.append(arg); + newArgs.add(arg); } } - return newArgs.toList().toArray(new String[newArgs.length()]); } - private static void loadCmdFile(String name, ListBuffer args) throws IOException { + /** + * Process the given environment variable and appends any Win32-style + * command files for the specified command line arguments and return + * the resulting arguments. A command file argument + * is of the form '@file' where 'file' is the name of the file whose + * contents are to be parsed for additional arguments. The contents of + * the command file are parsed using StreamTokenizer and the original + * '@file' argument replaced with the resulting tokens. Recursive command + * files are not supported. The '@' character itself can be quoted with + * the sequence '@@'. + * @param envVariable the env variable to process + * @param args the arguments that may contain @files + * @return the arguments, with environment variable's content and expansion of @files + * @throws IOException if there is a problem reading any of the @files + * @throws com.sun.tools.javac.main.CommandLine.UnmatchedQuote + */ + public static List parse(String envVariable, List args) + throws IOException, UnmatchedQuote { + + List inArgs = new ArrayList<>(); + appendParsedEnvVariables(inArgs, envVariable); + inArgs.addAll(args); + List newArgs = new ArrayList<>(); + appendParsedCommandArgs(newArgs, inArgs); + return newArgs; + } + + /** + * Process the given environment variable and appends any Win32-style + * command files for the specified command line arguments and return + * the resulting arguments. A command file argument + * is of the form '@file' where 'file' is the name of the file whose + * contents are to be parsed for additional arguments. The contents of + * the command file are parsed using StreamTokenizer and the original + * '@file' argument replaced with the resulting tokens. Recursive command + * files are not supported. The '@' character itself can be quoted with + * the sequence '@@'. + * @param envVariable the env variable to process + * @param args the arguments that may contain @files + * @return the arguments, with environment variable's content and expansion of @files + * @throws IOException if there is a problem reading any of the @files + * @throws com.sun.tools.javac.main.CommandLine.UnmatchedQuote + */ + public static String[] parse(String envVariable, String[] args) throws IOException, UnmatchedQuote { + List out = parse(envVariable, Arrays.asList(args)); + return out.toArray(new String[out.size()]); + } + + private static void loadCmdFile(String name, List args) throws IOException { try (Reader r = Files.newBufferedReader(Paths.get(name))) { Tokenizer t = new Tokenizer(r); String s; while ((s = t.nextToken()) != null) { - args.append(s); + args.add(s); } } } @@ -188,4 +241,75 @@ } } } + + @SuppressWarnings("fallthrough") + private static void appendParsedEnvVariables(List newArgs, String envVariable) + throws UnmatchedQuote { + + if (envVariable == null) { + return; + } + String in = System.getenv(envVariable); + if (in == null || in.trim().isEmpty()) { + return; + } + + final char NUL = (char)0; + final int len = in.length(); + + int pos = 0; + StringBuilder sb = new StringBuilder(); + char quote = NUL; + char ch; + + loop: + while (pos < len) { + ch = in.charAt(pos); + switch (ch) { + case '\"': case '\'': + if (quote == NUL) { + quote = ch; + } else if (quote == ch) { + quote = NUL; + } else { + sb.append(ch); + } + pos++; + break; + case '\f': case '\n': case '\r': case '\t': case ' ': + if (quote == NUL) { + newArgs.add(sb.toString()); + sb.setLength(0); + while (ch == '\f' || ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') { + pos++; + if (pos >= len) { + break loop; + } + ch = in.charAt(pos); + } + break; + } + // fall through + default: + sb.append(ch); + pos++; + } + } + if (sb.length() != 0) { + newArgs.add(sb.toString()); + } + if (quote != NUL) { + throw new UnmatchedQuote(envVariable); + } + } + + public static class UnmatchedQuote extends Exception { + private static final long serialVersionUID = 0; + + public final String variableName; + + UnmatchedQuote(String variable) { + this.variableName = variable; + } + } } diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Feb 16 18:29:03 2017 +0000 @@ -888,7 +888,7 @@ public void compile(List sourceFileObject) throws Throwable { - compile(sourceFileObject, List.nil(), null); + compile(sourceFileObject, List.nil(), null, List.nil()); } /** @@ -898,10 +898,13 @@ * @param classnames class names to process for annotations * @param processors user provided annotation processors to bypass * discovery, {@code null} means that no processors were provided + * @param addModules additional root modules to be used during + * module resolution. */ public void compile(Collection sourceFileObjects, Collection classnames, - Iterable processors) + Iterable processors, + Collection addModules) { if (!taskListener.isEmpty()) { taskListener.started(new TaskEvent(TaskEvent.Kind.COMPILATION)); @@ -932,6 +935,10 @@ } } + for (String moduleName : addModules) { + modules.addExtraAddModules(moduleName); + } + // These method calls must be chained to avoid memory leaks processAnnotations( enterTrees( diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,7 @@ import com.sun.tools.javac.file.BaseFileManager; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.jvm.Target; +import com.sun.tools.javac.main.CommandLine.UnmatchedQuote; import com.sun.tools.javac.platform.PlatformDescription; import com.sun.tools.javac.processing.AnnotationProcessingError; import com.sun.tools.javac.util.*; @@ -80,6 +81,7 @@ */ boolean apiMode; + private static final String ENV_OPT_NAME = "JDK_JAVAC_OPTIONS"; /** Result codes. */ @@ -201,19 +203,12 @@ return Result.CMDERR; } - // prefix argv with contents of _JAVAC_OPTIONS if set - String envOpt = System.getenv("_JAVAC_OPTIONS"); - if (envOpt != null && !envOpt.trim().isEmpty()) { - String[] envv = envOpt.split("\\s+"); - String[] result = new String[envv.length + argv.length]; - System.arraycopy(envv, 0, result, 0, envv.length); - System.arraycopy(argv, 0, result, envv.length, argv.length); - argv = result; - } - - // expand @-files + // prefix argv with contents of environment variable and expand @-files try { - argv = CommandLine.parse(argv); + argv = CommandLine.parse(ENV_OPT_NAME, argv); + } catch (UnmatchedQuote ex) { + error("err.unmatched.quote", ex.variableName); + return Result.CMDERR; } catch (FileNotFoundException | NoSuchFileException e) { warning("err.file.not.found", e.getMessage()); return Result.SYSERR; @@ -304,7 +299,7 @@ } try { - comp.compile(args.getFileObjects(), args.getClassNames(), null); + comp.compile(args.getFileObjects(), args.getClassNames(), null, List.nil()); if (log.expectDiagKeys != null) { if (log.expectDiagKeys.isEmpty()) { diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Thu Feb 16 18:29:03 2017 +0000 @@ -25,6 +25,7 @@ package com.sun.tools.javac.model; +import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Map; @@ -117,6 +118,14 @@ } @Override @DefinedBy(Api.LANGUAGE_MODEL) + public Set getAllModuleElements() { + if (allowModules) + return Collections.unmodifiableSet(modules.allModules()); + else + return Collections.emptySet(); + } + + @Override @DefinedBy(Api.LANGUAGE_MODEL) public ModuleSymbol getModuleElement(CharSequence name) { ensureEntered("getModuleElement"); if (modules.getDefaultModule() == syms.noModule) diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Feb 16 18:29:03 2017 +0000 @@ -915,6 +915,10 @@ {0} is not public in {1}; cannot be accessed from outside package # 0: symbol, 1: symbol +compiler.err.not.def.public=\ + {0} is not public in {1} + +# 0: symbol, 1: symbol compiler.misc.not.def.public.cant.access=\ {0} is not public in {1}; cannot be accessed from outside package @@ -1438,7 +1442,7 @@ # 0: string, 1: string, 2: string compiler.note.multiple.elements=\ - Multiple elements named '{1}' in modules '{2}' were found by javax.lang.model.util.Elements.{0}. + Multiple elements named ''{1}'' in modules ''{2}'' were found by javax.lang.model.util.Elements.{0}. ##### diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Thu Feb 16 18:29:03 2017 +0000 @@ -377,6 +377,9 @@ javac.err.repeated.value.for.patch.module=\ --patch-module specified more than once for {0} +javac.err.unmatched.quote=\ + unmatched quote in environment variable %s + ## messages javac.msg.usage.header=\ diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.compiler/share/classes/module-info.java --- a/langtools/src/jdk.compiler/share/classes/module-info.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.compiler/share/classes/module-info.java Thu Feb 16 18:29:03 2017 +0000 @@ -26,6 +26,8 @@ /** Defines the implementation of the * {@link javax.tools.ToolProvider#getSystemJavaCompiler system Java compiler} * and its command line equivalent, javac, as well as javah. + * + * @since 9 */ module jdk.compiler { requires transitive java.compiler; diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Thu Feb 16 18:29:03 2017 +0000 @@ -1705,7 +1705,6 @@ if (lessThanPos < 0) { return text; } - StringBuilder result = new StringBuilder(); main: while (lessThanPos != -1) { int currPos = lessThanPos + 1; @@ -1740,17 +1739,16 @@ if (ch == '>' && quoteKind == null) { foundGT = true; } - if (++currPos == len) + if (++currPos == len) { break; + } ch = text.charAt(currPos); } - startPos = currPos + 1; - currPos = startPos; + startPos = currPos; } lessThanPos = text.indexOf('<', currPos); } result.append(text.substring(startPos)); - return result.toString(); } @@ -1760,10 +1758,6 @@ ('1' <= ch && ch <= '6'); } - private static boolean isWhitespace(char ch) { - return Character.isWhitespace(ch); - } - /** * Add a link to the stylesheet file. * diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTaskImpl.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTaskImpl.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/api/JavadocTaskImpl.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,15 +25,20 @@ package jdk.javadoc.internal.api; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import javax.tools.DocumentationTool.DocumentationTask; import javax.tools.JavaFileObject; +import com.sun.tools.javac.main.Option; import com.sun.tools.javac.util.ClientCodeException; import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Options; import jdk.javadoc.internal.tool.Start; /** @@ -53,6 +58,7 @@ private Iterable options; private Iterable fileObjects; private Locale locale; + private List addModules = new ArrayList<>(); public JavadocTaskImpl(Context context, Class docletClass, Iterable options, Iterable fileObjects) { @@ -72,6 +78,16 @@ this.locale = locale; } + @Override + public void addModules(Iterable moduleNames) { + nullCheck(moduleNames); + if (used.get()) + throw new IllegalStateException(); + for (String name : moduleNames) { + addModules.add(name); + } + } + public Boolean call() { if (!used.getAndSet(true)) { initContext(); @@ -89,6 +105,12 @@ private void initContext() { //initialize compiler's default locale context.put(Locale.class, locale); + if (!addModules.isEmpty()) { + String names = String.join(",", addModules); + Options opts = Options.instance(context); + String prev = opts.get(Option.ADD_MODULES); + opts.put(Option.ADD_MODULES, (prev == null) ? names : prev + "," + names); + } } private static Iterable nullCheck(Iterable items) { diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Thu Feb 16 18:29:03 2017 +0000 @@ -647,6 +647,13 @@ tree.addContent(fixedNavDiv); HtmlTree paddingDiv = HtmlTree.DIV(HtmlStyle.navPadding, Contents.SPACE); tree.addContent(paddingDiv); + HtmlTree scriptTree = HtmlTree.SCRIPT(); + String scriptCode = "\n"; + RawHtml scriptContent = new RawHtml(scriptCode.replace("\n", DocletConstants.NL)); + scriptTree.addContent(scriptContent); + tree.addContent(scriptTree); } else { subDiv.addContent(getMarkerAnchor(SectionName.SKIP_NAVBAR_BOTTOM)); tree.addContent(subDiv); diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,6 @@ import javax.lang.model.element.ModuleElement; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; -import javax.lang.model.util.ElementFilter; import javax.lang.model.util.SimpleElementVisitor9; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; @@ -1116,7 +1115,7 @@ @Override public String toString() { - return names.toString(); + return Arrays.toString(names); } @Override diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,6 @@ import javax.lang.model.util.Elements; import javax.tools.FileObject; import javax.tools.JavaFileManager.Location; -import javax.tools.JavaFileObject; import com.sun.source.tree.CompilationUnitTree; import com.sun.source.util.JavacTask; @@ -62,7 +61,6 @@ import com.sun.tools.javac.code.Symbol.ModuleSymbol; import com.sun.tools.javac.code.Symbol.PackageSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol; -import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.model.JavacElements; @@ -297,6 +295,33 @@ return null; } + // TODO: the method jx.l.m.Elements::overrides does not check + // the return type, see JDK-8174840 until that is resolved, + // use a copy of the same method, with a return type check. + + // Note: the rider.overrides call in this method *must* be consistent + // with the call in overrideType(....), the method above. + public boolean overrides(ExecutableElement e1, ExecutableElement e2, TypeElement cls) { + MethodSymbol rider = (MethodSymbol)e1; + MethodSymbol ridee = (MethodSymbol)e2; + ClassSymbol origin = (ClassSymbol)cls; + + return rider.name == ridee.name && + + // not reflexive as per JLS + rider != ridee && + + // we don't care if ridee is static, though that wouldn't + // compile + !rider.isStatic() && + + // Symbol.overrides assumes the following + ridee.isMemberOf(origin, toolEnv.getTypes()) && + + // check access, signatures and check return types + rider.overrides(ridee, origin, toolEnv.getTypes(), true); + } + // TODO: jx.l.m ? public Location getLocationForModule(ModuleElement mdle) { ModuleSymbol msym = (ModuleSymbol)mdle; diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/script.js --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/script.js Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/script.js Thu Feb 16 18:29:03 2017 +0000 @@ -92,6 +92,9 @@ if (!tagSearchIndex) { createElem(doc, tag, 'tag-search-index.js'); } + $(window).resize(function() { + $('.navPadding').css('padding-top', $('.fixedNav').css("height")); + }); } function createElem(doc, tag, path) { diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css Thu Feb 16 18:29:03 2017 +0000 @@ -144,7 +144,7 @@ margin:0; } .navPadding { - padding-top: 100px; + padding-top: 107px; } .fixedNav { position:fixed; diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Thu Feb 16 18:29:03 2017 +0000 @@ -893,7 +893,7 @@ } List methods = te.getEnclosedElements(); for (ExecutableElement ee : ElementFilter.methodsIn(methods)) { - if (elementUtils.overrides(method, ee, origin)) { + if (configuration.workArounds.overrides(method, ee, origin)) { return ee; } } @@ -1886,11 +1886,6 @@ } @Override - public String visitPrimitive(PrimitiveType t, Void p) { - return t.toString(); - } - - @Override public String visitTypeVariable(javax.lang.model.type.TypeVariable t, Void p) { // The knee jerk reaction is to do this but don't!, as we would like // it to be compatible with the old world, now if we decide to do so @@ -1900,9 +1895,10 @@ } @Override - protected String defaultAction(TypeMirror e, Void p) { - throw new UnsupportedOperationException("should not happen"); + protected String defaultAction(TypeMirror t, Void p) { + return t.toString(); } + }.visit(t); } diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -338,7 +338,7 @@ } }, - X("-X", STANDARD) { + HELP_EXTRA("--help-extra -X", STANDARD) { @Override public void process(Helper helper) throws OptionException { throw new OptionException(OK, helper::Xusage); diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -205,7 +205,7 @@ main.opt.J.desc=\ Pass directly to the runtime system -main.opt.X.desc=\ +main.opt.help.extra.desc=\ Print a synopsis of nonstandard options and exit main.usage.foot=\n\ diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.javadoc/share/classes/module-info.java --- a/langtools/src/jdk.javadoc/share/classes/module-info.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.javadoc/share/classes/module-info.java Thu Feb 16 18:29:03 2017 +0000 @@ -26,6 +26,8 @@ /** Defines the implementation of the * {@link javax.tools.ToolProvider#getSystemDocumentationTool system documentation tool} * and its command line equivalent, javadoc. + * + * @since 9 */ module jdk.javadoc { requires transitive java.compiler; diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Graph.java --- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Graph.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Graph.java Thu Feb 16 18:29:03 2017 +0000 @@ -116,7 +116,7 @@ .forEach(u -> g.adjacentNodes(u).stream() .filter(v -> isAdjacent(u, v)) .forEach(v -> builder.addEdge(u, v))); - return builder.build(); + return builder.build().reduce(); } /** @@ -274,7 +274,7 @@ } public void addNodes(Set nodes) { - nodes.addAll(nodes); + this.nodes.addAll(nodes); } public void addEdge(T u, T v) { @@ -335,67 +335,4 @@ result.addLast(node); } } - - public static class DotGraph { - static final String ORANGE = "#e76f00"; - static final String BLUE = "#437291"; - static final String GRAY = "#dddddd"; - - static final String REEXPORTS = ""; - static final String REQUIRES = "style=\"dashed\""; - static final String REQUIRES_BASE = "color=\"" + GRAY + "\""; - - static final Set javaModules = modules(name -> - (name.startsWith("java.") && !name.equals("java.smartcardio"))); - static final Set jdkModules = modules(name -> - (name.startsWith("java.") || - name.startsWith("jdk.") || - name.startsWith("javafx.")) && !javaModules.contains(name)); - - private static Set modules(Predicate predicate) { - return ModuleFinder.ofSystem().findAll() - .stream() - .map(ModuleReference::descriptor) - .map(ModuleDescriptor::name) - .filter(predicate) - .collect(Collectors.toSet()); - } - - static void printAttributes(PrintWriter out) { - out.format(" size=\"25,25\";%n"); - out.format(" nodesep=.5;%n"); - out.format(" ranksep=1.5;%n"); - out.format(" pencolor=transparent;%n"); - out.format(" node [shape=plaintext, fontname=\"DejaVuSans\", fontsize=36, margin=\".2,.2\"];%n"); - out.format(" edge [penwidth=4, color=\"#999999\", arrowhead=open, arrowsize=2];%n"); - } - - static void printNodes(PrintWriter out, Graph graph) { - out.format(" subgraph se {%n"); - graph.nodes().stream() - .filter(javaModules::contains) - .forEach(mn -> out.format(" \"%s\" [fontcolor=\"%s\", group=%s];%n", - mn, ORANGE, "java")); - out.format(" }%n"); - graph.nodes().stream() - .filter(jdkModules::contains) - .forEach(mn -> out.format(" \"%s\" [fontcolor=\"%s\", group=%s];%n", - mn, BLUE, "jdk")); - - graph.nodes().stream() - .filter(mn -> !javaModules.contains(mn) && !jdkModules.contains(mn)) - .forEach(mn -> out.format(" \"%s\";%n", mn)); - } - - static void printEdges(PrintWriter out, Graph graph, - String node, Set requiresTransitive) { - graph.adjacentNodes(node).forEach(dn -> { - String attr = dn.equals("java.base") ? REQUIRES_BASE - : (requiresTransitive.contains(dn) ? REEXPORTS : REQUIRES); - out.format(" \"%s\" -> \"%s\" [%s];%n", node, dn, attr); - }); - } - } - - } diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsConfiguration.java --- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsConfiguration.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsConfiguration.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -207,16 +207,6 @@ } /** - * Returns the modules that the given module can read - */ - public Stream reads(Module module) { - return configuration.findModule(module.name()).get() - .reads().stream() - .map(ResolvedModule::name) - .map(nameToModule::get); - } - - /** * Returns the list of packages that split between resolved module and * unnamed module */ @@ -267,16 +257,15 @@ return nameToModule; } - public Stream resolve(Set roots) { - if (roots.isEmpty()) { - return nameToModule.values().stream(); - } else { - return Configuration.empty() - .resolve(finder, ModuleFinder.of(), roots) - .modules().stream() - .map(ResolvedModule::name) - .map(nameToModule::get); - } + /** + * Returns Configuration with the given roots + */ + public Configuration resolve(Set roots) { + if (roots.isEmpty()) + throw new IllegalArgumentException("empty roots"); + + return Configuration.empty() + .resolve(finder, ModuleFinder.of(), roots); } public List classPathArchives() { diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java --- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java Thu Feb 16 18:29:03 2017 +0000 @@ -721,9 +721,9 @@ return run(config, writer, type); } - boolean run(JdepsConfiguration config, JdepsWriter writer, Type type) throws IOException { - - + boolean run(JdepsConfiguration config, JdepsWriter writer, Type type) + throws IOException + { // analyze the dependencies DepsAnalyzer analyzer = new DepsAnalyzer(config, dependencyFilter(config), @@ -1024,8 +1024,10 @@ boolean run(JdepsConfiguration config) throws IOException { if ((options.showSummary || options.verbose == MODULE) && !options.addmods.isEmpty() && inputArgs.isEmpty()) { - // print module descriptor - return new ModuleAnalyzer(config, log).genDotFiles(dotOutputDir); + // generate dot graph from the resolved graph from module + // resolution. No class dependency analysis is performed. + return new ModuleDotGraph(config, options.apiOnly) + .genDotFiles(dotOutputDir); } Type type = getAnalyzerType(); diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleAnalyzer.java --- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleAnalyzer.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleAnalyzer.java Thu Feb 16 18:29:03 2017 +0000 @@ -59,15 +59,10 @@ private final JdepsConfiguration configuration; private final PrintWriter log; - private final DependencyFinder dependencyFinder; private final Map modules; public ModuleAnalyzer(JdepsConfiguration config, - PrintWriter log) { - this(config, log, Collections.emptySet()); - } - public ModuleAnalyzer(JdepsConfiguration config, PrintWriter log, Set names) { this.configuration = config; @@ -333,88 +328,6 @@ return true; } - /** - * Generate dotfile from module descriptor - * - * @param dir output directory - */ - public boolean genDotFiles(Path dir) throws IOException { - Files.createDirectories(dir); - for (Module m : modules.keySet()) { - genDotFile(dir, m.name()); - } - return true; - } - - - private void genDotFile(Path dir, String name) throws IOException { - try (OutputStream os = Files.newOutputStream(dir.resolve(name + ".dot")); - PrintWriter out = new PrintWriter(os)) { - Set modules = configuration.resolve(Set.of(name)) - .collect(Collectors.toSet()); - - // transitive reduction - Graph graph = gengraph(modules); - - out.format("digraph \"%s\" {%n", name); - DotGraph.printAttributes(out); - DotGraph.printNodes(out, graph); - - modules.stream() - .map(Module::descriptor) - .sorted(Comparator.comparing(ModuleDescriptor::name)) - .forEach(md -> { - String mn = md.name(); - Set requiresTransitive = md.requires().stream() - .filter(d -> d.modifiers().contains(TRANSITIVE)) - .map(d -> d.name()) - .collect(toSet()); - - DotGraph.printEdges(out, graph, mn, requiresTransitive); - }); - - out.println("}"); - } - } - - /** - * Returns a Graph of the given Configuration after transitive reduction. - * - * Transitive reduction of requires transitive edge and requires edge have - * to be applied separately to prevent the requires transitive edges - * (e.g. U -> V) from being reduced by a path (U -> X -> Y -> V) - * in which V would not be re-exported from U. - */ - private Graph gengraph(Set modules) { - // build a Graph containing only requires transitive edges - // with transitive reduction. - Graph.Builder rpgbuilder = new Graph.Builder<>(); - for (Module module : modules) { - ModuleDescriptor md = module.descriptor(); - String mn = md.name(); - md.requires().stream() - .filter(d -> d.modifiers().contains(TRANSITIVE)) - .map(d -> d.name()) - .forEach(d -> rpgbuilder.addEdge(mn, d)); - } - - Graph rpg = rpgbuilder.build().reduce(); - - // build the readability graph - Graph.Builder builder = new Graph.Builder<>(); - for (Module module : modules) { - ModuleDescriptor md = module.descriptor(); - String mn = md.name(); - builder.addNode(mn); - configuration.reads(module) - .map(Module::name) - .forEach(d -> builder.addEdge(mn, d)); - } - - // transitive reduction of requires edges - return builder.build().reduce(rpg); - } - // ---- for testing purpose public ModuleDescriptor[] descriptors(String name) { ModuleDeps moduleDeps = modules.keySet().stream() diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleDotGraph.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleDotGraph.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.tools.jdeps; + +import static java.lang.module.ModuleDescriptor.Requires.Modifier.*; +import static java.util.stream.Collectors.*; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.lang.module.Configuration; +import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleFinder; +import java.lang.module.ModuleReference; +import java.lang.module.ResolvedModule; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.TreeSet; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Generate dot graph for modules + */ +public class ModuleDotGraph { + private final Map configurations; + private final boolean apiOnly; + public ModuleDotGraph(JdepsConfiguration config, boolean apiOnly) { + this(config.rootModules().stream() + .map(Module::name) + .sorted() + .collect(toMap(Function.identity(), mn -> config.resolve(Set.of(mn)))), + apiOnly); + } + + public ModuleDotGraph(Map configurations, boolean apiOnly) { + this.configurations = configurations; + this.apiOnly = apiOnly; + } + + /** + * Generate dotfile for all modules + * + * @param dir output directory + */ + public boolean genDotFiles(Path dir) throws IOException { + Files.createDirectories(dir); + for (String mn : configurations.keySet()) { + Path path = dir.resolve(mn + ".dot"); + genDotFile(path, mn, configurations.get(mn)); + } + return true; + } + + /** + * Generate dotfile of the given path + */ + public void genDotFile(Path path, String name, Configuration configuration) + throws IOException + { + // transitive reduction + Graph graph = apiOnly + ? requiresTransitiveGraph(configuration, Set.of(name)) + : gengraph(configuration); + + DotGraphBuilder builder = new DotGraphBuilder(name, graph); + builder.subgraph("se", "java", DotGraphBuilder.ORANGE, + DotGraphBuilder.JAVA_SE_SUBGRAPH) + .subgraph("jdk", "jdk", DotGraphBuilder.BLUE, + DotGraphBuilder.JDK_SUBGRAPH) + .descriptors(graph.nodes().stream() + .map(mn -> configuration.findModule(mn).get() + .reference().descriptor())); + // build dot file + builder.build(path); + } + + /** + * Returns a Graph of the given Configuration after transitive reduction. + * + * Transitive reduction of requires transitive edge and requires edge have + * to be applied separately to prevent the requires transitive edges + * (e.g. U -> V) from being reduced by a path (U -> X -> Y -> V) + * in which V would not be re-exported from U. + */ + private Graph gengraph(Configuration cf) { + Graph.Builder builder = new Graph.Builder<>(); + cf.modules().stream() + .forEach(resolvedModule -> { + String mn = resolvedModule.reference().descriptor().name(); + builder.addNode(mn); + resolvedModule.reads().stream() + .map(ResolvedModule::name) + .forEach(target -> builder.addEdge(mn, target)); + }); + + Graph rpg = requiresTransitiveGraph(cf, builder.nodes); + return builder.build().reduce(rpg); + } + + + /** + * Returns a Graph containing only requires transitive edges + * with transitive reduction. + */ + public Graph requiresTransitiveGraph(Configuration cf, + Set roots) + { + Deque deque = new ArrayDeque<>(roots); + Set visited = new HashSet<>(); + Graph.Builder builder = new Graph.Builder<>(); + + while (deque.peek() != null) { + String mn = deque.pop(); + if (visited.contains(mn)) + continue; + + visited.add(mn); + builder.addNode(mn); + ModuleDescriptor descriptor = cf.findModule(mn).get() + .reference().descriptor(); + descriptor.requires().stream() + .filter(d -> d.modifiers().contains(TRANSITIVE) + || d.name().equals("java.base")) + .map(d -> d.name()) + .forEach(d -> { + deque.add(d); + builder.addEdge(mn, d); + }); + } + + return builder.build().reduce(); + } + + public static class DotGraphBuilder { + static final Set JAVA_SE_SUBGRAPH = javaSE(); + static final Set JDK_SUBGRAPH = jdk(); + + private static Set javaSE() { + String root = "java.se.ee"; + ModuleFinder system = ModuleFinder.ofSystem(); + if (system.find(root).isPresent()) { + return Stream.concat(Stream.of(root), + Configuration.empty().resolve(system, + ModuleFinder.of(), + Set.of(root)) + .findModule(root).get() + .reads().stream() + .map(ResolvedModule::name)) + .collect(toSet()); + } else { + // approximation + return system.findAll().stream() + .map(ModuleReference::descriptor) + .map(ModuleDescriptor::name) + .filter(name -> name.startsWith("java.") && + !name.equals("java.smartcardio")) + .collect(Collectors.toSet()); + } + } + + private static Set jdk() { + return ModuleFinder.ofSystem().findAll().stream() + .map(ModuleReference::descriptor) + .map(ModuleDescriptor::name) + .filter(name -> !JAVA_SE_SUBGRAPH.contains(name) && + (name.startsWith("java.") || + name.startsWith("jdk.") || + name.startsWith("javafx."))) + .collect(Collectors.toSet()); + } + + static class SubGraph { + final String name; + final String group; + final String color; + final Set nodes; + SubGraph(String name, String group, String color, Set nodes) { + this.name = Objects.requireNonNull(name); + this.group = Objects.requireNonNull(group); + this.color = Objects.requireNonNull(color); + this.nodes = Objects.requireNonNull(nodes); + } + } + + static final String ORANGE = "#e76f00"; + static final String BLUE = "#437291"; + static final String GRAY = "#dddddd"; + static final String BLACK = "#000000"; + + static final String FONT_NAME = "DejaVuSans"; + static final int FONT_SIZE = 12; + static final int ARROW_SIZE = 1; + static final int ARROW_WIDTH = 2; + static final int RANK_SEP = 1; + + static final String REEXPORTS = ""; + static final String REQUIRES = "style=\"dashed\""; + static final String REQUIRES_BASE = "color=\"" + GRAY + "\""; + + // can be configured + static double rankSep = RANK_SEP; + static String fontColor = BLACK; + static String fontName = FONT_NAME; + static int fontsize = FONT_SIZE; + static int arrowWidth = ARROW_WIDTH; + static int arrowSize = ARROW_SIZE; + static final Map weights = new HashMap<>(); + static final List> ranks = new ArrayList<>(); + + private final String name; + private final Graph graph; + private final Set descriptors = new TreeSet<>(); + private final List subgraphs = new ArrayList<>(); + public DotGraphBuilder(String name, Graph graph) { + this.name = name; + this.graph = graph; + } + + public DotGraphBuilder descriptors(Stream descriptors) { + descriptors.forEach(this.descriptors::add); + return this; + } + + public void build(Path filename) throws IOException { + try (BufferedWriter writer = Files.newBufferedWriter(filename); + PrintWriter out = new PrintWriter(writer)) { + + out.format("digraph \"%s\" {%n", name); + out.format(" nodesep=.5;%n"); + out.format(" ranksep=%f;%n", rankSep); + out.format(" pencolor=transparent;%n"); + out.format(" node [shape=plaintext, fontname=\"%s\", fontsize=%d, margin=\".2,.2\"];%n", + fontName, fontsize); + out.format(" edge [penwidth=%d, color=\"#999999\", arrowhead=open, arrowsize=%d];%n", + arrowWidth, arrowSize); + + // same RANKS + ranks.stream() + .map(nodes -> descriptors.stream() + .map(ModuleDescriptor::name) + .filter(nodes::contains) + .map(mn -> "\"" + mn + "\"") + .collect(joining(","))) + .filter(group -> group.length() > 0) + .forEach(group -> out.format(" {rank=same %s}%n", group)); + + subgraphs.forEach(subgraph -> { + out.format(" subgraph %s {%n", subgraph.name); + descriptors.stream() + .map(ModuleDescriptor::name) + .filter(subgraph.nodes::contains) + .forEach(mn -> printNode(out, mn, subgraph.color, subgraph.group)); + out.format(" }%n"); + }); + + descriptors.stream() + .filter(md -> graph.contains(md.name()) && + !graph.adjacentNodes(md.name()).isEmpty()) + .forEach(md -> printNode(out, md, graph.adjacentNodes(md.name()))); + + out.println("}"); + } + } + + public DotGraphBuilder subgraph(String name, String group, String color, + Set nodes) { + subgraphs.add(new SubGraph(name, group, color, nodes)); + return this; + } + + public void printNode(PrintWriter out, String node, String color, String group) { + out.format(" \"%s\" [fontcolor=\"%s\", group=%s];%n", + node, color, group); + } + + public void printNode(PrintWriter out, ModuleDescriptor md, Set edges) { + Set requiresTransitive = md.requires().stream() + .filter(d -> d.modifiers().contains(TRANSITIVE)) + .map(d -> d.name()) + .collect(toSet()); + + String mn = md.name(); + edges.stream().forEach(dn -> { + String attr = dn.equals("java.base") ? REQUIRES_BASE + : (requiresTransitive.contains(dn) ? REEXPORTS : REQUIRES); + + int w = weightOf(mn, dn); + if (w > 1) { + if (!attr.isEmpty()) + attr += ", "; + + attr += "weight=" + w; + } + out.format(" \"%s\" -> \"%s\" [%s];%n", mn, dn, attr); + }); + } + + public int weightOf(String s, String t) { + int w = weights.getOrDefault(s + ":" + t, 1); + if (w != 1) + return w; + if (s.startsWith("java.") && t.startsWith("java.")) + return 10; + return 1; + } + + public static void sameRankNodes(Set nodes) { + ranks.add(nodes); + } + + public static void weight(String s, String t, int w) { + weights.put(s + ":" + t, w); + } + + public static void setRankSep(double value) { + rankSep = value; + } + + public static void setFontSize(int size) { + fontsize = size; + } + + public static void setFontColor(String color) { + fontColor = color; + } + + public static void setArrowSize(int size) { + arrowSize = size; + } + + public static void setArrowWidth(int width) { + arrowWidth = width; + } + } +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.jdeps/share/classes/module-info.java --- a/langtools/src/jdk.jdeps/share/classes/module-info.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.jdeps/share/classes/module-info.java Thu Feb 16 18:29:03 2017 +0000 @@ -25,6 +25,8 @@ /** Defines tools for analysing dependencies in Java libraries and programs, including * the jdeps and javap tools. + * + * @since 9 */ module jdk.jdeps { requires java.base; diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Thu Feb 16 18:29:03 2017 +0000 @@ -349,9 +349,56 @@ } } + // check that the supplied string represent valid class/module paths + // converting any ~/ to user home + private Collection validPaths(Collection vals, String context, boolean isModulePath) { + Stream result = vals.stream() + .map(s -> Arrays.stream(s.split(File.pathSeparator)) + .map(sp -> toPathResolvingUserHome(sp)) + .filter(p -> checkValidPathEntry(p, context, isModulePath)) + .map(p -> p.toString()) + .collect(Collectors.joining(File.pathSeparator))); + if (failed) { + return Collections.emptyList(); + } else { + return result.collect(toList()); + } + } + + // Adapted from compiler method Locations.checkValidModulePathEntry + private boolean checkValidPathEntry(Path p, String context, boolean isModulePath) { + if (!Files.exists(p)) { + msg("jshell.err.file.not.found", context, p); + failed = true; + return false; + } + if (Files.isDirectory(p)) { + // if module-path, either an exploded module or a directory of modules + return true; + } + + String name = p.getFileName().toString(); + int lastDot = name.lastIndexOf("."); + if (lastDot > 0) { + switch (name.substring(lastDot)) { + case ".jar": + return true; + case ".jmod": + if (isModulePath) { + return true; + } + } + } + msg("jshell.err.arg", context, p); + failed = true; + return false; + } + Options parse(OptionSet options) { - addOptions(OptionKind.CLASS_PATH, options.valuesOf(argClassPath)); - addOptions(OptionKind.MODULE_PATH, options.valuesOf(argModulePath)); + addOptions(OptionKind.CLASS_PATH, + validPaths(options.valuesOf(argClassPath), "--class-path", false)); + addOptions(OptionKind.MODULE_PATH, + validPaths(options.valuesOf(argModulePath), "--module-path", true)); addOptions(OptionKind.ADD_MODULES, options.valuesOf(argAddModules)); addOptions(OptionKind.ADD_EXPORTS, options.valuesOf(argAddExports).stream() .map(mp -> mp.contains("=") ? mp : mp + "=ALL-UNNAMED") diff -r f402e32dfbf3 -r a12e388192c0 langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Thu Feb 16 18:29:03 2017 +0000 @@ -650,7 +650,7 @@ varinit -- variable declaration with init\n\t\ expression -- expression -- note: {name}==scratch-variable-name\n\t\ varvalue -- variable value expression\n\t\ - assignment -- assign variable\n\t\ + assignment -- assign variable\n\ The action selector kind describes what happened to the snippet. The values are:\n\t\ added -- snippet has been added\n\t\ modified -- an existing snippet has been modified\n\t\ diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/C.java --- a/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/C.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/C.java Thu Feb 16 18:29:03 2017 +0000 @@ -71,4 +71,9 @@ * caseA
  • end of sentence.
  • more
*/ public void caseA() {} + + /** + * caseB
A block quote example:
+ */ + public void caseB() {} } diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/Negative.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/Negative.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class Negative { + /** + * case1: A hanging < :
xx
< + */ + public void case1() {} +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java --- a/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java Thu Feb 16 18:29:03 2017 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8048628 + * @bug 8048628 8174715 * @summary Verify html inline tags are removed correctly in the first sentence. * @library ../lib * @modules jdk.javadoc @@ -39,22 +39,34 @@ } @Test - void test() { - javadoc("-d", "out", + void testPositive() { + javadoc("-d", "out1", "-sourcepath", testSrc, testSrc("C.java")); checkExit(Exit.OK); checkOutput("C.html", true, - "
case1 end of sentence.
", - "
case2 end of sentence.
", - "
case3 end of sentence.
", - "
case4 end of sentence.
", - "
case5 end of sentence.
", - "
case6 end of sentence.
", - "
case7 end of sentence.
", - "
case8 end of sentence.
", - "
case9 end of sentence.
", - "
caseA end of sentence.
"); + "
case1 end of sentence.
", + "
case2 end of sentence.
", + "
case3 end of sentence.
", + "
case4 end of sentence.
", + "
case5 end of sentence.
", + "
case6 end of sentence.
", + "
case7 end of sentence.
", + "
case8 end of sentence.
", + "
case9 end of sentence.
", + "
caseA end of sentence.
", + "
caseB A block quote example:
"); + } + + @Test + void testNegative() { + javadoc("-d", "out2", + "-sourcepath", testSrc, + testSrc("Negative.java")); + checkExit(Exit.FAILED); + + checkOutput("Negative.html", true, + "
case1: A hanging < : xx<
"); } } diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java --- a/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java Thu Feb 16 18:29:03 2017 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8072945 8081854 8141492 8148985 8150188 4649116 8173707 + * @bug 8072945 8081854 8141492 8148985 8150188 4649116 8173707 8151743 * @summary Test the version of HTML generated by the javadoc tool. * @author bpatel * @library ../lib @@ -710,6 +710,10 @@ "\n" + "\n" + "
 
\n" + + "\n" + "
", ""); @@ -723,6 +727,10 @@ "\n" + "\n" + "
 
\n" + + "\n" + "
\n" + "

Deprecated API

\n" + "

Contents

", @@ -747,6 +755,10 @@ "\n" + "
\n" + "
 
\n" + + "\n" + "
", "
  • \n" + "

    Package pkg

    "); @@ -761,6 +773,10 @@ "\n" + "
  • \n" + "
     
    \n" + + "\n" + "
    ", "
    \n" + "

    Class Hierarchy

    ", @@ -779,6 +795,10 @@ "\n" + "
    \n" + "
     
    \n" + + "\n" + "
    "); // Negated test for src-html page @@ -797,6 +817,10 @@ "\n" + "
    \n" + "
     
    \n" + + "\n" + "
    ", "
      \n" + "
    • \n" @@ -1005,6 +1029,10 @@ "\n" + "
    \n" + "
     
    \n" + + "\n" + "
    ", "
    ", "
  • \n" @@ -1123,6 +1151,10 @@ "\n" + "\n" + "
     
    \n" + + "\n" + "
    ", "
  • "); @@ -1136,6 +1168,10 @@ "\n" + "\n" + "
     
    \n" + + "\n" + "
    \n" + "

    Deprecated API

    \n" + "

    Contents

    ", @@ -1160,6 +1196,10 @@ "\n" + "
    \n" + "
     
    \n" + + "\n" + "
    ", "
  • \n" + "

    Package pkg

    "); @@ -1175,6 +1215,10 @@ "\n" + "
  • \n" + "
     
    \n" + + "\n" + "
    ", "

    Hierarchy For All Packages

    \n" + "Package Hierarchies:", @@ -1195,6 +1239,10 @@ "\n" + "
    \n" + "
     
    \n" + + "\n" + "
    "); // Test for src-html page @@ -1213,6 +1261,10 @@ "\n" + "
    \n" + "
     
    \n" + + "\n" + "
    ", "
      \n" + "
    • \n" @@ -1421,6 +1473,10 @@ "\n" + "
    \n" + "
     
    \n" + + "\n" + "
    ", "
    ", "
  • \n" diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testJavascript/TestJavascript.java --- a/langtools/test/jdk/javadoc/doclet/testJavascript/TestJavascript.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testJavascript/TestJavascript.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985 8151921 + * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985 8151921 8151743 * @summary Verify that the output has the right javascript. * @author jamieh * @library ../lib @@ -47,7 +47,11 @@ checkExit(Exit.OK); checkOutput("pkg/C.html", true, - "Frames"); + "Frames", + ""); checkOutput("TestJavascript.html", true, "Frames"); @@ -119,5 +123,10 @@ + " }\n" + " catch(err) {\n" + " }"); + + checkOutput("script.js", true, + "$(window).resize(function() {\n" + + " $('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n" + + " });"); } } diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testMissingType/TestMissingType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testMissingType/TestMissingType.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8173804 + * @summary make sure doclet can handle missing types + * @library ../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build JavadocTester + * @run main TestMissingType + */ + +public class TestMissingType extends JavadocTester { + + public static void main(String... args) throws Exception { + TestMissingType tester = new TestMissingType(); + tester.runTests(); + } + + @Test + void test() { + javadoc("-d", "out", + "-use", + "-sourcepath", testSrc, + "p"); + checkExit(Exit.OK); + checkFiles(true, "p/class-use/MissingType.html"); + } +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testMissingType/p/MissingType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testMissingType/p/MissingType.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package p; + +public final class MissingType { + /** + * Do something with a missing type. + * + * @param out use the missing type + */ + public void encode(MissingMe out) {} +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testNavigation/TestNavigation.java --- a/langtools/test/jdk/javadoc/doclet/testNavigation/TestNavigation.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testNavigation/TestNavigation.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4131628 4664607 7025314 8023700 7198273 8025633 8026567 8081854 8150188 + * @bug 4131628 4664607 7025314 8023700 7198273 8025633 8026567 8081854 8150188 8151743 * @summary Make sure the Next/Prev Class links iterate through all types. * Make sure the navagation is 2 columns, not 3. * @author jamieh @@ -77,12 +77,20 @@ "\n" + "\n" + "
     
    \n" + + "\n" + ""); checkOutput("pkg/package-summary.html", true, "\n" + "\n" + "
     
    \n" + + "\n" + "
    "); } @@ -98,6 +106,10 @@ "\n" + "
    \n" + "
     
    \n" + + "\n" + "\n" + "\n" + ""); @@ -106,6 +118,10 @@ "\n" + "\n" + "
     
    \n" + + "\n" + ""); } @@ -121,12 +137,20 @@ "\n" + "\n" + "
     
    \n" + + "\n" + ""); checkOutput("pkg/package-summary.html", false, "\n" + "\n" + "
     
    \n" + + "\n" + "
    "); } @@ -142,6 +166,10 @@ "\n" + "
    \n" + "
     
    \n" + + "\n" + "\n" + "\n" + ""); @@ -150,6 +178,10 @@ "\n" + "\n" + "
     
    \n" + + "\n" + ""); } } diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/C.java --- a/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/C.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/C.java Thu Feb 16 18:29:03 2017 +0000 @@ -71,4 +71,9 @@ * caseA
    • end of sentence.
    • more
    */ public void caseA() {} + + /** + * caseB
    A block quote example:
    + */ + public void caseB() {} } diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/Negative.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/Negative.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class Negative { + /** + * case1: A hanging < :
    xx
    < + */ + public void case1() {} +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java --- a/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java Thu Feb 16 18:29:03 2017 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8048628 + * @bug 8048628 8174715 * @summary Verify html inline tags are removed correctly in the first sentence. * @library ../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -39,8 +39,8 @@ } @Test - void test() { - javadoc("-d", "out", + void testPositive() { + javadoc("-d", "out1", "-sourcepath", testSrc, testSrc("C.java")); checkExit(Exit.OK); @@ -55,6 +55,18 @@ "
    case7 end of sentence.
    ", "
    case8 end of sentence.
    ", "
    case9 end of sentence.
    ", - "
    caseA end of sentence.
    "); + "
    caseA end of sentence.
    ", + "
    caseB A block quote example:
    "); + } + + @Test + void testNegative() { + javadoc("-d", "out2", + "-sourcepath", testSrc, + testSrc("Negative.java")); + checkExit(Exit.ERROR); + + checkOutput("Negative.html", true, + "
    case1: A hanging < : xx<
    "); } } diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testOverridenMethods/TestBadOverride.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testOverridenMethods/TestBadOverride.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8174839 + * @summary Bad overriding method should not crash + * @library ../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build JavadocTester + * @run main TestBadOverride + */ + +public class TestBadOverride extends JavadocTester { + + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String... args) throws Exception { + TestBadOverride tester = new TestBadOverride(); + tester.runTests(); + } + + @Test + void test() { + javadoc("-d", "out", + "-sourcepath", testSrc, + "pkg4"); + checkExit(Exit.OK); + + checkOutput("pkg4/Foo.html", true, + "
  • \n" + + "

    toString

    \n" + + "
    public void toString()
    \n" + + "
    Why can't I do this ?
    \n" + + "
  • "); + } +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testOverridenMethods/pkg4/Foo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testOverridenMethods/pkg4/Foo.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg4; + +public class Foo { + /** + * Why can't I do this ? + */ + public void toString() {} +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java --- a/langtools/test/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testStylesheet/TestStylesheet.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4494033 7028815 7052425 8007338 8023608 8008164 8016549 8072461 8154261 8162363 8160196 + * @bug 4494033 7028815 7052425 8007338 8023608 8008164 8016549 8072461 8154261 8162363 8160196 8151743 * @summary Run tests on doclet stylesheet. * @author jamieh * @library ../lib @@ -159,7 +159,10 @@ + " float:none;\n" + " display:inline;\n" + "}", - "@import url('resources/fonts/dejavu.css');"); + "@import url('resources/fonts/dejavu.css');", + ".navPadding {\n" + + " padding-top: 107px;\n" + + "}"); // Test whether a link to the stylesheet file is inserted properly // in the class documentation. diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/doclet/testXOption/TestXOption.java --- a/langtools/test/jdk/javadoc/doclet/testXOption/TestXOption.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testXOption/TestXOption.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,6 +62,16 @@ } @Test + void testWithHelpExtraOption() { + javadoc("-d", "out1", + "-sourcepath", testSrc, + "--help-extra", + testSrc("TestXOption.java")); + checkExit(Exit.OK); + checkOutput(true); + } + + @Test void testWithOption() { javadoc("-d", "out1", "-sourcepath", testSrc, diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/javadoc/tool/api/basic/AddModulesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/jdk/javadoc/tool/api/basic/AddModulesTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8173596 + * @summary DocumentationTool.DocumentationTask should support addModules + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * @library /tools/lib + * @build APITest toolbox.JavacTask toolbox.ToolBox + * @run main AddModulesTest + */ + +import java.io.StringWriter; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; + +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.DocumentationTool.Location; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +import toolbox.Assert; +import toolbox.JavacTask; +import toolbox.ToolBox; + +/** + * Tests for DocumentationTask.addModules method. + */ +public class AddModulesTest extends APITest { + public static void main(String... args) throws Exception { + new AddModulesTest().run(); + } + + private final ToolBox tb = new ToolBox(); + + /** + * Verify that addModules works as expected. + */ + @Test + public void testAddModules() throws Exception { + Path base = Paths.get("testAddModules"); + Path src = base.resolve("src"); + + // setup some utility modules + Path src_m1 = src.resolve("m1x"); + tb.writeJavaFiles(src_m1, + "module m1x { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2x"); + tb.writeJavaFiles(src_m2, + "module m2x { exports p2; }", + "package p2; public class C2 { }"); + Path modules = base.resolve("modules"); + tb.createDirectories(modules); + + new JavacTask(tb) + .options("--module-source-path", src.toString()) + .outdir(modules) + .files(tb.findJavaFiles(src)) + .run() + .writeAll(); + + // now test access to the modules + Path src2 = base.resolve("src2"); + tb.writeJavaFiles(src2, + "public class Dummy { p1.C1 c1; p2.C2 c2; }"); + Path api = base.resolve("api"); + tb.createDirectories(api); + + DocumentationTool tool = ToolProvider.getSystemDocumentationTool(); + try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { + fm.setLocationFromPaths(StandardLocation.MODULE_PATH, Arrays.asList(modules)); + fm.setLocationFromPaths(Location.DOCUMENTATION_OUTPUT, Arrays.asList(api)); + Iterable files = fm.getJavaFileObjects(tb.findJavaFiles(src2)); + + for (boolean useOption : new boolean[] { false, true }) { + System.err.println("Use --add-modules option: " + useOption); + StringWriter sw = new StringWriter(); + DocumentationTask t = tool.getTask(sw, fm, null, null, null, files); + if (useOption) { + t.addModules(Arrays.asList("m1x", "m2x")); + } + String out; + boolean ok; + try { + ok = t.call(); + } finally { + out = sw.toString(); + System.err.println(out); + } + System.err.println("ok: " + ok); + boolean expectErrors = !useOption; + check(out, "package p1 is not visible", expectErrors); + check(out, "package p2 is not visible", expectErrors); + System.err.println(); + } + } + } + + void check(String out, String text, boolean expected) { + System.err.println("Checking for " + + (expected ? "expected" : "unexpected") + + " text: " + text); + + if (expected) { + if (!out.contains(text)) { + error("expected text not found: " + text); + } + } else { + if (out.contains(text)) { + error("unexpected text found: " + text); + } + } + } +} + diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/jshell/ToolBasicTest.java --- a/langtools/test/jdk/jshell/ToolBasicTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/jdk/jshell/ToolBasicTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 8154714 8166649 8167643 8170162 8172102 8165405 + * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 8154714 8166649 8167643 8170162 8172102 8165405 8174796 8174797 * @summary Tests for Basic tests for REPL tool * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -35,6 +35,7 @@ * @run testng/timeout=600 ToolBasicTest */ +import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; @@ -272,23 +273,58 @@ ); } - public void testClasspathJar() { + private String makeSimpleJar() { Compiler compiler = new Compiler(); Path outDir = Paths.get("testClasspathJar"); compiler.compile(outDir, "package pkg; public class A { public String toString() { return \"A\"; } }"); String jarName = "test.jar"; compiler.jar(outDir, jarName, "pkg/A.class"); - Path jarPath = compiler.getPath(outDir).resolve(jarName); + return compiler.getPath(outDir).resolve(jarName).toString(); + } + + public void testClasspathJar() { + String jarPath = makeSimpleJar(); test( (a) -> assertCommand(a, "/env --class-path " + jarPath, "| Setting new options and restoring state."), (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") ); - test(new String[] { "--class-path", jarPath.toString() }, + test(new String[] { "--class-path", jarPath }, (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") ); } + public void testClasspathUserHomeExpansion() { + String jarPath = makeSimpleJar(); + String tilde = "~" + File.separator; + test( + (a) -> assertCommand(a, "/env --class-path " + tilde + "forblato", + "| File '" + System.getProperty("user.home") + File.separator + + "forblato' for '--class-path' is not found."), + (a) -> assertCommand(a, "/env --class-path " + jarPath + File.pathSeparator + + tilde + "forblato", + "| File '" + System.getProperty("user.home") + File.separator + + "forblato' for '--class-path' is not found.") + ); + } + + public void testBadClasspath() { + String jarPath = makeSimpleJar(); + Compiler compiler = new Compiler(); + Path t1 = compiler.getPath("whatever/thing.zip"); + compiler.writeToFile(t1, ""); + Path t2 = compiler.getPath("whatever/thing.jmod"); + compiler.writeToFile(t2, ""); + test( + (a) -> assertCommand(a, "/env --class-path " + t1.toString(), + "| Invalid '--class-path' argument: " + t1.toString()), + (a) -> assertCommand(a, "/env --class-path " + jarPath + File.pathSeparator + t1.toString(), + "| Invalid '--class-path' argument: " + t1.toString()), + (a) -> assertCommand(a, "/env --class-path " + t2.toString(), + "| Invalid '--class-path' argument: " + t2.toString()) + ); + } + public void testModulePath() { Compiler compiler = new Compiler(); Path modsDir = Paths.get("mods"); @@ -304,6 +340,25 @@ ); } + public void testModulePathUserHomeExpansion() { + String tilde = "~" + File.separatorChar; + test( + (a) -> assertCommand(a, "/env --module-path " + tilde + "snardugol", + "| File '" + System.getProperty("user.home") + + File.separatorChar + "snardugol' for '--module-path' is not found.") + ); + } + + public void testBadModulePath() { + Compiler compiler = new Compiler(); + Path t1 = compiler.getPath("whatever/thing.zip"); + compiler.writeToFile(t1, ""); + test( + (a) -> assertCommand(a, "/env --module-path " + t1.toString(), + "| Invalid '--module-path' argument: " + t1.toString()) + ); + } + public void testStartupFileOption() { Compiler compiler = new Compiler(); Path startup = compiler.getPath("StartupFileOption/startup.txt"); diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/jdk/jshell/ToolSimpleTest.java --- a/langtools/test/jdk/jshell/ToolSimpleTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/jdk/jshell/ToolSimpleTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848 8174041 8173916 8174028 8174262 + * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848 8174041 8173916 8174028 8174262 8174797 * @summary Simple jshell tool tests * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -212,6 +212,14 @@ } @Test + public void testInvalidClassPath() { + test( + a -> assertCommand(a, "/env --class-path snurgefusal", + "| File 'snurgefusal' for '--class-path' is not found.") + ); + } + + @Test public void testNoArgument() { test( (a) -> assertCommand(a, "/save", diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/ServiceImplNotPublic.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/ServiceImplNotPublic.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.not.def.public diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/example/ServiceImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/example/ServiceImpl.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package example; +class ServiceImpl implements example.SomeService { + public ServiceImpl() {} + public void foo() {} +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/example/SomeService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/example/SomeService.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package example; +public interface SomeService { + public void foo(); +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ServiceImplNotPublic/module-info.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +module m { + exports example; + provides example.SomeService with example.ServiceImpl; +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java --- a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -26,6 +26,7 @@ * @bug 8002099 8010822 * @summary Add support for intersection types in cast expression * @modules jdk.compiler/com.sun.tools.javac.util + * @run main/othervm IntersectionTargetTypeTest */ import com.sun.source.util.JavacTask; diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/main/EnvVariableTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/main/EnvVariableTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8173308 + * @summary Check JDK_JAVA_OPTIONS parsing behavior + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.main + * @build toolbox.ToolBox toolbox.TestRunner + * @run main EnvVariableTest + */ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.Path; + +import toolbox.*; + +import com.sun.tools.javac.main.CommandLine; + +public class EnvVariableTest extends TestRunner { + final String testClasses; + final ToolBox tb; + final Path javaExePath; + final ExecTask task; + final PrintStream ostream; + final ByteArrayOutputStream baos; + + public EnvVariableTest() { + super(System.err); + ostream = System.err; + baos = new ByteArrayOutputStream(); + testClasses = System.getProperty("test.classes"); + tb = new ToolBox(); + javaExePath = tb.getJDKTool("java"); + task = new ExecTask(tb, javaExePath); + } + + public static void main(String... args) throws Exception { + EnvVariableTest t = new EnvVariableTest(); + t.runTests(); + } + + @Test + public void testDoubleQuote() throws Exception { + // white space quoted with double quotes + test("-version -cp \"c:\\\\java libs\\\\one.jar\" \n", + "-version", "-cp", "c:\\\\java libs\\\\one.jar"); + } + + @Test + public void testSingleQuote() throws Exception { + // white space quoted with single quotes + test("-version -cp \'c:\\\\java libs\\\\one.jar\' \n", + "-version", "-cp", "c:\\\\java libs\\\\one.jar"); + } + + @Test + public void testEscapeCharacters() throws Exception { + // escaped characters + test("escaped chars testing \"\\a\\b\\c\\f\\n\\r\\t\\v\\9\\6\\23\\82\\28\\377\\477\\278\\287\"", + "escaped", "chars", "testing", "\\a\\b\\c\\f\\n\\r\\t\\v\\9\\6\\23\\82\\28\\377\\477\\278\\287"); + } + + @Test + public void testMixedQuotes() throws Exception { + // more mixing of quote types + test("\"mix 'single quote' in double\" 'mix \"double quote\" in single' partial\"quote me\"this", + "mix 'single quote' in double", "mix \"double quote\" in single", "partialquote methis"); + } + + @Test + public void testWhiteSpaces() throws Exception { + // whitespace tests + test("line one #comment\n'line #2' #rest are comment\r\n#comment on line 3\fline 4 #comment to eof", + "line", "one", "#comment", "line #2", "#rest", "are", "comment", "#comment", "on", "line", + "3", "line", "4", "#comment", "to", "eof"); + } + + @Test + public void testMismatchedDoubleQuote() throws Exception { + // mismatched quote + test("This is an \"open quote \n across line\n\t, note for WS.", + "Exception: JDK_JAVAC_OPTIONS"); + } + + @Test + public void testMismatchedSingleQuote() throws Exception { + // mismatched quote + test("This is an \'open quote \n across line\n\t, note for WS.", + "Exception: JDK_JAVAC_OPTIONS"); + } + + void test(String full, String... expectedArgs) throws Exception { + task.envVar("JDK_JAVAC_OPTIONS", full); + task.args("--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", + "-cp", testClasses, "EnvVariableTest$Tester"); + Task.Result tr = task.run(Task.Expect.SUCCESS); + String expected = Tester.arrayToString(expectedArgs); + String in = tr.getOutput(Task.OutputKind.STDOUT); + System.err.println("Matching..."); + System.err.println("Obtained: " + in); + System.err.println("Expected: " + expected); + if (in.contains(expected)) { + System.err.println("....OK"); + return; + } + throw new Exception("Expected strings not found"); + } + + /** + * A tester class that is invoked to invoke the CommandLine class, and + * print the result. + */ + public static class Tester { + private static final String[] EMPTY_ARRAY = new String[0]; + static String arrayToString(String... args) { + return String.join(", ", args); + } + public static void main(String... args) throws IOException { + try { + String[] argv = CommandLine.parse("JDK_JAVAC_OPTIONS", EMPTY_ARRAY); + System.out.print(arrayToString(argv)); + } catch (CommandLine.UnmatchedQuote ex) { + System.out.print("Exception: " + ex.variableName); + } + } + } +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/modules/AddModulesTest.java --- a/langtools/test/tools/javac/modules/AddModulesTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/modules/AddModulesTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,27 @@ /* * @test + * @bug 8167975 8173596 * @summary Test the --add-modules option * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase + * @build toolbox.Assert toolbox.ToolBox toolbox.JavacTask ModuleTestBase * @run main AddModulesTest */ import java.nio.file.Path; +import java.util.Arrays; +import javax.tools.JavaCompiler; +import javax.tools.JavaCompiler.CompilationTask; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +import toolbox.Assert; import toolbox.JavacTask; import toolbox.Task; @@ -227,5 +237,46 @@ .run() .writeAll(); } + + @Test + public void testAddModulesAPI(Path base) throws Exception { + Path src = base.resolve("src"); + + // setup some utility modules + Path src_m1 = src.resolve("m1x"); + tb.writeJavaFiles(src_m1, + "module m1x { exports p1; }", + "package p1; public class C1 { }"); + Path src_m2 = src.resolve("m2x"); + tb.writeJavaFiles(src_m2, + "module m2x { exports p2; }", + "package p2; public class C2 { }"); + Path modules = base.resolve("modules"); + tb.createDirectories(modules); + + new JavacTask(tb) + .options("--module-source-path", src.toString()) + .outdir(modules) + .files(findJavaFiles(src)) + .run() + .writeAll(); + + // now test access to the modules + Path src2 = base.resolve("src2"); + tb.writeJavaFiles(src2, + "class Dummy { p1.C1 c1; p2.C2 c2; }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { + fm.setLocationFromPaths(StandardLocation.MODULE_PATH, Arrays.asList(modules)); + fm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT, Arrays.asList(classes)); + Iterable files = fm.getJavaFileObjects(findJavaFiles(src2)); + CompilationTask t = c.getTask(null, fm, null, null, null, files); + t.addModules(Arrays.asList("m1x", "m2x")); + Assert.check(t.call()); + } + } } diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/modules/AllDefaultTest.java --- a/langtools/test/tools/javac/modules/AllDefaultTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/modules/AllDefaultTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -23,7 +23,7 @@ /** * @test - * @bug 0000000 + * @bug 8164590 8170691 * @summary Test use of ALL-DEFAULT token * @library /tools/lib * @modules diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java --- a/langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8169197 8172668 8173117 + * @bug 8169197 8172668 8173117 8175007 * @summary Check convenient errors are produced for inaccessible classes. * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -704,4 +704,44 @@ throw new Exception("Expected names not generated: " + actual); } } + + @Test + public void testInaccessibleInVisible(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_ma = src.resolve("ma"); + tb.writeJavaFiles(src_ma, + "module ma { exports ma; }", + "package ma; class NotApi { public static class Inner { } }"); + Path classes = base.resolve("classes"); + tb.createDirectories(classes); + + new JavacTask(tb) + .outdir(classes) + .files(findJavaFiles(src_ma)) + .run() + .writeAll(); + + Path src_mb = src.resolve("mb"); + tb.writeJavaFiles(src_mb, + "module mb { requires ma; }", + "package mb.a; public class Test { ma.NotApi.Inner i1; mb.b.NotApi.Inner i2; }", + "package mb.b; class NotApi { public static class Inner { } }"); + + List log = new JavacTask(tb) + .options("-XDrawDiagnostics", + "--module-path", classes.toString()) + .outdir(classes) + .files(findJavaFiles(src_mb)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + + List expected = Arrays.asList( + "Test.java:1:44: compiler.err.not.def.access.class.intf.cant.access: ma.NotApi.Inner, ma.NotApi", + "Test.java:1:66: compiler.err.not.def.access.class.intf.cant.access: mb.b.NotApi.Inner, mb.b.NotApi", + "2 errors"); + + if (!expected.equals(log)) + throw new Exception("expected output not found; actual: " + log); + } } diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/modules/EnvVarTest.java --- a/langtools/test/tools/javac/modules/EnvVarTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/modules/EnvVarTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* * @test * @bug 8156962 - * @summary Tests use of _JAVAC_OPTIONS env variable + * @summary Tests use of JDK_JAVAC_OPTIONS env variable * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -71,7 +71,7 @@ tb.out.println("test that addExports can be provided with env variable"); new JavacTask(tb, Mode.EXEC) - .envVar("_JAVAC_OPTIONS", "--add-exports jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED") + .envVar("JDK_JAVAC_OPTIONS", "--add-exports jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED") .outdir(classes) .files(findJavaFiles(src)) .run(Expect.SUCCESS) @@ -83,7 +83,7 @@ "--add-exports jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED"); new JavacTask(tb, Mode.EXEC) - .envVar("_JAVAC_OPTIONS", "@" + atFile) + .envVar("JDK_JAVAC_OPTIONS", "@" + atFile) .outdir(classes) .files(findJavaFiles(src)) .run(Expect.SUCCESS) diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java --- a/langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -238,7 +238,7 @@ Arrays.asList("--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED"); List files = Arrays.asList(findJavaFiles(src)); - String envName = "_JAVAC_OPTIONS"; + String envName = "JDK_JAVAC_OPTIONS"; String envValue = String.join(" ", testOpts); out.println(" javac:"); diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/modules/ModuleInfoTest.java --- a/langtools/test/tools/javac/modules/ModuleInfoTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/modules/ModuleInfoTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -557,4 +557,187 @@ throw new Exception("expected output not found for: " + moduleInfo + "; actual: " + log); } } -} + + @Test + public void testMalformedModuleNames(Path base) throws Exception { + testMalformedName(base, "m1.package", "module-info.java:1:11: compiler.err.expected: token.identifier"); + testMalformedName(base, "m1/package", "module-info.java:1:10: compiler.err.expected: '{'"); + testMalformedName(base, "m1->long", "module-info.java:1:10: compiler.err.expected: '{'"); + testMalformedName(base, "m1::long", "module-info.java:1:10: compiler.err.expected: '{'"); + testMalformedName(base, "m1&long", "module-info.java:1:10: compiler.err.expected: '{'"); + testMalformedName(base, "m1%long", "module-info.java:1:10: compiler.err.expected: '{'"); + testMalformedName(base, "m1@long", "module-info.java:1:10: compiler.err.expected: '{'"); + testMalformedName(base, "@m1", "module-info.java:1:7: compiler.err.expected: token.identifier"); + testMalformedName(base, "!", "module-info.java:1:7: compiler.err.expected: token.identifier"); + testMalformedName(base, "m1#long", "module-info.java:1:10: compiler.err.illegal.char: #"); + testMalformedName(base, "m1\\long", "module-info.java:1:10: compiler.err.illegal.char: \\"); + testMalformedName(base, "module.", "module-info.java:1:15: compiler.err.expected: token.identifier"); + testMalformedName(base, ".module", "module-info.java:1:7: compiler.err.expected: token.identifier"); + testMalformedName(base, "1module", "module-info.java:1:7: compiler.err.expected: token.identifier"); + testMalformedName(base, "module module", "module-info.java:1:14: compiler.err.expected: '{'"); + } + + private void testMalformedName(Path base, String name, String expected) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, "module " + name + " { }"); + + Path classes = base.resolve("classes"); + Files.createDirectories(classes); + + String log = new JavacTask(tb) + .options("-XDrawDiagnostics", "--module-source-path", src.toString()) + .outdir(classes) + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains(expected)) + throw new Exception("expected output not found. Name: " + name + " Expected: " + expected); + } + + @Test + public void testWrongOpensTransitiveFlag(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "module M { opens transitive p1; }", + "package p1; public class A { }"); + String log = new JavacTask(tb) + .options("-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("module-info.java:1:28: compiler.err.expected: ';'")) + throw new Exception("expected output not found"); + } + + @Test + public void testWrongOpensStaticFlag(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "module M { opens static p1; }", + "package p1; public class A { }"); + String log = new JavacTask(tb) + .options("-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("module-info.java:1:17: compiler.err.expected: token.identifier")) + throw new Exception("expected output not found"); + } + + @Test + public void testSeveralOpensDirectives(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "module M { opens opens p1; }", + "package p1; public class A { }"); + String log = new JavacTask(tb) + .options("-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("module-info.java:1:23: compiler.err.expected: ';'")) + throw new Exception("expected output not found"); + } + + @Test + public void testUnknownDirective(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "module M { boolean p1; }", + "package p1; public class A { }"); + String log = new JavacTask(tb) + .options("-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("module-info.java:1:11: compiler.err.expected: '}'")) + throw new Exception("expected output not found"); + } + + @Test + public void testUnknownModuleFlag(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "private module M { }", + "package p1; public class A { }"); + String log = new JavacTask(tb) + .options("-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("module-info.java:1:9: compiler.err.mod.not.allowed.here: private")) + throw new Exception("expected output not found"); + } + + @Test + public void testDirectiveOnModuleDeclaration(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "opens module M { }", + "package p1; public class A { }"); + String log = new JavacTask(tb) + .options("-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("module-info.java:1:1: compiler.err.expected.module.or.open")) + throw new Exception("expected output not found"); + } + + @Test + public void testTooOpenModule(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "open open module M { }", + "package p1; public class A { }"); + String log = new JavacTask(tb) + .options("-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("module-info.java:1:6: compiler.err.expected.module")) + throw new Exception("expected output not found"); + } + + @Test + public void testEnumAsModuleFlag(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "enum module M { }", + "package p1; public class A { }"); + String log = new JavacTask(tb) + .options("-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("module-info.java:1:12: compiler.err.expected: '{'")) + throw new Exception("expected output not found"); + } + + @Test + public void testClassInModule(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, "module M { class B { } }", + "package p1; public class A { }"); + String log = new JavacTask(tb) + .options("-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!log.contains("module-info.java:1:11: compiler.err.expected: '}'")) + throw new Exception("expected output not found"); + } +} \ No newline at end of file diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/modules/ProvidesTest.java --- a/langtools/test/tools/javac/modules/ProvidesTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/modules/ProvidesTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -377,7 +377,7 @@ .writeAll() .getOutputLines(Task.OutputKind.DIRECT); - List expected = Arrays.asList("module-info.java:1:34: compiler.err.not.def.public.cant.access: p2.C2, p2", + List expected = Arrays.asList("module-info.java:1:34: compiler.err.not.def.public: p2.C2, p2", "1 error"); if (!output.containsAll(expected)) { throw new Exception("Expected output not found"); diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/modules/WrongErrorMessageForNestedServiceProviderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/modules/WrongErrorMessageForNestedServiceProviderTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8174243 + * @summary incorrect error message for nested service provider + * @library /tools/lib + * @modules + * jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase + * @run main WrongErrorMessageForNestedServiceProviderTest + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; + +import toolbox.JavacTask; +import toolbox.Task; +import toolbox.ToolBox; + +public class WrongErrorMessageForNestedServiceProviderTest extends ModuleTestBase { + public static void main(String... args) throws Exception { + WrongErrorMessageForNestedServiceProviderTest t = new WrongErrorMessageForNestedServiceProviderTest(); + t.runTests(); + } + + private static final String twoServicesModuleDef = + "module m {\n" + + " exports example;\n" + + " provides example.SomeService with example.ServiceImpl;\n" + + " provides example.SomeServiceOuter with example.Outer.ServiceImplOuter;\n" + + "}"; + + private static final String someServiceInt = + "package example;\n" + + "public interface SomeService {\n" + + " public void foo();\n" + + "}"; + + private static final String someServiceIntOuter = + "package example;\n" + + "public interface SomeServiceOuter {\n" + + " public void foo();\n" + + "}"; + + @Test + public void testPositive(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, + twoServicesModuleDef, + someServiceInt, + someServiceIntOuter, + "package example;\n" + + "public class ServiceImpl implements example.SomeService {\n" + + " public ServiceImpl() {}\n" + + " public void foo() {}\n" + + "}", + + "package example;\n" + + "class Outer {\n" + + " public static class ServiceImplOuter implements example.SomeServiceOuter {\n" + + " public ServiceImplOuter() {}\n" + + " public void foo() {}\n" + + " }\n" + + "}"); + Path classes = base.resolve("classes"); + Files.createDirectories(classes); + + List output = new JavacTask(tb) + .outdir(classes) + .options("-Werror", "-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.SUCCESS) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + List expected = Arrays.asList(""); + if (!output.containsAll(expected)) { + throw new Exception("Expected output not found"); + } + } + + @Test + public void testNegative(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, + twoServicesModuleDef, + someServiceInt, + someServiceIntOuter, + + "package example;\n" + + "class ServiceImpl implements example.SomeService {\n" + + " public ServiceImpl() {}\n" + + " public void foo() {}\n" + + "}", + + "package example;\n" + + "class Outer {\n" + + " static class ServiceImplOuter implements example.SomeServiceOuter {\n" + + " public ServiceImplOuter() {}\n" + + " public void foo() {}\n" + + " }\n" + + "}"); + Path classes = base.resolve("classes"); + Files.createDirectories(classes); + + List output = new JavacTask(tb) + .outdir(classes) + .options("-Werror", "-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.FAIL) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + List expected = Arrays.asList( + "module-info.java:3:46: compiler.err.not.def.public: example.ServiceImpl, example", + "module-info.java:4:57: compiler.err.not.def.public: example.Outer.ServiceImplOuter, example.Outer", + "2 errors"); + if (!output.containsAll(expected)) { + throw new Exception("Expected output not found"); + } + } + + @Test + public void testClassWrappedByPrivateClass(Path base) throws Exception { + Path src = base.resolve("src"); + tb.writeJavaFiles(src, + "module m {\n" + + " exports example;\n" + + " provides example.SomeServiceOuter with example.Outer1.Outer2.ServiceImplOuter;\n" + + "}", + + someServiceIntOuter, + + "package example;\n" + + "class Outer1 {\n" + + " static private class Outer2 {\n" + + " public static class ServiceImplOuter implements example.SomeServiceOuter {\n" + + " public ServiceImplOuter() {}\n" + + " public void foo() {}\n" + + " }\n" + + " }\n" + + "}"); + Path classes = base.resolve("classes"); + Files.createDirectories(classes); + + List output = new JavacTask(tb) + .outdir(classes) + .options("-Werror", "-XDrawDiagnostics") + .files(findJavaFiles(src)) + .run(Task.Expect.SUCCESS) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + List expected = Arrays.asList(""); + if (!output.containsAll(expected)) { + throw new Exception("Expected output not found"); + } + } +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/processing/model/util/elements/TestAllFoos.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/util/elements/TestAllFoos.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8173945 + * @summary Test Elements.getAll{Type, Package, Module}Elements + * @library /tools/javac/lib + * @modules java.compiler + * jdk.compiler + * @build JavacTestingAbstractProcessor TestAllFoos + * @compile -processor TestAllFoos -proc:only --release 8 --source-path modules/m1/pkg modules/m1/pkg/C.java + * @compile -processor TestAllFoos -proc:only --release 8 --source-path modules/m2/pkg modules/m2/pkg/C.java + */ +// @compile -processor TestAllFoos -proc:only --module-source-path modules -m m1,m2 + +import java.util.Set; +import static java.util.Objects.*; +import javax.annotation.processing.*; +import static javax.lang.model.SourceVersion.*; +import javax.lang.model.element.*; +import javax.lang.model.util.*; + +/** + * Test basic workings of Elements.getAll{Type, Package, Module}Elements under + * pre- and post-modules. + */ +public class TestAllFoos extends JavacTestingAbstractProcessor { + public boolean process(Set annotations, + RoundEnvironment roundEnv) { + if (!roundEnv.processingOver()) { + boolean expectModules = + (processingEnv.getSourceVersion().compareTo(RELEASE_9) >= 0); + + testSetSize(eltUtils.getAllTypeElements("java.lang.String"), 1); + testSetSize(eltUtils.getAllTypeElements("example.com"), 0); + + if (!expectModules) { + // Expect empty modules set, single package named "pkg" with one type "pkg.C". + testSetSize(eltUtils.getAllModuleElements(), 0); + testSetSize(eltUtils.getAllPackageElements("pkg"), 1); + testSetSize(eltUtils.getAllTypeElements("pkg.C"), 1); + } else { + Set modules = + requireNonNull(eltUtils.getAllModuleElements()); + + ModuleElement m1 = requireNonNull(eltUtils.getModuleElement("m1")); + ModuleElement m2 = requireNonNull(eltUtils.getModuleElement("m2")); + + if (!modules.contains(m1) || + !modules.contains(m2) || + !modules.contains(requireNonNull(eltUtils.getModuleElement("java.base")))) + throw new RuntimeException("Missing modules " + modules); + + // Expect two packages named "pkg" and two types named "pkg.C". + testSetSize(eltUtils.getAllPackageElements("pkg"), 2); + testSetSize(eltUtils.getAllTypeElements("pkg.C"), 2); + } + } + return true; + } + + /** + * Check the set argument against null and throw an exception if + * the set is not of the expected size. + */ + private static Set testSetSize(Set set, int expectedSize) { + requireNonNull(set); + if (set.size() != expectedSize) + throw new RuntimeException("Unexpected size of set " + set); + return set; + } +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/processing/model/util/elements/modules/m1/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m1/module-info.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,4 @@ +/* /nodynamiccopyright/ */ + +module m1 { +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/processing/model/util/elements/modules/m1/pkg/C.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m1/pkg/C.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,11 @@ +/* /nodynamiccopyright/ */ + +package pkg; + +/** + * A lovely description of class C of package pkg in module m1. + */ +public class C { + public C() {} + public static String foo() {return "foo";} +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/processing/model/util/elements/modules/m1/pkg/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m1/pkg/package-info.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,6 @@ +/* /nodynamiccopyright/ */ + +/** + * A lovely description of package pkg in module m1. + */ +package pkg; diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/processing/model/util/elements/modules/m2/module-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m2/module-info.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,4 @@ +/* /nodynamiccopyright/ */ + +module m2 { +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/processing/model/util/elements/modules/m2/pkg/C.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m2/pkg/C.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,11 @@ +/* /nodynamiccopyright/ */ + +package pkg; + +/** + * A lovely description of class C of package pkg in module m2. + */ +public class C { + public C() {} + public static String bar() {return "bar";} +} diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/processing/model/util/elements/modules/m2/pkg/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/util/elements/modules/m2/pkg/package-info.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,6 @@ +/* /nodynamiccopyright/ */ + +/** + * A lovely description of package pkg in module m2. + */ +package pkg; diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/tree/JavacTreeScannerTest.java --- a/langtools/test/tools/javac/tree/JavacTreeScannerTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/tree/JavacTreeScannerTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -41,7 +41,7 @@ * jdk.compiler/com.sun.tools.javac.tree * jdk.compiler/com.sun.tools.javac.util * @build AbstractTreeScannerTest JavacTreeScannerTest - * @run main JavacTreeScannerTest -q -r . + * @run main/othervm JavacTreeScannerTest -q -r . */ import java.io.*; diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/tree/SourceTreeScannerTest.java --- a/langtools/test/tools/javac/tree/SourceTreeScannerTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/tree/SourceTreeScannerTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -41,7 +41,7 @@ * jdk.compiler/com.sun.tools.javac.tree * jdk.compiler/com.sun.tools.javac.util * @build AbstractTreeScannerTest SourceTreeScannerTest - * @run main SourceTreeScannerTest -q -r . + * @run main/othervm SourceTreeScannerTest -q -r . */ import java.io.*; diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/tree/TreePosTest.java --- a/langtools/test/tools/javac/tree/TreePosTest.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/tree/TreePosTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -108,7 +108,7 @@ * jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.tree * jdk.compiler/com.sun.tools.javac.util - * @run main TreePosTest -q -r . + * @run main/othervm TreePosTest -q -r . */ public class TreePosTest { /** diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/javac/varargs/7043922/T7043922.java --- a/langtools/test/tools/javac/varargs/7043922/T7043922.java Thu Feb 16 17:13:01 2017 +0000 +++ b/langtools/test/tools/javac/varargs/7043922/T7043922.java Thu Feb 16 18:29:03 2017 +0000 @@ -28,6 +28,7 @@ * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.util + * @run main/othervm T7043922 */ import com.sun.source.util.JavacTask; diff -r f402e32dfbf3 -r a12e388192c0 langtools/test/tools/jdeps/modules/DotFileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/jdeps/modules/DotFileTest.java Thu Feb 16 18:29:03 2017 +0000 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8173374 + * @summary Tests module dot graph + * @modules java.desktop + * java.sql + * jdk.jdeps/com.sun.tools.jdeps + * @run testng DotFileTest + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Set; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.spi.ToolProvider; +import java.util.stream.Collectors; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertEquals; + +public class DotFileTest { + private static final ToolProvider JDEPS = ToolProvider.findFirst("jdeps") + .orElseThrow(() -> new RuntimeException("jdeps not found")); + + private static final Path DOTS_DIR = Paths.get("dots"); + private static final Path SPEC_DIR = Paths.get("spec"); + + @DataProvider(name = "modules") + public Object[][] modules() { + return new Object[][]{ + {"java.desktop", Set.of("java.datatransfer -> java.base", + "java.desktop -> java.datatransfer", + "java.desktop -> java.prefs", + "java.prefs -> java.xml", + "java.xml -> java.base" ) + }, + { "java.sql", Set.of("java.logging -> java.base", + "java.sql -> java.logging", + "java.sql -> java.xml", + "java.xml -> java.base" ) + } + }; + } + @DataProvider(name = "specVersion") + public Object[][] specVersion() { + return new Object[][]{ + {"java.desktop", Set.of("java.datatransfer -> java.base", + "java.desktop -> java.datatransfer", + "java.desktop -> java.xml", + "java.xml -> java.base") + }, + { "java.sql", Set.of("java.logging -> java.base", + "java.sql -> java.logging", + "java.sql -> java.xml", + "java.xml -> java.base" ) + } + }; + } + + @Test(dataProvider = "modules") + public void test(String name, Set edges) throws Exception { + String[] options = new String[] { + "-dotoutput", DOTS_DIR.toString(), + "-s", "-m", name + }; + assertTrue(JDEPS.run(System.out, System.out, options) == 0); + + Path path = DOTS_DIR.resolve(name + ".dot"); + assertTrue(Files.exists(path)); + Set lines = Files.readAllLines(path).stream() + .filter(l -> l.contains(" -> ")) + .map(this::split) + .collect(Collectors.toSet()); + assertEquals(lines, edges); + } + + @Test(dataProvider = "specVersion") + public void testAPIOnly(String name, Set edges) throws Exception { + String[] options = new String[]{ + "-dotoutput", SPEC_DIR.toString(), + "-s", "-apionly", + "-m", name + }; + assertTrue(JDEPS.run(System.out, System.out, options) == 0); + + Path path = SPEC_DIR.resolve(name + ".dot"); + assertTrue(Files.exists(path)); + Set lines = Files.readAllLines(path).stream() + .filter(l -> l.contains(" -> ")) + .map(this::split) + .collect(Collectors.toSet()); + assertEquals(lines, edges); + } + + static Pattern PATTERN = Pattern.compile(" *\"(\\S+)\" -> \"(\\S+)\" .*"); + String split(String line) { + Matcher pm = PATTERN.matcher(line); + assertTrue(pm.find()); + return String.format("%s -> %s", pm.group(1), pm.group(2)); + } +}