This commit is contained in:
Lana Steuck 2017-02-16 18:29:03 +00:00
commit e9fc6a8286
82 changed files with 2511 additions and 311 deletions

View File

@ -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 @@ public abstract class AbstractProcessor implements Processor {
* 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

View File

@ -291,7 +291,7 @@ public interface Processor {
* @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.

View File

@ -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,12 +68,56 @@ public interface Elements {
* @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) {
return null;
}
/**
* 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<? extends PackageElement> getAllPackageElements(CharSequence name) {
Set<? extends ModuleElement> modules = getAllModuleElements();
if (modules.isEmpty()) {
PackageElement packageElt = getPackageElement(name);
return (packageElt != null) ?
Collections.singleton(packageElt):
Collections.emptySet();
} else {
Set<PackageElement> 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
@ -90,18 +137,62 @@ public interface Elements {
* @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) {
return null;
}
/**
* 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<? extends TypeElement> getAllTypeElements(CharSequence name) {
Set<? extends ModuleElement> modules = getAllModuleElements();
if (modules.isEmpty()) {
TypeElement typeElt = getTypeElement(name);
return (typeElt != null) ?
Collections.singleton(typeElt):
Collections.emptySet();
} else {
Set<TypeElement> 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 @@ public interface Elements {
*
* @param name the name
* @return the named module element, or {@code null} if it cannot be found
* @see #getAllModuleElements
* @since 9
* @spec JPMS
*/
@ -117,6 +209,27 @@ public interface Elements {
return null;
}
/**
* 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<? extends ModuleElement> getAllModuleElements() {
return Collections.emptySet();
}
/**
* Returns the values of an annotation's elements, including defaults.
*

View File

@ -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 @@ public interface DocumentationTool extends Tool, OptionChecker {
*/
interface DocumentationTask extends Callable<Boolean> {
/**
* 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<String> 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

View File

@ -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 @@ public interface JavaCompiler extends Tool, OptionChecker {
* {@linkplain #setProcessors setProcessors} method.
*/
interface CompilationTask extends Callable<Boolean> {
/**
* 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<String> moduleNames);
/**
* Sets processors (for annotation processing). This will
@ -307,7 +318,7 @@ public interface JavaCompiler extends Tool, OptionChecker {
void setProcessors(Iterable<? extends Processor> 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 @@ public interface JavaCompiler extends Tool, OptionChecker {
* in user code.
* @throws IllegalStateException if called more than once
*/
@Override
Boolean call();
}
}

View File

@ -130,7 +130,7 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* 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 {
/**

View File

@ -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;

View File

@ -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
@ -154,6 +154,11 @@ public class BasicJavacTask extends JavacTask {
return JavacTypes.instance(context);
}
@Override @DefinedBy(Api.COMPILER)
public void addModules(Iterable<String> moduleNames) {
throw new IllegalStateException();
}
@Override @DefinedBy(Api.COMPILER)
public void setProcessors(Iterable<? extends Processor> processors) {
throw new IllegalStateException();

View File

@ -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 java.util.concurrent.atomic.AtomicBoolean;
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 @@ public class JavacTaskImpl extends BasicJavacTask {
private ListBuffer<Env<AttrContext>> genList;
private final AtomicBoolean used = new AtomicBoolean();
private Iterable<? extends Processor> processors;
private ListBuffer<String> addModules = new ListBuffer<>();
protected JavacTaskImpl(Context context) {
super(context, true);
@ -101,7 +97,7 @@ public class JavacTaskImpl extends BasicJavacTask {
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 {
@ -113,6 +109,18 @@ public class JavacTaskImpl extends BasicJavacTask {
}
}
@Override @DefinedBy(Api.COMPILER)
public void addModules(Iterable<String> 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<? extends Processor> processors) {
Objects.requireNonNull(processors);

View File

@ -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 @@ public class AttrContext {
*/
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 @@ public class AttrContext {
info.isAnonymousDiamond = isAnonymousDiamond;
info.isNewClass = isNewClass;
info.preferredTreeForDiagnostics = preferredTreeForDiagnostics;
info.visitingServiceImplementation = visitingServiceImplementation;
return info;
}

View File

@ -996,8 +996,18 @@ public class Modules extends JCTree.Visitor {
}
ListBuffer<ClassSymbol> 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) {

View File

@ -307,6 +307,11 @@ public class Resolve {
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 @@ public class Resolve {
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 @@ public class Resolve {
for (S sym : candidates) {
if (validate.test(sym))
return new InvisibleSymbolError(env, suppressError, sym);
return createInvisibleSymbolError(env, suppressError, sym);
}
Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules());
@ -2113,7 +2123,7 @@ public class Resolve {
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 @@ public class Resolve {
return defaultResult;
}
private Symbol createInvisibleSymbolError(Env<AttrContext> 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<AttrContext> 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 @@ public class Resolve {
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(),

View File

@ -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.IOException;
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 @@ public class CommandLine {
* @throws IOException if there is a problem reading any of the @files
*/
public static String[] parse(String[] args) throws IOException {
ListBuffer<String> newArgs = new ListBuffer<>();
List<String> newArgs = new ArrayList<>();
appendParsedCommandArgs(newArgs, Arrays.asList(args));
return newArgs.toArray(new String[newArgs.size()]);
}
private static void appendParsedCommandArgs(List<String> newArgs, List<String> 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<String> 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<String> parse(String envVariable, List<String> args)
throws IOException, UnmatchedQuote {
List<String> inArgs = new ArrayList<>();
appendParsedEnvVariables(inArgs, envVariable);
inArgs.addAll(args);
List<String> 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<String> out = parse(envVariable, Arrays.asList(args));
return out.toArray(new String[out.size()]);
}
private static void loadCmdFile(String name, List<String> 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 @@ public class CommandLine {
}
}
}
@SuppressWarnings("fallthrough")
private static void appendParsedEnvVariables(List<String> 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;
}
}
}

View File

@ -888,7 +888,7 @@ public class JavaCompiler {
public void compile(List<JavaFileObject> sourceFileObject)
throws Throwable {
compile(sourceFileObject, List.nil(), null);
compile(sourceFileObject, List.nil(), null, List.nil());
}
/**
@ -898,10 +898,13 @@ public class JavaCompiler {
* @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<JavaFileObject> sourceFileObjects,
Collection<String> classnames,
Iterable<? extends Processor> processors)
Iterable<? extends Processor> processors,
Collection<String> addModules)
{
if (!taskListener.isEmpty()) {
taskListener.started(new TaskEvent(TaskEvent.Kind.COMPILATION));
@ -932,6 +935,10 @@ public class JavaCompiler {
}
}
for (String moduleName : addModules) {
modules.addExtraAddModules(moduleName);
}
// These method calls must be chained to avoid memory leaks
processAnnotations(
enterTrees(

View File

@ -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.CacheFSInfo;
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 @@ public class Main {
*/
boolean apiMode;
private static final String ENV_OPT_NAME = "JDK_JAVAC_OPTIONS";
/** Result codes.
*/
@ -201,19 +203,12 @@ public class Main {
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 @@ public class Main {
}
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()) {

View File

@ -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;
@ -116,6 +117,14 @@ public class JavacElements implements Elements {
allowModules = source.allowModules();
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public Set<? extends ModuleElement> getAllModuleElements() {
if (allowModules)
return Collections.unmodifiableSet(modules.allModules());
else
return Collections.emptySet();
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public ModuleSymbol getModuleElement(CharSequence name) {
ensureEntered("getModuleElement");

View File

@ -914,6 +914,10 @@ compiler.misc.cant.access.inner.cls.constr=\
compiler.err.not.def.public.cant.access=\
{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 @@ compiler.note.proc.messager=\
# 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}.
#####

View File

@ -377,6 +377,9 @@ javac.err.no.value.for.option=\
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=\

View File

@ -26,6 +26,8 @@
/** Defines the implementation of the
* {@link javax.tools.ToolProvider#getSystemJavaCompiler system Java compiler}
* and its command line equivalent, <em>javac</em>, as well as <em>javah</em>.
*
* @since 9
*/
module jdk.compiler {
requires transitive java.compiler;

View File

@ -1705,7 +1705,6 @@ public class HtmlDocletWriter extends HtmlDocWriter {
if (lessThanPos < 0) {
return text;
}
StringBuilder result = new StringBuilder();
main: while (lessThanPos != -1) {
int currPos = lessThanPos + 1;
@ -1740,17 +1739,16 @@ public class HtmlDocletWriter extends HtmlDocWriter {
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 @@ public class HtmlDocletWriter extends HtmlDocWriter {
('1' <= ch && ch <= '6');
}
private static boolean isWhitespace(char ch) {
return Character.isWhitespace(ch);
}
/**
* Add a link to the stylesheet file.
*

View File

@ -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 @@ public class JavadocTaskImpl implements DocumentationTask {
private Iterable<String> options;
private Iterable<? extends JavaFileObject> fileObjects;
private Locale locale;
private List<String> addModules = new ArrayList<>();
public JavadocTaskImpl(Context context, Class<?> docletClass,
Iterable<String> options, Iterable<? extends JavaFileObject> fileObjects) {
@ -72,6 +78,16 @@ public class JavadocTaskImpl implements DocumentationTask {
this.locale = locale;
}
@Override
public void addModules(Iterable<String> 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 @@ public class JavadocTaskImpl implements DocumentationTask {
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 <T> Iterable<T> nullCheck(Iterable<T> items) {

View File

@ -647,6 +647,13 @@ public class HtmlDocletWriter extends HtmlDocWriter {
tree.addContent(fixedNavDiv);
HtmlTree paddingDiv = HtmlTree.DIV(HtmlStyle.navPadding, Contents.SPACE);
tree.addContent(paddingDiv);
HtmlTree scriptTree = HtmlTree.SCRIPT();
String scriptCode = "<!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\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);

View File

@ -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.Element;
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 @@ public abstract class Configuration {
@Override
public String toString() {
return names.toString();
return Arrays.toString(names);
}
@Override

View File

@ -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.type.TypeMirror;
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.MethodSymbol;
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 @@ public class WorkArounds {
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;

View File

@ -92,6 +92,9 @@ function loadScripts(doc, tag) {
if (!tagSearchIndex) {
createElem(doc, tag, 'tag-search-index.js');
}
$(window).resize(function() {
$('.navPadding').css('padding-top', $('.fixedNav').css("height"));
});
}
function createElem(doc, tag, path) {

View File

@ -144,7 +144,7 @@ Navigation bar styles
margin:0;
}
.navPadding {
padding-top: 100px;
padding-top: 107px;
}
.fixedNav {
position:fixed;

View File

@ -893,7 +893,7 @@ public class Utils {
}
List<? extends Element> methods = te.getEnclosedElements();
for (ExecutableElement ee : ElementFilter.methodsIn(methods)) {
if (elementUtils.overrides(method, ee, origin)) {
if (configuration.workArounds.overrides(method, ee, origin)) {
return ee;
}
}
@ -1885,11 +1885,6 @@ public class Utils {
return visit(t.getComponentType());
}
@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
@ -1900,9 +1895,10 @@ public class Utils {
}
@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);
}

View File

@ -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 @@ public enum ToolOption {
}
},
X("-X", STANDARD) {
HELP_EXTRA("--help-extra -X", STANDARD) {
@Override
public void process(Helper helper) throws OptionException {
throw new OptionException(OK, helper::Xusage);

View File

@ -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.arg=\
main.opt.J.desc=\
Pass <flag> 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\

View File

@ -26,6 +26,8 @@
/** Defines the implementation of the
* {@link javax.tools.ToolProvider#getSystemDocumentationTool system documentation tool}
* and its command line equivalent, <em>javadoc</em>.
*
* @since 9
*/
module jdk.javadoc {
requires transitive java.compiler;

View File

@ -116,7 +116,7 @@ public final class Graph<T> {
.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 final class Graph<T> {
}
public void addNodes(Set<T> nodes) {
nodes.addAll(nodes);
this.nodes.addAll(nodes);
}
public void addEdge(T u, T v) {
@ -335,67 +335,4 @@ public final class Graph<T> {
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<String> javaModules = modules(name ->
(name.startsWith("java.") && !name.equals("java.smartcardio")));
static final Set<String> jdkModules = modules(name ->
(name.startsWith("java.") ||
name.startsWith("jdk.") ||
name.startsWith("javafx.")) && !javaModules.contains(name));
private static Set<String> modules(Predicate<String> 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<String> 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<String> graph,
String node, Set<String> 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);
});
}
}
}

View File

@ -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
@ -206,16 +206,6 @@ public class JdepsConfiguration implements AutoCloseable {
ALL_SYSTEM.equals(name);
}
/**
* Returns the modules that the given module can read
*/
public Stream<Module> 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 @@ public class JdepsConfiguration implements AutoCloseable {
return nameToModule;
}
public Stream<Module> resolve(Set<String> 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<String> roots) {
if (roots.isEmpty())
throw new IllegalArgumentException("empty roots");
return Configuration.empty()
.resolve(finder, ModuleFinder.of(), roots);
}
public List<Archive> classPathArchives() {

View File

@ -721,9 +721,9 @@ class JdepsTask {
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 @@ class JdepsTask {
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();

View File

@ -59,14 +59,9 @@ public class ModuleAnalyzer {
private final JdepsConfiguration configuration;
private final PrintWriter log;
private final DependencyFinder dependencyFinder;
private final Map<Module, ModuleDeps> modules;
public ModuleAnalyzer(JdepsConfiguration config,
PrintWriter log) {
this(config, log, Collections.emptySet());
}
public ModuleAnalyzer(JdepsConfiguration config,
PrintWriter log,
Set<String> names) {
@ -333,88 +328,6 @@ public class ModuleAnalyzer {
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<Module> modules = configuration.resolve(Set.of(name))
.collect(Collectors.toSet());
// transitive reduction
Graph<String> 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<String> 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<String> gengraph(Set<Module> modules) {
// build a Graph containing only requires transitive edges
// with transitive reduction.
Graph.Builder<String> 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<String> rpg = rpgbuilder.build().reduce();
// build the readability graph
Graph.Builder<String> 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()

View File

@ -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<String, Configuration> 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<String, Configuration> 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<String> 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<String> gengraph(Configuration cf) {
Graph.Builder<String> 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<String> rpg = requiresTransitiveGraph(cf, builder.nodes);
return builder.build().reduce(rpg);
}
/**
* Returns a Graph containing only requires transitive edges
* with transitive reduction.
*/
public Graph<String> requiresTransitiveGraph(Configuration cf,
Set<String> roots)
{
Deque<String> deque = new ArrayDeque<>(roots);
Set<String> visited = new HashSet<>();
Graph.Builder<String> 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<String> JAVA_SE_SUBGRAPH = javaSE();
static final Set<String> JDK_SUBGRAPH = jdk();
private static Set<String> 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<String> 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<String> nodes;
SubGraph(String name, String group, String color, Set<String> 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<String, Integer> weights = new HashMap<>();
static final List<Set<String>> ranks = new ArrayList<>();
private final String name;
private final Graph<String> graph;
private final Set<ModuleDescriptor> descriptors = new TreeSet<>();
private final List<SubGraph> subgraphs = new ArrayList<>();
public DotGraphBuilder(String name, Graph<String> graph) {
this.name = name;
this.graph = graph;
}
public DotGraphBuilder descriptors(Stream<ModuleDescriptor> 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<String> 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<String> edges) {
Set<String> 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<String> 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;
}
}
}

View File

@ -25,6 +25,8 @@
/** Defines tools for analysing dependencies in Java libraries and programs, including
* the <em>jdeps</em> and <em>javap</em> tools.
*
* @since 9
*/
module jdk.jdeps {
requires java.base;

View File

@ -349,9 +349,56 @@ public class JShellTool implements MessageHandler {
}
}
// check that the supplied string represent valid class/module paths
// converting any ~/ to user home
private Collection<String> validPaths(Collection<String> vals, String context, boolean isModulePath) {
Stream<String> 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")

View File

@ -650,7 +650,7 @@ The case selector kind describes the kind of snippet. The values are:\n\t\
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\

View File

@ -71,4 +71,9 @@ public class C {
* caseA <ul type='"a">b'> <li> end of sentence. <li> more </ul>
*/
public void caseA() {}
/**
* caseB <blockquote>A block quote example:</blockquote>
*/
public void caseB() {}
}

View File

@ -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 &lt; : <blockquote>xx</blockquote><
*/
public void case1() {}
}

View File

@ -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 @@ public class TestNonInlineHtmlTagRemoval extends JavadocTester {
}
@Test
void test() {
javadoc("-d", "out",
void testPositive() {
javadoc("-d", "out1",
"-sourcepath", testSrc,
testSrc("C.java"));
checkExit(Exit.OK);
checkOutput("C.html", true,
"<div class=\"block\">case1 end of sentence.</div>",
"<div class=\"block\">case2 end of sentence.</div>",
"<div class=\"block\">case3 end of sentence.</div>",
"<div class=\"block\">case4 end of sentence.</div>",
"<div class=\"block\">case5 end of sentence.</div>",
"<div class=\"block\">case6 end of sentence.</div>",
"<div class=\"block\">case7 end of sentence.</div>",
"<div class=\"block\">case8 end of sentence.</div>",
"<div class=\"block\">case9 end of sentence.</div>",
"<div class=\"block\">caseA end of sentence.</div>");
"<div class=\"block\">case1 end of sentence.</div>",
"<div class=\"block\">case2 end of sentence.</div>",
"<div class=\"block\">case3 end of sentence.</div>",
"<div class=\"block\">case4 end of sentence.</div>",
"<div class=\"block\">case5 end of sentence.</div>",
"<div class=\"block\">case6 end of sentence.</div>",
"<div class=\"block\">case7 end of sentence.</div>",
"<div class=\"block\">case8 end of sentence.</div>",
"<div class=\"block\">case9 end of sentence.</div>",
"<div class=\"block\">caseA end of sentence.</div>",
"<div class=\"block\">caseB A block quote example:</div>");
}
@Test
void testNegative() {
javadoc("-d", "out2",
"-sourcepath", testSrc,
testSrc("Negative.java"));
checkExit(Exit.FAILED);
checkOutput("Negative.html", true,
"<div class=\"block\">case1: A hanging &lt; : xx<</div>");
}
}

View File

@ -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 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">",
"<table class=\"constantsSummary\" summary=\"Constant Field Values table, listing constant fields, and values\">");
@ -723,6 +727,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">\n"
+ "<h1 title=\"Deprecated API\" class=\"title\">Deprecated API</h1>\n"
+ "<h2 title=\"Contents\">Contents</h2>",
@ -747,6 +755,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">",
"<li class=\"blockList\">\n"
+ "<h2 title=\"Package\">Package&nbsp;pkg</h2>");
@ -761,6 +773,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">",
"<div class=\"contentContainer\">\n"
+ "<h2 title=\"Class Hierarchy\">Class Hierarchy</h2>",
@ -779,6 +795,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"contentContainer\">");
// Negated test for src-html page
@ -797,6 +817,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">",
"<ul class=\"blockList\">\n"
+ "<li class=\"blockList\">\n"
@ -1005,6 +1029,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">",
"<table class=\"useSummary\" summary=\"Use table, listing packages, and an explanation\">",
"<li class=\"blockList\"><a name=\"pkg\">\n"
@ -1123,6 +1151,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">",
"<table class=\"constantsSummary\" summary=\"Constant Field Values table, listing constant fields, and values\">");
@ -1136,6 +1168,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">\n"
+ "<h1 title=\"Deprecated API\" class=\"title\">Deprecated API</h1>\n"
+ "<h2 title=\"Contents\">Contents</h2>",
@ -1160,6 +1196,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">",
"<li class=\"blockList\">\n"
+ "<h2 title=\"Package\">Package&nbsp;pkg</h2>");
@ -1175,6 +1215,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">",
"<h1 class=\"title\">Hierarchy For All Packages</h1>\n"
+ "<span class=\"packageHierarchyLabel\">Package Hierarchies:</span>",
@ -1195,6 +1239,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"contentContainer\">");
// Test for src-html page
@ -1213,6 +1261,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">",
"<ul class=\"blockList\">\n"
+ "<li class=\"blockList\">\n"
@ -1421,6 +1473,10 @@ public class TestHtmlVersion extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">",
"<table class=\"useSummary\" summary=\"Use table, listing packages, and an explanation\">",
"<li class=\"blockList\"><a name=\"pkg\">\n"

View File

@ -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 @@ public class TestJavascript extends JavadocTester {
checkExit(Exit.OK);
checkOutput("pkg/C.html", true,
"<a href=\"../index.html?pkg/C.html\" target=\"_top\">Frames</a>");
"<a href=\"../index.html?pkg/C.html\" target=\"_top\">Frames</a>",
"<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>");
checkOutput("TestJavascript.html", true,
"<a href=\"index.html?TestJavascript.html\" target=\"_top\">Frames</a>");
@ -119,5 +123,10 @@ public class TestJavascript extends JavadocTester {
+ " }\n"
+ " catch(err) {\n"
+ " }");
checkOutput("script.js", true,
"$(window).resize(function() {\n"
+ " $('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ " });");
}
}

View File

@ -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");
}
}

View File

@ -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) {}
}

View File

@ -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 @@ public class TestNavigation extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<!-- ======== START OF CLASS DATA ======== -->");
checkOutput("pkg/package-summary.html", true,
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">");
}
@ -98,6 +106,10 @@ public class TestNavigation extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "</nav>\n"
+ "</header>\n"
+ "<!-- ======== START OF CLASS DATA ======== -->");
@ -106,6 +118,10 @@ public class TestNavigation extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "</nav>");
}
@ -121,12 +137,20 @@ public class TestNavigation extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<!-- ======== START OF CLASS DATA ======== -->");
checkOutput("pkg/package-summary.html", false,
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "<div class=\"header\">");
}
@ -142,6 +166,10 @@ public class TestNavigation extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "</nav>\n"
+ "</header>\n"
+ "<!-- ======== START OF CLASS DATA ======== -->");
@ -150,6 +178,10 @@ public class TestNavigation extends JavadocTester {
"<!-- ========= END OF TOP NAVBAR ========= -->\n"
+ "</div>\n"
+ "<div class=\"navPadding\">&nbsp;</div>\n"
+ "<script type=\"text/javascript\"><!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n"
+ "</script>\n"
+ "</nav>");
}
}

View File

@ -71,4 +71,9 @@ public class C {
* caseA <ul type='"a">b'> <li> end of sentence. <li> more </ul>
*/
public void caseA() {}
/**
* caseB <blockquote>A block quote example:</blockquote>
*/
public void caseB() {}
}

View File

@ -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 &lt; : <blockquote>xx</blockquote><
*/
public void case1() {}
}

View File

@ -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 @@ public class TestNonInlineHtmlTagRemoval extends JavadocTester {
}
@Test
void test() {
javadoc("-d", "out",
void testPositive() {
javadoc("-d", "out1",
"-sourcepath", testSrc,
testSrc("C.java"));
checkExit(Exit.OK);
@ -55,6 +55,18 @@ public class TestNonInlineHtmlTagRemoval extends JavadocTester {
"<div class=\"block\">case7 end of sentence.</div>",
"<div class=\"block\">case8 end of sentence.</div>",
"<div class=\"block\">case9 end of sentence.</div>",
"<div class=\"block\">caseA end of sentence.</div>");
"<div class=\"block\">caseA end of sentence.</div>",
"<div class=\"block\">caseB A block quote example:</div>");
}
@Test
void testNegative() {
javadoc("-d", "out2",
"-sourcepath", testSrc,
testSrc("Negative.java"));
checkExit(Exit.ERROR);
checkOutput("Negative.html", true,
"<div class=\"block\">case1: A hanging &lt; : xx<</div>");
}
}

View File

@ -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,
"<li class=\"blockList\">\n"
+ "<h4>toString</h4>\n"
+ "<pre>public&nbsp;void&nbsp;toString()</pre>\n"
+ "<div class=\"block\">Why can't I do this ?</div>\n"
+ "</li>");
}
}

