TransitiveDependencies.java revision 4171:77a2d6c1f321
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 "--system", "none", 63 "--module-source-path", args[0], 64 "--add-modules", Arrays.stream(args) 65 .skip(1) 66 .collect(Collectors.joining(","))); 67 List<String> jlObjectList = Arrays.asList("java.lang.Object"); 68 JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, null, d -> {}, options, jlObjectList, null); 69 task.enter(); 70 Elements elements = task.getElements(); 71 List<String> todo = new LinkedList<>(); 72 Arrays.stream(args).skip(1).forEach(todo::add); 73 Set<String> allModules = new HashSet<>(); 74 75 while (!todo.isEmpty()) { 76 String current = todo.remove(0); 77 78 if (!allModules.add(current)) 79 continue; 80 81 ModuleSymbol mod = (ModuleSymbol) elements.getModuleElement(current); 82 83 if (mod == null) { 84 throw new IllegalStateException("Missing: " + current); 85 } 86 87 //use the internal structure to avoid unnecesarily completing the symbol using the UsesProvidesVisitor: 88 for (RequiresDirective rd : mod.requires) { 89 if (rd.isTransitive()) { 90 todo.add(rd.getDependency().getQualifiedName().toString()); 91 } 92 } 93 } 94 95 allModules.add("java.base"); 96 allModules.add("jdk.unsupported"); 97 98 allModules.stream() 99 .sorted() 100 .forEach(System.out::println); 101 } 102 103} 104