TransitiveDependencies.java revision 4254:d601b22360fa
1/* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package build.tools.symbolgenerator; 27 28import java.io.IOException; 29import java.util.Arrays; 30import java.util.HashSet; 31import java.util.LinkedList; 32import java.util.List; 33import java.util.Set; 34import java.util.stream.Collectors; 35 36import javax.lang.model.element.ModuleElement.RequiresDirective; 37import javax.lang.model.util.Elements; 38import javax.tools.JavaCompiler; 39import javax.tools.ToolProvider; 40 41import com.sun.tools.javac.api.JavacTaskImpl; 42import com.sun.tools.javac.code.Symbol.ModuleSymbol; 43 44/** 45 * Print reflexive transitive closure of the given modules along their requires transitive edges. 46 */ 47public class TransitiveDependencies { 48 49 private static void help() { 50 System.err.println("java TransitiveDependencies <module-source-path> <root-modules>"); 51 } 52 53 public static void main(String... args) throws IOException { 54 if (args.length < 1) { 55 help(); 56 return ; 57 } 58 59 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 60 List<String> options = Arrays.asList("-source", "9", 61 "-target", "9", 62 "-proc:only", 63 "--system", "none", 64 "--module-source-path", args[0], 65 "--add-modules", Arrays.stream(args) 66 .skip(1) 67 .collect(Collectors.joining(","))); 68 List<String> jlObjectList = Arrays.asList("java.lang.Object"); 69 JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, null, null, options, jlObjectList, null); 70 task.enter(); 71 Elements elements = task.getElements(); 72 List<String> todo = new LinkedList<>(); 73 Arrays.stream(args).skip(1).forEach(todo::add); 74 Set<String> allModules = new HashSet<>(); 75 76 while (!todo.isEmpty()) { 77 String current = todo.remove(0); 78 79 if (!allModules.add(current)) 80 continue; 81 82 ModuleSymbol mod = (ModuleSymbol) elements.getModuleElement(current); 83 84 if (mod == null) { 85 throw new IllegalStateException("Missing: " + current); 86 } 87 88 //use the internal structure to avoid unnecesarily completing the symbol using the UsesProvidesVisitor: 89 for (RequiresDirective rd : mod.requires) { 90 if (rd.isTransitive()) { 91 todo.add(rd.getDependency().getQualifiedName().toString()); 92 } 93 } 94 } 95 96 allModules.add("java.base"); 97 allModules.add("jdk.unsupported"); 98 99 allModules.stream() 100 .sorted() 101 .forEach(System.out::println); 102 } 103 104} 105