8169069: Module system implementation refresh (11/2016)

Co-authored-by: Jonathan Gibbons <jonathan.gibbons@oracle.com>
Co-authored-by: Jan Lahoda <jan.lahoda@oracle.com>
Co-authored-by: Mandy Chung <mandy.chung@oracle.com>
Co-authored-by: Bhavesh Patel <bhavesh.x.patel@oracle.com>
Co-authored-by: Andrey Nazarov <andrey.x.nazarov@oracle.com>
Reviewed-by: mcimadamore, jjg, mchung, anazarov
This commit is contained in:
Alan Bateman 2016-12-01 09:02:42 +00:00
parent 51f50b64e5
commit 22e233b2e9
214 changed files with 5453 additions and 1175 deletions

View File

@ -96,10 +96,12 @@ public interface ModuleElement extends Element, QualifiedNameable {
* @since 9
*/
enum DirectiveKind {
/** A "requires [public] module-name" directive. */
/** A "requires (static|transitive)* module-name" directive. */
REQUIRES,
/** An "exports package-name [to module-name-list]" directive. */
EXPORTS,
/** An "opens package-name [to module-name-list]" directive. */
OPENS,
/** A "uses service-name" directive. */
USES,
/** A "provides service-name with implementation-name" directive. */
@ -127,10 +129,16 @@ public interface ModuleElement extends Element, QualifiedNameable {
*/
interface RequiresDirective extends Directive {
/**
* Returns whether or not this is a public dependency.
* @return whether or not this is a public dependency
* Returns whether or not this is a static dependency.
* @return whether or not this is a static dependency
*/
boolean isPublic();
boolean isStatic();
/**
* Returns whether or not this is a transitive dependency.
* @return whether or not this is a transitive dependency
*/
boolean isTransitive();
/**
* Returns the module that is required
@ -144,6 +152,7 @@ public interface ModuleElement extends Element, QualifiedNameable {
* @since 9
*/
interface ExportsDirective extends Directive {
/**
* Returns the package being exported.
* @return the package being exported
@ -159,6 +168,27 @@ public interface ModuleElement extends Element, QualifiedNameable {
List<? extends ModuleElement> getTargetModules();
}
/**
* An opened package of a module.
* @since 9
*/
interface OpensDirective extends Directive {
/**
* Returns the package being opened.
* @return the package being opened
*/
PackageElement getPackage();
/**
* Returns the specific modules to which the package is being open
* or null, if the package is open all modules which
* have readability to this module.
* @return the specific modules to which the package is being opened
*/
List<? extends ModuleElement> getTargetModules();
}
/**
* An implementation of a service provided by a module.
* @since 9
@ -171,10 +201,10 @@ public interface ModuleElement extends Element, QualifiedNameable {
TypeElement getService();
/**
* Returns the implementation of the service being provided.
* @return the implementation of the service being provided
* Returns the implementations of the service being provided.
* @return the implementations of the service being provided
*/
TypeElement getImplementation();
List<? extends TypeElement> getImplementations();
}
/**

View File

@ -39,11 +39,12 @@ import java.util.List;
* @since 9
*/
public interface ExportsTree extends DirectiveTree {
/**
* Returns the name of the package to be exported.
* @return the name of the package to be exported
*/
ExpressionTree getExportName();
ExpressionTree getPackageName();
/**
* Returns the names of the modules to which the package is exported,

View File

@ -33,7 +33,8 @@ import java.util.List;
*
* For example:
* <pre>
* module <em>module-name</em> {
* <em>annotations</em>
* [open] module <em>module-name</em> {
* <em>directives</em>
* }
* </pre>
@ -41,6 +42,18 @@ import java.util.List;
* @since 9
*/
public interface ModuleTree extends Tree {
/**
* Returns the annotations associated with this module declaration.
* @return the annotations
*/
List<? extends AnnotationTree> getAnnotations();
/**
* Returns the type of this module.
* @return the type of this module
*/
ModuleKind getModuleType();
/**
* Returns the name of the module.
* @return the name of the module
@ -52,4 +65,19 @@ public interface ModuleTree extends Tree {
* @return the directives in the module declaration
*/
List<? extends DirectiveTree> getDirectives();
/**
* The kind of the module.
*/
enum ModuleKind {
/**
* Open module.
*/
OPEN,
/**
* Strong module.
*/
STRONG;
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2009, 2016, 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.source.tree;
import java.util.List;
/**
* A tree node for an 'opens' directive in a module declaration.
*
* For example:
* <pre>
* opens <em>package-name</em>;
* opens <em>package-name</em> to <em>module-name</em>;
* </pre>
*
* @since 9
*/
public interface OpensTree extends DirectiveTree {
/**
* Returns the name of the package to be opened.
* @return the name of the package to be opened
*/
ExpressionTree getPackageName();
/**
* Returns the names of the modules to which the package is opened,
* or null, if the package is opened to all modules.
*
* @return the names of the modules to which the package is opened, or null
*/
List<? extends ExpressionTree> getModuleNames();
}

View File

@ -25,6 +25,8 @@
package com.sun.source.tree;
import java.util.List;
/**
* A tree node for a 'provides' directive in a module declaration.
*
@ -43,8 +45,8 @@ public interface ProvidesTree extends DirectiveTree {
ExpressionTree getServiceName();
/**
* Returns the name of the implementation type being provided.
* @return the name of the implementation type being provided
* Returns the names of the implementation types being provided.
* @return the names of the implementation types being provided
*/
ExpressionTree getImplementationName();
List<? extends ExpressionTree> getImplementationNames();
}

View File

@ -31,17 +31,24 @@ package com.sun.source.tree;
* For example:
* <pre>
* requires <em>module-name</em>;
* requires public <em>module-name</em>;
* requires static <em>module-name</em>;
* requires transitive <em>module-name</em>;
* </pre>
*
* @since 9
*/
public interface RequiresTree extends DirectiveTree {
/**
* Returns true if this is a "requires public" directive.
* @return true if this is a "requires public" directive
* Returns true if this is a "requires static" directive.
* @return true if this is a "requires static" directive
*/
boolean isPublic();
boolean isStatic();
/**
* Returns true if this is a "requires transitive" directive.
* @return true if this is a "requires transitive" directive
*/
boolean isTransitive();
/**
* Returns the name of the module that is required.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2016, 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
@ -610,25 +610,31 @@ public interface Tree {
/**
* Used for instances of {@link ExportsTree} representing
* export directives in a module declaration.
* exports directives in a module declaration.
*/
EXPORTS(ExportsTree.class),
/**
* Used for instances of {@link ExportsTree} representing
* opens directives in a module declaration.
*/
OPENS(OpensTree.class),
/**
* Used for instances of {@link ProvidesTree} representing
* export directives in a module declaration.
* provides directives in a module declaration.
*/
PROVIDES(ProvidesTree.class),
/**
* Used for instances of {@link RequiresTree} representing
* export directives in a module declaration.
* requires directives in a module declaration.
*/
REQUIRES(RequiresTree.class),
/**
* Used for instances of {@link UsesTree} representing
* export directives in a module declaration.
* uses directives in a module declaration.
*/
USES(UsesTree.class),

View File

@ -497,6 +497,14 @@ public interface TreeVisitor<R,P> {
*/
R visitExports(ExportsTree node, P p);
/**
* Visits an OpensTree node.
* @param node the node being visited
* @param p a parameter value
* @return a result value
*/
R visitOpens(OpensTree node, P p);
/**
* Visits a ProvidesTree node.
* @param node the node being visited

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2016, 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
@ -728,6 +728,11 @@ public class SimpleTreeVisitor <R,P> implements TreeVisitor<R,P> {
return defaultAction(node, p);
}
@Override
public R visitOpens(OpensTree node, P p) {
return defaultAction(node, p);
}
@Override
public R visitProvides(ProvidesTree node, P p) {
return defaultAction(node, p);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2016, 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
@ -846,28 +846,41 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
return r;
}
@Override
public R visitModule(ModuleTree node, P p) {
R r = scan(node.getName(), p);
R r = scan(node.getAnnotations(), p);
r = scanAndReduce(node.getName(), p, r);
r = scanAndReduce(node.getDirectives(), p, r);
return r;
}
@Override
public R visitExports(ExportsTree node, P p) {
R r = scan(node.getExportName(), p);
R r = scan(node.getPackageName(), p);
r = scanAndReduce(node.getModuleNames(), p, r);
return r;
}
public R visitProvides(ProvidesTree node, P p) {
R r = scan(node.getServiceName(), p);
r = scanAndReduce(node.getImplementationName(), p, r);
@Override
public R visitOpens(OpensTree node, P p) {
R r = scan(node.getPackageName(), p);
r = scanAndReduce(node.getModuleNames(), p, r);
return r;
}
@Override
public R visitProvides(ProvidesTree node, P p) {
R r = scan(node.getServiceName(), p);
r = scanAndReduce(node.getImplementationNames(), p, r);
return r;
}
@Override
public R visitRequires(RequiresTree node, P p) {
return scan(node.getModuleName(), p);
}
@Override
public R visitUses(UsesTree node, P p) {
return scan(node.getServiceName(), p);
}

View File

@ -29,13 +29,16 @@ import java.io.IOException;
import java.nio.file.Path;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
@ -558,17 +561,17 @@ public class ClassFinder {
if (wantClassFiles && (classLocn != null)) {
fillIn(p, classLocn,
fileManager.list(classLocn,
packageName,
classKinds,
false));
list(classLocn,
p,
packageName,
classKinds));
}
if (wantSourceFiles && (sourceLocn != null)) {
fillIn(p, sourceLocn,
fileManager.list(sourceLocn,
packageName,
sourceKinds,
false));
list(sourceLocn,
p,
packageName,
sourceKinds));
}
}
@ -620,23 +623,23 @@ public class ClassFinder {
String packageName = p.fullname.toString();
if (wantSourceFiles && !haveSourcePath) {
fillIn(p, CLASS_PATH,
fileManager.list(CLASS_PATH,
packageName,
kinds,
false));
list(CLASS_PATH,
p,
packageName,
kinds));
} else {
if (wantClassFiles)
fillIn(p, CLASS_PATH,
fileManager.list(CLASS_PATH,
packageName,
classKinds,
false));
list(CLASS_PATH,
p,
packageName,
classKinds));
if (wantSourceFiles)
fillIn(p, SOURCE_PATH,
fileManager.list(SOURCE_PATH,
packageName,
sourceKinds,
false));
list(SOURCE_PATH,
p,
packageName,
sourceKinds));
}
}
@ -645,12 +648,12 @@ public class ClassFinder {
*/
private void scanPlatformPath(PackageSymbol p) throws IOException {
fillIn(p, PLATFORM_CLASS_PATH,
fileManager.list(PLATFORM_CLASS_PATH,
p.fullname.toString(),
allowSigFiles ? EnumSet.of(JavaFileObject.Kind.CLASS,
JavaFileObject.Kind.OTHER)
: EnumSet.of(JavaFileObject.Kind.CLASS),
false));
list(PLATFORM_CLASS_PATH,
p,
p.fullname.toString(),
allowSigFiles ? EnumSet.of(JavaFileObject.Kind.CLASS,
JavaFileObject.Kind.OTHER)
: EnumSet.of(JavaFileObject.Kind.CLASS)));
}
// where
@SuppressWarnings("fallthrough")
@ -662,10 +665,7 @@ public class ClassFinder {
for (JavaFileObject fo : files) {
switch (fo.getKind()) {
case OTHER:
boolean sigFile = location == PLATFORM_CLASS_PATH &&
allowSigFiles &&
fo.getName().endsWith(".sig");
if (!sigFile) {
if (!isSigFile(location, fo)) {
extraFileActions(p, fo);
break;
}
@ -682,10 +682,61 @@ public class ClassFinder {
}
default:
extraFileActions(p, fo);
break;
}
}
}
boolean isSigFile(Location location, JavaFileObject fo) {
return location == PLATFORM_CLASS_PATH &&
allowSigFiles &&
fo.getName().endsWith(".sig");
}
Iterable<JavaFileObject> list(Location location,
PackageSymbol p,
String packageName,
Set<Kind> kinds) throws IOException {
Iterable<JavaFileObject> listed = fileManager.list(location,
packageName,
EnumSet.allOf(Kind.class),
false);
return () -> new Iterator<JavaFileObject>() {
private final Iterator<JavaFileObject> original = listed.iterator();
private JavaFileObject next;
@Override
public boolean hasNext() {
if (next == null) {
while (original.hasNext()) {
JavaFileObject fo = original.next();
if (fo.getKind() != Kind.CLASS &&
fo.getKind() != Kind.SOURCE &&
!isSigFile(currentLoc, fo)) {
p.flags_field |= Flags.HAS_RESOURCE;
}
if (kinds.contains(fo.getKind())) {
next = fo;
break;
}
}
}
return next != null;
}
@Override
public JavaFileObject next() {
if (!hasNext())
throw new NoSuchElementException();
JavaFileObject result = next;
next = null;
return result;
}
};
}
/**
* Used for bad class definition files, such as bad .class files or
* for .java files with unexpected package or class names.

View File

@ -53,7 +53,8 @@ public abstract class Directive implements ModuleElement.Directive {
/** Flags for RequiresDirective. */
public enum RequiresFlag {
PUBLIC(0x0020),
TRANSITIVE(0x0010),
STATIC_PHASE(0x0020),
SYNTHETIC(0x1000),
MANDATED(0x8000),
EXTRA(0x10000);
@ -73,17 +74,44 @@ public abstract class Directive implements ModuleElement.Directive {
public final int value;
}
/** Flags for ExportsDirective. */
public enum ExportsFlag {
SYNTHETIC(0x1000),
MANDATED(0x8000);
// overkill? move to ClassWriter?
public static int value(Set<ExportsFlag> s) {
int v = 0;
for (ExportsFlag f: s)
v |= f.value;
return v;
}
ExportsFlag(int value) {
this.value = value;
}
public final int value;
}
/**
* 'exports' Package ';'
* 'exports' Package 'to' ModuleList ';'
*/
public static class ExportsDirective extends Directive
implements ModuleElement.ExportsDirective {
public final PackageSymbol packge;
public final List<ModuleSymbol> modules;
public final Set<ExportsFlag> flags;
public ExportsDirective(PackageSymbol packge, List<ModuleSymbol> modules) {
this(packge, modules, EnumSet.noneOf(ExportsFlag.class));
}
public ExportsDirective(PackageSymbol packge, List<ModuleSymbol> modules, Set<ExportsFlag> flags) {
this.packge = packge;
this.modules = modules;
this.flags = flags;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
@ -92,12 +120,12 @@ public abstract class Directive implements ModuleElement.Directive {
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public PackageElement getPackage() {
public PackageSymbol getPackage() {
return packge;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public java.util.List<? extends ModuleElement> getTargetModules() {
public java.util.List<ModuleSymbol> getTargetModules() {
return modules == null
? null
: Collections.unmodifiableList(modules);
@ -112,17 +140,83 @@ public abstract class Directive implements ModuleElement.Directive {
}
}
/** Flags for OpensDirective. */
public enum OpensFlag {
SYNTHETIC(0x1000),
MANDATED(0x8000);
// overkill? move to ClassWriter?
public static int value(Set<OpensFlag> s) {
int v = 0;
for (OpensFlag f: s)
v |= f.value;
return v;
}
OpensFlag(int value) {
this.value = value;
}
public final int value;
}
/**
* 'opens' Package ';'
* 'opens' Package 'to' ModuleList ';'
*/
public static class OpensDirective extends Directive
implements ModuleElement.OpensDirective {
public final PackageSymbol packge;
public final List<ModuleSymbol> modules;
public final Set<OpensFlag> flags;
public OpensDirective(PackageSymbol packge, List<ModuleSymbol> modules) {
this(packge, modules, EnumSet.noneOf(OpensFlag.class));
}
public OpensDirective(PackageSymbol packge, List<ModuleSymbol> modules, Set<OpensFlag> flags) {
this.packge = packge;
this.modules = modules;
this.flags = flags;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public ModuleElement.DirectiveKind getKind() {
return ModuleElement.DirectiveKind.OPENS;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public PackageSymbol getPackage() {
return packge;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public java.util.List<ModuleSymbol> getTargetModules() {
return modules == null
? null
: Collections.unmodifiableList(modules);
}
@Override
public String toString() {
if (modules == null)
return "Opens[" + packge + "]";
else
return "Opens[" + packge + ":" + modules + "]";
}
}
/**
* 'provides' ServiceName 'with' QualifiedIdentifer ';'
*/
public static class ProvidesDirective extends Directive
implements ModuleElement.ProvidesDirective {
public final ClassSymbol service;
public final ClassSymbol impl;
public final List<ClassSymbol> impls;
public ProvidesDirective(ClassSymbol service, ClassSymbol impl) {
public ProvidesDirective(ClassSymbol service, List<ClassSymbol> impls) {
this.service = service;
this.impl = impl;
this.impls = impls;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
@ -131,37 +225,39 @@ public abstract class Directive implements ModuleElement.Directive {
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeElement getService() {
public ClassSymbol getService() {
return service;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeElement getImplementation() {
return impl;
public List<ClassSymbol> getImplementations() {
return impls;
}
@Override
public String toString() {
return "Provides[" + service + "," + impl + "]";
return "Provides[" + service + "," + impls + "]";
}
// TODO: delete?
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ProvidesDirective)) {
return false;
}
ProvidesDirective other = (ProvidesDirective)obj;
return service == other.service && impl == other.impl;
return service == other.service && impls.equals(other.impls);
}
// TODO: delete?
@Override
public int hashCode() {
return service.hashCode() * 31 + impl.hashCode() * 37;
return service.hashCode() * 31 + impls.hashCode() * 37;
}
}
/**
* 'requires' ['public'] ModuleName ';'
* 'requires' ('static' | 'transitive')* ModuleName ';'
*/
public static class RequiresDirective extends Directive
implements ModuleElement.RequiresDirective {
@ -183,12 +279,17 @@ public abstract class Directive implements ModuleElement.Directive {
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public boolean isPublic() {
return flags.contains(RequiresFlag.PUBLIC);
public boolean isStatic() {
return flags.contains(RequiresFlag.STATIC_PHASE);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public ModuleElement getDependency() {
public boolean isTransitive() {
return flags.contains(RequiresFlag.TRANSITIVE);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public ModuleSymbol getDependency() {
return module;
}
@ -215,7 +316,7 @@ public abstract class Directive implements ModuleElement.Directive {
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeElement getService() {
public ClassSymbol getService() {
return service;
}
@ -224,6 +325,7 @@ public abstract class Directive implements ModuleElement.Directive {
return "Uses[" + service + "]";
}
// TODO: delete?
@Override
public boolean equals(Object obj) {
if (!(obj instanceof UsesDirective)) {
@ -233,6 +335,7 @@ public abstract class Directive implements ModuleElement.Directive {
return service == other.service;
}
// TODO: delete?
@Override
public int hashCode() {
return service.hashCode() * 31;

View File

@ -293,10 +293,20 @@ public class Flags {
*/
public static final long SYSTEM_MODULE = 1L<<53;
/**
* Flag to indicate the given symbol has a @Deprecated annotation.
*/
public static final long DEPRECATED_ANNOTATION = 1L<<54;
/**
* Flag to indicate the given symbol has been deprecated and marked for removal.
*/
public static final long DEPRECATED_REMOVAL = 1L<<54;
public static final long DEPRECATED_REMOVAL = 1L<<55;
/**
* Flag to indicate the given PackageSymbol contains any non-.java and non-.class resources.
*/
public static final long HAS_RESOURCE = 1L<<56;
/** Modifier masks.
*/
@ -408,7 +418,11 @@ public class Flags {
LAMBDA_METHOD(Flags.LAMBDA_METHOD),
TYPE_TRANSLATED(Flags.TYPE_TRANSLATED),
MODULE(Flags.MODULE),
DEPRECATED_REMOVAL(Flags.DEPRECATED_REMOVAL);
AUTOMATIC_MODULE(Flags.AUTOMATIC_MODULE),
SYSTEM_MODULE(Flags.SYSTEM_MODULE),
DEPRECATED_ANNOTATION(Flags.DEPRECATED_ANNOTATION),
DEPRECATED_REMOVAL(Flags.DEPRECATED_REMOVAL),
HAS_RESOURCE(Flags.HAS_RESOURCE);
Flag(long flag) {
this.value = flag;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2016, 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

View File

@ -28,6 +28,7 @@ package com.sun.tools.javac.code;
import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
@ -47,6 +48,7 @@ import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.ClassFinder.BadEnclosingMethodAttr;
import com.sun.tools.javac.code.Directive.RequiresFlag;
import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
import com.sun.tools.javac.code.Scope.WriteableScope;
@ -359,6 +361,10 @@ public abstract class Symbol extends AnnoConstruct implements Element {
return (flags_field & DEPRECATED) != 0;
}
public boolean hasDeprecatedAnnotation() {
return (flags_field & DEPRECATED_ANNOTATION) != 0;
}
public boolean isDeprecatedForRemoval() {
return (flags_field & DEPRECATED_REMOVAL) != 0;
}
@ -907,6 +913,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
public List<com.sun.tools.javac.code.Directive> directives;
public List<com.sun.tools.javac.code.Directive.RequiresDirective> requires;
public List<com.sun.tools.javac.code.Directive.ExportsDirective> exports;
public List<com.sun.tools.javac.code.Directive.OpensDirective> opens;
public List<com.sun.tools.javac.code.Directive.ProvidesDirective> provides;
public List<com.sun.tools.javac.code.Directive.UsesDirective> uses;
@ -917,6 +924,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
public List<Symbol> enclosedPackages = List.nil();
public Completer usesProvidesCompleter = Completer.NULL_COMPLETER;
public final Set<ModuleFlags> flags = EnumSet.noneOf(ModuleFlags.class);
/**
* Create a ModuleSymbol with an associated module-info ClassSymbol.
@ -942,6 +950,11 @@ public abstract class Symbol extends AnnoConstruct implements Element {
return name.isEmpty() && owner == null;
}
@Override
public boolean isDeprecated() {
return hasDeprecatedAnnotation();
}
public boolean isNoModule() {
return false;
}
@ -1007,6 +1020,26 @@ public abstract class Symbol extends AnnoConstruct implements Element {
}
public enum ModuleFlags {
OPEN(0x0020),
SYNTHETIC(0x1000),
MANDATED(0x8000);
public static int value(Set<ModuleFlags> s) {
int v = 0;
for (ModuleFlags f: s)
v |= f.value;
return v;
}
private ModuleFlags(int value) {
this.value = value;
}
public final int value;
}
/** A class for package symbols
*/
public static class PackageSymbol extends TypeSymbol

View File

@ -237,6 +237,9 @@ public class TypeAnnotations {
// TYPE_PARAMETER doesn't aid in distinguishing between
// Type annotations and declaration annotations on an
// Element
} else if (e.value.name == names.MODULE) {
if (s.kind == MDL)
return AnnotationType.DECLARATION;
} else {
Assert.error("annotationTargetType(): unrecognized Attribute name " + e.value.name +
" (" + e.value.name.getClass() + ")");

View File

@ -45,6 +45,7 @@ import javax.tools.JavaFileObject;
import java.util.*;
import static com.sun.tools.javac.code.Flags.SYNTHETIC;
import static com.sun.tools.javac.code.Kinds.Kind.MDL;
import static com.sun.tools.javac.code.Kinds.Kind.MTH;
import static com.sun.tools.javac.code.Kinds.Kind.VAR;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
@ -337,9 +338,9 @@ public class Annotate {
// Note: @Deprecated has no effect on local variables and parameters
if (!c.type.isErroneous()
&& toAnnotate.owner.kind != MTH
&& (toAnnotate.kind == MDL || toAnnotate.owner.kind != MTH)
&& types.isSameType(c.type, syms.deprecatedType)) {
toAnnotate.flags_field |= Flags.DEPRECATED;
toAnnotate.flags_field |= (Flags.DEPRECATED | Flags.DEPRECATED_ANNOTATION);
Attribute fr = c.member(names.forRemoval);
if (fr instanceof Attribute.Constant) {
Attribute.Constant v = (Attribute.Constant) fr;

View File

@ -4432,6 +4432,17 @@ public class Attr extends JCTree.Visitor {
public void visitModuleDef(JCModuleDecl tree) {
tree.sym.completeUsesProvides();
ModuleSymbol msym = tree.sym;
Lint lint = env.outer.info.lint = env.outer.info.lint.augment(msym);
Lint prevLint = chk.setLint(lint);
chk.checkDeprecatedAnnotation(tree, msym);
try {
deferredLintHandler.flush(tree.pos());
} finally {
chk.setLint(prevLint);
}
}
/** Finish the attribution of a class. */

View File

@ -227,10 +227,18 @@ public class Check {
void warnDeprecated(DiagnosticPosition pos, Symbol sym) {
if (sym.isDeprecatedForRemoval()) {
if (!lint.isSuppressed(LintCategory.REMOVAL)) {
removalHandler.report(pos, "has.been.deprecated.for.removal", sym, sym.location());
if (sym.kind == MDL) {
removalHandler.report(pos, "has.been.deprecated.for.removal.module", sym);
} else {
removalHandler.report(pos, "has.been.deprecated.for.removal", sym, sym.location());
}
}
} else if (!lint.isSuppressed(LintCategory.DEPRECATION)) {
deprecationHandler.report(pos, "has.been.deprecated", sym, sym.location());
if (sym.kind == MDL) {
deprecationHandler.report(pos, "has.been.deprecated.module", sym);
} else {
deprecationHandler.report(pos, "has.been.deprecated", sym, sym.location());
}
}
}
@ -3245,7 +3253,7 @@ public class Check {
void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
if ( (s.isDeprecatedForRemoval()
|| s.isDeprecated() && !other.isDeprecated())
&& s.outermostClass() != other.outermostClass()) {
&& (s.outermostClass() != other.outermostClass() || s.outermostClass() == null)) {
deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
@Override
public void report() {
@ -3851,7 +3859,7 @@ public class Check {
}
if (whatPackage.modle != inPackage.modle && whatPackage.modle != syms.java_base) {
//check that relativeTo.modle requires public what.modle, somehow:
//check that relativeTo.modle requires transitive what.modle, somehow:
List<ModuleSymbol> todo = List.of(inPackage.modle);
while (todo.nonEmpty()) {
@ -3860,13 +3868,13 @@ public class Check {
if (current == whatPackage.modle)
return ; //OK
for (RequiresDirective req : current.requires) {
if (req.isPublic()) {
if (req.isTransitive()) {
todo = todo.prepend(req.module);
}
}
}
log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleNotRequiredPublic(kindName(what), what, what.packge().modle));
log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleNotRequiredTransitive(kindName(what), what, what.packge().modle));
}
}
}

View File

@ -167,6 +167,9 @@ public class Enter extends JCTree.Visitor {
*/
ListBuffer<ClassSymbol> uncompleted;
/** The queue of modules whose imports still need to be checked. */
ListBuffer<JCCompilationUnit> unfinishedModules = new ListBuffer<>();
/** A dummy class to serve as enclClass for toplevel environments.
*/
private JCClassDecl predefClassDef;
@ -308,6 +311,10 @@ public class Enter extends JCTree.Visitor {
boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info",
JavaFileObject.Kind.SOURCE);
if (TreeInfo.isModuleInfo(tree)) {
JCPackageDecl pd = tree.getPackage();
if (pd != null) {
log.error(pd.pos(), Errors.NoPkgInModuleInfoJava);
}
tree.packge = syms.rootPackage;
Env<AttrContext> topEnv = topLevelEnv(tree);
classEnter(tree.defs, topEnv);
@ -509,7 +516,9 @@ public class Enter extends JCTree.Visitor {
public void visitModuleDef(JCModuleDecl tree) {
Env<AttrContext> moduleEnv = moduleEnv(tree, env);
typeEnvs.put(tree.sym, moduleEnv);
todo.append(moduleEnv);
if (modules.isInModuleGraph(tree.sym)) {
todo.append(moduleEnv);
}
}
/** Default class enter visitor method: do nothing.
@ -552,7 +561,19 @@ public class Enter extends JCTree.Visitor {
prevUncompleted.append(clazz);
}
typeEnter.ensureImportsChecked(trees);
if (!modules.modulesInitialized()) {
for (JCCompilationUnit cut : trees) {
if (cut.getModuleDecl() != null) {
unfinishedModules.append(cut);
} else {
typeEnter.ensureImportsChecked(List.of(cut));
}
}
} else {
typeEnter.ensureImportsChecked(unfinishedModules.toList());
unfinishedModules.clear();
typeEnter.ensureImportsChecked(trees);
}
}
} finally {
uncompleted = prevUncompleted;

View File

@ -2387,6 +2387,7 @@ public class Lower extends TreeTranslator {
public void visitModuleDef(JCModuleDecl tree) {
ModuleSymbol msym = tree.sym;
ClassSymbol c = msym.module_info;
c.setAttributes(msym);
c.flags_field |= Flags.MODULE;
createInfoClass(List.<JCAnnotation>nil(), tree.sym.module_info);
}

View File

@ -50,9 +50,14 @@ import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardLocation;
import com.sun.source.tree.ModuleTree.ModuleKind;
import com.sun.tools.javac.code.ClassFinder;
import com.sun.tools.javac.code.DeferredLintHandler;
import com.sun.tools.javac.code.Directive;
import com.sun.tools.javac.code.Directive.ExportsDirective;
import com.sun.tools.javac.code.Directive.ExportsFlag;
import com.sun.tools.javac.code.Directive.OpensDirective;
import com.sun.tools.javac.code.Directive.OpensFlag;
import com.sun.tools.javac.code.Directive.RequiresDirective;
import com.sun.tools.javac.code.Directive.RequiresFlag;
import com.sun.tools.javac.code.Directive.UsesDirective;
@ -66,6 +71,7 @@ import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.Completer;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.ModuleFlags;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symtab;
@ -78,14 +84,18 @@ import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCDirective;
import com.sun.tools.javac.tree.JCTree.JCExports;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
import com.sun.tools.javac.tree.JCTree.JCOpens;
import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
import com.sun.tools.javac.tree.JCTree.JCProvides;
import com.sun.tools.javac.tree.JCTree.JCRequires;
import com.sun.tools.javac.tree.JCTree.JCUses;
import com.sun.tools.javac.tree.JCTree.Tag;
import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.util.Abort;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic;
@ -96,20 +106,15 @@ import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.Options;
import static com.sun.tools.javac.code.Flags.UNATTRIBUTED;
import static com.sun.tools.javac.code.Kinds.Kind.MDL;
import static com.sun.tools.javac.code.TypeTag.CLASS;
import com.sun.tools.javac.tree.JCTree.JCDirective;
import com.sun.tools.javac.tree.JCTree.Tag;
import com.sun.tools.javac.util.Abort;
import com.sun.tools.javac.util.Position;
import static com.sun.tools.javac.code.Flags.ABSTRACT;
import static com.sun.tools.javac.code.Flags.ENUM;
import static com.sun.tools.javac.code.Flags.PUBLIC;
import static com.sun.tools.javac.tree.JCTree.Tag.MODULEDEF;
import static com.sun.tools.javac.code.Flags.UNATTRIBUTED;
import static com.sun.tools.javac.code.Kinds.Kind.MDL;
import static com.sun.tools.javac.code.Kinds.Kind.MTH;
import static com.sun.tools.javac.code.TypeTag.CLASS;
/**
* TODO: fill in
@ -127,6 +132,8 @@ public class Modules extends JCTree.Visitor {
private final Names names;
private final Symtab syms;
private final Attr attr;
private final Check chk;
private final DeferredLintHandler deferredLintHandler;
private final TypeEnvs typeEnvs;
private final Types types;
private final JavaFileManager fileManager;
@ -169,6 +176,8 @@ public class Modules extends JCTree.Visitor {
names = Names.instance(context);
syms = Symtab.instance(context);
attr = Attr.instance(context);
chk = Check.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
typeEnvs = TypeEnvs.instance(context);
moduleFinder = ModuleFinder.instance(context);
types = Types.instance(context);
@ -276,6 +285,10 @@ public class Modules extends JCTree.Visitor {
return defaultModule;
}
public boolean modulesInitialized() {
return allModules != null;
}
private Set<ModuleSymbol> enterModules(List<JCCompilationUnit> trees, ClassSymbol c) {
Set<ModuleSymbol> modules = new LinkedHashSet<>();
for (JCCompilationUnit tree : trees) {
@ -292,9 +305,9 @@ public class Modules extends JCTree.Visitor {
private void enterModule(JCCompilationUnit toplevel, ClassSymbol c, Set<ModuleSymbol> modules) {
boolean isModuleInfo = toplevel.sourcefile.isNameCompatible("module-info", Kind.SOURCE);
boolean isModuleDecl = toplevel.defs.nonEmpty() && toplevel.defs.head.hasTag(MODULEDEF);
boolean isModuleDecl = toplevel.getModuleDecl() != null;
if (isModuleDecl) {
JCModuleDecl decl = (JCModuleDecl) toplevel.defs.head;
JCModuleDecl decl = toplevel.getModuleDecl();
if (!isModuleInfo) {
log.error(decl.pos(), Errors.ModuleDeclSbInModuleInfoJava);
}
@ -352,8 +365,8 @@ public class Modules extends JCTree.Visitor {
if (locn != null) {
Name name = names.fromString(fileManager.inferModuleName(locn));
ModuleSymbol msym;
if (tree.defs.head.hasTag(MODULEDEF)) {
JCModuleDecl decl = (JCModuleDecl) tree.defs.head;
JCModuleDecl decl = tree.getModuleDecl();
if (decl != null) {
msym = decl.sym;
if (msym.name != name) {
log.error(decl.qualId, Errors.ModuleNameMismatch(msym.name, name));
@ -449,17 +462,14 @@ public class Modules extends JCTree.Visitor {
}
private Location getModuleLocation(JCCompilationUnit tree) throws IOException {
switch (tree.defs.head.getTag()) {
case MODULEDEF:
return getModuleLocation(tree.sourcefile, null);
case PACKAGEDEF:
JCPackageDecl pkg = (JCPackageDecl) tree.defs.head;
return getModuleLocation(tree.sourcefile, TreeInfo.fullName(pkg.pid));
default:
// code in unnamed module
return null;
if (tree.getModuleDecl() != null) {
return getModuleLocation(tree.sourcefile, null);
} else if (tree.getPackage() != null) {
JCPackageDecl pkg = tree.getPackage();
return getModuleLocation(tree.sourcefile, TreeInfo.fullName(pkg.pid));
} else {
// code in unnamed module
return null;
}
}
@ -535,6 +545,7 @@ public class Modules extends JCTree.Visitor {
String pack = binName.lastIndexOf('.') != (-1) ? binName.substring(0, binName.lastIndexOf('.')) : ""; //unnamed package????
if (seenPackages.add(pack)) {
ExportsDirective d = new ExportsDirective(syms.enterPackage(msym, names.fromString(pack)), null);
//TODO: opens?
directives.add(d);
exports.add(d);
}
@ -562,7 +573,7 @@ public class Modules extends JCTree.Visitor {
if (ms == syms.unnamedModule || ms == msym)
continue;
Set<RequiresFlag> flags = (ms.flags_field & Flags.AUTOMATIC_MODULE) != 0 ?
EnumSet.of(RequiresFlag.PUBLIC) : EnumSet.noneOf(RequiresFlag.class);
EnumSet.of(RequiresFlag.TRANSITIVE) : EnumSet.noneOf(RequiresFlag.class);
RequiresDirective d = new RequiresDirective(ms, flags);
directives.add(d);
requires.add(d);
@ -585,9 +596,10 @@ public class Modules extends JCTree.Visitor {
ModuleVisitor v = new ModuleVisitor();
JavaFileObject prev = log.useSource(tree.sourcefile);
try {
tree.defs.head.accept(v);
checkCyclicDependencies((JCModuleDecl) tree.defs.head);
JCModuleDecl moduleDecl = tree.getModuleDecl();
moduleDecl.accept(v);
completeModule(msym);
checkCyclicDependencies(moduleDecl);
} finally {
log.useSource(prev);
msym.flags_field &= ~UNATTRIBUTED;
@ -605,17 +617,25 @@ public class Modules extends JCTree.Visitor {
class ModuleVisitor extends JCTree.Visitor {
private ModuleSymbol sym;
private final Set<ModuleSymbol> allRequires = new HashSet<>();
private final Set<PackageSymbol> allExports = new HashSet<>();
private final Map<PackageSymbol,List<ExportsDirective>> allExports = new HashMap<>();
private final Map<PackageSymbol,List<OpensDirective>> allOpens = new HashMap<>();
@Override
public void visitModuleDef(JCModuleDecl tree) {
sym = Assert.checkNonNull(tree.sym);
if (tree.getModuleType() == ModuleKind.OPEN) {
sym.flags.add(ModuleFlags.OPEN);
}
sym.flags_field |= (tree.mods.flags & Flags.DEPRECATED);
sym.requires = List.nil();
sym.exports = List.nil();
sym.opens = List.nil();
tree.directives.forEach(t -> t.accept(this));
sym.requires = sym.requires.reverse();
sym.exports = sym.exports.reverse();
sym.opens = sym.opens.reverse();
ensureJavaBase();
}
@ -629,8 +649,10 @@ public class Modules extends JCTree.Visitor {
} else {
allRequires.add(msym);
Set<RequiresFlag> flags = EnumSet.noneOf(RequiresFlag.class);
if (tree.isPublic)
flags.add(RequiresFlag.PUBLIC);
if (tree.isTransitive)
flags.add(RequiresFlag.TRANSITIVE);
if (tree.isStaticPhase)
flags.add(RequiresFlag.STATIC_PHASE);
RequiresDirective d = new RequiresDirective(msym, flags);
tree.directive = d;
sym.requires = sym.requires.prepend(d);
@ -642,31 +664,125 @@ public class Modules extends JCTree.Visitor {
Name name = TreeInfo.fullName(tree.qualid);
PackageSymbol packge = syms.enterPackage(sym, name);
attr.setPackageSymbols(tree.qualid, packge);
if (!allExports.add(packge)) {
log.error(tree.qualid.pos(), Errors.DuplicateExports(packge));
if (tree.hasTag(Tag.OPENS) && sym.flags.contains(ModuleFlags.OPEN)) {
log.error(tree.pos(), Errors.NoOpensUnlessStrong);
}
List<ExportsDirective> exportsForPackage = allExports.computeIfAbsent(packge, p -> List.nil());
for (ExportsDirective d : exportsForPackage) {
reportExportsConflict(tree, packge);
}
List<ModuleSymbol> toModules = null;
if (tree.moduleNames != null) {
Set<ModuleSymbol> to = new HashSet<>();
Set<ModuleSymbol> to = new LinkedHashSet<>();
for (JCExpression n: tree.moduleNames) {
ModuleSymbol msym = lookupModule(n);
if (msym.kind != MDL) {
log.error(n.pos(), Errors.ModuleNotFound(msym));
} else if (!to.add(msym)) {
log.error(n.pos(), Errors.DuplicateExports(msym));
} else {
for (ExportsDirective d : exportsForPackage) {
checkDuplicateExportsToModule(n, msym, d);
}
if (!to.add(msym)) {
reportExportsConflictToModule(n, msym);
}
}
}
toModules = List.from(to);
}
if (toModules == null || !toModules.isEmpty()) {
ExportsDirective d = new ExportsDirective(packge, toModules);
tree.directive = d;
Set<ExportsFlag> flags = EnumSet.noneOf(ExportsFlag.class);
ExportsDirective d = new ExportsDirective(packge, toModules, flags);
sym.exports = sym.exports.prepend(d);
tree.directive = d;
allExports.put(packge, exportsForPackage.prepend(d));
}
}
private void reportExportsConflict(JCExports tree, PackageSymbol packge) {
log.error(tree.qualid.pos(), Errors.ConflictingExports(packge));
}
private void checkDuplicateExportsToModule(JCExpression name, ModuleSymbol msym,
ExportsDirective d) {
if (d.modules != null) {
for (ModuleSymbol other : d.modules) {
if (msym == other) {
reportExportsConflictToModule(name, msym);
}
}
}
}
private void reportExportsConflictToModule(JCExpression name, ModuleSymbol msym) {
log.error(name.pos(), Errors.ConflictingExportsToModule(msym));
}
@Override
public void visitOpens(JCOpens tree) {
Name name = TreeInfo.fullName(tree.qualid);
PackageSymbol packge = syms.enterPackage(sym, name);
attr.setPackageSymbols(tree.qualid, packge);
if (sym.flags.contains(ModuleFlags.OPEN)) {
log.error(tree.pos(), Errors.NoOpensUnlessStrong);
}
List<OpensDirective> opensForPackage = allOpens.computeIfAbsent(packge, p -> List.nil());
for (OpensDirective d : opensForPackage) {
reportOpensConflict(tree, packge);
}
List<ModuleSymbol> toModules = null;
if (tree.moduleNames != null) {
Set<ModuleSymbol> to = new LinkedHashSet<>();
for (JCExpression n: tree.moduleNames) {
ModuleSymbol msym = lookupModule(n);
if (msym.kind != MDL) {
log.error(n.pos(), Errors.ModuleNotFound(msym));
} else {
for (OpensDirective d : opensForPackage) {
checkDuplicateOpensToModule(n, msym, d);
}
if (!to.add(msym)) {
reportOpensConflictToModule(n, msym);
}
}
}
toModules = List.from(to);
}
if (toModules == null || !toModules.isEmpty()) {
Set<OpensFlag> flags = EnumSet.noneOf(OpensFlag.class);
OpensDirective d = new OpensDirective(packge, toModules, flags);
sym.opens = sym.opens.prepend(d);
tree.directive = d;
allOpens.put(packge, opensForPackage.prepend(d));
}
}
private void reportOpensConflict(JCOpens tree, PackageSymbol packge) {
log.error(tree.qualid.pos(), Errors.ConflictingOpens(packge));
}
private void checkDuplicateOpensToModule(JCExpression name, ModuleSymbol msym,
OpensDirective d) {
if (d.modules != null) {
for (ModuleSymbol other : d.modules) {
if (msym == other) {
reportOpensConflictToModule(name, msym);
}
}
}
}
private void reportOpensConflictToModule(JCExpression name, ModuleSymbol msym) {
log.error(name.pos(), Errors.ConflictingOpensToModule(msym));
}
@Override
public void visitProvides(JCProvides tree) { }
@ -706,10 +822,14 @@ public class Modules extends JCTree.Visitor {
Env<AttrContext> env = typeEnvs.get(msym);
UsesProvidesVisitor v = new UsesProvidesVisitor(msym, env);
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
JCModuleDecl decl = env.toplevel.getModuleDecl();
DiagnosticPosition prevLintPos = deferredLintHandler.setPos(decl.pos());
try {
env.toplevel.defs.head.accept(v);
decl.accept(v);
} finally {
log.useSource(prev);
deferredLintHandler.setPos(prevLintPos);
}
};
}
@ -718,8 +838,8 @@ public class Modules extends JCTree.Visitor {
private final ModuleSymbol msym;
private final Env<AttrContext> env;
private final Set<Directive.UsesDirective> allUses = new HashSet<>();
private final Set<Directive.ProvidesDirective> allProvides = new HashSet<>();
private final Set<ClassSymbol> allUses = new HashSet<>();
private final Map<ClassSymbol, Set<ClassSymbol>> allProvides = new HashMap<>();
public UsesProvidesVisitor(ModuleSymbol msym, Env<AttrContext> env) {
this.msym = msym;
@ -752,6 +872,15 @@ public class Modules extends JCTree.Visitor {
msym.directives = msym.directives.prepend(tree.directive);
}
@Override
public void visitOpens(JCOpens tree) {
if (tree.directive.packge.members().isEmpty() &&
((tree.directive.packge.flags() & Flags.HAS_RESOURCE) == 0)) {
log.error(tree.qualid.pos(), Errors.PackageEmptyOrNotFound(tree.directive.packge));
}
msym.directives = msym.directives.prepend(tree.directive);
}
MethodSymbol noArgsConstructor(ClassSymbol tsym) {
for (Symbol sym : tsym.members().getSymbolsByName(names.init)) {
MethodSymbol mSym = (MethodSymbol)sym;
@ -762,34 +891,61 @@ public class Modules extends JCTree.Visitor {
return null;
}
MethodSymbol factoryMethod(ClassSymbol tsym) {
for (Symbol sym : tsym.members().getSymbolsByName(names.provider, sym -> sym.kind == MTH)) {
MethodSymbol mSym = (MethodSymbol)sym;
if (mSym.isStatic() && (mSym.flags() & Flags.PUBLIC) != 0 && mSym.params().isEmpty()) {
return mSym;
}
}
return null;
}
Map<Directive.ProvidesDirective, JCProvides> directiveToTreeMap = new HashMap<>();
@Override
public void visitProvides(JCProvides tree) {
Type st = attr.attribType(tree.serviceName, env, syms.objectType);
Type it = attr.attribType(tree.implName, env, syms.objectType);
ClassSymbol service = (ClassSymbol) st.tsym;
ClassSymbol impl = (ClassSymbol) it.tsym;
if (!types.isSubtype(it, st)) {
log.error(tree.implName.pos(), Errors.ServiceImplementationMustBeSubtypeOfServiceInterface);
}
if ((impl.flags() & ABSTRACT) != 0) {
log.error(tree.implName.pos(), Errors.ServiceImplementationIsAbstract(impl));
} else if (impl.isInner()) {
log.error(tree.implName.pos(), Errors.ServiceImplementationIsInner(impl));
} else {
MethodSymbol constr = noArgsConstructor(impl);
if (constr == null) {
log.error(tree.implName.pos(), Errors.ServiceImplementationDoesntHaveANoArgsConstructor(impl));
} else if ((constr.flags() & PUBLIC) == 0) {
log.error(tree.implName.pos(), Errors.ServiceImplementationNoArgsConstructorNotPublic(impl));
ListBuffer<ClassSymbol> impls = new ListBuffer<>();
for (JCExpression implName : tree.implNames) {
Type it = attr.attribType(implName, env, syms.objectType);
ClassSymbol impl = (ClassSymbol) it.tsym;
//find provider factory:
MethodSymbol factory = factoryMethod(impl);
if (factory != null) {
Type returnType = factory.type.getReturnType();
if (!types.isSubtype(returnType, st)) {
log.error(implName.pos(), Errors.ServiceImplementationProviderReturnMustBeSubtypeOfServiceInterface);
}
} else {
if (!types.isSubtype(it, st)) {
log.error(implName.pos(), Errors.ServiceImplementationMustBeSubtypeOfServiceInterface);
} else if ((impl.flags() & ABSTRACT) != 0) {
log.error(implName.pos(), Errors.ServiceImplementationIsAbstract(impl));
} else if (impl.isInner()) {
log.error(implName.pos(), Errors.ServiceImplementationIsInner(impl));
} else {
MethodSymbol constr = noArgsConstructor(impl);
if (constr == null) {
log.error(implName.pos(), Errors.ServiceImplementationDoesntHaveANoArgsConstructor(impl));
} else if ((constr.flags() & PUBLIC) == 0) {
log.error(implName.pos(), Errors.ServiceImplementationNoArgsConstructorNotPublic(impl));
}
}
}
if (it.hasTag(CLASS)) {
// For now, we just check the pair (service-type, impl-type) is unique
// TODO, check only one provides per service type as well
if (allProvides.computeIfAbsent(service, s -> new HashSet<>()).add(impl)) {
impls.append(impl);
} else {
log.error(implName.pos(), Errors.DuplicateProvides(service, impl));
}
}
}
if (st.hasTag(CLASS) && it.hasTag(CLASS)) {
Directive.ProvidesDirective d = new Directive.ProvidesDirective(service, impl);
if (!allProvides.add(d)) {
log.error(tree.pos(), Errors.DuplicateProvides(service, impl));
}
if (st.hasTag(CLASS) && !impls.isEmpty()) {
Directive.ProvidesDirective d = new Directive.ProvidesDirective(service, impls.toList());
msym.provides = msym.provides.prepend(d);
msym.directives = msym.directives.prepend(d);
directiveToTreeMap.put(d, tree);
@ -799,6 +955,7 @@ public class Modules extends JCTree.Visitor {
@Override
public void visitRequires(JCRequires tree) {
if (tree.directive != null) {
chk.checkDeprecated(tree.moduleName.pos(), msym, tree.directive.module);
msym.directives = msym.directives.prepend(tree.directive);
}
}
@ -811,53 +968,58 @@ public class Modules extends JCTree.Visitor {
log.error(tree.qualid.pos(), Errors.ServiceDefinitionIsEnum(st.tsym));
} else if (st.hasTag(CLASS)) {
ClassSymbol service = (ClassSymbol) st.tsym;
Directive.UsesDirective d = new Directive.UsesDirective(service);
if (!allUses.add(d)) {
if (allUses.add(service)) {
Directive.UsesDirective d = new Directive.UsesDirective(service);
msym.uses = msym.uses.prepend(d);
msym.directives = msym.directives.prepend(d);
} else {
log.error(tree.pos(), Errors.DuplicateUses(service));
}
msym.uses = msym.uses.prepend(d);
msym.directives = msym.directives.prepend(d);
}
}
private void checkForCorrectness() {
for (Directive.ProvidesDirective provides : allProvides) {
for (Directive.ProvidesDirective provides : msym.provides) {
JCProvides tree = directiveToTreeMap.get(provides);
/* The implementation must be defined in the same module as the provides directive
* (else, error)
*/
PackageSymbol implementationDefiningPackage = provides.impl.packge();
if (implementationDefiningPackage.modle != msym) {
log.error(tree.pos(), Errors.ServiceImplementationNotInRightModule(implementationDefiningPackage.modle));
}
/* There is no inherent requirement that module that provides a service should actually
* use it itself. However, it is a pointless declaration if the service package is not
* exported and there is no uses for the service.
*/
PackageSymbol interfaceDeclaringPackage = provides.service.packge();
boolean isInterfaceDeclaredInCurrentModule = interfaceDeclaringPackage.modle == msym;
boolean isInterfaceExportedFromAReadableModule =
msym.visiblePackages.get(interfaceDeclaringPackage.fullname) == interfaceDeclaringPackage;
if (isInterfaceDeclaredInCurrentModule && !isInterfaceExportedFromAReadableModule) {
// ok the interface is declared in this module. Let's check if it's exported
boolean warn = true;
for (ExportsDirective export : msym.exports) {
if (interfaceDeclaringPackage == export.packge) {
warn = false;
break;
}
for (ClassSymbol impl : provides.impls) {
/* The implementation must be defined in the same module as the provides directive
* (else, error)
*/
PackageSymbol implementationDefiningPackage = impl.packge();
if (implementationDefiningPackage.modle != msym) {
// TODO: should use tree for the implentation name, not the entire provides tree
// TODO: should improve error message to identify the implementation type
log.error(tree.pos(), Errors.ServiceImplementationNotInRightModule(implementationDefiningPackage.modle));
}
if (warn) {
for (UsesDirective uses : msym.uses) {
if (provides.service == uses.service) {
/* There is no inherent requirement that module that provides a service should actually
* use it itself. However, it is a pointless declaration if the service package is not
* exported and there is no uses for the service.
*/
PackageSymbol interfaceDeclaringPackage = provides.service.packge();
boolean isInterfaceDeclaredInCurrentModule = interfaceDeclaringPackage.modle == msym;
boolean isInterfaceExportedFromAReadableModule =
msym.visiblePackages.get(interfaceDeclaringPackage.fullname) == interfaceDeclaringPackage;
if (isInterfaceDeclaredInCurrentModule && !isInterfaceExportedFromAReadableModule) {
// ok the interface is declared in this module. Let's check if it's exported
boolean warn = true;
for (ExportsDirective export : msym.exports) {
if (interfaceDeclaringPackage == export.packge) {
warn = false;
break;
}
}
}
if (warn) {
log.warning(tree.pos(), Warnings.ServiceProvidedButNotExportedOrUsed(provides.service));
if (warn) {
for (UsesDirective uses : msym.uses) {
if (provides.service == uses.service) {
warn = false;
break;
}
}
}
if (warn) {
log.warning(tree.pos(), Warnings.ServiceProvidedButNotExportedOrUsed(provides.service));
}
}
}
}
@ -973,6 +1135,10 @@ public class Modules extends JCTree.Visitor {
allModules = result;
}
public boolean isInModuleGraph(ModuleSymbol msym) {
return allModules == null || allModules.contains(msym);
}
private Set<ModuleSymbol> computeTransitiveClosure(Iterable<? extends ModuleSymbol> base, Set<ModuleSymbol> observable) {
List<ModuleSymbol> todo = List.nil();
@ -1019,7 +1185,8 @@ public class Modules extends JCTree.Visitor {
return ;
}
ModuleSymbol msym = (ModuleSymbol) sym;
Set<ModuleSymbol> allModules = allModules();
Set<ModuleSymbol> allModules = new HashSet<>(allModules());
allModules.remove(syms.unnamedModule);
for (ModuleSymbol m : allModules) {
m.complete();
}
@ -1033,7 +1200,7 @@ public class Modules extends JCTree.Visitor {
};
}
private final Map<ModuleSymbol, Set<ModuleSymbol>> requiresPublicCache = new HashMap<>();
private final Map<ModuleSymbol, Set<ModuleSymbol>> requiresTransitiveCache = new HashMap<>();
private void completeModule(ModuleSymbol msym) {
if (inInitModules) {
@ -1079,34 +1246,36 @@ public class Modules extends JCTree.Visitor {
}
Set<ModuleSymbol> readable = new LinkedHashSet<>();
Set<ModuleSymbol> requiresPublic = new HashSet<>();
Set<ModuleSymbol> requiresTransitive = new HashSet<>();
for (RequiresDirective d : msym.requires) {
d.module.complete();
readable.add(d.module);
Set<ModuleSymbol> s = retrieveRequiresPublic(d.module);
Set<ModuleSymbol> s = retrieveRequiresTransitive(d.module);
Assert.checkNonNull(s, () -> "no entry in cache for " + d.module);
readable.addAll(s);
if (d.flags.contains(RequiresFlag.PUBLIC)) {
requiresPublic.add(d.module);
requiresPublic.addAll(s);
if (d.flags.contains(RequiresFlag.TRANSITIVE)) {
requiresTransitive.add(d.module);
requiresTransitive.addAll(s);
}
}
requiresPublicCache.put(msym, requiresPublic);
requiresTransitiveCache.put(msym, requiresTransitive);
initVisiblePackages(msym, readable);
for (ExportsDirective d: msym.exports) {
d.packge.modle = msym;
if (d.packge != null) {
d.packge.modle = msym;
}
}
}
private Set<ModuleSymbol> retrieveRequiresPublic(ModuleSymbol msym) {
Set<ModuleSymbol> requiresPublic = requiresPublicCache.get(msym);
private Set<ModuleSymbol> retrieveRequiresTransitive(ModuleSymbol msym) {
Set<ModuleSymbol> requiresTransitive = requiresTransitiveCache.get(msym);
if (requiresPublic == null) {
if (requiresTransitive == null) {
//the module graph may contain cycles involving automatic modules or --add-reads edges
requiresPublic = new HashSet<>();
requiresTransitive = new HashSet<>();
Set<ModuleSymbol> seen = new HashSet<>();
List<ModuleSymbol> todo = List.of(msym);
@ -1116,14 +1285,14 @@ public class Modules extends JCTree.Visitor {
todo = todo.tail;
if (!seen.add(current))
continue;
requiresPublic.add(current);
requiresTransitive.add(current);
current.complete();
Iterable<? extends RequiresDirective> requires;
if (current != syms.unnamedModule) {
Assert.checkNonNull(current.requires, () -> current + ".requires == null; " + msym);
requires = current.requires;
for (RequiresDirective rd : requires) {
if (rd.isPublic())
if (rd.isTransitive())
todo = todo.prepend(rd.module);
}
} else {
@ -1133,10 +1302,10 @@ public class Modules extends JCTree.Visitor {
}
}
requiresPublic.remove(msym);
requiresTransitive.remove(msym);
}
return requiresPublic;
return requiresTransitive;
}
private void initVisiblePackages(ModuleSymbol msym, Collection<ModuleSymbol> readable) {

View File

@ -160,8 +160,6 @@ public class TypeEnter implements Completer {
// if there remain any unimported toplevels (these must have
// no classes at all), process their import statements as well.
for (JCCompilationUnit tree : trees) {
if (tree.defs.nonEmpty() && tree.defs.head.hasTag(MODULEDEF))
continue;
if (!tree.starImportScope.isFilled()) {
Env<AttrContext> topEnv = enter.topLevelEnv(tree);
finishImports(tree, () -> { completeClass.resolveImports(tree, topEnv); });
@ -344,13 +342,22 @@ public class TypeEnter implements Completer {
throw new FatalError(diags.fragment("fatal.err.no.java.lang"));
importAll(make.at(tree.pos()).Import(make.QualIdent(javaLang), false), javaLang, env);
JCModuleDecl decl = tree.getModuleDecl();
// Process the package def and all import clauses.
if (tree.getPackage() != null)
if (tree.getPackage() != null && decl == null)
checkClassPackageClash(tree.getPackage());
for (JCImport imp : tree.getImports()) {
doImport(imp);
}
if (decl != null) {
//check @Deprecated:
markDeprecated(decl.sym, decl.mods.annotations, env);
// process module annotations
annotate.annotateLater(decl.mods.annotations, env, env.toplevel.modle, null);
}
} finally {
this.env = prevEnv;
chk.setLint(prevLint);
@ -745,12 +752,7 @@ public class TypeEnter implements Completer {
}
}
// Annotations.
// In general, we cannot fully process annotations yet, but we
// can attribute the annotation types and then check to see if the
// @Deprecated annotation is present.
attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
handleDeprecatedAnnotation(tree.mods.annotations, sym);
markDeprecated(sym, tree.mods.annotations, baseEnv);
chk.checkNonCyclicDecl(tree);
}
@ -765,32 +767,6 @@ public class TypeEnter implements Completer {
return superType;
}
/**
* If a list of annotations contains a reference to java.lang.Deprecated,
* set the DEPRECATED flag.
* If the annotation is marked forRemoval=true, also set DEPRECATED_REMOVAL.
**/
private void handleDeprecatedAnnotation(List<JCAnnotation> annotations, Symbol sym) {
for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
JCAnnotation a = al.head;
if (a.annotationType.type == syms.deprecatedType) {
sym.flags_field |= Flags.DEPRECATED;
a.args.stream()
.filter(e -> e.hasTag(ASSIGN))
.map(e -> (JCAssign) e)
.filter(assign -> TreeInfo.name(assign.lhs) == names.forRemoval)
.findFirst()
.ifPresent(assign -> {
JCExpression rhs = TreeInfo.skipParens(assign.rhs);
if (rhs.hasTag(LITERAL)
&& Boolean.TRUE.equals(((JCLiteral) rhs).getValue())) {
sym.flags_field |= DEPRECATED_REMOVAL;
}
});
}
}
}
@Override
public void complete(Symbol sym) throws CompletionFailure {
Assert.check((topLevelPhase instanceof ImportsPhase) ||
@ -1135,4 +1111,41 @@ public class TypeEnter implements Completer {
List<JCExpression> typeargs = typarams.nonEmpty() ? make.Types(typarams) : null;
return make.Exec(make.Apply(typeargs, meth, make.Idents(params)));
}
/**
* Mark sym deprecated if annotations contain @Deprecated annotation.
*/
public void markDeprecated(Symbol sym, List<JCAnnotation> annotations, Env<AttrContext> env) {
// In general, we cannot fully process annotations yet, but we
// can attribute the annotation types and then check to see if the
// @Deprecated annotation is present.
attr.attribAnnotationTypes(annotations, env);
handleDeprecatedAnnotations(annotations, sym);
}
/**
* If a list of annotations contains a reference to java.lang.Deprecated,
* set the DEPRECATED flag.
* If the annotation is marked forRemoval=true, also set DEPRECATED_REMOVAL.
**/
private void handleDeprecatedAnnotations(List<JCAnnotation> annotations, Symbol sym) {
for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
JCAnnotation a = al.head;
if (a.annotationType.type == syms.deprecatedType) {
sym.flags_field |= (Flags.DEPRECATED | Flags.DEPRECATED_ANNOTATION);
a.args.stream()
.filter(e -> e.hasTag(ASSIGN))
.map(e -> (JCAssign) e)
.filter(assign -> TreeInfo.name(assign.lhs) == names.forRemoval)
.findFirst()
.ifPresent(assign -> {
JCExpression rhs = TreeInfo.skipParens(assign.rhs);
if (rhs.hasTag(LITERAL)
&& Boolean.TRUE.equals(((JCLiteral) rhs).getValue())) {
sym.flags_field |= DEPRECATED_REMOVAL;
}
});
}
}
}
}

View File

@ -29,6 +29,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
@ -128,7 +129,7 @@ public abstract class BaseFileManager implements JavaFileManager {
protected String classLoaderClass;
protected Locations locations;
protected final Locations locations;
/**
* A flag for clients to use to indicate that this file manager should
@ -209,7 +210,10 @@ public abstract class BaseFileManager implements JavaFileManager {
addReadsMethod.invoke(thisModule, targetModule);
} catch (NoSuchMethodException e) {
// ignore
} catch (Exception e) {
} catch (IllegalAccessException
| IllegalArgumentException
| SecurityException
| InvocationTargetException e) {
throw new Abort(e);
}
return targetLoader;
@ -324,12 +328,12 @@ public abstract class BaseFileManager implements JavaFileManager {
@SuppressWarnings("cast")
public CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) {
String encodingName = getEncodingName();
String encName = getEncodingName();
CharsetDecoder decoder;
try {
decoder = getDecoder(encodingName, ignoreEncodingErrors);
decoder = getDecoder(encName, ignoreEncodingErrors);
} catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
log.error("unsupported.encoding", encodingName);
log.error("unsupported.encoding", encName);
return (CharBuffer)CharBuffer.allocate(1).flip();
}
@ -365,7 +369,7 @@ public abstract class BaseFileManager implements JavaFileManager {
unmappable.append(String.format("%02X", inbuf.get()));
}
String charsetName = charset == null ? encodingName : charset.name();
String charsetName = charset == null ? encName : charset.name();
log.error(dest.limit(),
Errors.IllegalCharForEncoding(unmappable.toString(), charsetName));

View File

@ -1091,7 +1091,8 @@ public class Locations {
}
// finally clean up the module name
mn = mn.replaceAll("[^A-Za-z0-9]", ".") // replace non-alphanumeric
mn = mn.replaceAll("(\\.|\\d)*$", "") // remove trailing version
.replaceAll("[^A-Za-z0-9]", ".") // replace non-alphanumeric
.replaceAll("(\\.)(\\1)+", ".") // collapse repeating dots
.replaceAll("^\\.", "") // drop leading dots
.replaceAll("\\.$", ""); // drop trailing dots

View File

@ -129,8 +129,11 @@ public class ClassFile {
* String Translation Routines
***********************************************************************/
/** Return internal representation of buf[offset..offset+len-1],
* converting '/' to '.'.
/**
* Return internal representation of buf[offset..offset+len-1], converting '/' to '.'.
*
* Note: the naming is the inverse of that used by JVMS 4.2 The Internal Form Of Names,
* which defines "internal name" to be the form using "/" instead of "."
*/
public static byte[] internalize(byte[] buf, int offset, int len) {
byte[] translated = new byte[len];
@ -142,15 +145,21 @@ public class ClassFile {
return translated;
}
/** Return internal representation of given name,
* converting '/' to '.'.
/**
* Return internal representation of given name, converting '/' to '.'.
*
* Note: the naming is the inverse of that used by JVMS 4.2 The Internal Form Of Names,
* which defines "internal name" to be the form using "/" instead of "."
*/
public static byte[] internalize(Name name) {
return internalize(name.getByteArray(), name.getByteOffset(), name.getByteLength());
}
/** Return external representation of buf[offset..offset+len-1],
* converting '.' to '/'.
/**
* Return external representation of buf[offset..offset+len-1], converting '.' to '/'.
*
* Note: the naming is the inverse of that used by JVMS 4.2 The Internal Form Of Names,
* which defines "internal name" to be the form using "/" instead of "."
*/
public static byte[] externalize(byte[] buf, int offset, int len) {
byte[] translated = new byte[len];
@ -162,8 +171,11 @@ public class ClassFile {
return translated;
}
/** Return external representation of given name,
* converting '/' to '.'.
/**
* Return external representation of given name, converting '/' to '.'.
*
* Note: the naming is the inverse of that used by JVMS 4.2 The Internal Form Of Names,
* which defines "internal name" to be the form using "/" instead of "."
*/
public static byte[] externalize(Name name) {
return externalize(name.getByteArray(), name.getByteOffset(), name.getByteLength());

View File

@ -62,7 +62,9 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import com.sun.tools.javac.code.Scope.LookupKind;
import static com.sun.tools.javac.code.TypeTag.ARRAY;
import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
@ -159,6 +161,9 @@ public class ClassReader {
*/
protected ModuleSymbol currentModule = null;
// FIXME: temporary compatibility code
private boolean readNewModuleAttribute;
/** The buffer containing the currently read class file.
*/
byte[] buf = new byte[INITIAL_BUFFER_SIZE];
@ -584,6 +589,53 @@ public class ClassReader {
throw badClassFile("bad.module-info.name");
}
/** Read the name of a module.
* The name is stored in a CONSTANT_Utf8 entry, in
* JVMS 4.2 internal form (with '/' instead of '.')
*/
Name readModuleName(int i) {
Name name = readName(i);
// FIXME: temporary compatibility code
if (readNewModuleAttribute) {
return names.fromUtf(internalize(name));
} else {
return name;
}
}
/** Read module_flags.
*/
Set<ModuleFlags> readModuleFlags(int flags) {
Set<ModuleFlags> set = EnumSet.noneOf(ModuleFlags.class);
for (ModuleFlags f : ModuleFlags.values()) {
if ((flags & f.value) != 0)
set.add(f);
}
return set;
}
/** Read exports_flags.
*/
Set<ExportsFlag> readExportsFlags(int flags) {
Set<ExportsFlag> set = EnumSet.noneOf(ExportsFlag.class);
for (ExportsFlag f: ExportsFlag.values()) {
if ((flags & f.value) != 0)
set.add(f);
}
return set;
}
/** Read opens_flags.
*/
Set<OpensFlag> readOpensFlags(int flags) {
Set<OpensFlag> set = EnumSet.noneOf(OpensFlag.class);
for (OpensFlag f: OpensFlag.values()) {
if ((flags & f.value) != 0)
set.add(f);
}
return set;
}
/** Read requires_flags.
*/
Set<RequiresFlag> readRequiresFlags(int flags) {
@ -996,7 +1048,9 @@ public class ClassReader {
new AttributeReader(names.Deprecated, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
protected void read(Symbol sym, int attrLen) {
sym.flags_field |= DEPRECATED;
Symbol s = sym.owner.kind == MDL ? sym.owner : sym;
s.flags_field |= DEPRECATED;
}
},
@ -1228,11 +1282,20 @@ public class ClassReader {
ModuleSymbol msym = (ModuleSymbol) sym.owner;
ListBuffer<Directive> directives = new ListBuffer<>();
// FIXME: temporary compatibility code
if (readNewModuleAttribute) {
Name moduleName = readModuleName(nextChar());
if (currentModule.name != moduleName) {
throw badClassFile("module.name.mismatch", moduleName, currentModule.name);
}
}
msym.flags.addAll(readModuleFlags(nextChar()));
ListBuffer<RequiresDirective> requires = new ListBuffer<>();
int nrequires = nextChar();
for (int i = 0; i < nrequires; i++) {
Name name = readName(nextChar());
ModuleSymbol rsym = syms.enterModule(name);
ModuleSymbol rsym = syms.enterModule(readModuleName(nextChar()));
Set<RequiresFlag> flags = readRequiresFlags(nextChar());
requires.add(new RequiresDirective(rsym, flags));
}
@ -1244,6 +1307,7 @@ public class ClassReader {
for (int i = 0; i < nexports; i++) {
Name n = readName(nextChar());
PackageSymbol p = syms.enterPackage(currentModule, names.fromUtf(internalize(n)));
Set<ExportsFlag> flags = readExportsFlags(nextChar());
int nto = nextChar();
List<ModuleSymbol> to;
if (nto == 0) {
@ -1251,13 +1315,36 @@ public class ClassReader {
} else {
ListBuffer<ModuleSymbol> lb = new ListBuffer<>();
for (int t = 0; t < nto; t++)
lb.append(syms.enterModule(readName(nextChar())));
lb.append(syms.enterModule(readModuleName(nextChar())));
to = lb.toList();
}
exports.add(new ExportsDirective(p, to));
exports.add(new ExportsDirective(p, to, flags));
}
msym.exports = exports.toList();
directives.addAll(msym.exports);
ListBuffer<OpensDirective> opens = new ListBuffer<>();
int nopens = nextChar();
if (nopens != 0 && msym.flags.contains(ModuleFlags.OPEN)) {
throw badClassFile("module.non.zero.opens", currentModule.name);
}
for (int i = 0; i < nopens; i++) {
Name n = readName(nextChar());
PackageSymbol p = syms.enterPackage(currentModule, names.fromUtf(internalize(n)));
Set<OpensFlag> flags = readOpensFlags(nextChar());
int nto = nextChar();
List<ModuleSymbol> to;
if (nto == 0) {
to = null;
} else {
ListBuffer<ModuleSymbol> lb = new ListBuffer<>();
for (int t = 0; t < nto; t++)
lb.append(syms.enterModule(readModuleName(nextChar())));
to = lb.toList();
}
opens.add(new OpensDirective(p, to, flags));
}
msym.opens = opens.toList();
directives.addAll(msym.opens);
msym.directives = directives.toList();
@ -1271,17 +1358,21 @@ public class ClassReader {
ListBuffer<InterimProvidesDirective> provides = new ListBuffer<>();
int nprovides = nextChar();
for (int i = 0; i < nprovides; i++) {
for (int p = 0; p < nprovides; p++) {
Name srvc = readClassName(nextChar());
Name impl = readClassName(nextChar());
provides.add(new InterimProvidesDirective(srvc, impl));
int nimpls = nextChar();
ListBuffer<Name> impls = new ListBuffer<>();
for (int i = 0; i < nimpls; i++) {
impls.append(readClassName(nextChar()));
provides.add(new InterimProvidesDirective(srvc, impls.toList()));
}
}
interimProvides = provides.toList();
}
}
},
new AttributeReader(names.Version, V53, CLASS_ATTRIBUTE) {
new AttributeReader(names.ModuleVersion, V53, CLASS_ATTRIBUTE) {
@Override
protected boolean accepts(AttributeKind kind) {
return super.accepts(kind) && allowModules;
@ -1480,7 +1571,7 @@ public class ClassReader {
} else if (proxy.type.tsym == syms.repeatableType.tsym) {
repeatable = proxy;
} else if (proxy.type.tsym == syms.deprecatedType.tsym) {
sym.flags_field |= DEPRECATED;
sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
for (Pair<Name, Attribute> v : proxy.values) {
if (v.fst == names.forRemoval && v.snd instanceof Attribute.Constant) {
Attribute.Constant c = (Attribute.Constant) v.snd;
@ -1547,7 +1638,7 @@ public class ClassReader {
// support preliminary jsr175-format class files
if (buf[poolIdx[i]] == CONSTANT_Class)
return readClassSymbol(i).type;
return readType(i);
return readTypeToProxy(i);
}
Type readEnumType(int i) {
// support preliminary jsr175-format class files
@ -1555,11 +1646,25 @@ public class ClassReader {
int length = getChar(index + 1);
if (buf[index + length + 2] != ';')
return enterClass(readName(i)).type;
return readType(i);
return readTypeToProxy(i);
}
Type readTypeToProxy(int i) {
if (currentModule.module_info == currentOwner) {
int index = poolIdx[i];
return new ProxyType(Arrays.copyOfRange(buf, index + 3, index + 3 + getChar(index + 1)));
} else {
return readType(i);
}
}
CompoundAnnotationProxy readCompoundAnnotation() {
Type t = readTypeOrClassSymbol(nextChar());
Type t;
if (currentModule.module_info == currentOwner) {
int index = poolIdx[nextChar()];
t = new ProxyType(Arrays.copyOfRange(buf, index + 3, index + 3 + getChar(index + 1)));
} else {
t = readTypeOrClassSymbol(nextChar());
}
int numFields = nextChar();
ListBuffer<Pair<Name,Attribute>> pairs = new ListBuffer<>();
for (int i=0; i<numFields; i++) {
@ -1800,7 +1905,7 @@ public class ClassReader {
case 'e':
return new EnumAttributeProxy(readEnumType(nextChar()), readName(nextChar()));
case 'c':
return new Attribute.Class(types, readTypeOrClassSymbol(nextChar()));
return new ClassAttributeProxy(readTypeOrClassSymbol(nextChar()));
case '[': {
int n = nextChar();
ListBuffer<Attribute> l = new ListBuffer<>();
@ -1817,6 +1922,7 @@ public class ClassReader {
interface ProxyVisitor extends Attribute.Visitor {
void visitEnumAttributeProxy(EnumAttributeProxy proxy);
void visitClassAttributeProxy(ClassAttributeProxy proxy);
void visitArrayAttributeProxy(ArrayAttributeProxy proxy);
void visitCompoundAnnotationProxy(CompoundAnnotationProxy proxy);
}
@ -1836,6 +1942,19 @@ public class ClassReader {
}
}
static class ClassAttributeProxy extends Attribute {
Type classType;
public ClassAttributeProxy(Type classType) {
super(null);
this.classType = classType;
}
public void accept(Visitor v) { ((ProxyVisitor)v).visitClassAttributeProxy(this); }
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public String toString() {
return "/*proxy class*/" + classType + ".class";
}
}
static class ArrayAttributeProxy extends Attribute {
List<Attribute> values;
ArrayAttributeProxy(List<Attribute> values) {
@ -1909,14 +2028,15 @@ public class ClassReader {
}
Attribute.Compound deproxyCompound(CompoundAnnotationProxy a) {
Type annotationType = resolvePossibleProxyType(a.type);
ListBuffer<Pair<Symbol.MethodSymbol,Attribute>> buf = new ListBuffer<>();
for (List<Pair<Name,Attribute>> l = a.values;
l.nonEmpty();
l = l.tail) {
MethodSymbol meth = findAccessMethod(a.type, l.head.fst);
MethodSymbol meth = findAccessMethod(annotationType, l.head.fst);
buf.append(new Pair<>(meth, deproxy(meth.type.getReturnType(), l.head.snd)));
}
return new Attribute.Compound(a.type, buf.toList());
return new Attribute.Compound(annotationType, buf.toList());
}
MethodSymbol findAccessMethod(Type container, Name name) {
@ -2000,7 +2120,8 @@ public class ClassReader {
public void visitEnumAttributeProxy(EnumAttributeProxy proxy) {
// type.tsym.flatName() should == proxy.enumFlatName
TypeSymbol enumTypeSym = proxy.enumType.tsym;
Type enumType = resolvePossibleProxyType(proxy.enumType);
TypeSymbol enumTypeSym = enumType.tsym;
VarSymbol enumerator = null;
CompletionFailure failure = null;
try {
@ -2030,6 +2151,12 @@ public class ClassReader {
}
}
@Override
public void visitClassAttributeProxy(ClassAttributeProxy proxy) {
Type classType = resolvePossibleProxyType(proxy.classType);
result = new Attribute.Class(types, classType);
}
public void visitArrayAttributeProxy(ArrayAttributeProxy proxy) {
int length = proxy.values.length();
Attribute[] ats = new Attribute[length];
@ -2044,6 +2171,21 @@ public class ClassReader {
public void visitCompoundAnnotationProxy(CompoundAnnotationProxy proxy) {
result = deproxyCompound(proxy);
}
Type resolvePossibleProxyType(Type t) {
if (t instanceof ProxyType) {
Assert.check(requestingOwner.owner.kind == MDL);
ModuleSymbol prevCurrentModule = currentModule;
currentModule = (ModuleSymbol) requestingOwner.owner;
try {
return ((ProxyType) t).resolve();
} finally {
currentModule = prevCurrentModule;
}
} else {
return t;
}
}
}
class AnnotationDefaultCompleter extends AnnotationDeproxy implements Runnable {
@ -2086,7 +2228,11 @@ public class ClassReader {
AnnotationCompleter(Symbol sym, List<CompoundAnnotationProxy> l) {
super(currentOwner.kind == MTH
? currentOwner.enclClass() : (ClassSymbol)currentOwner);
this.sym = sym;
if (sym.kind == TYP && sym.owner.kind == MDL) {
this.sym = sym.owner;
} else {
this.sym = sym;
}
this.l = l;
this.classFile = currentClassFile;
}
@ -2097,6 +2243,18 @@ public class ClassReader {
try {
currentClassFile = classFile;
List<Attribute.Compound> newList = deproxyCompoundList(l);
for (Attribute.Compound attr : newList) {
if (attr.type.tsym == syms.deprecatedType.tsym) {
sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
Attribute forRemoval = attr.member(names.forRemoval);
if (forRemoval instanceof Attribute.Constant) {
Attribute.Constant c = (Attribute.Constant) forRemoval;
if (c.type == syms.booleanType && ((Integer) c.value) != 0) {
sym.flags_field |= DEPRECATED_REMOVAL;
}
}
}
}
if (sym.annotationsPendingCompletion()) {
sym.setDeclarationAttributes(newList);
} else {
@ -2407,15 +2565,22 @@ public class ClassReader {
}
} else {
c.flags_field = flags;
Name modInfoName = readModuleInfoName(nextChar());
currentModule = (ModuleSymbol) c.owner;
if (currentModule.name.append('.', names.module_info) != modInfoName) {
//strip trailing .module-info, if exists:
int modInfoStart = modInfoName.length() - names.module_info.length();
modInfoName = modInfoName.subName(modInfoStart, modInfoName.length()) == names.module_info &&
modInfoName.charAt(modInfoStart - 1) == '.' ?
modInfoName.subName(0, modInfoStart - 1) : modInfoName;
throw badClassFile("module.name.mismatch", modInfoName, currentModule.name);
int this_class = nextChar();
// FIXME: temporary compatibility code
if (this_class == 0) {
readNewModuleAttribute = true;
} else {
Name modInfoName = readModuleInfoName(this_class);
if (currentModule.name.append('.', names.module_info) != modInfoName) {
//strip trailing .module-info, if exists:
int modInfoStart = modInfoName.length() - names.module_info.length();
modInfoName = modInfoName.subName(modInfoStart, modInfoName.length()) == names.module_info &&
modInfoName.charAt(modInfoStart - 1) == '.' ?
modInfoName.subName(0, modInfoStart - 1) : modInfoName;
throw badClassFile("module.name.mismatch", modInfoName, currentModule.name);
}
readNewModuleAttribute = false;
}
}
@ -2500,7 +2665,7 @@ public class ClassReader {
minorVersion = nextChar();
majorVersion = nextChar();
int maxMajor = Version.MAX().major;
int maxMajor = 53; // Version.MAX().major; //******* TEMPORARY *******
int maxMinor = Version.MAX().minor;
if (majorVersion > maxMajor ||
majorVersion * 1000 + minorVersion <
@ -2542,6 +2707,8 @@ public class ClassReader {
List<Type> found = foundTypeVariables;
missingTypeVariables = List.nil();
foundTypeVariables = List.nil();
interimUses = List.nil();
interimProvides = List.nil();
filling = false;
ClassType ct = (ClassType)currentOwner.type;
ct.supertype_field =
@ -2808,6 +2975,36 @@ public class ClassReader {
}
}
private class ProxyType extends Type {
private final byte[] content;
public ProxyType(byte[] content) {
super(syms.noSymbol, TypeMetadata.EMPTY);
this.content = content;
}
@Override
public TypeTag getTag() {
return TypeTag.NONE;
}
@Override
public Type cloneWithMetadata(TypeMetadata metadata) {
throw new UnsupportedOperationException();
}
public Type resolve() {
return sigToType(content, 0, content.length);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public String toString() {
return "<ProxyType>";
}
}
private static final class InterimUsesDirective {
public final Name service;
@ -2819,11 +3016,11 @@ public class ClassReader {
private static final class InterimProvidesDirective {
public final Name service;
public final Name impl;
public final List<Name> impls;
public InterimProvidesDirective(Name service, Name impl) {
public InterimProvidesDirective(Name service, List<Name> impls) {
this.service = service;
this.impl = impl;
this.impls = impls;
}
}
@ -2852,8 +3049,12 @@ public class ClassReader {
currentModule.uses = uses.toList();
ListBuffer<ProvidesDirective> provides = new ListBuffer<>();
for (InterimProvidesDirective interim : interimProvidesCopy) {
ListBuffer<ClassSymbol> impls = new ListBuffer<>();
for (Name impl : interim.impls) {
impls.append(syms.enterClass(currentModule, impl));
}
ProvidesDirective d = new ProvidesDirective(syms.enterClass(currentModule, interim.service),
syms.enterClass(currentModule, interim.impl));
impls.toList());
provides.add(d);
directives.add(d);
}

View File

@ -30,6 +30,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.LinkedHashSet;
import javax.tools.JavaFileManager;
import javax.tools.FileObject;
@ -952,6 +953,10 @@ public class ClassWriter extends ClassFile {
ModuleSymbol m = (ModuleSymbol) c.owner;
int alenIdx = writeAttr(names.Module);
databuf.appendChar(pool.put(names.fromUtf(externalize(m.name))));
databuf.appendChar(ModuleFlags.value(m.flags)); // module_flags
ListBuffer<RequiresDirective> requires = new ListBuffer<>();
for (RequiresDirective r: m.requires) {
if (!r.flags.contains(RequiresFlag.EXTRA))
@ -959,7 +964,7 @@ public class ClassWriter extends ClassFile {
}
databuf.appendChar(requires.size());
for (RequiresDirective r: requires) {
databuf.appendChar(pool.put(r.module.name));
databuf.appendChar(pool.put(names.fromUtf(externalize(r.module.name))));
databuf.appendChar(RequiresFlag.value(r.flags));
}
@ -967,12 +972,29 @@ public class ClassWriter extends ClassFile {
databuf.appendChar(exports.size());
for (ExportsDirective e: exports) {
databuf.appendChar(pool.put(names.fromUtf(externalize(e.packge.flatName()))));
databuf.appendChar(ExportsFlag.value(e.flags));
if (e.modules == null) {
databuf.appendChar(0);
} else {
databuf.appendChar(e.modules.size());
for (ModuleSymbol msym: e.modules)
databuf.appendChar(pool.put(msym.name));
for (ModuleSymbol msym: e.modules) {
databuf.appendChar(pool.put(names.fromUtf(externalize(msym.name))));
}
}
}
List<OpensDirective> opens = m.opens;
databuf.appendChar(opens.size());
for (OpensDirective o: opens) {
databuf.appendChar(pool.put(names.fromUtf(externalize(o.packge.flatName()))));
databuf.appendChar(OpensFlag.value(o.flags));
if (o.modules == null) {
databuf.appendChar(0);
} else {
databuf.appendChar(o.modules.size());
for (ModuleSymbol msym: o.modules) {
databuf.appendChar(pool.put(names.fromUtf(externalize(msym.name))));
}
}
}
@ -982,12 +1004,19 @@ public class ClassWriter extends ClassFile {
databuf.appendChar(pool.put(s.service));
}
List<ProvidesDirective> services = m.provides;
databuf.appendChar(services.size());
for (ProvidesDirective s: services) {
databuf.appendChar(pool.put(s.service));
databuf.appendChar(pool.put(s.impl));
// temporary fix to merge repeated provides clause for same service;
// eventually this should be disallowed when analyzing the module,
// so that each service type only appears once.
Map<ClassSymbol, Set<ClassSymbol>> mergedProvides = new LinkedHashMap<>();
for (ProvidesDirective p : m.provides) {
mergedProvides.computeIfAbsent(p.service, s -> new LinkedHashSet<>()).addAll(p.impls);
}
databuf.appendChar(mergedProvides.size());
mergedProvides.forEach((srvc, impls) -> {
databuf.appendChar(pool.put(srvc));
databuf.appendChar(impls.size());
impls.forEach(impl -> databuf.appendChar(pool.put(impl)));
});
endAttr(alenIdx);
return 1;
@ -1688,7 +1717,11 @@ public class ClassWriter extends ClassFile {
}
databuf.appendChar(flags);
databuf.appendChar(pool.put(c));
if (c.owner.kind == MDL) {
databuf.appendChar(0);
} else {
databuf.appendChar(pool.put(c));
}
databuf.appendChar(supertype.hasTag(CLASS) ? pool.put(supertype.tsym) : 0);
databuf.appendChar(interfaces.length());
for (List<Type> l = interfaces; l.nonEmpty(); l = l.tail)
@ -1766,12 +1799,20 @@ public class ClassWriter extends ClassFile {
acount += writeEnclosingMethodAttribute(c);
if (c.owner.kind == MDL) {
acount += writeModuleAttribute(c);
acount += writeFlagAttrs(c.owner.flags());
}
acount += writeExtraClassAttributes(c);
poolbuf.appendInt(JAVA_MAGIC);
poolbuf.appendChar(target.minorVersion);
poolbuf.appendChar(target.majorVersion);
if (c.owner.kind == MDL) {
// temporarily overide to force use of v53 for module-info.class
poolbuf.appendChar(0);
poolbuf.appendChar(53);
} else {
poolbuf.appendChar(target.minorVersion);
poolbuf.appendChar(target.majorVersion);
}
writePool(c.pool);

View File

@ -31,8 +31,6 @@ import java.nio.file.Path;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.jvm.ClassFile;
import static com.sun.tools.javac.jvm.ClassFile.*;
@ -93,11 +91,44 @@ public class ModuleNameReader {
int minorVersion = nextChar();
int majorVersion = nextChar();
if (majorVersion < 53)
throw new BadClassFile("bad major version number for module: " + majorVersion);
indexPool();
int accessflags = nextChar();
return readModuleInfoName(nextChar());
int access_flags = nextChar();
if (access_flags != 0x8000)
throw new BadClassFile("invalid access flags for module: 0x" + Integer.toHexString(access_flags));
// FIXME: temporary compatibility code
int this_class = nextChar();
if (this_class == 0) {
// new form
checkZero(nextChar(), "super_class");
checkZero(nextChar(), "interface_count");
checkZero(nextChar(), "fields_count");
checkZero(nextChar(), "methods_count");
int attributes_count = nextChar();
for (int i = 0; i < attributes_count; i++) {
int attr_name = nextChar();
int attr_length = nextInt();
if (getUtf8Value(attr_name, false).equals("Module") && attr_length > 2) {
return getUtf8Value(nextChar(), true);
} else {
// skip over unknown attributes
bp += attr_length;
}
}
throw new BadClassFile("no Module attribute");
} else {
// old form
return readModuleInfoName(this_class);
}
}
void checkZero(int count, String name) throws BadClassFile {
if (count != 0)
throw new BadClassFile("invalid " + name + " for module: " + count);
}
/** Extract a character at position bp from buf.
@ -166,6 +197,20 @@ public class ModuleNameReader {
}
}
String getUtf8Value(int index, boolean internalize) throws BadClassFile {
int utf8Index = poolIdx[index];
if (buf[utf8Index] == CONSTANT_Utf8) {
int len = getChar(utf8Index + 1);
int start = utf8Index + 3;
if (internalize) {
return new String(ClassFile.internalize(buf, start, len));
} else {
return new String(buf, start, len);
}
}
throw new BadClassFile("bad name at index " + index);
}
/** Read the class name of a module-info.class file.
* The name is stored in a CONSTANT_Class entry, where the
* class name is of the form module-name/module-info.

View File

@ -608,8 +608,9 @@ public class Arguments {
log.error(Errors.ProcessorpathNoProcessormodulepath);
}
if (obsoleteOptionFound)
if (obsoleteOptionFound && lintOptions) {
log.warning(LintCategory.OPTIONS, "option.obsolete.suppression");
}
SourceVersion sv = Source.toSourceVersion(source);
validateAddExports(sv);
@ -617,6 +618,10 @@ public class Arguments {
validateAddReads(sv);
validateLimitModules(sv);
if (lintOptions && options.isSet(Option.ADD_OPENS)) {
log.warning(LintCategory.OPTIONS, Warnings.AddopensIgnored);
}
return !errors && (log.nerrors == 0);
}

View File

@ -584,6 +584,8 @@ public enum Option {
}
},
ADD_OPENS("--add-opens", null, null, HIDDEN, BASIC),
ADD_READS("--add-reads", "opt.arg.addReads", "opt.addReads", EXTENDED, BASIC) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {

View File

@ -375,7 +375,8 @@ public class JavacElements implements Elements {
@DefinedBy(Api.LANGUAGE_MODEL)
public boolean isDeprecated(Element e) {
Symbol sym = cast(Symbol.class, e);
return (sym.flags() & Flags.DEPRECATED) != 0;
sym.complete();
return sym.isDeprecated();
}
@DefinedBy(Api.LANGUAGE_MODEL)

View File

@ -29,6 +29,7 @@ import java.util.*;
import java.util.stream.Collectors;
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
import com.sun.source.tree.ModuleTree.ModuleKind;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.parser.Tokens.*;
@ -51,7 +52,6 @@ import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
/** The parser maps a token sequence into an abstract syntax
* tree. It operates by recursive descent, with code derived
@ -3105,65 +3105,78 @@ public class JavacParser implements Parser {
Token firstToken = token;
JCModifiers mods = null;
boolean consumedToplevelDoc = false;
boolean seenImport = false;
boolean seenPackage = false;
ListBuffer<JCTree> defs = new ListBuffer<>();
if (token.kind == MONKEYS_AT)
mods = modifiersOpt();
if (token.kind == IDENTIFIER && token.name() == names.module) {
defs.append(moduleDecl(token.comment(CommentStyle.JAVADOC)));
if (token.kind == PACKAGE) {
int packagePos = token.pos;
List<JCAnnotation> annotations = List.nil();
seenPackage = true;
if (mods != null) {
checkNoMods(mods.flags);
annotations = mods.annotations;
mods = null;
}
nextToken();
JCExpression pid = qualident(false);
accept(SEMI);
JCPackageDecl pd = F.at(packagePos).PackageDecl(annotations, pid);
attach(pd, firstToken.comment(CommentStyle.JAVADOC));
consumedToplevelDoc = true;
} else {
boolean seenImport = false;
boolean seenPackage = false;
if (token.kind == MONKEYS_AT)
mods = modifiersOpt();
if (token.kind == PACKAGE) {
int packagePos = token.pos;
List<JCAnnotation> annotations = List.nil();
seenPackage = true;
if (mods != null) {
checkNoMods(mods.flags);
annotations = mods.annotations;
mods = null;
}
nextToken();
JCExpression pid = qualident(false);
accept(SEMI);
JCPackageDecl pd = F.at(packagePos).PackageDecl(annotations, pid);
attach(pd, firstToken.comment(CommentStyle.JAVADOC));
consumedToplevelDoc = true;
storeEnd(pd, token.pos);
defs.append(pd);
}
boolean checkForImports = true;
boolean firstTypeDecl = true;
while (token.kind != EOF) {
if (token.pos <= endPosTable.errorEndPos) {
// error recovery
skip(checkForImports, false, false, false);
if (token.kind == EOF)
break;
}
if (checkForImports && mods == null && token.kind == IMPORT) {
seenImport = true;
defs.append(importDeclaration());
} else {
Comment docComment = token.comment(CommentStyle.JAVADOC);
if (firstTypeDecl && !seenImport && !seenPackage) {
docComment = firstToken.comment(CommentStyle.JAVADOC);
consumedToplevelDoc = true;
}
JCTree def = typeDeclaration(mods, docComment);
if (def instanceof JCExpressionStatement)
def = ((JCExpressionStatement)def).expr;
defs.append(def);
if (def instanceof JCClassDecl)
checkForImports = false;
mods = null;
firstTypeDecl = false;
}
}
storeEnd(pd, token.pos);
defs.append(pd);
}
boolean checkForImports = true;
boolean firstTypeDecl = true;
while (token.kind != EOF) {
if (token.pos <= endPosTable.errorEndPos) {
// error recovery
skip(checkForImports, false, false, false);
if (token.kind == EOF)
break;
}
if (checkForImports && mods == null && token.kind == IMPORT) {
seenImport = true;
defs.append(importDeclaration());
} else {
Comment docComment = token.comment(CommentStyle.JAVADOC);
if (firstTypeDecl && !seenImport && !seenPackage) {
docComment = firstToken.comment(CommentStyle.JAVADOC);
consumedToplevelDoc = true;
}
if (mods != null || token.kind != SEMI)
mods = modifiersOpt(mods);
if (firstTypeDecl && token.kind == IDENTIFIER) {
ModuleKind kind = ModuleKind.STRONG;
if (token.name() == names.open) {
kind = ModuleKind.OPEN;
nextToken();
}
if (token.kind == IDENTIFIER && token.name() == names.module) {
if (mods != null) {
checkNoMods(mods.flags & ~Flags.DEPRECATED);
}
defs.append(moduleDecl(mods, kind, docComment));
consumedToplevelDoc = true;
break;
} else if (kind != ModuleKind.STRONG) {
reportSyntaxError(token.pos, "expected.module");
}
}
JCTree def = typeDeclaration(mods, docComment);
if (def instanceof JCExpressionStatement)
def = ((JCExpressionStatement)def).expr;
defs.append(def);
if (def instanceof JCClassDecl)
checkForImports = false;
mods = null;
firstTypeDecl = false;
}
}
JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(defs.toList());
if (!consumedToplevelDoc)
attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
@ -3178,7 +3191,7 @@ public class JavacParser implements Parser {
return toplevel;
}
JCModuleDecl moduleDecl(Comment dc) {
JCModuleDecl moduleDecl(JCModifiers mods, ModuleKind kind, Comment dc) {
int pos = token.pos;
if (!allowModules) {
log.error(pos, Errors.ModulesNotSupportedInSource(source.name));
@ -3194,7 +3207,7 @@ public class JavacParser implements Parser {
accept(RBRACE);
accept(EOF);
JCModuleDecl result = toP(F.at(pos).ModuleDef(name, directives));
JCModuleDecl result = toP(F.at(pos).ModuleDef(mods, kind, name, directives));
attach(result, dc);
return result;
}
@ -3205,15 +3218,38 @@ public class JavacParser implements Parser {
int pos = token.pos;
if (token.name() == names.requires) {
nextToken();
boolean isPublic = false;
if (token.kind == PUBLIC) {
isPublic = true;
boolean isTransitive = false;
boolean isStaticPhase = false;
loop:
while (true) {
switch (token.kind) {
case IDENTIFIER:
if (token.name() == names.transitive && !isTransitive) {
Token t1 = S.token(1);
if (t1.kind == SEMI || t1.kind == DOT) {
break loop;
}
isTransitive = true;
break;
} else {
break loop;
}
case STATIC:
if (isStaticPhase) {
error(token.pos, "repeated.modifier");
}
isStaticPhase = true;
break;
default:
break loop;
}
nextToken();
}
JCExpression moduleName = qualident(false);
accept(SEMI);
defs.append(toP(F.at(pos).Requires(isPublic, moduleName)));
} else if (token.name() == names.exports) {
defs.append(toP(F.at(pos).Requires(isTransitive, isStaticPhase, moduleName)));
} else if (token.name() == names.exports || token.name() == names.opens) {
boolean exports = token.name() == names.exports;
nextToken();
JCExpression pkgName = qualident(false);
List<JCExpression> moduleNames = null;
@ -3222,15 +3258,21 @@ public class JavacParser implements Parser {
moduleNames = qualidentList(false);
}
accept(SEMI);
defs.append(toP(F.at(pos).Exports(pkgName, moduleNames)));
JCDirective d;
if (exports) {
d = F.at(pos).Exports(pkgName, moduleNames);
} else {
d = F.at(pos).Opens(pkgName, moduleNames);
}
defs.append(toP(d));
} else if (token.name() == names.provides) {
nextToken();
JCExpression serviceName = qualident(false);
if (token.kind == IDENTIFIER && token.name() == names.with) {
nextToken();
JCExpression implName = qualident(false);
List<JCExpression> implNames = qualidentList(false);
accept(SEMI);
defs.append(toP(F.at(pos).Provides(serviceName, implName)));
defs.append(toP(F.at(pos).Provides(serviceName, implNames)));
} else {
error(token.pos, "expected", "'" + names.with + "'");
skip(false, false, false, false);

View File

@ -872,6 +872,9 @@ compiler.err.operator.cant.be.applied.1=\
compiler.err.pkg.annotations.sb.in.package-info.java=\
package annotations should be in file package-info.java
compiler.err.no.pkg.in.module-info.java=\
package clauses should not be in file module-info.java
# 0: symbol
compiler.err.pkg.clashes.with.class.of.same.name=\
package {0} clashes with class of same name
@ -1462,6 +1465,14 @@ compiler.warn.has.been.deprecated=\
compiler.warn.has.been.deprecated.for.removal=\
{0} in {1} has been deprecated and marked for removal
# 0: symbol
compiler.warn.has.been.deprecated.module=\
module {0} has been deprecated
# 0: symbol
compiler.warn.has.been.deprecated.for.removal.module=\
module {0} has been deprecated and marked for removal
# 0: symbol
compiler.warn.sun.proprietary=\
{0} is internal proprietary API and may be removed in a future release
@ -1796,6 +1807,9 @@ compiler.err.premature.eof=\
reached end of file while parsing
## The following are related in form, but do not easily fit the above paradigm.
compiler.err.expected.module=\
''module'' expected
compiler.err.dot.class.expected=\
''.class'' expected
@ -2747,8 +2761,23 @@ compiler.err.duplicate.requires=\
duplicate requires: {0}
# 0: symbol
compiler.err.duplicate.exports=\
duplicate export: {0}
compiler.err.conflicting.exports=\
duplicate or conflicting exports: {0}
# 0: symbol
compiler.err.conflicting.opens=\
duplicate or conflicting opens: {0}
# 0: symbol
compiler.err.conflicting.exports.to.module=\
duplicate or conflicting exports to module: {0}
# 0: symbol
compiler.err.conflicting.opens.to.module=\
duplicate or conflicting opens to module: {0}
compiler.err.no.opens.unless.strong=\
''opens'' only allowed in strong modules
# 0: symbol, 1: symbol
compiler.err.duplicate.provides=\
@ -2763,7 +2792,11 @@ compiler.err.service.implementation.is.abstract=\
the service implementation is an abstract class: {0}
compiler.err.service.implementation.must.be.subtype.of.service.interface=\
the service implementation type must be a subtype of the service interface type
the service implementation type must be a subtype of the service interface type, or \
have a public static no-args method named "provider" returning the service implementation
compiler.err.service.implementation.provider.return.must.be.subtype.of.service.interface=\
the "provider" method return type must be a subtype of the service interface type
# 0: symbol
compiler.err.service.implementation.is.inner=\
@ -2799,6 +2832,14 @@ compiler.err.module.name.mismatch=\
compiler.misc.module.name.mismatch=\
module name {0} does not match expected name {1}
# 0: name
compiler.err.module.non.zero.opens=\
open module {0} has non-zero opens_count
# 0: name
compiler.misc.module.non.zero.opens=\
open module {0} has non-zero opens_count
compiler.err.module.decl.sb.in.module-info.java=\
module declarations should be in a file named module-info.java
@ -2855,6 +2896,9 @@ compiler.warn.module.for.option.not.found=\
compiler.err.addmods.all.module.path.invalid=\
--add-modules ALL-MODULE-PATH can only be used when compiling the unnamed module
compiler.warn.addopens.ignored=\
--add-opens has no effect at compile time
compiler.misc.locn.module_source_path=\
module source path
@ -2885,8 +2929,8 @@ compiler.warn.leaks.not.accessible=\
compiler.warn.leaks.not.accessible.unexported=\
{0} {1} in module {2} is not exported
# 0: kind name, 1: symbol, 2: symbol
compiler.warn.leaks.not.accessible.not.required.public=\
{0} {1} in module {2} is not indirectly exported using 'requires public'
compiler.warn.leaks.not.accessible.not.required.transitive=\
{0} {1} in module {2} is not indirectly exported using 'requires transitive'
# 0: kind name, 1: symbol, 2: symbol
compiler.warn.leaks.not.accessible.unexported.qualified=\
{0} {1} in module {2} may not be visible to all clients that require this module

View File

@ -841,7 +841,7 @@ compiler.err.class.public.should.be.in.file=\u30AF\u30E9\u30B9{0}\u306Fpublic\u3
## All errors which do not refer to a particular line in the source code are
## preceded by this string.
compiler.err.error=\u30A8\u30E9\u30FC:
compiler.err.error=\u30A8\u30E9\u30FC:
# The following error messages do not refer to a line in the source code.
compiler.err.cant.read.file={0}\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093
@ -1021,7 +1021,7 @@ compiler.warn.warning=\u8B66\u544A:
## Warning messages may also include the following prefix to identify a
## lint option
# 0: option name
compiler.warn.lintOption=[{0}]
compiler.warn.lintOption=[{0}]
# 0: symbol
compiler.warn.constant.SVUID=serialVersionUID\u306F\u30AF\u30E9\u30B9{0}\u306E\u5B9A\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059

View File

@ -841,7 +841,7 @@ compiler.err.class.public.should.be.in.file=\u7C7B{0}\u662F\u516C\u5171\u7684, \
## All errors which do not refer to a particular line in the source code are
## preceded by this string.
compiler.err.error=\u9519\u8BEF:
compiler.err.error=\u9519\u8BEF:
# The following error messages do not refer to a line in the source code.
compiler.err.cant.read.file=\u65E0\u6CD5\u8BFB\u53D6: {0}
@ -927,7 +927,7 @@ compiler.note.mref.stat=\u8F6C\u6362\u65B9\u6CD5\u5F15\u7528\n\u66FF\u4EE3 metaf
# 0: boolean, 1: symbol
compiler.note.mref.stat.1=\u8F6C\u6362\u65B9\u6CD5\u5F15\u7528\n\u66FF\u4EE3 metafactory = {0}\nbridge \u65B9\u6CD5 = {1}
compiler.note.note=\u6CE8:
compiler.note.note=\u6CE8:
# 0: file name
compiler.note.deprecated.filename={0}\u4F7F\u7528\u6216\u8986\u76D6\u4E86\u5DF2\u8FC7\u65F6\u7684 API\u3002
@ -1016,12 +1016,12 @@ compiler.misc.resume.abort=\u7EE7\u7EED(R), \u653E\u5F03(A)>
##
## All warning messages are preceded by the following string.
compiler.warn.warning=\u8B66\u544A:
compiler.warn.warning=\u8B66\u544A:
## Warning messages may also include the following prefix to identify a
## lint option
# 0: option name
compiler.warn.lintOption=[{0}]
compiler.warn.lintOption=[{0}]
# 0: symbol
compiler.warn.constant.SVUID=serialVersionUID \u5728\u7C7B{0}\u4E2D\u5FC5\u987B\u662F\u5E38\u91CF

View File

@ -47,7 +47,10 @@ import static com.sun.tools.javac.tree.JCTree.Tag.*;
import javax.tools.JavaFileManager.Location;
import com.sun.source.tree.ModuleTree.ModuleKind;
import com.sun.tools.javac.code.Directive.ExportsDirective;
import com.sun.tools.javac.code.Directive.OpensDirective;
import com.sun.tools.javac.code.Type.ModuleType;
/**
* Root class for abstract syntax tree nodes. It provides definitions
@ -352,6 +355,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
MODULEDEF,
EXPORTS,
OPENS,
PROVIDES,
REQUIRES,
USES,
@ -527,6 +531,16 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
@DefinedBy(Api.COMPILER_TREE)
public Kind getKind() { return Kind.COMPILATION_UNIT; }
public JCModuleDecl getModuleDecl() {
for (JCTree tree : defs) {
if (tree.hasTag(MODULEDEF)) {
return (JCModuleDecl) tree;
}
}
return null;
}
@DefinedBy(Api.COMPILER_TREE)
public JCPackageDecl getPackage() {
// PackageDecl must be the first entry if it exists
@ -2619,11 +2633,17 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
}
public static class JCModuleDecl extends JCTree implements ModuleTree {
public JCModifiers mods;
public ModuleType type;
private final ModuleKind kind;
public JCExpression qualId;
public List<JCDirective> directives;
public ModuleSymbol sym;
protected JCModuleDecl(JCExpression qualId, List<JCDirective> directives) {
protected JCModuleDecl(JCModifiers mods, ModuleKind kind,
JCExpression qualId, List<JCDirective> directives) {
this.mods = mods;
this.kind = kind;
this.qualId = qualId;
this.directives = directives;
}
@ -2636,6 +2656,16 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
return Kind.MODULE;
}
@Override @DefinedBy(Api.COMPILER_TREE)
public List<? extends AnnotationTree> getAnnotations() {
return mods.annotations;
}
@Override @DefinedBy(Api.COMPILER_TREE)
public ModuleKind getModuleType() {
return kind;
}
@Override @DefinedBy(Api.COMPILER_TREE)
public JCExpression getName() {
return qualId;
@ -2677,7 +2707,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
}
@Override @DefinedBy(Api.COMPILER_TREE)
public JCExpression getExportName() {
public JCExpression getPackageName() {
return qualid;
}
@ -2693,18 +2723,58 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
@Override
public Tag getTag() {
return EXPORTS;
return Tag.EXPORTS;
}
}
public static class JCOpens extends JCDirective
implements OpensTree {
public JCExpression qualid;
public List<JCExpression> moduleNames;
public OpensDirective directive;
protected JCOpens(JCExpression qualId, List<JCExpression> moduleNames) {
this.qualid = qualId;
this.moduleNames = moduleNames;
}
@Override
public void accept(Visitor v) { v.visitOpens(this); }
@Override @DefinedBy(Api.COMPILER_TREE)
public Kind getKind() {
return Kind.OPENS;
}
@Override @DefinedBy(Api.COMPILER_TREE)
public JCExpression getPackageName() {
return qualid;
}
@Override @DefinedBy(Api.COMPILER_TREE)
public List<JCExpression> getModuleNames() {
return moduleNames;
}
@Override @DefinedBy(Api.COMPILER_TREE)
public <R, D> R accept(TreeVisitor<R, D> v, D d) {
return v.visitOpens(this, d);
}
@Override
public Tag getTag() {
return Tag.OPENS;
}
}
public static class JCProvides extends JCDirective
implements ProvidesTree {
public JCExpression serviceName;
public JCExpression implName;
public List<JCExpression> implNames;
protected JCProvides(JCExpression serviceName, JCExpression implName) {
protected JCProvides(JCExpression serviceName, List<JCExpression> implNames) {
this.serviceName = serviceName;
this.implName = implName;
this.implNames = implNames;
}
@Override
@ -2726,8 +2796,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
}
@Override @DefinedBy(Api.COMPILER_TREE)
public JCExpression getImplementationName() {
return implName;
public List<JCExpression> getImplementationNames() {
return implNames;
}
@Override
@ -2738,12 +2808,14 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public static class JCRequires extends JCDirective
implements RequiresTree {
public boolean isPublic;
public boolean isTransitive;
public boolean isStaticPhase;
public JCExpression moduleName;
public RequiresDirective directive;
protected JCRequires(boolean isPublic, JCExpression moduleName) {
this.isPublic = isPublic;
protected JCRequires(boolean isTransitive, boolean isStaticPhase, JCExpression moduleName) {
this.isTransitive = isTransitive;
this.isStaticPhase = isStaticPhase;
this.moduleName = moduleName;
}
@ -2761,8 +2833,13 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
}
@Override @DefinedBy(Api.COMPILER_TREE)
public boolean isPublic() {
return isPublic;
public boolean isTransitive() {
return isTransitive;
}
@Override @DefinedBy(Api.COMPILER_TREE)
public boolean isStatic() {
return isStaticPhase;
}
@Override @DefinedBy(Api.COMPILER_TREE)
@ -2946,10 +3023,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args);
JCModifiers Modifiers(long flags, List<JCAnnotation> annotations);
JCErroneous Erroneous(List<? extends JCTree> errs);
JCModuleDecl ModuleDef(JCExpression qualId, List<JCDirective> directives);
JCModuleDecl ModuleDef(JCModifiers mods, ModuleKind kind, JCExpression qualId, List<JCDirective> directives);
JCExports Exports(JCExpression qualId, List<JCExpression> moduleNames);
JCProvides Provides(JCExpression serviceName, JCExpression implName);
JCRequires Requires(boolean isPublic, JCExpression qualId);
JCOpens Opens(JCExpression qualId, List<JCExpression> moduleNames);
JCProvides Provides(JCExpression serviceName, List<JCExpression> implNames);
JCRequires Requires(boolean isTransitive, boolean isStaticPhase, JCExpression qualId);
JCUses Uses(JCExpression qualId);
LetExpr LetExpr(List<JCVariableDecl> defs, JCExpression expr);
}
@ -3013,6 +3091,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public void visitErroneous(JCErroneous that) { visitTree(that); }
public void visitModuleDef(JCModuleDecl that) { visitTree(that); }
public void visitExports(JCExports that) { visitTree(that); }
public void visitOpens(JCOpens that) { visitTree(that); }
public void visitProvides(JCProvides that) { visitTree(that); }
public void visitRequires(JCRequires that) { visitTree(that); }
public void visitUses(JCUses that) { visitTree(that); }

View File

@ -28,6 +28,7 @@ package com.sun.tools.javac.tree;
import java.io.*;
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
import com.sun.source.tree.ModuleTree.ModuleKind;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.*;
@ -441,6 +442,10 @@ public class Pretty extends JCTree.Visitor {
@Override
public void visitModuleDef(JCModuleDecl tree) {
try {
printAnnotations(tree.mods.annotations);
if (tree.getModuleType() == ModuleKind.OPEN) {
print("open ");
}
print("module ");
printExpr(tree.qualId);
if (tree.directives == null) {
@ -457,7 +462,11 @@ public class Pretty extends JCTree.Visitor {
@Override
public void visitExports(JCExports tree) {
try {
print("exports ");
if (tree.hasTag(EXPORTS)) {
print("exports ");
} else {
print("opens ");
}
printExpr(tree.qualid);
if (tree.moduleNames != null) {
print(" to ");
@ -475,7 +484,7 @@ public class Pretty extends JCTree.Visitor {
print("provides ");
printExpr(tree.serviceName);
print(" with ");
printExpr(tree.implName);
printExprs(tree.implNames);
print(";");
} catch (IOException e) {
throw new UncheckedIOException(e);
@ -486,8 +495,10 @@ public class Pretty extends JCTree.Visitor {
public void visitRequires(JCRequires tree) {
try {
print("requires ");
if (tree.isPublic)
print("public ");
if (tree.isStaticPhase)
print("static ");
if (tree.isTransitive)
print("transitive ");
printExpr(tree.moduleName);
print(";");
} catch (IOException e) {

View File

@ -26,6 +26,7 @@
package com.sun.tools.javac.tree;
import com.sun.source.tree.*;
import com.sun.source.tree.Tree.Kind;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
@ -508,9 +509,10 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
@Override @DefinedBy(Api.COMPILER_TREE)
public JCTree visitModule(ModuleTree node, P p) {
JCModuleDecl t = (JCModuleDecl) node;
JCModifiers mods = copy(t.mods, p);
JCExpression qualId = copy(t.qualId);
List<JCDirective> directives = copy(t.directives);
return M.at(t.pos).ModuleDef(qualId, directives);
return M.at(t.pos).ModuleDef(mods, t.getModuleType(), qualId, directives);
}
@Override @DefinedBy(Api.COMPILER_TREE)
@ -521,19 +523,27 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
return M.at(t.pos).Exports(qualId, moduleNames);
}
@Override @DefinedBy(Api.COMPILER_TREE)
public JCOpens visitOpens(OpensTree node, P p) {
JCOpens t = (JCOpens) node;
JCExpression qualId = copy(t.qualid, p);
List<JCExpression> moduleNames = copy(t.moduleNames, p);
return M.at(t.pos).Opens(qualId, moduleNames);
}
@Override @DefinedBy(Api.COMPILER_TREE)
public JCProvides visitProvides(ProvidesTree node, P p) {
JCProvides t = (JCProvides) node;
JCExpression serviceName = copy(t.serviceName, p);
JCExpression implName = copy(t.implName, p);
return M.at(t.pos).Provides(serviceName, implName);
List<JCExpression> implNames = copy(t.implNames, p);
return M.at(t.pos).Provides(serviceName, implNames);
}
@Override @DefinedBy(Api.COMPILER_TREE)
public JCRequires visitRequires(RequiresTree node, P p) {
JCRequires t = (JCRequires) node;
JCExpression moduleName = copy(t.moduleName, p);
return M.at(t.pos).Requires(t.isPublic, moduleName);
return M.at(t.pos).Requires(t.isTransitive, t.isStaticPhase, moduleName);
}
@Override @DefinedBy(Api.COMPILER_TREE)

View File

@ -378,6 +378,11 @@ public class TreeInfo {
return Position.NOPOS;
switch(tree.getTag()) {
case MODULEDEF: {
JCModuleDecl md = (JCModuleDecl)tree;
return md.mods.annotations.isEmpty() ? md.pos :
md.mods.annotations.head.pos;
}
case PACKAGEDEF: {
JCPackageDecl pd = (JCPackageDecl)tree;
return pd.annotations.isEmpty() ? pd.pos :
@ -769,8 +774,9 @@ public class TreeInfo {
switch (node.getTag()) {
case TOPLEVEL:
JCCompilationUnit cut = (JCCompilationUnit) node;
if (isModuleInfo(cut) && cut.defs.nonEmpty() && cut.defs.head.hasTag(MODULEDEF))
return symbolFor(cut.defs.head);
JCModuleDecl moduleDecl = cut.getModuleDecl();
if (isModuleInfo(cut) && moduleDecl != null)
return symbolFor(moduleDecl);
return cut.packge;
case MODULEDEF:
return ((JCModuleDecl) node).sym;
@ -1076,6 +1082,11 @@ public class TreeInfo {
case TYPE_ANNOTATION:
return Tree.Kind.TYPE_ANNOTATION;
case EXPORTS:
return Tree.Kind.EXPORTS;
case OPENS:
return Tree.Kind.OPENS;
default:
return null;
}
@ -1158,7 +1169,7 @@ public class TreeInfo {
public static boolean isModuleInfo(JCCompilationUnit tree) {
return tree.sourcefile.isNameCompatible("module-info", JavaFileObject.Kind.SOURCE)
&& tree.defs.nonEmpty() && tree.defs.head.hasTag(MODULEDEF);
&& tree.getModuleDecl() != null;
}
public static JCModuleDecl getModule(JCCompilationUnit t) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2016, 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
@ -27,6 +27,8 @@ package com.sun.tools.javac.tree;
import java.util.Iterator;
import com.sun.source.tree.ModuleTree.ModuleKind;
import com.sun.source.tree.Tree.Kind;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
@ -538,8 +540,9 @@ public class TreeMaker implements JCTree.Factory {
}
@Override
public JCModuleDecl ModuleDef(JCExpression qualid, List<JCDirective> directives) {
JCModuleDecl tree = new JCModuleDecl(qualid, directives);
public JCModuleDecl ModuleDef(JCModifiers mods, ModuleKind kind,
JCExpression qualid, List<JCDirective> directives) {
JCModuleDecl tree = new JCModuleDecl(mods, kind, qualid, directives);
tree.pos = pos;
return tree;
}
@ -552,15 +555,22 @@ public class TreeMaker implements JCTree.Factory {
}
@Override
public JCProvides Provides(JCExpression serviceName, JCExpression implName) {
JCProvides tree = new JCProvides(serviceName, implName);
public JCOpens Opens(JCExpression qualId, List<JCExpression> moduleNames) {
JCOpens tree = new JCOpens(qualId, moduleNames);
tree.pos = pos;
return tree;
}
@Override
public JCRequires Requires(boolean isPublic, JCExpression qualId) {
JCRequires tree = new JCRequires(isPublic, qualId);
public JCProvides Provides(JCExpression serviceName, List<JCExpression> implNames) {
JCProvides tree = new JCProvides(serviceName, implNames);
tree.pos = pos;
return tree;
}
@Override
public JCRequires Requires(boolean isTransitive, boolean isStaticPhase, JCExpression qualId) {
JCRequires tree = new JCRequires(isTransitive, isStaticPhase, qualId);
tree.pos = pos;
return tree;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2016, 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
@ -73,6 +73,7 @@ public class TreeScanner extends Visitor {
@Override
public void visitModuleDef(JCModuleDecl tree) {
scan(tree.mods);
scan(tree.qualId);
scan(tree.directives);
}
@ -83,10 +84,16 @@ public class TreeScanner extends Visitor {
scan(tree.moduleNames);
}
@Override
public void visitOpens(JCOpens tree) {
scan(tree.qualid);
scan(tree.moduleNames);
}
@Override
public void visitProvides(JCProvides tree) {
scan(tree.serviceName);
scan(tree.implName);
scan(tree.implNames);
}
@Override

View File

@ -51,4 +51,5 @@ public class ModuleHelper {
from.addExports(pack, to);
}
}
}
}

View File

@ -64,11 +64,14 @@ public class Names {
public final Name _super;
public final Name _this;
public final Name exports;
public final Name opens;
public final Name module;
public final Name provides;
public final Name requires;
public final Name to;
public final Name transitive;
public final Name uses;
public final Name open;
public final Name with;
// field and method names
@ -101,6 +104,7 @@ public class Names {
public final Name length;
public final Name next;
public final Name ordinal;
public final Name provider;
public final Name serialVersionUID;
public final Name toString;
public final Name value;
@ -146,6 +150,7 @@ public class Names {
public final Name LocalVariableTypeTable;
public final Name MethodParameters;
public final Name Module;
public final Name ModuleVersion;
public final Name RuntimeInvisibleAnnotations;
public final Name RuntimeInvisibleParameterAnnotations;
public final Name RuntimeInvisibleTypeAnnotations;
@ -160,7 +165,6 @@ public class Names {
public final Name Synthetic;
public final Name Value;
public final Name Varargs;
public final Name Version;
// members of java.lang.annotation.ElementType
public final Name ANNOTATION_TYPE;
@ -168,6 +172,7 @@ public class Names {
public final Name FIELD;
public final Name LOCAL_VARIABLE;
public final Name METHOD;
public final Name MODULE;
public final Name PACKAGE;
public final Name PARAMETER;
public final Name TYPE;
@ -220,11 +225,14 @@ public class Names {
_super = fromString("super");
_this = fromString("this");
exports = fromString("exports");
opens = fromString("opens");
module = fromString("module");
provides = fromString("provides");
requires = fromString("requires");
to = fromString("to");
transitive = fromString("transitive");
uses = fromString("uses");
open = fromString("open");
with = fromString("with");
// field and method names
@ -257,6 +265,7 @@ public class Names {
length = fromString("length");
next = fromString("next");
ordinal = fromString("ordinal");
provider = fromString("provider");
serialVersionUID = fromString("serialVersionUID");
toString = fromString("toString");
value = fromString("value");
@ -303,6 +312,7 @@ public class Names {
LocalVariableTypeTable = fromString("LocalVariableTypeTable");
MethodParameters = fromString("MethodParameters");
Module = fromString("Module");
ModuleVersion = fromString("ModuleVersion");
RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations");
RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
@ -317,7 +327,6 @@ public class Names {
Synthetic = fromString("Synthetic");
Value = fromString("Value");
Varargs = fromString("Varargs");
Version = fromString("Version");
// members of java.lang.annotation.ElementType
ANNOTATION_TYPE = fromString("ANNOTATION_TYPE");
@ -325,6 +334,7 @@ public class Names {
FIELD = fromString("FIELD");
LOCAL_VARIABLE = fromString("LOCAL_VARIABLE");
METHOD = fromString("METHOD");
MODULE = fromString("MODULE");
PACKAGE = fromString("PACKAGE");
PARAMETER = fromString("PARAMETER");
TYPE = fromString("TYPE");

View File

@ -28,7 +28,7 @@
* and its command line equivalent, <em>javac</em>, as well as <em>javah</em>.
*/
module jdk.compiler {
requires public java.compiler;
requires transitive java.compiler;
exports com.sun.source.doctree;
exports com.sun.source.tree;

View File

@ -79,7 +79,7 @@
* module declaration, to create a module set to considered for documentation
* as follows:
* <ul>
* <li> public -- follows and expands all "requires public" edges in the module graph
* <li> transitive -- follows and expands all "requires transitive" edges in the module graph
* <li> all -- follows and expands all "requires" edges in the module graph.
* By default, only the specified modules will be considered, without expansion
* of the module dependencies.

View File

@ -28,11 +28,18 @@ package jdk.javadoc.internal.doclets.formats.html;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.SortedSet;
import javax.lang.model.element.Element;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import com.sun.source.doctree.DocTree;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.util.DeprecatedAPIListBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.DeprecatedAPIListBuilder.DeprElementKind;
@ -57,6 +64,8 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
private String getAnchorName(DeprElementKind kind) {
switch (kind) {
case MODULE:
return "module";
case PACKAGE:
return "package";
case INTERFACE:
@ -88,6 +97,8 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
private String getHeadingKey(DeprElementKind kind) {
switch (kind) {
case MODULE:
return "doclet.Deprecated_Modules";
case PACKAGE:
return "doclet.Deprecated_Packages";
case INTERFACE:
@ -119,6 +130,8 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
private String getSummaryKey(DeprElementKind kind) {
switch (kind) {
case MODULE:
return "doclet.deprecated_modules";
case PACKAGE:
return "doclet.deprecated_packages";
case INTERFACE:
@ -150,6 +163,8 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
private String getHeaderKey(DeprElementKind kind) {
switch (kind) {
case MODULE:
return "doclet.Module";
case PACKAGE:
return "doclet.Package";
case INTERFACE:
@ -197,6 +212,7 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
writerMap = new EnumMap<>(DeprElementKind.class);
for (DeprElementKind kind : DeprElementKind.values()) {
switch (kind) {
case MODULE:
case PACKAGE:
case INTERFACE:
case CLASS:
@ -268,12 +284,16 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
List<String> memberTableHeader = new ArrayList<>();
memberTableHeader.add(resources.getText(getHeaderKey(kind)));
memberTableHeader.add(resources.getText("doclet.Description"));
if (kind == DeprElementKind.PACKAGE)
if (kind == DeprElementKind.MODULE) {
addModuleDeprecatedAPI(deprapi.getSet(kind),
getHeadingKey(kind), memberTableSummary, memberTableHeader, div);
} else if (kind == DeprElementKind.PACKAGE) {
addPackageDeprecatedAPI(deprapi.getSet(kind),
getHeadingKey(kind), memberTableSummary, memberTableHeader, div);
else
} else {
writerMap.get(kind).addDeprecatedAPI(deprapi.getSet(kind),
getHeadingKey(kind), memberTableSummary, memberTableHeader, div);
}
}
}
if (configuration.allowTag(HtmlTag.MAIN)) {
@ -373,4 +393,88 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.deprecatedLabel);
return li;
}
/**
* Add module deprecation information to the documentation tree
*
* @param deprMdles list of deprecated modules
* @param headingKey the caption for the deprecated module table
* @param tableSummary the summary for the deprecated module table
* @param tableHeader table headers for the deprecated module table
* @param contentTree the content tree to which the deprecated module table will be added
*/
protected void addModuleDeprecatedAPI(SortedSet<Element> deprMdles, String headingKey,
String tableSummary, List<String> tableHeader, Content contentTree) {
if (deprMdles.size() > 0) {
Content caption = getTableCaption(configuration.getContent(headingKey));
Content table = (configuration.isOutputHtml5())
? HtmlTree.TABLE(HtmlStyle.deprecatedSummary, caption)
: HtmlTree.TABLE(HtmlStyle.deprecatedSummary, tableSummary, caption);
table.addContent(getSummaryTableHeader(tableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
boolean altColor = true;
for (Element e : deprMdles) {
ModuleElement mdle = (ModuleElement) e;
HtmlTree thRow = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst,
getModuleLink(mdle, new StringContent(mdle.getQualifiedName())));
HtmlTree tr = HtmlTree.TR(thRow);
HtmlTree tdDesc = new HtmlTree(HtmlTag.TD);
tdDesc.addStyle(HtmlStyle.colLast);
List<? extends DocTree> tags = utils.getDeprecatedTrees(mdle);
if (!tags.isEmpty()) {
addInlineDeprecatedComment(mdle, tags.get(0), tdDesc);
}
tr.addContent(tdDesc);
tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
altColor = !altColor;
tbody.addContent(tr);
}
table.addContent(tbody);
Content li = HtmlTree.LI(HtmlStyle.blockList, table);
Content ul = HtmlTree.UL(HtmlStyle.blockList, li);
contentTree.addContent(ul);
}
}
/**
* Add package deprecation information to the documentation tree
*
* @param deprPkgs list of deprecated packages
* @param headingKey the caption for the deprecated package table
* @param tableSummary the summary for the deprecated package table
* @param tableHeader table headers for the deprecated package table
* @param contentTree the content tree to which the deprecated package table will be added
*/
protected void addPackageDeprecatedAPI(SortedSet<Element> deprPkgs, String headingKey,
String tableSummary, List<String> tableHeader, Content contentTree) {
if (deprPkgs.size() > 0) {
Content caption = getTableCaption(configuration.getContent(headingKey));
Content table = (configuration.isOutputHtml5())
? HtmlTree.TABLE(HtmlStyle.deprecatedSummary, caption)
: HtmlTree.TABLE(HtmlStyle.deprecatedSummary, tableSummary, caption);
table.addContent(getSummaryTableHeader(tableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
boolean altColor = true;
for (Element e : deprPkgs) {
PackageElement pkg = (PackageElement) e;
HtmlTree thRow = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst,
getPackageLink(pkg, getPackageName(pkg)));
HtmlTree tr = HtmlTree.TR(thRow);
HtmlTree tdDesc = new HtmlTree(HtmlTag.TD);
tdDesc.addStyle(HtmlStyle.colLast);
List<? extends DocTree> tags = utils.getDeprecatedTrees(pkg);
if (!tags.isEmpty()) {
addInlineDeprecatedComment(pkg, tags.get(0), tdDesc);
}
tr.addContent(tdDesc);
tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
altColor = !altColor;
tbody.addContent(tr);
}
table.addContent(tbody);
Content li = HtmlTree.LI(HtmlStyle.blockList, table);
Content ul = HtmlTree.UL(HtmlStyle.blockList, li);
contentTree.addContent(ul);
}
}
}

View File

@ -1045,48 +1045,6 @@ public class HtmlDocletWriter extends HtmlDocWriter {
return new StringContent(packageName);
}
/**
* Add package deprecation information to the documentation tree
*
* @param deprPkgs list of deprecated packages
* @param headingKey the caption for the deprecated package table
* @param tableSummary the summary for the deprecated package table
* @param tableHeader table headers for the deprecated package table
* @param contentTree the content tree to which the deprecated package table will be added
*/
protected void addPackageDeprecatedAPI(SortedSet<Element> deprPkgs, String headingKey,
String tableSummary, List<String> tableHeader, Content contentTree) {
if (deprPkgs.size() > 0) {
Content caption = getTableCaption(configuration.getContent(headingKey));
Content table = (configuration.isOutputHtml5())
? HtmlTree.TABLE(HtmlStyle.deprecatedSummary, caption)
: HtmlTree.TABLE(HtmlStyle.deprecatedSummary, tableSummary, caption);
table.addContent(getSummaryTableHeader(tableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
boolean altColor = true;
for (Element e : deprPkgs) {
PackageElement pkg = (PackageElement) e;
HtmlTree thRow = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst,
getPackageLink(pkg, getPackageName(pkg)));
HtmlTree tr = HtmlTree.TR(thRow);
HtmlTree tdDesc = new HtmlTree(HtmlTag.TD);
tdDesc.addStyle(HtmlStyle.colLast);
List<? extends DocTree> tags = utils.getDeprecatedTrees(pkg);
if (!tags.isEmpty()) {
addInlineDeprecatedComment(pkg, tags.get(0), tdDesc);
}
tr.addContent(tdDesc);
tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
altColor = !altColor;
tbody.addContent(tr);
}
table.addContent(tbody);
Content li = HtmlTree.LI(HtmlStyle.blockList, table);
Content ul = HtmlTree.UL(HtmlStyle.blockList, li);
contentTree.addContent(ul);
}
}
/**
* Return the path to the class page for a typeElement.
*

View File

@ -114,6 +114,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
*
* @param heading the heading for the section
*/
@Override
public Content getModuleHeader(String heading) {
HtmlTree bodyTree = getBody(true, getWindowTitle(mdle.getQualifiedName().toString()));
HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
@ -126,6 +127,9 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
}
HtmlTree div = new HtmlTree(HtmlTag.DIV);
div.addStyle(HtmlStyle.header);
Content annotationContent = new HtmlTree(HtmlTag.P);
addAnnotationInfo(mdle, annotationContent);
div.addContent(annotationContent);
Content tHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
HtmlStyle.title, contents.moduleLabel);
tHeading.addContent(Contents.SPACE);
@ -143,6 +147,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
/**
* Get the content header.
*/
@Override
public Content getContentHeader() {
HtmlTree div = new HtmlTree(HtmlTag.DIV);
div.addStyle(HtmlStyle.contentContainer);
@ -152,6 +157,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
/**
* Get the summary section header.
*/
@Override
public Content getSummaryHeader() {
HtmlTree li = new HtmlTree(HtmlTag.LI);
li.addStyle(HtmlStyle.blockList);
@ -163,6 +169,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
*
* @param summaryContentTree the content tree to be added to the summary tree.
*/
@Override
public Content getSummaryTree(Content summaryContentTree) {
HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, summaryContentTree);
return ul;
@ -225,7 +232,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
* Add the list of directives for the module.
*
* @param dirs the list of module directives
* @params tbody the content tree to which the list is added
* @param tbody the content tree to which the list is added
*/
public void addList(List<ModuleElement.Directive> dirs, Content tbody) {
boolean altColor = true;
@ -238,6 +245,9 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
case EXPORTS:
addExportedPackagesList((ModuleElement.ExportsDirective) direct, tbody, altColor);
break;
case OPENS:
//XXX ignore for now
break;
case USES:
addUsesList((ModuleElement.UsesDirective) direct, tbody, altColor);
break;
@ -254,6 +264,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
/**
* {@inheritDoc}
*/
@Override
public void addModulesSummary(Content summaryContentTree) {
List<ModuleElement.Directive> dirs = directiveMap.get(DirectiveKind.REQUIRES);
if (dirs != null && !dirs.isEmpty()) {
@ -307,6 +318,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
/**
* {@inheritDoc}
*/
@Override
public void addPackagesSummary(Content summaryContentTree) {
List<ModuleElement.Directive> dirs = directiveMap.get(DirectiveKind.EXPORTS);
if (dirs != null && !dirs.isEmpty()) {
@ -376,6 +388,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
/**
* {@inheritDoc}
*/
@Override
public void addServicesSummary(Content summaryContentTree) {
List<ModuleElement.Directive> usesDirs = directiveMap.get(DirectiveKind.USES);
List<ModuleElement.Directive> providesDirs = directiveMap.get(DirectiveKind.PROVIDES);
@ -459,33 +472,60 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
* @param altColor true if altColor style should be used or false if rowColor style should be used
*/
public void addProvidesList(ModuleElement.ProvidesDirective direct, Content tbody, boolean altColor) {
TypeElement impl = direct.getImplementation();
TypeElement srv = direct.getService();
Content implLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, impl));
Content srvLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, srv));
HtmlTree thType = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, srvLinkContent);
thType.addContent(new HtmlTree(HtmlTag.BR));
thType.addContent("(");
HtmlTree implSpan = HtmlTree.SPAN(HtmlStyle.implementationLabel, contents.implementation);
thType.addContent(implSpan);
thType.addContent(Contents.SPACE);
thType.addContent(implLinkContent);
thType.addContent(")");
HtmlTree tdDesc = new HtmlTree(HtmlTag.TD);
tdDesc.addStyle(HtmlStyle.colLast);
addSummaryComment(srv, tdDesc);
HtmlTree tr = HtmlTree.TR(thType);
tr.addContent(tdDesc);
tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
tbody.addContent(tr);
List<? extends TypeElement> impls = direct.getImplementations();
for (TypeElement impl : impls) {
TypeElement srv = direct.getService();
Content implLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, impl));
Content srvLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, srv));
HtmlTree thType = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, srvLinkContent);
thType.addContent(new HtmlTree(HtmlTag.BR));
thType.addContent("(");
HtmlTree implSpan = HtmlTree.SPAN(HtmlStyle.implementationLabel, contents.implementation);
thType.addContent(implSpan);
thType.addContent(Contents.SPACE);
thType.addContent(implLinkContent);
thType.addContent(")");
HtmlTree tdDesc = new HtmlTree(HtmlTag.TD);
tdDesc.addStyle(HtmlStyle.colLast);
addSummaryComment(srv, tdDesc);
HtmlTree tr = HtmlTree.TR(thType);
tr.addContent(tdDesc);
tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
tbody.addContent(tr);
}
}
/**
* Add the module deprecation information to the documentation tree.
*
* @param div the content tree to which the deprecation information will be added
*/
public void addDeprecationInfo(Content div) {
List<? extends DocTree> deprs = utils.getBlockTags(mdle, DocTree.Kind.DEPRECATED);
if (utils.isDeprecated(mdle)) {
CommentHelper ch = utils.getCommentHelper(mdle);
HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
deprDiv.addStyle(HtmlStyle.deprecatedContent);
Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, contents.deprecatedPhrase);
deprDiv.addContent(deprPhrase);
if (!deprs.isEmpty()) {
List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
if (!commentTags.isEmpty()) {
addInlineDeprecatedComment(mdle, deprs.get(0), deprDiv);
}
}
div.addContent(deprDiv);
}
}
/**
* {@inheritDoc}
*/
@Override
public void addModuleDescription(Content moduleContentTree) {
if (!utils.getFullBody(mdle).isEmpty()) {
Content tree = configuration.allowTag(HtmlTag.SECTION) ? HtmlTree.SECTION() : moduleContentTree;
addDeprecationInfo(tree);
tree.addContent(HtmlConstants.START_OF_MODULE_DESCRIPTION);
tree.addContent(getMarkerAnchor(SectionName.MODULE_DESCRIPTION));
addInlineComment(mdle, tree);
@ -498,6 +538,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
/**
* {@inheritDoc}
*/
@Override
public void addModuleTags(Content moduleContentTree) {
Content tree = (configuration.allowTag(HtmlTag.SECTION))
? HtmlTree.SECTION()
@ -513,6 +554,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
*
* @param subDiv the content tree to which the summary detail links will be added
*/
@Override
protected void addSummaryDetailLinks(Content subDiv) {
Content div = HtmlTree.DIV(getNavSummaryLinks());
subDiv.addContent(div);
@ -560,6 +602,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
/**
* {@inheritDoc}
*/
@Override
public void addModuleContent(Content contentTree, Content moduleContentTree) {
if (configuration.allowTag(HtmlTag.MAIN)) {
mainTree.addContent(moduleContentTree);
@ -572,6 +615,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
/**
* {@inheritDoc}
*/
@Override
public void addModuleFooter(Content contentTree) {
Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
? HtmlTree.FOOTER()
@ -633,6 +677,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
*
* @return a content tree for the previous link
*/
@Override
public Content getNavLinkPrevious() {
Content li;
if (prevModule == null) {
@ -649,6 +694,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
*
* @return a content tree for the next link
*/
@Override
public Content getNavLinkNext() {
Content li;
if (nextModule == null) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2016, 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

View File

@ -71,6 +71,7 @@ doclet.see.class_or_package_not_found=Tag {0}: reference not found: {1}
doclet.see.class_or_package_not_accessible=Tag {0}: reference not accessible: {1}
doclet.tag.invalid_usage=invalid usage of tag {0}
doclet.Deprecated_API=Deprecated API
doclet.Deprecated_Modules=Deprecated Modules
doclet.Deprecated_Packages=Deprecated Packages
doclet.Deprecated_Classes=Deprecated Classes
doclet.Deprecated_Enums=Deprecated Enums
@ -83,6 +84,7 @@ doclet.Deprecated_Constructors=Deprecated Constructors
doclet.Deprecated_Methods=Deprecated Methods
doclet.Deprecated_Enum_Constants=Deprecated Enum Constants
doclet.Deprecated_Annotation_Type_Members=Deprecated Annotation Type Elements
doclet.deprecated_modules=deprecated modules
doclet.deprecated_packages=deprecated packages
doclet.deprecated_classes=deprecated classes
doclet.deprecated_enums=deprecated enums

View File

@ -99,7 +99,7 @@ doclet.Subclasses=\u76F4\u7CFB\u306E\u65E2\u77E5\u306E\u30B5\u30D6\u30AF\u30E9\u
doclet.Subinterfaces=\u65E2\u77E5\u306E\u30B5\u30D6\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306E\u30EA\u30B9\u30C8:
doclet.Implementing_Classes=\u65E2\u77E5\u306E\u5B9F\u88C5\u30AF\u30E9\u30B9\u306E\u30EA\u30B9\u30C8:
doclet.Functional_Interface=\u6A5F\u80FD\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9
doclet.Functional_Interface_Message=\u3053\u308C\u306F\u6A5F\u80FD\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306A\u306E\u3067\u3001\u30E9\u30E0\u30C0\u5F0F\u307E\u305F\u306F\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u306E\u5272\u5F53\u3066\u30BF\u30FC\u30B2\u30C3\u30C8\u3068\u3057\u3066\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002
doclet.Functional_Interface_Message=\u3053\u308C\u306F\u6A5F\u80FD\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306A\u306E\u3067\u3001\u30E9\u30E0\u30C0\u5F0F\u307E\u305F\u306F\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u306E\u5272\u5F53\u3066\u30BF\u30FC\u30B2\u30C3\u30C8\u3068\u3057\u3066\u4F7F\u7528\u3067\u304D\u307E\u3059\u3002
doclet.also=\u540C\u69D8\u306B
doclet.Frames=\u30D5\u30EC\u30FC\u30E0
doclet.No_Frames=\u30D5\u30EC\u30FC\u30E0\u306A\u3057

View File

@ -28,6 +28,7 @@ package jdk.javadoc.internal.doclets.toolkit.util;
import java.util.*;
import javax.lang.model.element.Element;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
@ -51,6 +52,7 @@ public class DeprecatedAPIListBuilder {
private final Configuration configuration;
private final Utils utils;
public static enum DeprElementKind {
MODULE,
PACKAGE,
INTERFACE,
CLASS,
@ -82,12 +84,19 @@ public class DeprecatedAPIListBuilder {
/**
* Build the sorted list of all the deprecated APIs in this run.
* Build separate lists for deprecated packages, classes, constructors,
* Build separate lists for deprecated modules, packages, classes, constructors,
* methods and fields.
*
* @param configuration the current configuration of the doclet.
*/
private void buildDeprecatedAPIInfo() {
SortedSet<ModuleElement> modules = configuration.modules;
SortedSet<Element> mset = deprecatedMap.get(DeprElementKind.MODULE);
for (Element me : modules) {
if (utils.isDeprecated(me)) {
mset.add(me);
}
}
SortedSet<PackageElement> packages = configuration.packages;
SortedSet<Element> pset = deprecatedMap.get(DeprElementKind.PACKAGE);
for (Element pe : packages) {
@ -95,7 +104,6 @@ public class DeprecatedAPIListBuilder {
pset.add(pe);
}
}
deprecatedMap.put(DeprElementKind.PACKAGE, pset);
for (Element e : configuration.docEnv.getIncludedTypeElements()) {
TypeElement te = (TypeElement)e;
SortedSet<Element> eset;

View File

@ -516,10 +516,10 @@ public class ElementsTable {
private Set<ModuleElement> getModuleRequires(ModuleElement mdle, boolean isPublic) {
Set<ModuleElement> result = new HashSet<>();
for (RequiresDirective rd : ElementFilter.requiresIn(mdle.getDirectives())) {
if (isPublic && rd.isPublic()) {
if (isPublic && rd.isTransitive()) {
result.add(rd.getDependency());
}
if (!isPublic && !rd.isPublic()) {
if (!isPublic && !rd.isTransitive()) {
result.add(rd.getDependency());
}
}

View File

@ -479,7 +479,7 @@ public enum ToolOption {
void setExpandRequires(ToolOption opt, String arg) throws OptionException {
switch (arg) {
case "public":
case "transitive":
jdtoolOpts.put(opt, AccessKind.PUBLIC);
break;
case "all":

View File

@ -81,8 +81,8 @@ main.opt.expand.requires.arg=\
main.opt.expand.requires.desc=\
Instructs the tool to expand the set of modules to be\n\
documented. By default, only the modules given explicitly on\n\
the command line will be documented. A value of "public" will\n\
additionally include all "requires public" dependencies of\n\
the command line will be documented. A value of "transitive" will\n\
additionally include all "requires transitive" dependencies of\n\
those modules. A value of "all" will include all dependencies\n\
of those modules.

View File

@ -28,8 +28,8 @@
* and its command line equivalent, <em>javadoc</em>.
*/
module jdk.javadoc {
requires public java.compiler;
requires public jdk.compiler;
requires transitive java.compiler;
requires transitive jdk.compiler;
requires java.xml;
exports com.sun.javadoc;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2016, 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
@ -42,20 +42,22 @@ public abstract class Attribute {
public static final String BootstrapMethods = "BootstrapMethods";
public static final String CharacterRangeTable = "CharacterRangeTable";
public static final String Code = "Code";
public static final String ConcealedPackages = "ConcealedPackages";
public static final String ConstantValue = "ConstantValue";
public static final String CompilationID = "CompilationID";
public static final String Deprecated = "Deprecated";
public static final String EnclosingMethod = "EnclosingMethod";
public static final String Exceptions = "Exceptions";
public static final String Hashes = "Hashes";
public static final String InnerClasses = "InnerClasses";
public static final String LineNumberTable = "LineNumberTable";
public static final String LocalVariableTable = "LocalVariableTable";
public static final String LocalVariableTypeTable = "LocalVariableTypeTable";
public static final String MainClass = "MainClass";
public static final String MethodParameters = "MethodParameters";
public static final String Module = "Module";
public static final String ModuleHashes = "ModuleHashes";
public static final String ModuleMainClass = "ModuleMainClass";
public static final String ModulePackages = "ModulePackages";
public static final String ModuleTarget = "ModuleTarget";
public static final String ModuleVersion = "ModuleVersion";
public static final String RuntimeVisibleAnnotations = "RuntimeVisibleAnnotations";
public static final String RuntimeInvisibleAnnotations = "RuntimeInvisibleAnnotations";
public static final String RuntimeVisibleParameterAnnotations = "RuntimeVisibleParameterAnnotations";
@ -69,8 +71,6 @@ public abstract class Attribute {
public static final String StackMap = "StackMap";
public static final String StackMapTable = "StackMapTable";
public static final String Synthetic = "Synthetic";
public static final String TargetPlatform = "TargetPlatform";
public static final String Version = "Version";
public static class Factory {
public Factory() {
@ -115,19 +115,21 @@ public abstract class Attribute {
standardAttributes.put(CharacterRangeTable, CharacterRangeTable_attribute.class);
standardAttributes.put(Code, Code_attribute.class);
standardAttributes.put(CompilationID, CompilationID_attribute.class);
standardAttributes.put(ConcealedPackages, ConcealedPackages_attribute.class);
standardAttributes.put(ConstantValue, ConstantValue_attribute.class);
standardAttributes.put(Deprecated, Deprecated_attribute.class);
standardAttributes.put(EnclosingMethod, EnclosingMethod_attribute.class);
standardAttributes.put(Exceptions, Exceptions_attribute.class);
standardAttributes.put(Hashes, Hashes_attribute.class);
standardAttributes.put(InnerClasses, InnerClasses_attribute.class);
standardAttributes.put(LineNumberTable, LineNumberTable_attribute.class);
standardAttributes.put(LocalVariableTable, LocalVariableTable_attribute.class);
standardAttributes.put(LocalVariableTypeTable, LocalVariableTypeTable_attribute.class);
standardAttributes.put(MainClass, MainClass_attribute.class);
standardAttributes.put(MethodParameters, MethodParameters_attribute.class);
standardAttributes.put(Module, Module_attribute.class);
standardAttributes.put(ModuleHashes, ModuleHashes_attribute.class);
standardAttributes.put(ModuleMainClass, ModuleMainClass_attribute.class);
standardAttributes.put(ModulePackages, ModulePackages_attribute.class);
standardAttributes.put(ModuleTarget, ModuleTarget_attribute.class);
standardAttributes.put(ModuleVersion, ModuleVersion_attribute.class);
standardAttributes.put(RuntimeInvisibleAnnotations, RuntimeInvisibleAnnotations_attribute.class);
standardAttributes.put(RuntimeInvisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations_attribute.class);
standardAttributes.put(RuntimeVisibleAnnotations, RuntimeVisibleAnnotations_attribute.class);
@ -141,8 +143,6 @@ public abstract class Attribute {
standardAttributes.put(StackMap, StackMap_attribute.class);
standardAttributes.put(StackMapTable, StackMapTable_attribute.class);
standardAttributes.put(Synthetic, Synthetic_attribute.class);
standardAttributes.put(TargetPlatform, TargetPlatform_attribute.class);
standardAttributes.put(Version, Version_attribute.class);
}
private Map<String,Class<? extends Attribute>> standardAttributes;
@ -178,19 +178,21 @@ public abstract class Attribute {
R visitCharacterRangeTable(CharacterRangeTable_attribute attr, P p);
R visitCode(Code_attribute attr, P p);
R visitCompilationID(CompilationID_attribute attr, P p);
R visitConcealedPackages(ConcealedPackages_attribute attr, P p);
R visitConstantValue(ConstantValue_attribute attr, P p);
R visitDeprecated(Deprecated_attribute attr, P p);
R visitEnclosingMethod(EnclosingMethod_attribute attr, P p);
R visitExceptions(Exceptions_attribute attr, P p);
R visitHashes(Hashes_attribute attr, P p);
R visitInnerClasses(InnerClasses_attribute attr, P p);
R visitLineNumberTable(LineNumberTable_attribute attr, P p);
R visitLocalVariableTable(LocalVariableTable_attribute attr, P p);
R visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, P p);
R visitMainClass(MainClass_attribute attr, P p);
R visitMethodParameters(MethodParameters_attribute attr, P p);
R visitModule(Module_attribute attr, P p);
R visitModuleHashes(ModuleHashes_attribute attr, P p);
R visitModuleMainClass(ModuleMainClass_attribute attr, P p);
R visitModulePackages(ModulePackages_attribute attr, P p);
R visitModuleTarget(ModuleTarget_attribute attr, P p);
R visitModuleVersion(ModuleVersion_attribute attr, P p);
R visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, P p);
R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p);
R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p);
@ -204,7 +206,5 @@ public abstract class Attribute {
R visitStackMap(StackMap_attribute attr, P p);
R visitStackMapTable(StackMapTable_attribute attr, P p);
R visitSynthetic(Synthetic_attribute attr, P p);
R visitTargetPlatform(TargetPlatform_attribute attr, P p);
R visitVersion(Version_attribute attr, P p);
}
}

View File

@ -55,6 +55,9 @@ public class ClassWriter {
/**
* Write a ClassFile data structure to a file.
* @param classFile the classfile object to be written
* @param f the file
* @throws IOException if an error occurs while writing the file
*/
public void write(ClassFile classFile, File f) throws IOException {
try (FileOutputStream f_out = new FileOutputStream(f)) {
@ -64,6 +67,9 @@ public class ClassWriter {
/**
* Write a ClassFile data structure to a stream.
* @param classFile the classfile object to be written
* @param s the stream
* @throws IOException if an error occurs while writing the file
*/
public void write(ClassFile classFile, OutputStream s) throws IOException {
this.classFile = classFile;
@ -419,7 +425,7 @@ public class ClassWriter {
}
@Override
public Void visitConcealedPackages(ConcealedPackages_attribute attr, ClassOutputStream out) {
public Void visitModulePackages(ModulePackages_attribute attr, ClassOutputStream out) {
out.writeShort(attr.packages_count);
for (int i: attr.packages_index)
out.writeShort(i);
@ -461,12 +467,15 @@ public class ClassWriter {
}
@Override
public Void visitHashes(Hashes_attribute attr, ClassOutputStream out) {
public Void visitModuleHashes(ModuleHashes_attribute attr, ClassOutputStream out) {
out.writeShort(attr.algorithm_index);
out.writeShort(attr.hashes_table.length);
for (Hashes_attribute.Entry e: attr.hashes_table) {
out.writeShort(e.requires_index);
out.writeShort(e.hash_index);
for (ModuleHashes_attribute.Entry e: attr.hashes_table) {
out.writeShort(e.module_name_index);
out.writeShort(e.hash.length);
for (byte b: e.hash) {
out.writeByte(b);
}
}
return null;
}
@ -534,33 +543,54 @@ public class ClassWriter {
}
@Override
public Void visitMainClass(MainClass_attribute attr, ClassOutputStream out) {
public Void visitModuleMainClass(ModuleMainClass_attribute attr, ClassOutputStream out) {
out.writeShort(attr.main_class_index);
return null;
}
@Override
public Void visitModule(Module_attribute attr, ClassOutputStream out) {
out.writeShort(attr.module_name);
out.writeShort(attr.module_flags);
out.writeShort(attr.requires.length);
for (Module_attribute.RequiresEntry e: attr.requires) {
out.writeShort(e.requires_index);
out.writeShort(e.requires_flags);
}
out.writeShort(attr.exports.length);
for (Module_attribute.ExportsEntry e: attr.exports) {
out.writeShort(e.exports_index);
out.writeShort(e.exports_flags);
out.writeShort(e.exports_to_index.length);
for (int index: e.exports_to_index)
out.writeShort(index);
}
out.writeShort(attr.opens.length);
for (Module_attribute.OpensEntry e: attr.opens) {
out.writeShort(e.opens_index);
out.writeShort(e.opens_flags);
out.writeShort(e.opens_to_index.length);
for (int index: e.opens_to_index)
out.writeShort(index);
}
out.writeShort(attr.uses_index.length);
for (int index: attr.uses_index)
for (int index: attr.uses_index) {
out.writeShort(index);
}
out.writeShort(attr.provides.length);
for (Module_attribute.ProvidesEntry e: attr.provides) {
out.writeShort(e.provides_index);
out.writeShort(e.with_index);
out.writeShort(e.with_count);
for (int with : e.with_index) {
out.writeShort(with);
}
}
return null;
}
@ -656,7 +686,7 @@ public class ClassWriter {
}
@Override
public Void visitTargetPlatform(TargetPlatform_attribute attr, ClassOutputStream out) {
public Void visitModuleTarget(ModuleTarget_attribute attr, ClassOutputStream out) {
out.writeShort(attr.os_name_index);
out.writeShort(attr.os_arch_index);
out.writeShort(attr.os_version_index);
@ -668,7 +698,7 @@ public class ClassWriter {
}
@Override
public Void visitVersion(Version_attribute attr, ClassOutputStream out) {
public Void visitModuleVersion(ModuleVersion_attribute attr, ClassOutputStream out) {
out.writeShort(attr.version_index);
return null;
}

View File

@ -35,8 +35,8 @@ import java.io.IOException;
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class Hashes_attribute extends Attribute {
Hashes_attribute(ClassReader cr, int name_index, int length) throws IOException {
public class ModuleHashes_attribute extends Attribute {
ModuleHashes_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
algorithm_index = cr.readUnsignedShort();
hashes_table_length = cr.readUnsignedShort();
@ -45,13 +45,13 @@ public class Hashes_attribute extends Attribute {
hashes_table[i] = new Entry(cr);
}
public Hashes_attribute(ConstantPool constant_pool, int algorithm_index, Entry[] hashes_table)
public ModuleHashes_attribute(ConstantPool constant_pool, int algorithm_index, Entry[] hashes_table)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.Hashes), algorithm_index, hashes_table);
this(constant_pool.getUTF8Index(Attribute.ModuleHashes), algorithm_index, hashes_table);
}
public Hashes_attribute(int name_index, int algorithm_index, Entry[] hashes_table) {
super(name_index, 4 + hashes_table.length * Entry.length());
public ModuleHashes_attribute(int name_index, int algorithm_index, Entry[] hashes_table) {
super(name_index, 2 + 2 + length(hashes_table));
this.algorithm_index = algorithm_index;
this.hashes_table_length = hashes_table.length;
this.hashes_table = hashes_table;
@ -59,7 +59,15 @@ public class Hashes_attribute extends Attribute {
@Override
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitHashes(this, data);
return visitor.visitModuleHashes(this, data);
}
private static int length(Entry[] hashes_table) {
int len = 0;
for (Entry e: hashes_table) {
len += e.length();
}
return len;
}
public final int algorithm_index;
@ -68,16 +76,20 @@ public class Hashes_attribute extends Attribute {
public static class Entry {
Entry(ClassReader cr) throws IOException {
requires_index = cr.readUnsignedShort();
hash_index = cr.readUnsignedShort();
module_name_index = cr.readUnsignedShort();
int hash_length = cr.readUnsignedShort();
hash = new byte[hash_length];
for (int i=0; i<hash_length; i++) {
hash[i] = (byte) cr.readUnsignedByte();
}
}
public static int length() {
return 4;
public int length() {
return 4 + hash.length;
}
public final int requires_index;
public final int hash_index;
public final int module_name_index;
public final byte[] hash;
}
}

View File

@ -35,18 +35,18 @@ import java.io.IOException;
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class MainClass_attribute extends Attribute {
MainClass_attribute(ClassReader cr, int name_index, int length) throws IOException {
public class ModuleMainClass_attribute extends Attribute {
ModuleMainClass_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
main_class_index = cr.readUnsignedShort();
}
public MainClass_attribute(ConstantPool constant_pool, int mainClass_index)
public ModuleMainClass_attribute(ConstantPool constant_pool, int mainClass_index)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.Version), mainClass_index);
this(constant_pool.getUTF8Index(Attribute.ModuleMainClass), mainClass_index);
}
public MainClass_attribute(int name_index, int mainClass_index) {
public ModuleMainClass_attribute(int name_index, int mainClass_index) {
super(name_index, 2);
this.main_class_index = mainClass_index;
}
@ -57,7 +57,7 @@ public class MainClass_attribute extends Attribute {
@Override
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitMainClass(this, data);
return visitor.visitModuleMainClass(this, data);
}
public final int main_class_index;

View File

@ -35,8 +35,8 @@ import java.io.IOException;
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class ConcealedPackages_attribute extends Attribute {
ConcealedPackages_attribute(ClassReader cr, int name_index, int length)
public class ModulePackages_attribute extends Attribute {
ModulePackages_attribute(ClassReader cr, int name_index, int length)
throws IOException {
super(name_index, length);
packages_count = cr.readUnsignedShort();
@ -45,15 +45,15 @@ public class ConcealedPackages_attribute extends Attribute {
packages_index[i] = cr.readUnsignedShort();
}
public ConcealedPackages_attribute(ConstantPool constant_pool,
int[] packages_index)
public ModulePackages_attribute(ConstantPool constant_pool,
int[] packages_index)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.ConcealedPackages),
this(constant_pool.getUTF8Index(Attribute.ModulePackages),
packages_index);
}
public ConcealedPackages_attribute(int name_index,
int[] packages_index) {
public ModulePackages_attribute(int name_index,
int[] packages_index) {
super(name_index, 2 + packages_index.length * 2);
this.packages_count = packages_index.length;
this.packages_index = packages_index;
@ -66,7 +66,7 @@ public class ConcealedPackages_attribute extends Attribute {
@Override
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitConcealedPackages(this, data);
return visitor.visitModulePackages(this, data);
}
public final int packages_count;

View File

@ -35,8 +35,8 @@ import java.io.IOException;
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class TargetPlatform_attribute extends Attribute {
TargetPlatform_attribute(ClassReader cr, int name_index, int length) throws IOException {
public class ModuleTarget_attribute extends Attribute {
ModuleTarget_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
os_name_index = cr.readUnsignedShort();
os_arch_index = cr.readUnsignedShort();
@ -45,7 +45,7 @@ public class TargetPlatform_attribute extends Attribute {
@Override
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitTargetPlatform(this, data);
return visitor.visitModuleTarget(this, data);
}
public final int os_name_index;

View File

@ -35,25 +35,25 @@ import java.io.IOException;
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class Version_attribute extends Attribute {
Version_attribute(ClassReader cr, int name_index, int length) throws IOException {
public class ModuleVersion_attribute extends Attribute {
ModuleVersion_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
version_index = cr.readUnsignedShort();
}
public Version_attribute(ConstantPool constant_pool, int version_index)
public ModuleVersion_attribute(ConstantPool constant_pool, int version_index)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.Version), version_index);
this(constant_pool.getUTF8Index(Attribute.ModuleVersion), version_index);
}
public Version_attribute(int name_index, int version_index) {
public ModuleVersion_attribute(int name_index, int version_index) {
super(name_index, 2);
this.version_index = version_index;
}
@Override
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitVersion(this, data);
return visitor.visitModuleVersion(this, data);
}
public final int version_index;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, 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
@ -36,24 +36,38 @@ import java.io.IOException;
* deletion without notice.</b>
*/
public class Module_attribute extends Attribute {
public static final int ACC_PUBLIC = 0x20;
public static final int ACC_SYNTHETIC = 0x1000;
public static final int ACC_MANDATED = 0x8000;
public static final int ACC_TRANSITIVE = 0x10;
public static final int ACC_STATIC_PHASE = 0x20;
public static final int ACC_OPEN = 0x20;
public static final int ACC_SYNTHETIC = 0x1000;
public static final int ACC_MANDATED = 0x8000;
Module_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
module_name = cr.readUnsignedShort();
module_flags = cr.readUnsignedShort();
requires_count = cr.readUnsignedShort();
requires = new RequiresEntry[requires_count];
for (int i = 0; i < requires_count; i++)
requires[i] = new RequiresEntry(cr);
exports_count = cr.readUnsignedShort();
exports = new ExportsEntry[exports_count];
for (int i = 0; i < exports_count; i++)
exports[i] = new ExportsEntry(cr);
opens_count = cr.readUnsignedShort();
opens = new OpensEntry[opens_count];
for (int i = 0; i < opens_count; i++)
opens[i] = new OpensEntry(cr);
uses_count = cr.readUnsignedShort();
uses_index = new int[uses_count];
for (int i = 0; i < uses_count; i++)
uses_index[i] = cr.readUnsignedShort();
provides_count = cr.readUnsignedShort();
provides = new ProvidesEntry[provides_count];
for (int i = 0; i < provides_count; i++)
@ -61,20 +75,26 @@ public class Module_attribute extends Attribute {
}
public Module_attribute(int name_index,
int module_name,
int module_flags,
RequiresEntry[] requires,
ExportsEntry[] exports,
OpensEntry[] opens,
int[] uses,
ProvidesEntry[] provides) {
super(name_index, 2);
this.module_name = module_name;
this.module_flags = module_flags;
requires_count = requires.length;
this.requires = requires;
exports_count = exports.length;
this.exports = exports;
opens_count = opens.length;
this.opens = opens;
uses_count = uses.length;
this.uses_index = uses;
provides_count = provides.length;
this.provides = provides;
}
public String getUses(int index, ConstantPool constant_pool) throws ConstantPoolException {
@ -87,10 +107,14 @@ public class Module_attribute extends Attribute {
return visitor.visitModule(this, data);
}
public final int module_name;
public final int module_flags;
public final int requires_count;
public final RequiresEntry[] requires;
public final int exports_count;
public final ExportsEntry[] exports;
public final int opens_count;
public final OpensEntry[] opens;
public final int uses_count;
public final int[] uses_index;
public final int provides_count;
@ -120,14 +144,16 @@ public class Module_attribute extends Attribute {
public static class ExportsEntry {
ExportsEntry(ClassReader cr) throws IOException {
exports_index = cr.readUnsignedShort();
exports_flags = cr.readUnsignedShort();
exports_to_count = cr.readUnsignedShort();
exports_to_index = new int[exports_to_count];
for (int i = 0; i < exports_to_count; i++)
exports_to_index[i] = cr.readUnsignedShort();
}
public ExportsEntry(int index, int[] to) {
public ExportsEntry(int index, int flags, int[] to) {
this.exports_index = index;
this.exports_flags = flags;
this.exports_to_count = to.length;
this.exports_to_index = to;
}
@ -137,24 +163,57 @@ public class Module_attribute extends Attribute {
}
public final int exports_index;
public final int exports_flags;
public final int exports_to_count;
public final int[] exports_to_index;
}
public static class OpensEntry {
OpensEntry(ClassReader cr) throws IOException {
opens_index = cr.readUnsignedShort();
opens_flags = cr.readUnsignedShort();
opens_to_count = cr.readUnsignedShort();
opens_to_index = new int[opens_to_count];
for (int i = 0; i < opens_to_count; i++)
opens_to_index[i] = cr.readUnsignedShort();
}
public OpensEntry(int index, int flags, int[] to) {
this.opens_index = index;
this.opens_flags = flags;
this.opens_to_count = to.length;
this.opens_to_index = to;
}
public int length() {
return 4 + 2 * opens_to_index.length;
}
public final int opens_index;
public final int opens_flags;
public final int opens_to_count;
public final int[] opens_to_index;
}
public static class ProvidesEntry {
ProvidesEntry(ClassReader cr) throws IOException {
provides_index = cr.readUnsignedShort();
with_index = cr.readUnsignedShort();
with_count = cr.readUnsignedShort();
with_index = new int[with_count];
for (int i = 0; i < with_count; i++)
with_index[i] = cr.readUnsignedShort();
}
public ProvidesEntry(int provides, int with) {
public ProvidesEntry(int provides, int[] with) {
this.provides_index = provides;
this.with_count = with.length;
this.with_index = with;
}
public static final int length = 4;
public final int provides_index;
public final int with_index;
public final int with_count;
public final int[] with_index;
}
}

View File

@ -34,7 +34,6 @@ import com.sun.tools.classfile.CharacterRangeTable_attribute;
import com.sun.tools.classfile.CharacterRangeTable_attribute.Entry;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.CompilationID_attribute;
import com.sun.tools.classfile.ConcealedPackages_attribute;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.ConstantValue_attribute;
@ -42,15 +41,18 @@ import com.sun.tools.classfile.DefaultAttribute;
import com.sun.tools.classfile.Deprecated_attribute;
import com.sun.tools.classfile.EnclosingMethod_attribute;
import com.sun.tools.classfile.Exceptions_attribute;
import com.sun.tools.classfile.Hashes_attribute;
import com.sun.tools.classfile.InnerClasses_attribute;
import com.sun.tools.classfile.InnerClasses_attribute.Info;
import com.sun.tools.classfile.LineNumberTable_attribute;
import com.sun.tools.classfile.LocalVariableTable_attribute;
import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
import com.sun.tools.classfile.MainClass_attribute;
import com.sun.tools.classfile.MethodParameters_attribute;
import com.sun.tools.classfile.Module_attribute;
import com.sun.tools.classfile.ModuleHashes_attribute;
import com.sun.tools.classfile.ModuleMainClass_attribute;
import com.sun.tools.classfile.ModulePackages_attribute;
import com.sun.tools.classfile.ModuleTarget_attribute;
import com.sun.tools.classfile.ModuleVersion_attribute;
import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;
import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;
import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute;
@ -64,8 +66,6 @@ import com.sun.tools.classfile.SourceID_attribute;
import com.sun.tools.classfile.StackMapTable_attribute;
import com.sun.tools.classfile.StackMap_attribute;
import com.sun.tools.classfile.Synthetic_attribute;
import com.sun.tools.classfile.TargetPlatform_attribute;
import com.sun.tools.classfile.Version_attribute;
import static com.sun.tools.classfile.AccessFlags.*;
@ -237,7 +237,7 @@ public class AttributeWriter extends BasicWriter
return null;
}
private String getJavaPackage(ConcealedPackages_attribute attr, int index) {
private String getJavaPackage(ModulePackages_attribute attr, int index) {
try {
return getJavaName(attr.getPackage(index, constant_pool));
} catch (ConstantPoolException e) {
@ -246,8 +246,8 @@ public class AttributeWriter extends BasicWriter
}
@Override
public Void visitConcealedPackages(ConcealedPackages_attribute attr, Void ignore) {
println("ConcealedPackages: ");
public Void visitModulePackages(ModulePackages_attribute attr, Void ignore) {
println("ModulePackages: ");
indent(+1);
for (int i = 0; i < attr.packages_count; i++) {
print("#" + attr.packages_index[i]);
@ -323,22 +323,24 @@ public class AttributeWriter extends BasicWriter
}
@Override
public Void visitHashes(Hashes_attribute attr, Void ignore) {
println("Hashes:");
public Void visitModuleHashes(ModuleHashes_attribute attr, Void ignore) {
println("ModuleHashes:");
indent(+1);
print("algorithm #" + attr.algorithm_index);
tab();
println("// " + getAlgorithm(attr));
for (Hashes_attribute.Entry e : attr.hashes_table) {
print("#" + e.requires_index + ", #" + e.hash_index);
for (ModuleHashes_attribute.Entry e : attr.hashes_table) {
print("#" + e.module_name_index);
tab();
println("// " + getRequires(e) + ": " + getHash(e));
println("// " + getModuleName(e));
println("hash_length: " + e.hash.length);
println("hash: [" + toHex(e.hash) + "]");
}
indent(-1);
return null;
}
private String getAlgorithm(Hashes_attribute attr) {
private String getAlgorithm(ModuleHashes_attribute attr) {
try {
return constant_pool.getUTF8Value(attr.algorithm_index);
} catch (ConstantPoolException e) {
@ -346,17 +348,9 @@ public class AttributeWriter extends BasicWriter
}
}
private String getRequires(Hashes_attribute.Entry entry) {
private String getModuleName(ModuleHashes_attribute.Entry entry) {
try {
return constant_pool.getUTF8Value(entry.requires_index);
} catch (ConstantPoolException e) {
return report(e);
}
}
private String getHash(Hashes_attribute.Entry entry) {
try {
return constant_pool.getUTF8Value(entry.hash_index);
return constant_pool.getUTF8Value(entry.module_name_index);
} catch (ConstantPoolException e) {
return report(e);
}
@ -456,15 +450,15 @@ public class AttributeWriter extends BasicWriter
}
@Override
public Void visitMainClass(MainClass_attribute attr, Void ignore) {
print("MainClass: #" + attr.main_class_index);
public Void visitModuleMainClass(ModuleMainClass_attribute attr, Void ignore) {
print("ModuleMainClass: #" + attr.main_class_index);
tab();
print("// " + getJavaClassName(attr));
println();
return null;
}
private String getJavaClassName(MainClass_attribute a) {
private String getJavaClassName(ModuleMainClass_attribute a) {
try {
return getJavaName(a.getMainClassName(constant_pool));
} catch (ConstantPoolException e) {
@ -477,7 +471,6 @@ public class AttributeWriter extends BasicWriter
@Override
public Void visitMethodParameters(MethodParameters_attribute attr,
Void ignore) {
final String header = String.format(format, "Name", "Flags");
println("MethodParameters:");
indent(+1);
@ -501,8 +494,25 @@ public class AttributeWriter extends BasicWriter
public Void visitModule(Module_attribute attr, Void ignore) {
println("Module:");
indent(+1);
print(attr.module_name);
tab();
println("// " + constantWriter.stringValue(attr.module_name));
print(String.format("%x", attr.module_flags));
tab();
print("// ");
if ((attr.module_flags & Module_attribute.ACC_OPEN) != 0)
print(" ACC_OPEN");
if ((attr.module_flags & Module_attribute.ACC_MANDATED) != 0)
print(" ACC_MANDATED");
if ((attr.module_flags & Module_attribute.ACC_SYNTHETIC) != 0)
print(" ACC_SYNTHETIC");
println();
printRequiresTable(attr);
printExportsTable(attr);
printOpensTable(attr);
printUsesTable(attr);
printProvidesTable(attr);
indent(-1);
@ -511,63 +521,107 @@ public class AttributeWriter extends BasicWriter
protected void printRequiresTable(Module_attribute attr) {
Module_attribute.RequiresEntry[] entries = attr.requires;
println(entries.length + "\t// " + "requires");
print(entries.length);
tab();
println("// " + "requires");
indent(+1);
for (Module_attribute.RequiresEntry e: entries) {
print("#" + e.requires_index + "," +
String.format("%x", e.requires_flags)+ "\t// requires");
if ((e.requires_flags & Module_attribute.ACC_PUBLIC) != 0)
print(" public");
print("#" + e.requires_index + "," + String.format("%x", e.requires_flags));
tab();
print("// " + constantWriter.stringValue(e.requires_index));
if ((e.requires_flags & Module_attribute.ACC_TRANSITIVE) != 0)
print(" ACC_TRANSITIVE");
if ((e.requires_flags & Module_attribute.ACC_STATIC_PHASE) != 0)
print(" ACC_STATIC_PHASE");
if ((e.requires_flags & Module_attribute.ACC_SYNTHETIC) != 0)
print(" synthetic");
print(" ACC_SYNTHETIC");
if ((e.requires_flags & Module_attribute.ACC_MANDATED) != 0)
print(" mandated");
println(" " + constantWriter.stringValue(e.requires_index));
print(" ACC_MANDATED");
println();
}
indent(-1);
}
protected void printExportsTable(Module_attribute attr) {
Module_attribute.ExportsEntry[] entries = attr.exports;
println(entries.length + "\t// " + "exports");
print(entries.length);
tab();
println("// exports");
indent(+1);
for (Module_attribute.ExportsEntry e: entries) {
print("#" + e.exports_index + "\t// exports");
print(" " + constantWriter.stringValue(e.exports_index));
if (e.exports_to_index.length == 0) {
println();
} else {
println(" to ... " + e.exports_to_index.length);
indent(+1);
for (int to: e.exports_to_index) {
println("#" + to + "\t// ... to " + constantWriter.stringValue(to));
}
indent(-1);
}
printExportOpenEntry(e.exports_index, e.exports_flags, e.exports_to_index);
}
indent(-1);
}
protected void printOpensTable(Module_attribute attr) {
Module_attribute.OpensEntry[] entries = attr.opens;
print(entries.length);
tab();
println("// opens");
indent(+1);
for (Module_attribute.OpensEntry e: entries) {
printExportOpenEntry(e.opens_index, e.opens_flags, e.opens_to_index);
}
indent(-1);
}
protected void printExportOpenEntry(int index, int flags, int[] to_index) {
print("#" + index + "," + String.format("%x", flags));
tab();
print("// ");
print(constantWriter.stringValue(index));
if ((flags & Module_attribute.ACC_MANDATED) != 0)
print(" ACC_MANDATED");
if ((flags & Module_attribute.ACC_SYNTHETIC) != 0)
print(" ACC_SYNTHETIC");
if (to_index.length == 0) {
println();
} else {
println(" to ... " + to_index.length);
indent(+1);
for (int to: to_index) {
print("#" + to);
tab();
println("// ... to " + constantWriter.stringValue(to));
}
indent(-1);
}
}
protected void printUsesTable(Module_attribute attr) {
int[] entries = attr.uses_index;
println(entries.length + "\t// " + "uses services");
print(entries.length);
tab();
println("// " + "uses");
indent(+1);
for (int e: entries) {
println("#" + e + "\t// uses " + constantWriter.stringValue(e));
print("#" + e);
tab();
println("// " + constantWriter.stringValue(e));
}
indent(-1);
}
protected void printProvidesTable(Module_attribute attr) {
Module_attribute.ProvidesEntry[] entries = attr.provides;
println(entries.length + "\t// " + "provides services");
print(entries.length);
tab();
println("// " + "provides");
indent(+1);
for (Module_attribute.ProvidesEntry e: entries) {
print("#" + e.provides_index + ",#" +
e.with_index + "\t// provides ");
print("#" + e.provides_index);
tab();
print("// ");
print(constantWriter.stringValue(e.provides_index));
print (" with ");
println(constantWriter.stringValue(e.with_index));
println(" with ... " + e.with_count);
indent(+1);
for (int with : e.with_index) {
print("#" + with);
tab();
println("// ... with " + constantWriter.stringValue(with));
}
indent(-1);
}
indent(-1);
}
@ -876,8 +930,8 @@ public class AttributeWriter extends BasicWriter
}
@Override
public Void visitTargetPlatform(TargetPlatform_attribute attr, Void ignore) {
println("TargetPlatform:");
public Void visitModuleTarget(ModuleTarget_attribute attr, Void ignore) {
println("ModuleTarget:");
indent(+1);
print("os_name: #" + attr.os_name_index);
if (attr.os_name_index != 0) {
@ -901,7 +955,7 @@ public class AttributeWriter extends BasicWriter
return null;
}
private String getOSName(TargetPlatform_attribute attr) {
private String getOSName(ModuleTarget_attribute attr) {
try {
return constant_pool.getUTF8Value(attr.os_name_index);
} catch (ConstantPoolException e) {
@ -909,7 +963,7 @@ public class AttributeWriter extends BasicWriter
}
}
private String getOSArch(TargetPlatform_attribute attr) {
private String getOSArch(ModuleTarget_attribute attr) {
try {
return constant_pool.getUTF8Value(attr.os_arch_index);
} catch (ConstantPoolException e) {
@ -917,7 +971,7 @@ public class AttributeWriter extends BasicWriter
}
}
private String getOSVersion(TargetPlatform_attribute attr) {
private String getOSVersion(ModuleTarget_attribute attr) {
try {
return constant_pool.getUTF8Value(attr.os_version_index);
} catch (ConstantPoolException e) {
@ -926,8 +980,8 @@ public class AttributeWriter extends BasicWriter
}
@Override
public Void visitVersion(Version_attribute attr, Void ignore) {
print("Version: #" + attr.version_index);
public Void visitModuleVersion(ModuleVersion_attribute attr, Void ignore) {
print("ModuleVersion: #" + attr.version_index);
indent(+1);
tab();
println("// " + getVersion(attr));
@ -935,7 +989,7 @@ public class AttributeWriter extends BasicWriter
return null;
}
private String getVersion(Version_attribute attr) {
private String getVersion(ModuleVersion_attribute attr) {
try {
return constant_pool.getUTF8Value(attr.version_index);
} catch (ConstantPoolException e) {
@ -962,6 +1016,14 @@ public class AttributeWriter extends BasicWriter
return StringUtils.toUpperCase(s);
}
static String toHex(byte[] ba) {
StringBuilder sb = new StringBuilder(ba.length);
for (byte b: ba) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
}
private final AnnotationWriter annotationWriter;
private final CodeWriter codeWriter;
private final ConstantWriter constantWriter;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2016, 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
@ -40,7 +40,7 @@ import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.ConstantValue_attribute;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.DescriptorException;
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
import com.sun.tools.classfile.Exceptions_attribute;
import com.sun.tools.classfile.Field;
import com.sun.tools.classfile.Method;
@ -157,21 +157,36 @@ public class ClassWriter extends BasicWriter {
indent(-1);
}
String name = getJavaName(classFile);
AccessFlags flags = cf.access_flags;
writeModifiers(flags.getClassModifiers());
if (classFile.access_flags.is(AccessFlags.ACC_MODULE) && name.endsWith(".module-info")) {
print("module ");
print(name.replace(".module-info", ""));
if (classFile.access_flags.is(AccessFlags.ACC_MODULE)) {
Attribute attr = classFile.attributes.get(Attribute.Module);
if (attr instanceof Module_attribute) {
Module_attribute modAttr = (Module_attribute) attr;
String name;
try {
name = getJavaName(constant_pool.getUTF8Value(modAttr.module_name));
} catch (ConstantPoolException e) {
name = report(e);
}
if ((modAttr.module_flags & Module_attribute.ACC_OPEN) != 0) {
print("open ");
}
print("module ");
print(name);
} else {
// fallback for malformed class files
print("class ");
print(getJavaName(classFile));
}
} else {
if (classFile.isClass())
print("class ");
else if (classFile.isInterface())
print("interface ");
print(name);
print(getJavaName(classFile));
}
Signature_attribute sigAttr = getSignature(cf.attributes);
@ -210,7 +225,23 @@ public class ClassWriter extends BasicWriter {
indent(+1);
println("minor version: " + cf.minor_version);
println("major version: " + cf.major_version);
writeList("flags: ", flags.getClassFlags(), "\n");
writeList(String.format("flags: (0x%04x) ", flags.flags), flags.getClassFlags(), "\n");
print("this_class: #" + cf.this_class);
if (cf.this_class != 0) {
tab();
print("// " + constantWriter.stringValue(cf.this_class));
}
println();
print("super_class: #" + cf.super_class);
if (cf.super_class != 0) {
tab();
print("// " + constantWriter.stringValue(cf.super_class));
}
println();
print("interfaces: " + cf.interfaces.length);
print(", fields: " + cf.fields.length);
print(", methods: " + cf.methods.length);
println(", attributes: " + cf.attributes.attrs.length);
indent(-1);
constantWriter.writeConstantPool();
} else {
@ -249,17 +280,20 @@ public class ClassWriter extends BasicWriter {
return builder.toString();
}
@Override
public StringBuilder visitSimpleType(SimpleType type, StringBuilder sb) {
sb.append(getJavaName(type.name));
return sb;
}
@Override
public StringBuilder visitArrayType(ArrayType type, StringBuilder sb) {
append(sb, type.elemType);
sb.append("[]");
return sb;
}
@Override
public StringBuilder visitMethodType(MethodType type, StringBuilder sb) {
appendIfNotEmpty(sb, "<", type.typeParamTypes, "> ");
append(sb, type.returnType);
@ -268,6 +302,7 @@ public class ClassWriter extends BasicWriter {
return sb;
}
@Override
public StringBuilder visitClassSigType(ClassSigType type, StringBuilder sb) {
appendIfNotEmpty(sb, "<", type.typeParamTypes, ">");
if (isInterface) {
@ -283,6 +318,7 @@ public class ClassWriter extends BasicWriter {
return sb;
}
@Override
public StringBuilder visitClassType(ClassType type, StringBuilder sb) {
if (type.outerType != null) {
append(sb, type.outerType);
@ -293,6 +329,7 @@ public class ClassWriter extends BasicWriter {
return sb;
}
@Override
public StringBuilder visitTypeParamType(TypeParamType type, StringBuilder sb) {
sb.append(type.name);
String sep = " extends ";
@ -312,6 +349,7 @@ public class ClassWriter extends BasicWriter {
return sb;
}
@Override
public StringBuilder visitWildcardType(WildcardType type, StringBuilder sb) {
switch (type.kind) {
case UNBOUNDED:
@ -402,7 +440,7 @@ public class ClassWriter extends BasicWriter {
println("descriptor: " + getValue(f.descriptor));
if (options.verbose)
writeList("flags: ", flags.getFieldFlags(), "\n");
writeList(String.format("flags: (0x%04x) ", flags.flags), flags.getFieldFlags(), "\n");
if (options.showAllAttrs) {
for (Attribute attr: f.attributes)
@ -459,16 +497,20 @@ public class ClassWriter extends BasicWriter {
if (methodType != null) {
print(new JavaTypePrinter(false).printTypeArgs(methodType.typeParamTypes));
}
if (getName(m).equals("<init>")) {
print(getJavaName(classFile));
print(getJavaParameterTypes(d, flags));
} else if (getName(m).equals("<clinit>")) {
print("{}");
} else {
print(getJavaReturnType(d));
print(" ");
print(getName(m));
print(getJavaParameterTypes(d, flags));
switch (getName(m)) {
case "<init>":
print(getJavaName(classFile));
print(getJavaParameterTypes(d, flags));
break;
case "<clinit>":
print("{}");
break;
default:
print(getJavaReturnType(d));
print(" ");
print(getName(m));
print(getJavaParameterTypes(d, flags));
break;
}
Attribute e_attr = m.attributes.get(Attribute.Exceptions);
@ -499,7 +541,7 @@ public class ClassWriter extends BasicWriter {
}
if (options.verbose) {
writeList("flags: ", flags.getMethodFlags(), "\n");
writeList(String.format("flags: (0x%04x) ", flags.flags), flags.getMethodFlags(), "\n");
}
Code_attribute code = null;
@ -555,15 +597,18 @@ public class ClassWriter extends BasicWriter {
Module_attribute m = (Module_attribute) attr;
for (Module_attribute.RequiresEntry entry: m.requires) {
print("requires");
if ((entry.requires_flags & Module_attribute.ACC_PUBLIC) != 0)
print(" public");
if ((entry.requires_flags & Module_attribute.ACC_STATIC_PHASE) != 0)
print(" static");
if ((entry.requires_flags & Module_attribute.ACC_TRANSITIVE) != 0)
print(" transitive");
print(" ");
print(getUTF8Value(entry.requires_index).replace('/', '.'));
println(";");
}
for (Module_attribute.ExportsEntry entry: m.exports) {
print("exports ");
print("exports");
print(" ");
print(getUTF8Value(entry.exports_index).replace('/', '.'));
boolean first = true;
for (int i: entry.exports_to_index) {
@ -587,6 +632,32 @@ public class ClassWriter extends BasicWriter {
indent(-1);
}
for (Module_attribute.OpensEntry entry: m.opens) {
print("opens");
print(" ");
print(getUTF8Value(entry.opens_index).replace('/', '.'));
boolean first = true;
for (int i: entry.opens_to_index) {
String mname;
try {
mname = classFile.constant_pool.getUTF8Value(i).replace('/', '.');
} catch (ConstantPoolException e) {
mname = report(e);
}
if (first) {
println(" to");
indent(+1);
first = false;
} else {
println(",");
}
print(mname);
}
println(";");
if (!first)
indent(-1);
}
for (int entry: m.uses_index) {
print("uses ");
print(getClassName(entry).replace('/', '.'));
@ -594,13 +665,22 @@ public class ClassWriter extends BasicWriter {
}
for (Module_attribute.ProvidesEntry entry: m.provides) {
print("provides ");
print("provides ");
print(getClassName(entry.provides_index).replace('/', '.'));
println(" with");
indent(+1);
print(getClassName(entry.with_index).replace('/', '.'));
boolean first = true;
for (int i: entry.with_index) {
if (first) {
println(" with");
indent(+1);
first = false;
} else {
println(",");
}
print(getClassName(i).replace('/', '.'));
}
println(";");
indent(-1);
if (!first)
indent(-1);
}
}
@ -679,7 +759,7 @@ public class ClassWriter extends BasicWriter {
return getJavaName(d.getFieldType(constant_pool));
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
} catch (InvalidDescriptor e) {
return report(e);
}
}
@ -689,7 +769,7 @@ public class ClassWriter extends BasicWriter {
return getJavaName(d.getReturnType(constant_pool));
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
} catch (InvalidDescriptor e) {
return report(e);
}
}
@ -699,7 +779,7 @@ public class ClassWriter extends BasicWriter {
return getJavaName(adjustVarargs(flags, d.getParameterTypes(constant_pool)));
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
} catch (InvalidDescriptor e) {
return report(e);
}
}
@ -766,12 +846,16 @@ public class ClassWriter extends BasicWriter {
ConstantPool.CONSTANT_Integer_info info =
(ConstantPool.CONSTANT_Integer_info) cpInfo;
String t = d.getValue(constant_pool);
if (t.equals("C")) { // character
return getConstantCharValue((char) info.value);
} else if (t.equals("Z")) { // boolean
return String.valueOf(info.value == 1);
} else { // other: assume integer
return String.valueOf(info.value);
switch (t) {
case "C":
// character
return getConstantCharValue((char) info.value);
case "Z":
// boolean
return String.valueOf(info.value == 1);
default:
// other: assume integer
return String.valueOf(info.value);
}
}
@ -823,10 +907,10 @@ public class ClassWriter extends BasicWriter {
}
}
private Options options;
private AttributeWriter attrWriter;
private CodeWriter codeWriter;
private ConstantWriter constantWriter;
private final Options options;
private final AttributeWriter attrWriter;
private final CodeWriter codeWriter;
private final ConstantWriter constantWriter;
private ClassFile classFile;
private URI uri;
private long lastModified;

View File

@ -136,7 +136,7 @@ public class TraverseProc extends AbstractProcessor {
Set<PackageElement> set = new HashSet<>();
for (ModuleElement m : mods) {
for (ModuleElement.Directive dir : m.getDirectives()) {
if (dir.getKind() == ModuleElement.DirectiveKind.EXPORTS) {
if (dir.getKind() == ModuleElement.DirectiveKind.EXPORTS) { //XXX
ModuleElement.ExportsDirective exp = (ModuleElement.ExportsDirective)dir;
if (exp.getTargetModules() == null) {
set.add(exp.getPackage());

View File

@ -25,6 +25,7 @@
package com.sun.tools.jdeps;
import com.sun.tools.classfile.AccessFlags;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Dependencies.ClassFileError;
@ -170,7 +171,9 @@ public class ClassFileReader implements Closeable {
protected Set<String> scan() {
try {
ClassFile cf = ClassFile.read(path);
return Collections.singleton(cf.getName());
String name = cf.access_flags.is(AccessFlags.ACC_MODULE)
? "module-info" : cf.getName();
return Collections.singleton(name);
} catch (ConstantPoolException|IOException e) {
throw new ClassFileError(e);
}

View File

@ -37,6 +37,7 @@ import com.sun.tools.classfile.Dependency.Location;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
@ -175,6 +176,9 @@ class DependencyFinder {
public Set<Location> call() throws Exception {
Set<Location> targets = new HashSet<>();
for (ClassFile cf : archive.reader().getClassFiles()) {
if (cf.access_flags.is(AccessFlags.ACC_MODULE))
continue;
String classFileName;
try {
classFileName = cf.getName();
@ -216,9 +220,13 @@ class DependencyFinder {
{
ClassFile cf = archive.reader().getClassFile(name);
if (cf == null) {
throw new IllegalArgumentException(archive.getName() + " does not contain " + name);
throw new IllegalArgumentException(archive.getName() +
" does not contain " + name);
}
if (cf.access_flags.is(AccessFlags.ACC_MODULE))
return Collections.emptySet();
Set<Location> targets = new HashSet<>();
String cn;
try {

View File

@ -29,11 +29,9 @@ import com.sun.tools.classfile.Dependency.Location;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedDeque;
@ -263,7 +261,7 @@ public class DepsAnalyzer {
public static enum Info {
REQUIRES,
REQUIRES_PUBLIC,
REQUIRES_TRANSITIVE,
EXPORTED_API,
MODULE_PRIVATE,
QUALIFIED_EXPORTED_API,
@ -288,7 +286,7 @@ public class DepsAnalyzer {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
if (info != Info.REQUIRES && info != Info.REQUIRES_PUBLIC)
if (info != Info.REQUIRES && info != Info.REQUIRES_TRANSITIVE)
sb.append(source).append("/");
sb.append(name);
@ -325,7 +323,7 @@ public class DepsAnalyzer {
* Returns a graph of module dependences.
*
* Each Node represents a module and each edge is a dependence.
* No analysis on "requires public".
* No analysis on "requires transitive".
*/
public Graph<Node> moduleGraph() {
Graph.Builder<Node> builder = new Graph.Builder<>();

View File

@ -388,10 +388,10 @@ public final class Graph<T> {
}
static void printEdges(PrintWriter out, Graph<String> graph,
String node, Set<String> requiresPublic) {
String node, Set<String> requiresTransitive) {
graph.adjacentNodes(node).forEach(dn -> {
String attr = dn.equals("java.base") ? REQUIRES_BASE
: (requiresPublic.contains(dn) ? REEXPORTS : REQUIRES);
: (requiresTransitive.contains(dn) ? REEXPORTS : REQUIRES);
out.format(" \"%s\" -> \"%s\" [%s];%n", node, dn, attr);
});
}

View File

@ -38,6 +38,8 @@ import java.io.InputStream;
import java.io.UncheckedIOException;
import java.lang.module.Configuration;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleDescriptor.Exports;
import java.lang.module.ModuleDescriptor.Opens;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReader;
import java.lang.module.ModuleReference;
@ -408,7 +410,7 @@ public class JdepsConfiguration implements AutoCloseable {
}
@Override
public void close() throws IOException {
public void close() {
}
};
}
@ -421,12 +423,18 @@ public class JdepsConfiguration implements AutoCloseable {
}
private ModuleDescriptor dropHashes(ModuleDescriptor md) {
ModuleDescriptor.Builder builder = new ModuleDescriptor.Builder(md.name());
ModuleDescriptor.Builder builder = ModuleDescriptor.module(md.name());
md.requires().forEach(builder::requires);
md.exports().forEach(builder::exports);
md.provides().values().stream().forEach(builder::provides);
md.opens().forEach(builder::opens);
md.provides().stream().forEach(builder::provides);
md.uses().stream().forEach(builder::uses);
builder.conceals(md.conceals());
Set<String> concealed = new HashSet<>(md.packages());
md.exports().stream().map(Exports::source).forEach(concealed::remove);
md.opens().stream().map(Opens::source).forEach(concealed::remove);
concealed.forEach(builder::contains);
return builder.build();
}

View File

@ -154,6 +154,7 @@ class JdepsTask {
ANALYZE_DEPS(""),
GENERATE_DOT_FILE("-dotoutput", "--dot-output"),
GENERATE_MODULE_INFO("--generate-module-info"),
GENERATE_OPEN_MODULE("--generate-open-module"),
LIST_DEPS("--list-deps"),
LIST_REDUCED_DEPS("--list-reduced-deps"),
CHECK_MODULES("--check");
@ -248,7 +249,15 @@ class JdepsTask {
if (task.command != null) {
throw new BadArgs("err.command.set", task.command, opt);
}
task.command = task.genModuleInfo(Paths.get(arg));
task.command = task.genModuleInfo(Paths.get(arg), false);
}
},
new Option(true, CommandOption.GENERATE_OPEN_MODULE) {
void process(JdepsTask task, String opt, String arg) throws BadArgs {
if (task.command != null) {
throw new BadArgs("err.command.set", task.command, opt);
}
task.command = task.genModuleInfo(Paths.get(arg), true);
}
},
new Option(false, CommandOption.LIST_DEPS) {
@ -596,11 +605,11 @@ class JdepsTask {
return new GenDotFile(dir);
}
private GenModuleInfo genModuleInfo(Path dir) throws BadArgs {
private GenModuleInfo genModuleInfo(Path dir, boolean openModule) throws BadArgs {
if (Files.exists(dir) && (!Files.isDirectory(dir) || !Files.isWritable(dir))) {
throw new BadArgs("err.invalid.path", dir.toString());
}
return new GenModuleInfo(dir);
return new GenModuleInfo(dir, openModule);
}
private ListModuleDeps listModuleDeps(boolean reduced) throws BadArgs {
@ -823,9 +832,11 @@ class JdepsTask {
class GenModuleInfo extends Command {
final Path dir;
GenModuleInfo(Path dir) {
final boolean openModule;
GenModuleInfo(Path dir, boolean openModule) {
super(CommandOption.GENERATE_MODULE_INFO);
this.dir = dir;
this.openModule = openModule;
}
@Override
@ -866,7 +877,7 @@ class JdepsTask {
}
ModuleInfoBuilder builder
= new ModuleInfoBuilder(config, inputArgs, dir);
= new ModuleInfoBuilder(config, inputArgs, dir, openModule);
boolean ok = builder.run();
if (!ok && !options.nowarning) {

View File

@ -26,6 +26,8 @@
package com.sun.tools.jdeps;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleDescriptor.Exports;
import java.lang.module.ModuleDescriptor.Opens;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
@ -240,18 +242,24 @@ class Module extends Archive {
private StrictModule(Module m, Map<String, Boolean> requires) {
super(m.name(), m.location, m.descriptor, m.exports, m.isSystem, m.reader());
ModuleDescriptor.Builder builder = new ModuleDescriptor.Builder(m.name());
ModuleDescriptor.Builder builder = ModuleDescriptor.module(m.name());
requires.keySet().forEach(mn -> {
if (requires.get(mn).equals(Boolean.TRUE)) {
builder.requires(ModuleDescriptor.Requires.Modifier.PUBLIC, mn);
builder.requires(Set.of(ModuleDescriptor.Requires.Modifier.TRANSITIVE), mn);
} else {
builder.requires(mn);
}
});
m.descriptor.exports().forEach(e -> builder.exports(e));
m.descriptor.opens().forEach(o -> builder.opens(o));
m.descriptor.uses().forEach(s -> builder.uses(s));
m.descriptor.provides().values().forEach(p -> builder.provides(p));
builder.conceals(m.descriptor.conceals());
m.descriptor.provides().forEach(p -> builder.provides(p));
Set<String> concealed = new HashSet<>(m.descriptor.packages());
m.descriptor.exports().stream().map(Exports::source).forEach(concealed::remove);
m.descriptor.opens().stream().map(Opens::source).forEach(concealed::remove);
concealed.forEach(builder::contains);
this.md = builder.build();
}

View File

@ -87,8 +87,8 @@ public class ModuleAnalyzer {
public boolean run() throws IOException {
try {
// compute "requires public" dependences
modules.values().forEach(ModuleDeps::computeRequiresPublic);
// compute "requires transitive" dependences
modules.values().forEach(ModuleDeps::computeRequiresTransitive);
modules.values().forEach(md -> {
// compute "requires" dependences
@ -104,7 +104,7 @@ public class ModuleAnalyzer {
class ModuleDeps {
final Module root;
Set<Module> requiresPublic;
Set<Module> requiresTransitive;
Set<Module> requires;
Map<String, Set<String>> unusedQualifiedExports;
@ -113,15 +113,15 @@ public class ModuleAnalyzer {
}
/**
* Compute 'requires public' dependences by analyzing API dependencies
* Compute 'requires transitive' dependences by analyzing API dependencies
*/
private void computeRequiresPublic() {
// record requires public
this.requiresPublic = computeRequires(true)
private void computeRequiresTransitive() {
// record requires transitive
this.requiresTransitive = computeRequires(true)
.filter(m -> !m.name().equals(JAVA_BASE))
.collect(toSet());
trace("requires public: %s%n", requiresPublic);
trace("requires transitive: %s%n", requiresTransitive);
}
private void computeRequires() {
@ -144,24 +144,24 @@ public class ModuleAnalyzer {
}
ModuleDescriptor descriptor() {
return descriptor(requiresPublic, requires);
return descriptor(requiresTransitive, requires);
}
private ModuleDescriptor descriptor(Set<Module> requiresPublic,
private ModuleDescriptor descriptor(Set<Module> requiresTransitive,
Set<Module> requires) {
ModuleDescriptor.Builder builder = new ModuleDescriptor.Builder(root.name());
ModuleDescriptor.Builder builder = ModuleDescriptor.module(root.name());
if (!root.name().equals(JAVA_BASE))
builder.requires(MANDATED, JAVA_BASE);
builder.requires(Set.of(MANDATED), JAVA_BASE);
requiresPublic.stream()
requiresTransitive.stream()
.filter(m -> !m.name().equals(JAVA_BASE))
.map(Module::name)
.forEach(mn -> builder.requires(PUBLIC, mn));
.forEach(mn -> builder.requires(Set.of(TRANSITIVE), mn));
requires.stream()
.filter(m -> !requiresPublic.contains(m))
.filter(m -> !requiresTransitive.contains(m))
.filter(m -> !m.name().equals(JAVA_BASE))
.map(Module::name)
.forEach(mn -> builder.requires(mn));
@ -172,10 +172,10 @@ public class ModuleAnalyzer {
private Graph<Module> buildReducedGraph() {
ModuleGraphBuilder rpBuilder = new ModuleGraphBuilder(configuration);
rpBuilder.addModule(root);
requiresPublic.stream()
requiresTransitive.stream()
.forEach(m -> rpBuilder.addEdge(root, m));
// requires public graph
// requires transitive graph
Graph<Module> rbg = rpBuilder.build().reduce();
ModuleGraphBuilder gb = new ModuleGraphBuilder(configuration);
@ -198,7 +198,7 @@ public class ModuleAnalyzer {
*/
ModuleDescriptor reduced() {
Graph<Module> g = buildReducedGraph();
return descriptor(requiresPublic, g.adjacentNodes(root));
return descriptor(requiresTransitive, g.adjacentNodes(root));
}
/**
@ -309,16 +309,16 @@ public class ModuleAnalyzer {
}
private boolean matches(ModuleDescriptor md, ModuleDescriptor other) {
// build requires public from ModuleDescriptor
Set<ModuleDescriptor.Requires> reqPublic = md.requires().stream()
.filter(req -> req.modifiers().contains(PUBLIC))
// build requires transitive from ModuleDescriptor
Set<ModuleDescriptor.Requires> reqTransitive = md.requires().stream()
.filter(req -> req.modifiers().contains(TRANSITIVE))
.collect(toSet());
Set<ModuleDescriptor.Requires> otherReqPublic = other.requires().stream()
.filter(req -> req.modifiers().contains(PUBLIC))
Set<ModuleDescriptor.Requires> otherReqTransitive = other.requires().stream()
.filter(req -> req.modifiers().contains(TRANSITIVE))
.collect(toSet());
if (!reqPublic.equals(otherReqPublic)) {
trace("mismatch requires public: %s%n", reqPublic);
if (!reqTransitive.equals(otherReqTransitive)) {
trace("mismatch requires transitive: %s%n", reqTransitive);
return false;
}
@ -365,12 +365,12 @@ public class ModuleAnalyzer {
.sorted(Comparator.comparing(ModuleDescriptor::name))
.forEach(md -> {
String mn = md.name();
Set<String> requiresPublic = md.requires().stream()
.filter(d -> d.modifiers().contains(PUBLIC))
Set<String> requiresTransitive = md.requires().stream()
.filter(d -> d.modifiers().contains(TRANSITIVE))
.map(d -> d.name())
.collect(toSet());
DotGraph.printEdges(out, graph, mn, requiresPublic);
DotGraph.printEdges(out, graph, mn, requiresTransitive);
});
out.println("}");
@ -380,20 +380,20 @@ public class ModuleAnalyzer {
/**
* Returns a Graph of the given Configuration after transitive reduction.
*
* Transitive reduction of requires public edge and requires edge have
* to be applied separately to prevent the requires public edges
* 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 public edges
// 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(PUBLIC))
.filter(d -> d.modifiers().contains(TRANSITIVE))
.map(d -> d.name())
.forEach(d -> rpgbuilder.addEdge(mn, d));
}

View File

@ -178,7 +178,7 @@ public class ModuleExportsAnalyzer extends DepsAnalyzer {
RootModule(String name) {
super(name);
ModuleDescriptor.Builder builder = new ModuleDescriptor.Builder(name);
ModuleDescriptor.Builder builder = ModuleDescriptor.module(name);
this.descriptor = builder.build();
}

View File

@ -98,7 +98,7 @@ public class ModuleGraphBuilder extends Graph.Builder<Module> {
});
});
// read requires public from ModuleDescriptor
// read requires transitive from ModuleDescriptor
Module source;
while ((source = deque.poll()) != null) {
if (visited.contains(source))
@ -107,7 +107,7 @@ public class ModuleGraphBuilder extends Graph.Builder<Module> {
visited.add(source);
builder.addNode(source);
Module from = source;
requiresPublic(from).forEach(m -> {
requiresTransitive(from).forEach(m -> {
deque.add(m);
builder.addEdge(from, m);
});
@ -116,13 +116,13 @@ public class ModuleGraphBuilder extends Graph.Builder<Module> {
}
/*
* Returns a stream of modules upon which the given module `requires public`
* Returns a stream of modules upon which the given module `requires transitive`
*/
public Stream<Module> requiresPublic(Module m) {
// find requires public
public Stream<Module> requiresTransitive(Module m) {
// find requires transitive
return m.descriptor()
.requires().stream()
.filter(req -> req.modifiers().contains(PUBLIC))
.filter(req -> req.modifiers().contains(TRANSITIVE))
.map(ModuleDescriptor.Requires::name)
.map(config::findModule)
.flatMap(Optional::stream);

View File

@ -47,13 +47,14 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.stream.Collectors.*;
public class ModuleInfoBuilder {
final JdepsConfiguration configuration;
final Path outputdir;
final boolean open;
final DependencyFinder dependencyFinder;
final Analyzer analyzer;
@ -63,9 +64,11 @@ public class ModuleInfoBuilder {
final Map<Module, Module> automaticToExplicitModule;
public ModuleInfoBuilder(JdepsConfiguration configuration,
List<String> args,
Path outputdir) {
Path outputdir,
boolean open) {
this.configuration = configuration;
this.outputdir = outputdir;
this.open = open;
this.dependencyFinder = new DependencyFinder(configuration, DEFAULT_FILTER);
this.analyzer = new Analyzer(configuration, Type.CLASS, DEFAULT_FILTER);
@ -73,13 +76,13 @@ public class ModuleInfoBuilder {
// add targets to modulepath if it has module-info.class
List<Path> paths = args.stream()
.map(fn -> Paths.get(fn))
.collect(Collectors.toList());
.collect(toList());
// automatic module to convert to explicit module
this.automaticToExplicitModule = ModuleFinder.of(paths.toArray(new Path[0]))
.findAll().stream()
.map(configuration::toModule)
.collect(Collectors.toMap(Function.identity(), Function.identity()));
.collect(toMap(Function.identity(), Function.identity()));
Optional<Module> om = automaticToExplicitModule.keySet().stream()
.filter(m -> !m.descriptor().isAutomatic())
@ -96,7 +99,7 @@ public class ModuleInfoBuilder {
public boolean run() throws IOException {
try {
// pass 1: find API dependencies
Map<Archive, Set<Archive>> requiresPublic = computeRequiresPublic();
Map<Archive, Set<Archive>> requiresTransitive = computeRequiresTransitive();
// pass 2: analyze all class dependences
dependencyFinder.parse(automaticModules().stream());
@ -105,13 +108,13 @@ public class ModuleInfoBuilder {
boolean missingDeps = false;
for (Module m : automaticModules()) {
Set<Archive> apiDeps = requiresPublic.containsKey(m)
? requiresPublic.get(m)
Set<Archive> apiDeps = requiresTransitive.containsKey(m)
? requiresTransitive.get(m)
: Collections.emptySet();
Path file = outputdir.resolve(m.name()).resolve("module-info.java");
// computes requires and requires public
// computes requires and requires transitive
Module explicitModule = toExplicitModule(m, apiDeps);
if (explicitModule != null) {
automaticToExplicitModule.put(m, explicitModule);
@ -136,7 +139,7 @@ public class ModuleInfoBuilder {
return m == NOT_FOUND || m == REMOVED_JDK_INTERNALS;
}
private Module toExplicitModule(Module module, Set<Archive> requiresPublic)
private Module toExplicitModule(Module module, Set<Archive> requiresTransitive)
throws IOException
{
// done analysis
@ -148,7 +151,7 @@ public class ModuleInfoBuilder {
}
Map<String, Boolean> requires = new HashMap<>();
requiresPublic.stream()
requiresTransitive.stream()
.map(Archive::getModule)
.forEach(m -> requires.put(m.name(), Boolean.TRUE));
@ -183,53 +186,60 @@ public class ModuleInfoBuilder {
});
}
void writeModuleInfo(Path file, ModuleDescriptor descriptor) {
void writeModuleInfo(Path file, ModuleDescriptor md) {
try {
Files.createDirectories(file.getParent());
try (PrintWriter pw = new PrintWriter(Files.newOutputStream(file))) {
printModuleInfo(pw, descriptor);
printModuleInfo(pw, md);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private void printModuleInfo(PrintWriter writer, ModuleDescriptor descriptor) {
writer.format("module %s {%n", descriptor.name());
private void printModuleInfo(PrintWriter writer, ModuleDescriptor md) {
writer.format("%smodule %s {%n", open ? "open " : "", md.name());
Map<String, Module> modules = configuration.getModules();
// first print the JDK modules
descriptor.requires().stream()
.filter(req -> !req.name().equals("java.base")) // implicit requires
.sorted(Comparator.comparing(Requires::name))
.forEach(req -> writer.format(" requires %s;%n", req));
md.requires().stream()
.filter(req -> !req.name().equals("java.base")) // implicit requires
.sorted(Comparator.comparing(Requires::name))
.forEach(req -> writer.format(" requires %s;%n", req));
descriptor.exports().stream()
.peek(exp -> {
if (exp.targets().size() > 0)
throw new InternalError(descriptor.name() + " qualified exports: " + exp);
})
.sorted(Comparator.comparing(Exports::source))
.forEach(exp -> writer.format(" exports %s;%n", exp.source()));
if (!open) {
md.exports().stream()
.peek(exp -> {
if (exp.targets().size() > 0)
throw new InternalError(md.name() + " qualified exports: " + exp);
})
.sorted(Comparator.comparing(Exports::source))
.forEach(exp -> writer.format(" exports %s;%n", exp.source()));
}
descriptor.provides().values().stream()
.sorted(Comparator.comparing(Provides::service))
.forEach(p -> p.providers().stream()
.sorted()
.forEach(impl -> writer.format(" provides %s with %s;%n", p.service(), impl)));
md.provides().stream()
.sorted(Comparator.comparing(Provides::service))
.map(p -> p.providers().stream()
.map(impl -> " " + impl.replace('$', '.'))
.collect(joining(",\n",
String.format(" provides %s with%n",
p.service().replace('$', '.')),
";")))
.forEach(writer::println);
writer.println("}");
}
private Set<Module> automaticModules() {
return automaticToExplicitModule.keySet();
}
/**
* Compute 'requires public' dependences by analyzing API dependencies
* Compute 'requires transitive' dependences by analyzing API dependencies
*/
private Map<Archive, Set<Archive>> computeRequiresPublic() throws IOException {
private Map<Archive, Set<Archive>> computeRequiresTransitive()
throws IOException
{
// parse the input modules
dependencyFinder.parseExportedAPIs(automaticModules().stream());

View File

@ -125,6 +125,13 @@ main.opt.generate-module-info=\
\ --generate-module-info <dir> Generate module-info.java under the specified\n\
\ directory. The specified JAR files will be\n\
\ analyzed. This option cannot be used with\n\
\ --dot-output or --class-path. Use \n\
\ --generate-open-module option for open modules.
main.opt.generate-open-module=\
\ --generate-open-module <dir> Generate module-info.java for the specified\n\
\ JAR files under the specified directory as\n\
\ open modules. This option cannot be used with\n\
\ --dot-output or --class-path.
main.opt.check=\

View File

@ -33,9 +33,7 @@ module jdk.jdeps {
exports com.sun.tools.classfile to
jdk.jlink;
provides java.util.spi.ToolProvider
with com.sun.tools.javap.Main.JavapToolProvider;
provides java.util.spi.ToolProvider
with com.sun.tools.jdeps.Main.JDepsToolProvider;
provides java.util.spi.ToolProvider with
com.sun.tools.javap.Main.JavapToolProvider,
com.sun.tools.jdeps.Main.JDepsToolProvider;
}

View File

@ -126,7 +126,7 @@ jshell.err.retained.mode.failure = \u4FDD\u6301\u3055\u308C\u305F\u30E2\u30FC\u3
jshell.console.see.more = <\u8A73\u7D30\u306F\u3001\u30BF\u30D6\u3092\u62BC\u3057\u3066\u304F\u3060\u3055\u3044>
jshell.console.do.nothing = \u4F55\u3082\u3057\u306A\u3044
jshell.console.choice = \u9078\u629E:
jshell.console.choice = \u9078\u629E:
jshell.console.create.variable = \u5909\u6570\u306E\u4F5C\u6210
jshell.console.resolvable = \n\u8B58\u5225\u5B50\u306F\u3053\u306E\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3067\u89E3\u6C7A\u3067\u304D\u307E\u3059\u3002
jshell.console.no.candidate = \n\u30A4\u30F3\u30DD\u30FC\u30C8\u3059\u308B\u5019\u88DC\u306E\u5B8C\u5168\u4FEE\u98FE\u3055\u308C\u305F\u540D\u524D\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002

View File

@ -29,7 +29,7 @@
* Read-Eval-Print Loops (REPLs).
*/
module jdk.jshell {
requires public java.compiler;
requires transitive java.compiler;
requires java.prefs;
requires jdk.compiler;
requires jdk.internal.le;

View File

@ -14,8 +14,8 @@ keys=intermittent randomness
# Group definitions
groups=TEST.groups
# Tests using jtreg 4.2 b03 features
requiredVersion=4.2 b03
# Tests using jtreg 4.2 b04 features
requiredVersion=4.2 b04
# Use new module options
useNewOptions=true

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8154119 8154262 8156077 8157987 8154261 8154817 8135291 8155995 8162363
* @bug 8154119 8154262 8156077 8157987 8154261 8154817 8135291 8155995 8162363 8168766
* @summary Test modules support in javadoc.
* @author bpatel
* @library ../lib
@ -181,6 +181,34 @@ public class TestModules extends JavadocTester {
checkModuleFilesAndLinks(true);
}
/**
* Test generated module pages for a deprecated module.
*/
@Test
void testModuleDeprecation() {
javadoc("-d", "out-moduledepr",
"-tag", "regular:a:Regular Tag:",
"-tag", "moduletag:s:Module Tag:",
"--module-source-path", testSrc,
"--module", "module1,module2,moduletags",
"testpkgmdl1", "testpkgmdl2", "testpkgmdltags");
checkExit(Exit.OK);
checkModuleDeprecation(true);
}
/**
* Test annotations on modules.
*/
@Test
void testModuleAnnotation() {
javadoc("-d", "out-moduleanno",
"--module-source-path", testSrc,
"--module", "module1,module2",
"testpkgmdl1", "testpkgmdl2");
checkExit(Exit.OK);
checkModuleAnnotation();
}
void checkDescription(boolean found) {
checkOutput("module1-summary.html", found,
"<!-- ============ MODULE DESCRIPTION =========== -->\n"
@ -218,6 +246,9 @@ public class TestModules extends JavadocTester {
void checkHtml5Description(boolean found) {
checkOutput("module1-summary.html", found,
"<section role=\"region\">\n"
+ "<div class=\"deprecatedContent\"><span class=\"deprecatedLabel\">Deprecated.</span>\n"
+ "<div class=\"block\"><span class=\"deprecationComment\">This module is deprecated.</span></div>\n"
+ "</div>\n"
+ "<!-- ============ MODULE DESCRIPTION =========== -->\n"
+ "<a id=\"module.description\">\n"
+ "<!-- -->\n"
@ -556,4 +587,37 @@ public class TestModules extends JavadocTester {
+ "<dd>&nbsp;</dd>\n"
+ "</dl>");
}
void checkModuleDeprecation(boolean found) {
checkOutput("module1-summary.html", found,
"<div class=\"deprecatedContent\"><span class=\"deprecatedLabel\">Deprecated.</span>\n"
+ "<div class=\"block\"><span class=\"deprecationComment\">This module is deprecated.</span></div>\n"
+ "</div>");
checkOutput("deprecated-list.html", found,
"<ul>\n"
+ "<li><a href=\"#module\">Deprecated Modules</a></li>\n"
+ "</ul>",
"<tr class=\"altColor\">\n"
+ "<th class=\"colFirst\" scope=\"row\"><a href=\"module1-summary.html\">module1</a></th>\n"
+ "<td class=\"colLast\">\n"
+ "<div class=\"block\"><span class=\"deprecationComment\">This module is deprecated.</span></div>\n"
+ "</td>\n"
+ "</tr>");
checkOutput("module2-summary.html", !found,
"<div class=\"deprecatedContent\"><span class=\"deprecatedLabel\">Deprecated.</span>\n"
+ "<div class=\"block\"><span class=\"deprecationComment\">This module is deprecated using just the javadoc tag.</span></div>");
checkOutput("moduletags-summary.html", found,
"<p>@Deprecated\n"
+ "</p>",
"<div class=\"deprecatedContent\"><span class=\"deprecatedLabel\">Deprecated.</span></div>");
}
void checkModuleAnnotation() {
checkOutput("module2-summary.html", true,
"<p><a href=\"testpkgmdl2/AnnotationType.html\" title=\"annotation in testpkgmdl2\">@AnnotationType</a>(<a href=\"testpkgmdl2/AnnotationType.html#optional--\">optional</a>=\"Module Annotation\",\n"
+ " <a href=\"testpkgmdl2/AnnotationType.html#required--\">required</a>=2016)\n"
+ "</p>");
checkOutput("module2-summary.html", false,
"@AnnotationTypeUndocumented");
}
}

View File

@ -25,7 +25,10 @@
/**
* This is a test description for the module1 module. Search phrase {@index "search phrase" with description}.
*
* @deprecated This module is deprecated.
*/
@Deprecated
module module1 {
requires module2;

View File

@ -25,7 +25,11 @@
/**
* This is a test description for the module2 module. Search word {@index search_word} with no description.
*
* @deprecated This module is deprecated using just the javadoc tag.
*/
@testpkgmdl2.AnnotationType(optional="Module Annotation", required=2016)
@testpkgmdl2.AnnotationTypeUndocumented(optional="Module Annotation", required=2016)
module module2 {
exports testpkgmdl2;

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2016, 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 testpkgmdl2;
import java.lang.annotation.*;
/**
* This is a test annotation type.
*/
@Documented public @interface AnnotationType {
/**
* The copyright holder.
*
* @return a string.
*/
String optional() default "unknown";
/**
* The year of the copyright.
*
* @return an int.
*/
int required();
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2016, 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 testpkgmdl2;
import java.lang.annotation.*;
/**
* This is a test annotation type this is not documented because it
* is missing the @Documented tag.
*/
public @interface AnnotationTypeUndocumented {
/**
* The copyright holder.
*
* @return a string.
*/
String optional() default "unknown";
/**
* The year of the copyright.
*
* @return an int.
*/
int required();
}

View File

@ -37,6 +37,7 @@
* @moduletag Just a simple module tag.
* @version 1.0
*/
@Deprecated
module moduletags {
requires module2;

View File

@ -393,14 +393,14 @@ public class Modules extends ModuleTestBase {
* Module M : test module, with variable requires
*
* Module N :
* requires public O ---> Module O:
* requires J ----> Module J:
* exports openO exports openJ
* requires transitive O ---> Module O:
* requires J ----> Module J:
* exports openO exports openJ
*
*
* Module L :
* requires public P ---> Module P:
* exports openP
* requires transitive P ---> Module P:
* exports openP
*
*
*/
@ -431,14 +431,14 @@ public class Modules extends ModuleTestBase {
}
@Test
public void testExpandRequiresPublic(Path base) throws Exception {
public void testExpandRequiresTransitive(Path base) throws Exception {
Path src = base.resolve("src");
createAuxiliaryModules(src);
new ModuleBuilder(tb, "M")
.comment("The M module.")
.requiresPublic("N", src)
.requiresTransitive("N", src)
.requires("L", src)
.exports("p")
.classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
@ -446,7 +446,7 @@ public class Modules extends ModuleTestBase {
execTask("--module-source-path", src.toString(),
"--module", "M",
"--expand-requires", "public");
"--expand-requires", "transitive");
checkModulesSpecified("M", "N", "O");
checkModulesIncluded("M", "N", "O");
@ -462,7 +462,7 @@ public class Modules extends ModuleTestBase {
new ModuleBuilder(tb, "M")
.comment("The M module.")
.requiresPublic("N", src)
.requiresTransitive("N", src)
.requires("L", src)
.requires("O", src)
.exports("p")
@ -490,7 +490,7 @@ public class Modules extends ModuleTestBase {
new ModuleBuilder(tb, "M")
.comment("The M module.")
.requiresPublic("N", src)
.requiresTransitive("N", src)
.requires("L", src)
.requires("O", src)
.exports("p")
@ -512,7 +512,7 @@ public class Modules extends ModuleTestBase {
new ModuleBuilder(tb, "M")
.comment("The M module.")
.requiresPublic("N", src)
.requiresTransitive("N", src)
.requires("L", src)
.requires("O", src)
.exports("p")
@ -538,7 +538,7 @@ public class Modules extends ModuleTestBase {
new ModuleBuilder(tb, "L")
.comment("The L module.")
.exports("openL")
.requiresPublic("P")
. requiresTransitive("P")
.classes("package openL; /** Class L open */ public class L { }")
.classes("package closedL; /** Class L closed */ public class L { }")
.write(src);
@ -546,7 +546,7 @@ public class Modules extends ModuleTestBase {
new ModuleBuilder(tb, "N")
.comment("The N module.")
.exports("openN")
.requiresPublic("O")
.requiresTransitive("O")
.classes("package openN; /** Class N open */ public class N { }")
.classes("package closedN; /** Class N closed */ public class N { }")
.write(src);

View File

@ -29,6 +29,7 @@
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.javap
* jdk.jshell/jdk.jshell:open
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask
* @build KullaTesting TestingInputStream Compiler
* @run testng CompletionSuggestionTest

View File

@ -28,6 +28,7 @@
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jshell/jdk.jshell:open
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask
* @build KullaTesting TestingInputStream Compiler
* @run testng ComputeFQNsTest

View File

@ -26,7 +26,7 @@
* @bug 8166744
* @summary Test Completion
* @modules jdk.internal.le/jdk.internal.jline.extra
* jdk.jshell/jdk.internal.jshell.tool
* jdk.jshell/jdk.internal.jshell.tool:+open
* @build HistoryTest
* @run testng HistoryTest
*/

View File

@ -28,7 +28,7 @@
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jshell
* jdk.jshell/jdk.jshell:open
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask
* @build KullaTesting TestingInputStream Compiler
* @run testng JavadocTest

View File

@ -25,7 +25,7 @@
* @test 8167461
* @summary Verify PipeInputStream works.
* @modules jdk.compiler/com.sun.tools.javac.util
* jdk.jshell
* jdk.jshell/jdk.jshell.execution:open
* @run testng PipeInputStreamTest
*/

View File

@ -1188,7 +1188,7 @@ public class ClassfileInspector {
}
@Override
public Void visitConcealedPackages(ConcealedPackages_attribute attr, T p) {
public Void visitModulePackages(ModulePackages_attribute attr, T p) {
return null;
}
@ -1238,7 +1238,7 @@ public class ClassfileInspector {
}
@Override
public Void visitHashes(Hashes_attribute attr, T p) {
public Void visitModuleHashes(ModuleHashes_attribute attr, T p) {
return null;
}
@ -1263,7 +1263,7 @@ public class ClassfileInspector {
}
@Override
public Void visitMainClass(MainClass_attribute attr, T p) {
public Void visitModuleMainClass(ModuleMainClass_attribute attr, T p) {
return null;
}
@ -1343,12 +1343,12 @@ public class ClassfileInspector {
}
@Override
public Void visitTargetPlatform(TargetPlatform_attribute attr, T p) {
public Void visitModuleTarget(ModuleTarget_attribute attr, T p) {
return null;
}
@Override
public Void visitVersion(Version_attribute attr, T p) {
public Void visitModuleVersion(ModuleVersion_attribute attr, T p) {
return null;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2016, 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
@ -28,7 +28,7 @@
* @modules jdk.compiler/com.sun.tools.javac.file
* jdk.compiler/com.sun.tools.javac.parser
* jdk.compiler/com.sun.tools.javac.tree
* jdk.compiler/com.sun.tools.javac.util
* jdk.compiler/com.sun.tools.javac.util:+open
*/
import java.lang.reflect.Field;
import java.io.InputStream;

View File

@ -27,7 +27,7 @@
* @summary REGRESSION: javac crashes if -d or -s argument is a file
* @author Peter von der Ah\u00e9
* @modules java.compiler
* jdk.compiler/com.sun.tools.javac.util
* jdk.compiler/com.sun.tools.javac.util:open
*/
import java.lang.reflect.Field;

View File

@ -26,7 +26,7 @@
* @bug 8006582
* @summary javac should generate method parameters correctly.
* @modules jdk.jdeps/com.sun.tools.classfile
* @build MethodParametersTester
* @build MethodParametersTester ClassFileVisitor ReflectionVisitor
* @compile -parameters AnnotationTest.java
* @run main MethodParametersTester AnnotationTest AnnotationTest.out
*/

Some files were not shown because too many files have changed in this diff Show More