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:
parent
51f50b64e5
commit
22e233b2e9
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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),
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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() + ")");
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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); }
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -51,4 +51,5 @@ public class ModuleHelper {
|
||||
from.addExports(pack, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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":
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
@ -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;
|
@ -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;
|
@ -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;
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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<>();
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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=\
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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> </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");
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -37,6 +37,7 @@
|
||||
* @moduletag Just a simple module tag.
|
||||
* @version 1.0
|
||||
*/
|
||||
@Deprecated
|
||||
module moduletags {
|
||||
requires module2;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user