View File

@ -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() {}
}

View File

@ -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 @@ public class TestStylesheet extends JavadocTester {
+ " 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.

View File

@ -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
@ -61,6 +61,16 @@ public class TestXOption extends JavadocTester {
}
}
@Test
void testWithHelpExtraOption() {
javadoc("-d", "out1",
"-sourcepath", testSrc,
"--help-extra",
testSrc("TestXOption.java"));
checkExit(Exit.OK);
checkOutput(true);
}
@Test
void testWithOption() {
javadoc("-d", "out1",

View File

@ -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<? extends JavaFileObject> 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);
}
}
}
}

View File

@ -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 class ToolBasicTest extends ReplToolTesting {
);
}
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 class ToolBasicTest extends ReplToolTesting {
);
}
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");

View File

@ -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
@ -211,6 +211,14 @@ public class ToolSimpleTest extends ReplToolTesting {
test(after -> assertCommand(after, "/env --class-path", "| Argument to class-path missing."));
}
@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(

View File

@ -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

View File

@ -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() {}
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}
}
}
}

View File

@ -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 @@ public class AddModulesTest extends ModuleTestBase {
.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<? extends JavaFileObject> 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());
}
}
}

View File

@ -23,7 +23,7 @@
/**
* @test
* @bug 0000000
* @bug 8164590 8170691
* @summary Test use of ALL-DEFAULT token
* @library /tools/lib
* @modules

View File

@ -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 @@ public class ConvenientAccessErrorsTest extends ModuleTestBase {
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<String> 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<String> 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);
}
}

View File

@ -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 @@ public class EnvVarTest extends ModuleTestBase {
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 @@ public class EnvVarTest extends ModuleTestBase {
"--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)

View File

@ -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 @@ public class InheritRuntimeEnvironmentTest extends ModuleTestBase {
Arrays.asList("--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED");
List<Path> files = Arrays.asList(findJavaFiles(src));
String envName = "_JAVAC_OPTIONS";
String envName = "JDK_JAVAC_OPTIONS";
String envValue = String.join(" ", testOpts);
out.println(" javac:");

View File

@ -557,4 +557,187 @@ public class ModuleInfoTest extends ModuleTestBase {
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");
}
}

View File

@ -377,7 +377,7 @@ public class ProvidesTest extends ModuleTestBase {
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
List<String> expected = Arrays.asList("module-info.java:1:34: compiler.err.not.def.public.cant.access: p2.C2, p2",
List<String> 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");

View File

@ -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<String> output = new JavacTask(tb)
.outdir(classes)
.options("-Werror", "-XDrawDiagnostics")
.files(findJavaFiles(src))
.run(Task.Expect.SUCCESS)
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
List<String> 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<String> output = new JavacTask(tb)
.outdir(classes)
.options("-Werror", "-XDrawDiagnostics")
.files(findJavaFiles(src))
.run(Task.Expect.FAIL)
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
List<String> 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<String> output = new JavacTask(tb)
.outdir(classes)
.options("-Werror", "-XDrawDiagnostics")
.files(findJavaFiles(src))
.run(Task.Expect.SUCCESS)
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
List<String> expected = Arrays.asList("");
if (!output.containsAll(expected)) {
throw new Exception("Expected output not found");
}
}
}

View File

@ -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<? extends TypeElement> 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<? extends ModuleElement> 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 <E> Set<E> testSetSize(Set<E> set, int expectedSize) {
requireNonNull(set);
if (set.size() != expectedSize)
throw new RuntimeException("Unexpected size of set " + set);
return set;
}
}

View File

@ -0,0 +1,4 @@
/* /nodynamiccopyright/ */
module m1 {
}

View File

@ -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";}
}

View File

@ -0,0 +1,6 @@
/* /nodynamiccopyright/ */
/**
* A lovely description of package pkg in module m1.
*/
package pkg;

View File

@ -0,0 +1,4 @@
/* /nodynamiccopyright/ */
module m2 {
}

View File

@ -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";}
}

View File

@ -0,0 +1,6 @@
/* /nodynamiccopyright/ */
/**
* A lovely description of package pkg in module m2.
*/
package pkg;

View File

@ -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.*;

View File

@ -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.*;

View File

@ -108,7 +108,7 @@ import static com.sun.tools.javac.util.Position.NOPOS;
* 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 {
/**

View File

@ -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;

View File

@ -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<String> 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<String> 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<String> 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<String> 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));
}
}