下面列出了怎么用javax.lang.model.element.ModuleElement的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public String toString(List<? extends DocTree> tags, Element element) {
if (!enableModuleGraph) {
return "";
}
String moduleName = ((ModuleElement) element).getQualifiedName().toString();
String imageFile = moduleName + "-graph.png";
int thumbnailHeight = -1;
String hoverImage = "";
if (!moduleName.equals("java.base")) {
thumbnailHeight = 100; // also appears in the stylesheet
hoverImage = "<span>"
+ getImage(moduleName, imageFile, -1, true)
+ "</span>";
}
return "<dt>"
+ "<span class=\"simpleTagLabel\">Module Graph:</span>\n"
+ "</dt>"
+ "<dd>"
+ "<a class=moduleGraph href=\"" + imageFile + "\">"
+ getImage(moduleName, imageFile, thumbnailHeight, false)
+ hoverImage
+ "</a>"
+ "</dd>";
}
/**
* Add the list of modules.
*
* @param mdleMap map of modules and modifiers
* @param tbody the content tree to which the list will be added
*/
public void addModulesList(Map<ModuleElement, Content> mdleMap, Content tbody) {
boolean altColor = true;
for (ModuleElement m : mdleMap.keySet()) {
Content tdModifiers = HtmlTree.TD(HtmlStyle.colFirst, mdleMap.get(m));
Content moduleLinkContent = getModuleLink(m, new StringContent(m.getQualifiedName()));
Content thModule = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colSecond, moduleLinkContent);
HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
tdSummary.addStyle(HtmlStyle.colLast);
addSummaryComment(m, tdSummary);
HtmlTree tr = HtmlTree.TR(tdModifiers);
tr.addContent(thModule);
tr.addContent(tdSummary);
tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
tbody.addContent(tr);
altColor = !altColor;
}
}
public Element resolve(ASTService ast, Elements elements, String what, Element original, ModuleElement modle) {
Element result = original;
if (classes.containsKey(what)) {
result = createElement(ast, elements, what, null, modle);
}
if (result == null) {
result = modle != null ? elements.getTypeElement(modle, what) : elements.getTypeElement(what);
}
if (result == null) {
result = modle != null ? elements.getPackageElement(modle, what) : elements.getPackageElement(what);
}
result = createElement(ast, elements, what, result, modle);
return result;
}
public Collection<? extends Element> getAllVisibleThrough(ASTService ast, Elements elements, String what, ClassTree tree, ModuleElement modle) {
Collection<Element> result = new ArrayList<Element>();
Element current = what != null ? resolve(ast, elements, what, modle) : null;
if (current == null) {
//can happen if:
//what == null: anonymous class
//TODO: what != null: apparently happens for JDK (where the same class occurs twice on one source path)
//might be possible to use ASTService.getElementImpl(tree) to thet the correct element
//use only supertypes:
//XXX: will probably not work correctly for newly created NCT (as the ClassTree does not have the correct extends/implements:
for (String sup : superFQNs(tree)) {
Element c = resolve(ast, elements, sup, modle);
if (c != null) {//may legitimely be null, e.g. if the super type is not resolvable at all.
result.add(c);
}
}
} else {
result.addAll(getAllMembers(ast, elements, current));
}
return result;
}
@Test
public void testTreePathForModuleDecl(Path base) throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) {
Path src = base.resolve("src");
tb.writeJavaFiles(src, "/** Test module */ module m1x {}");
Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(findJavaFiles(src));
JavacTask task = (JavacTask) compiler.getTask(null, fm, null, null, null, files);
task.analyze();
JavacTrees trees = JavacTrees.instance(task);
ModuleElement mdle = (ModuleElement) task.getElements().getModuleElement("m1x");
TreePath path = trees.getPath(mdle);
assertNotNull("path", path);
ModuleElement mdle1 = (ModuleElement) trees.getElement(path);
assertNotNull("mdle1", mdle1);
DocCommentTree docCommentTree = trees.getDocCommentTree(mdle);
assertNotNull("docCommentTree", docCommentTree);
}
}
public boolean isSpecified(Element e) {
if (specifiedVisitor == null) {
specifiedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
@Override
public Boolean visitModule(ModuleElement e, Void p) {
return configuration.getSpecifiedModuleElements().contains(e);
}
@Override
public Boolean visitPackage(PackageElement e, Void p) {
return configuration.getSpecifiedPackageElements().contains(e);
}
@Override
public Boolean visitType(TypeElement e, Void p) {
return configuration.getSpecifiedTypeElements().contains(e);
}
@Override
protected Boolean defaultAction(Element e, Void p) {
return false;
}
};
}
return specifiedVisitor.visit(e);
}
public UsagesVisitor (
@NonNull final JavacTaskImpl jt,
@NonNull final CompilationUnitTree cu,
@NonNull final JavaFileManager manager,
@NonNull final javax.tools.JavaFileObject sibling,
@NullAllowed final Set<? super ElementHandle<TypeElement>> newTypes,
@NullAllowed final Set<? super ElementHandle<ModuleElement>> newModules,
final JavaCustomIndexer.CompileTuple tuple) throws MalformedURLException, IllegalArgumentException {
this(
jt,
cu,
inferBinaryName(manager, sibling),
tuple.virtual ? tuple.indexable.getURL() : sibling.toUri().toURL(),
true,
tuple.virtual,
newTypes,
newModules,
null);
}
/**
* Generate a module type summary page for the left-hand bottom frame.
*
* @param configuration the current configuration of the doclet.
* @param moduleElement The package for which "module_name-type-frame.html" is to be generated.
* @throws DocFileIOException if there is a problem generating the module summary file
*/
public static void generate(ConfigurationImpl configuration, ModuleElement moduleElement)
throws DocFileIOException {
ModuleFrameWriter mdlgen = new ModuleFrameWriter(configuration, moduleElement);
String mdlName = moduleElement.getQualifiedName().toString();
Content mdlLabel = new StringContent(mdlName);
HtmlTree body = mdlgen.getBody(false, mdlgen.getWindowTitle(mdlName));
HtmlTree htmlTree = (configuration.allowTag(HtmlTag.MAIN))
? HtmlTree.MAIN()
: body;
Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, HtmlStyle.bar,
mdlgen.getHyperLink(DocPaths.moduleSummary(moduleElement), mdlLabel, "", "classFrame"));
htmlTree.addContent(heading);
HtmlTree div = new HtmlTree(HtmlTag.DIV);
div.addStyle(HtmlStyle.indexContainer);
mdlgen.addClassListing(div);
htmlTree.addContent(div);
if (configuration.allowTag(HtmlTag.MAIN)) {
body.addContent(htmlTree);
}
mdlgen.printHtmlDocument(
configuration.metakeywords.getMetaKeywordsForModule(moduleElement), false, body);
}
public void analyze(
@NonNull final Iterable<? extends CompilationUnitTree> trees,
@NonNull final JavacTaskImpl jt,
@NonNull final CompileTuple active,
@NonNull final Set<? super ElementHandle<TypeElement>> newTypes,
@NonNull final Set<? super ElementHandle<ModuleElement>> newModules,
@NonNull /*@Out*/ final boolean[] mainMethod) throws IOException {
final SourceAnalyzerFactory.StorableAnalyzer analyzer = getSourceAnalyzer();
assert analyzer != null;
analyzer.analyse(trees, jt, active, newTypes, newModules, mainMethod);
final Lookup pluginServices = getPluginServices(jt);
for (CompilationUnitTree cu : trees) {
for (JavaIndexerPlugin plugin : getPlugins()) {
plugin.process(cu, active.indexable, pluginServices);
}
}
}
Set<Element> getAllSelectedElements(DocletEnvironment docenv) {
Set<Element> result = new TreeSet<Element>((Element e1, Element e2) -> {
// some grouping by kind preferred
int rc = e1.getKind().compareTo(e2.getKind());
if (rc != 0) return rc;
rc = e1.toString().compareTo(e2.toString());
if (rc != 0) return rc;
return Integer.compare(e1.hashCode(), e2.hashCode());
});
Set<? extends Element> elements = docenv.getIncludedElements();
for (ModuleElement me : ElementFilter.modulesIn(elements)) {
addEnclosedElements(docenv, result, me);
}
for (PackageElement pe : ElementFilter.packagesIn(elements)) {
ModuleElement mdle = docenv.getElementUtils().getModuleOf(pe);
if (mdle != null)
addEnclosedElements(docenv, result, mdle);
addEnclosedElements(docenv, result, pe);
}
for (TypeElement te : ElementFilter.typesIn(elements)) {
addEnclosedElements(docenv, result, te);
}
return result;
}
/**
* Returns each package name as a separate link.
*
* @param pkg PackageElement
* @param mdle the module being documented
* @return content for the package link
*/
protected Content getPackage(PackageElement pkg, ModuleElement mdle) {
Content packageLinkContent;
Content pkgLabel;
if (!pkg.isUnnamed()) {
pkgLabel = getPackageLabel(utils.getPackageName(pkg));
packageLinkContent = getHyperLink(pathString(pkg,
DocPaths.PACKAGE_FRAME), pkgLabel, "",
"packageFrame");
} else {
pkgLabel = new StringContent("<unnamed package>");
packageLinkContent = getHyperLink(DocPaths.PACKAGE_FRAME,
pkgLabel, "", "packageFrame");
}
Content li = HtmlTree.LI(packageLinkContent);
return li;
}
private static Set<String> getDeclaredModules(final JavaSource src) {
Set<String> declaredModuleNames = new HashSet<>();
try {
src.runUserActionTask((cc)-> {
cc.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
final List<? extends Tree> decls = cc.getCompilationUnit().getTypeDecls();
final ModuleElement me = !decls.isEmpty() && decls.get(0).getKind() == Tree.Kind.MODULE ?
(ModuleElement) cc.getTrees().getElement(TreePath.getPath(cc.getCompilationUnit(), decls.get(0))) :
null;
if (me != null) {
for (ModuleElement.Directive d : me.getDirectives()) {
if (d.getKind() == ModuleElement.DirectiveKind.REQUIRES) {
final ModuleElement.RequiresDirective reqD = (ModuleElement.RequiresDirective) d;
final String name = reqD.getDependency().getQualifiedName().toString();
declaredModuleNames.add(name);
}
}
}
}, true);
} catch (IOException ex) {
LOG.log(Level.WARNING, null, ex);
}
log("Declared modules:", declaredModuleNames); // NOI18N
return declaredModuleNames;
}
/**
* {@inheritDoc}
*/
protected void addModulesList(Collection<ModuleElement> modules, String text,
String tableSummary, Content body) {
Content heading = HtmlTree.HEADING(HtmlConstants.MODULE_HEADING, true,
contents.modulesLabel);
HtmlTree htmlTree = (configuration.allowTag(HtmlTag.MAIN))
? HtmlTree.MAIN(HtmlStyle.indexContainer, heading)
: HtmlTree.DIV(HtmlStyle.indexContainer, heading);
HtmlTree ul = new HtmlTree(HtmlTag.UL);
ul.setTitle(contents.modulesLabel);
for (ModuleElement mdle: modules) {
ul.addContent(getModuleLink(mdle));
}
htmlTree.addContent(ul);
body.addContent(htmlTree);
}
private static int directivePosInKind(ModuleElement.DirectiveKind kind) {
switch (kind) {
case EXPORTS:
return 0;
case OPENS:
return 1;
case REQUIRES:
return 2;
case USES:
return 3;
case PROVIDES:
return 4;
default:
return 100;
}
}
@NonNull
public static Openable openable(
@NonNull final ModuleElement module,
@NonNull final ModuleElement.Directive directive,
@NonNull final ClasspathInfo cpInfo) {
final String displayName = module.getQualifiedName().toString();
final ElementHandle<ModuleElement> moduleHandle = ElementHandle.create(module);
final Object[] directiveHandle = createDirectiveHandle(directive);
return () -> {
final FileObject source = SourceUtils.getFile(moduleHandle, cpInfo);
if (source == null) {
noSource(displayName);
}
TreePathHandle path = resolveDirectiveHandle(source, directiveHandle);
if (path == null) {
noSource(displayName);
}
if (!ElementOpen.open(source, path)) {
noSource(displayName);
}
};
}
/**
* {@inheritDoc}
*/
@Override // defined by AbstractDoclet
protected void generateModuleFiles() throws DocletException {
if (configuration.showModules) {
if (configuration.frames && configuration.modules.size() > 1) {
ModuleIndexFrameWriter.generate(configuration);
}
ModuleElement prevModule = null, nextModule;
List<ModuleElement> mdles = new ArrayList<>(configuration.modulePackages.keySet());
int i = 0;
for (ModuleElement mdle : mdles) {
if (configuration.frames && configuration.modules.size() > 1) {
ModulePackageIndexFrameWriter.generate(configuration, mdle);
ModuleFrameWriter.generate(configuration, mdle);
}
nextModule = (i + 1 < mdles.size()) ? mdles.get(i + 1) : null;
AbstractBuilder moduleSummaryBuilder =
configuration.getBuilderFactory().getModuleSummaryBuilder(
mdle, prevModule, nextModule);
moduleSummaryBuilder.build();
prevModule = mdle;
i++;
}
}
}
private void computeSpecifiedPackages() throws ToolException {
computeSubpackages();
Set<PackageElement> packlist = new LinkedHashSet<>();
cmdLinePackages.forEach((modpkg) -> {
PackageElement pkg;
if (modpkg.hasModule()) {
ModuleElement mdle = toolEnv.elements.getModuleElement(modpkg.moduleName);
pkg = toolEnv.elements.getPackageElement(mdle, modpkg.packageName);
} else {
pkg = toolEnv.elements.getPackageElement(modpkg.toString());
}
if (pkg != null) {
packlist.add(pkg);
} else {
messager.printWarningUsingKey("main.package_not_found", modpkg.toString());
}
});
specifiedPackageElements = Collections.unmodifiableSet(packlist);
}
/**
* {@inheritDoc}
*/
@Override
public Content getPackageHeader(String heading) {
HtmlTree bodyTree = getBody(true, getWindowTitle(utils.getPackageName(packageElement)));
HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
? HtmlTree.HEADER()
: bodyTree;
addTop(htmlTree);
addNavLinks(true, htmlTree);
if (configuration.allowTag(HtmlTag.HEADER)) {
bodyTree.addContent(htmlTree);
}
HtmlTree div = new HtmlTree(HtmlTag.DIV);
div.addStyle(HtmlStyle.header);
if (configuration.showModules) {
ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(packageElement);
Content classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInPackage, contents.moduleLabel);
Content moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classModuleLabel);
moduleNameDiv.addContent(Contents.SPACE);
moduleNameDiv.addContent(getModuleLink(mdle,
new StringContent(mdle.getQualifiedName().toString())));
div.addContent(moduleNameDiv);
}
Content annotationContent = new HtmlTree(HtmlTag.P);
addAnnotationInfo(packageElement, annotationContent);
div.addContent(annotationContent);
Content tHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
HtmlStyle.title, contents.packageLabel);
tHeading.addContent(Contents.SPACE);
Content packageHead = new StringContent(heading);
tHeading.addContent(packageHead);
div.addContent(tHeading);
if (configuration.allowTag(HtmlTag.MAIN)) {
mainTree.addContent(div);
} else {
bodyTree.addContent(div);
}
return bodyTree;
}
/**
* Constructor to construct ModuleWriter object and to generate "moduleName-summary.html" file.
*
* @param configuration the configuration of the doclet.
* @param mdle Module under consideration.
* @param prevModule Previous module in the sorted array.
* @param nextModule Next module in the sorted array.
*/
public ModuleWriterImpl(ConfigurationImpl configuration,
ModuleElement mdle, ModuleElement prevModule, ModuleElement nextModule) {
super(configuration, DocPaths.moduleSummary(mdle));
this.prevModule = prevModule;
this.nextModule = nextModule;
this.mdle = mdle;
this.moduleMode = configuration.docEnv.getModuleMode();
computeModulesData();
}
protected Location getLocationForModule(ModuleElement mdle) {
Location loc = configuration.workArounds.getLocationForModule(mdle);
if (loc != null)
return loc;
return defaultLocation();
}
@DefinedBy(Api.LANGUAGE_MODEL)
public ModuleElement getModuleOf(Element e) {
Symbol sym = cast(Symbol.class, e);
if (modules.getDefaultModule() == syms.noModule)
return null;
return (sym.kind == MDL) ? ((ModuleElement) e) : sym.packge().modle;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public Origin getOrigin(ModuleElement m, ModuleElement.Directive directive) {
switch (directive.getKind()) {
case REQUIRES:
RequiresDirective rd = cast(RequiresDirective.class, directive);
if (rd.flags.contains(RequiresFlag.MANDATED))
return Origin.MANDATED;
if (rd.flags.contains(RequiresFlag.SYNTHETIC))
return Origin.SYNTHETIC;
return Origin.EXPLICIT;
case EXPORTS:
ExportsDirective ed = cast(ExportsDirective.class, directive);
if (ed.flags.contains(ExportsFlag.MANDATED))
return Origin.MANDATED;
if (ed.flags.contains(ExportsFlag.SYNTHETIC))
return Origin.SYNTHETIC;
return Origin.EXPLICIT;
case OPENS:
OpensDirective od = cast(OpensDirective.class, directive);
if (od.flags.contains(OpensFlag.MANDATED))
return Origin.MANDATED;
if (od.flags.contains(OpensFlag.SYNTHETIC))
return Origin.SYNTHETIC;
return Origin.EXPLICIT;
}
return Origin.EXPLICIT;
}
/**
* Returns a representation of the package truncated to two levels.
* For instance if the given package represents foo.bar.baz will return
* a representation of foo.bar
* @param pkg the PackageElement
* @return an abbreviated PackageElement
*/
public PackageElement getAbbreviatedPackageElement(PackageElement pkg) {
String parsedPackageName = utils.parsePackageName(pkg);
ModuleElement encl = (ModuleElement) pkg.getEnclosingElement();
PackageElement abbrevPkg = encl == null
? utils.elementUtils.getPackageElement(parsedPackageName)
: ((JavacElements) utils.elementUtils).getPackageElement(encl, parsedPackageName);
return abbrevPkg;
}
@Test
public void testVisitor(Path base) throws Exception {
Path src = base.resolve("src");
Path src_m1 = src.resolve("m1x");
tb.writeJavaFiles(src_m1,
"module m1x { "
+ " requires m2x;"
+ " exports p1;"
+ " opens p2;"
+ " uses p1.Service;"
+ " provides p1.Service with p2.Impl;"
+ "}",
"package p1; public interface Service { }",
"package p2; public class Impl implements p1.Service { }");
Path src_m2 = src.resolve("m2x");
tb.writeJavaFiles(src_m2,
"module m2x { }");
Path modules = base.resolve("modules");
tb.createDirectories(modules);
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) {
Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(findJavaFiles(src));
List<String> options = List.of(
"--module-source-path", src.toString(),
"-d", modules.toString()
);
JavacTask t = (JavacTask) javac.getTask(null, fm, null, options, null, files);
t.analyze();
ModuleElement e = t.getElements().getModuleElement("m1x");
Set<DirectiveKind> kinds = EnumSet.<DirectiveKind>allOf(DirectiveKind.class);
Visitor v = new Visitor();
v.visit(e, kinds);
if (!kinds.equals(EnumSet.<DirectiveKind>noneOf(DirectiveKind.class))) {
error("Some kinds not found: " + kinds);
}
}
}
private StringBuilder getElementHeader(final Element element, final CompilationInfo info) {
final StringBuilder sb = new StringBuilder();
if (element != null) {
sb.append(getContainingClassOrPackageHeader(element, info.getElements(), info.getElementUtilities()));
switch(element.getKind()) {
case METHOD:
case CONSTRUCTOR:
sb.append(getMethodHeader((ExecutableElement)element));
break;
case FIELD:
case ENUM_CONSTANT:
sb.append(getFieldHeader((VariableElement)element));
break;
case CLASS:
case INTERFACE:
case ENUM:
case ANNOTATION_TYPE:
sb.append(getClassHeader((TypeElement)element));
break;
case PACKAGE:
sb.append(getPackageHeader((PackageElement)element));
break;
case MODULE:
sb.append(getModuleHeader((ModuleElement)element));
break;
}
}
return sb;
}
@Override
public boolean process(Set<? extends TypeElement> u, RoundEnvironment r) {
ModuleElement sm = processingEnv.getElementUtils().getModuleElement("service");
if (sm == null) {
throw new AssertionError("Cannot find the service module!");
}
boolean foundjd = false;
for (RequiresDirective rd : ElementFilter.requiresIn(sm.getDirectives())) {
foundjd |= rd.getDependency().getQualifiedName().contentEquals("java.desktop");
}
if (!foundjd) {
throw new AssertionError("Missing dependency on java desktop module!");
}
return false;
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
ModuleElement m2Module = processingEnv.getElementUtils().getModuleElement("m2x");
if (m2Module == null) {
throw new AssertionError("Cannot find the m2x module!");
}
boolean foundM1 = false;
for (RequiresDirective rd : ElementFilter.requiresIn(m2Module.getDirectives())) {
foundM1 |= rd.getDependency().getSimpleName().contentEquals("m1x");
}
if (!foundM1) {
throw new AssertionError("Cannot find the dependency on m1x module!");
}
return false;
}
private List<? extends ExpressionTree> constructModuleList(List<? extends ModuleElement> params) {
List<ExpressionTree> result = new LinkedList<>();
if (params != null) {
for (ModuleElement e : params) {
result.add(make.QualIdent(e.getQualifiedName().toString()));
}
}
return result;
}
ClassIndexImplEvent (
final ClassIndexImpl source,
final URL root,
final ElementHandle<ModuleElement> module,
final Iterable<? extends ElementHandle<TypeElement>> types) {
super (source);
assert root != null;
assert types != null;
this.root = root;
this.module = module;
this.types = types;
}
@NonNull
private static String getDirectiveName(
@NonNull final ModuleElement.Directive directive,
final boolean fqn) {
final StringBuilder sb = new StringBuilder();
switch (directive.getKind()) {
case EXPORTS:
sb.append(((ModuleElement.ExportsDirective)directive).getPackage().getQualifiedName());
break;
case OPENS:
sb.append(((ModuleElement.OpensDirective)directive).getPackage().getQualifiedName());
break;
case REQUIRES:
sb.append(((ModuleElement.RequiresDirective)directive).getDependency().getQualifiedName());
break;
case USES:
final TypeElement service = ((ModuleElement.UsesDirective)directive).getService();
sb.append(fqn ? service.getQualifiedName() : service.getSimpleName());
break;
case PROVIDES:
final TypeElement impl = ((ModuleElement.ProvidesDirective)directive).getService();
sb.append(fqn ? impl.getQualifiedName() : impl.getSimpleName());
break;
default:
throw new IllegalArgumentException(directive.toString());
}
return sb.toString();
}