Path: blob/master/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/TraverseProc.java
41161 views
/*1* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.tools.jdeprscan;2627import java.util.ArrayList;28import java.util.Collection;29import java.util.Comparator;30import java.util.HashMap;31import java.util.HashSet;32import java.util.List;33import java.util.Map;34import java.util.Set;3536import javax.annotation.processing.AbstractProcessor;37import javax.annotation.processing.Messager;38import javax.annotation.processing.ProcessingEnvironment;39import javax.annotation.processing.RoundEnvironment;40import javax.annotation.processing.SupportedAnnotationTypes;41import javax.annotation.processing.SupportedSourceVersion;4243import javax.lang.model.SourceVersion;44import javax.lang.model.element.Element;45import javax.lang.model.element.ElementKind;46import javax.lang.model.element.Modifier;47import javax.lang.model.element.ModuleElement;48import javax.lang.model.element.PackageElement;49import javax.lang.model.element.TypeElement;50import javax.lang.model.util.Elements;51import javax.tools.Diagnostic;5253@SupportedAnnotationTypes("*")54public class TraverseProc extends AbstractProcessor {55Elements elements;56Messager messager;57final List<String> moduleRoots;58Map<PackageElement, List<TypeElement>> publicTypes;5960TraverseProc(List<String> roots) {61moduleRoots = roots;62}6364@Override65public void init(ProcessingEnvironment pe) {66super.init(pe);67elements = pe.getElementUtils();68messager = pe.getMessager();69}7071@Override72public SourceVersion getSupportedSourceVersion() {73return SourceVersion.latest();74}7576@Override77public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {78if (roundEnv.processingOver()) {79return false;80}8182Set<ModuleElement> modules = new HashSet<>();83for (String mname : moduleRoots) {84ModuleElement me = elements.getModuleElement(mname);85if (me == null) {86messager.printMessage(Diagnostic.Kind.ERROR,87String.format("module %s not found%n", mname));88} else {89modules.addAll(findModules(me));90}91}9293Set<PackageElement> packages = findPackages(modules);9495publicTypes = findPublicTypes(packages);9697return true;98}99100void printPublicTypes() {101printPublicTypes(publicTypes);102}103104public Map<PackageElement, List<TypeElement>> getPublicTypes() {105return publicTypes;106}107108void printPublicTypes(Map<PackageElement, List<TypeElement>> types) {109System.out.println("All public types:");110types.entrySet().stream()111.sorted(Comparator.comparing(e -> e.getKey().toString()))112.forEach(e -> {113System.out.println(" " + e.getKey());114e.getValue().stream()115.sorted(Comparator.comparing(TypeElement::toString))116.forEach(t -> System.out.println(" " + t));117});118System.out.println();119System.out.flush();120}121122Set<ModuleElement> findModules(ModuleElement root) {123return findModules0(root, new HashSet<>(), 0);124}125126Set<ModuleElement> findModules0(ModuleElement m, Set<ModuleElement> set, int nesting) {127set.add(m);128for (ModuleElement.Directive dir : m.getDirectives()) {129if (dir.getKind() == ModuleElement.DirectiveKind.REQUIRES) {130ModuleElement.RequiresDirective req = (ModuleElement.RequiresDirective)dir;131findModules0(req.getDependency(), set, nesting + 1);132}133}134return set;135}136137Set<PackageElement> findPackages(Collection<ModuleElement> mods) {138Set<PackageElement> set = new HashSet<>();139for (ModuleElement m : mods) {140for (ModuleElement.Directive dir : m.getDirectives()) {141if (dir.getKind() == ModuleElement.DirectiveKind.EXPORTS) { //XXX142ModuleElement.ExportsDirective exp = (ModuleElement.ExportsDirective)dir;143if (exp.getTargetModules() == null) {144set.add(exp.getPackage());145}146}147}148}149return set;150}151152Map<PackageElement, List<TypeElement>> findPublicTypes(Collection<PackageElement> pkgs) {153Map<PackageElement, List<TypeElement>> map = new HashMap<>();154for (PackageElement pkg : pkgs) {155List<TypeElement> enclosed = new ArrayList<>();156for (Element e : pkg.getEnclosedElements()) {157addPublicTypes(enclosed, e);158}159map.put(pkg, enclosed);160}161return map;162}163164void addPublicTypes(List<TypeElement> list, Element e) {165ElementKind kind = e.getKind();166if ((kind.isClass() || kind.isInterface())167&& e.getModifiers().contains(Modifier.PUBLIC)) {168list.add((TypeElement)e);169for (Element enc : e.getEnclosedElements()) {170addPublicTypes(list, enc);171}172}173}174}175176177