1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/sjavac/comp/Dependencies.java Mon Feb 04 18:08:53 2013 -0500 1.3 @@ -0,0 +1,188 @@ 1.4 +/* 1.5 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.sjavac.comp; 1.30 + 1.31 +import javax.lang.model.element.Element; 1.32 +import java.util.Arrays; 1.33 +import java.util.Comparator; 1.34 +import java.util.HashMap; 1.35 +import java.util.HashSet; 1.36 +import java.util.Map; 1.37 +import java.util.Set; 1.38 + 1.39 +import com.sun.tools.javac.code.Symbol.ClassSymbol; 1.40 +import com.sun.tools.javac.util.Context; 1.41 +import com.sun.tools.javac.util.Log; 1.42 +import com.sun.tools.javac.util.Name; 1.43 + 1.44 +/** Utility class containing dependency information between packages 1.45 + * and the pubapi for a package. 1.46 + * 1.47 + * <p><b>This is NOT part of any supported API. 1.48 + * If you write code that depends on this, you do so at your own 1.49 + * risk. This code and its internal interfaces are subject to change 1.50 + * or deletion without notice.</b></p> 1.51 + */ 1.52 +public class Dependencies { 1.53 + protected static final Context.Key<Dependencies> dependenciesKey = 1.54 + new Context.Key<Dependencies>(); 1.55 + 1.56 + // The log to be used for error reporting. 1.57 + protected Log log; 1.58 + // Map from package name to packages that the package depends upon. 1.59 + protected Map<Name,Set<Name>> deps; 1.60 + // This is the set of all packages that are supplied 1.61 + // through the java files at the command line. 1.62 + protected Set<Name> explicitPackages; 1.63 + 1.64 + // Map from a package name to its public api. 1.65 + // Will the Name encode the module in the future? 1.66 + // If not, this will have to change to map from Module+Name to public api. 1.67 + protected Map<Name,StringBuffer> publicApiPerClass; 1.68 + 1.69 + public static Dependencies instance(Context context) { 1.70 + Dependencies instance = context.get(dependenciesKey); 1.71 + if (instance == null) 1.72 + instance = new Dependencies(context); 1.73 + return instance; 1.74 + } 1.75 + 1.76 + private Dependencies(Context context) { 1.77 + context.put(dependenciesKey, this); 1.78 + log = Log.instance(context); 1.79 + } 1.80 + 1.81 + public void reset() 1.82 + { 1.83 + deps = new HashMap<Name, Set<Name>>(); 1.84 + explicitPackages = new HashSet<Name>(); 1.85 + publicApiPerClass = new HashMap<Name,StringBuffer>(); 1.86 + } 1.87 + 1.88 + /** 1.89 + * Fetch the set of dependencies that are relevant to the compile 1.90 + * that has just been performed. I.e. we are only interested in 1.91 + * dependencies for classes that were explicitly compiled. 1.92 + * @return 1.93 + */ 1.94 + public Map<String,Set<String>> getDependencies() { 1.95 + Map<String,Set<String>> new_deps = new HashMap<String,Set<String>>(); 1.96 + if (explicitPackages == null) return new_deps; 1.97 + for (Name pkg : explicitPackages) { 1.98 + Set<Name> set = deps.get(pkg); 1.99 + if (set != null) { 1.100 + Set<String> new_set = new_deps.get(pkg.toString()); 1.101 + if (new_set == null) { 1.102 + new_set = new HashSet<String>(); 1.103 + // Modules beware.... 1.104 + new_deps.put(":"+pkg.toString(), new_set); 1.105 + } 1.106 + for (Name d : set) { 1.107 + new_set.add(":"+d.toString()); 1.108 + } 1.109 + } 1.110 + } 1.111 + return new_deps; 1.112 + } 1.113 + 1.114 + class CompareNames implements Comparator<Name> { 1.115 + public int compare(Name a, Name b) { 1.116 + return a.toString().compareTo(b.toString()); 1.117 + } 1.118 + 1.119 + public boolean equals(Object obj) { 1.120 + return super.equals(obj); 1.121 + } 1.122 + } 1.123 + 1.124 + /** 1.125 + * Convert the map from class names to their pubapi to a map 1.126 + * from package names to their pubapi (which is the sorted concatenation 1.127 + * of all the class pubapis) 1.128 + */ 1.129 + public Map<String,String> getPubapis() { 1.130 + Map<String,String> publicApiPerPackage = new HashMap<String,String>(); 1.131 + if (publicApiPerClass == null) return publicApiPerPackage; 1.132 + Name[] keys = publicApiPerClass.keySet().toArray(new Name[0]); 1.133 + Arrays.sort(keys, new CompareNames()); 1.134 + StringBuffer newPublicApi = new StringBuffer(); 1.135 + int i=0; 1.136 + String prevPkg = ""; 1.137 + for (Name k : keys) { 1.138 + String cn = k.toString(); 1.139 + String pn = ""; 1.140 + int dp = cn.lastIndexOf('.'); 1.141 + if (dp != -1) { 1.142 + pn = cn.substring(0,dp); 1.143 + } 1.144 + if (!pn.equals(prevPkg)) { 1.145 + if (!prevPkg.equals("")) { 1.146 + // Add default module name ":" 1.147 + publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString()); 1.148 + } 1.149 + newPublicApi = new StringBuffer(); 1.150 + prevPkg = pn; 1.151 + } 1.152 + newPublicApi.append(publicApiPerClass.get(k)); 1.153 + i++; 1.154 + } 1.155 + if (!prevPkg.equals("")) 1.156 + publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString()); 1.157 + return publicApiPerPackage; 1.158 + } 1.159 + 1.160 + /** 1.161 + * Visit the api of a class and construct a pubapi string and 1.162 + * store it into the pubapi_perclass map. 1.163 + */ 1.164 + public void visitPubapi(Element e) { 1.165 + Name n = ((ClassSymbol)e).fullname; 1.166 + Name p = ((ClassSymbol)e).packge().fullname; 1.167 + StringBuffer sb = publicApiPerClass.get(n); 1.168 + assert(sb == null); 1.169 + sb = new StringBuffer(); 1.170 + PubapiVisitor v = new PubapiVisitor(sb); 1.171 + v.visit(e); 1.172 + if (sb.length()>0) { 1.173 + publicApiPerClass.put(n, sb); 1.174 + } 1.175 + explicitPackages.add(p); 1.176 + } 1.177 + 1.178 + /** 1.179 + * Collect a dependency. curr_pkg is marked as depending on dep_pkg. 1.180 + */ 1.181 + public void collect(Name currPkg, Name depPkg) { 1.182 + if (!currPkg.equals(depPkg)) { 1.183 + Set<Name> theset = deps.get(currPkg); 1.184 + if (theset==null) { 1.185 + theset = new HashSet<Name>(); 1.186 + deps.put(currPkg, theset); 1.187 + } 1.188 + theset.add(depPkg); 1.189 + } 1.190 + } 1.191 +}