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 26 package com.sun.tools.sjavac.comp; 27 28 import java.util.Iterator; 29 import java.util.List; 30 import javax.lang.model.element.Modifier; 31 import javax.lang.model.element.ExecutableElement; 32 import javax.lang.model.element.TypeElement; 33 import javax.lang.model.element.VariableElement; 34 import javax.lang.model.type.TypeMirror; 35 import javax.lang.model.util.ElementScanner9; 36 37 /** Utility class that constructs a textual representation 38 * of the public api of a class. 39 * 40 * <p><b>This is NOT part of any supported API. 41 * If you write code that depends on this, you do so at your own 42 * risk. This code and its internal interfaces are subject to change 43 * or deletion without notice.</b></p> 44 */ 45 public class PubapiVisitor extends ElementScanner9<Void, Void> { 46 47 StringBuffer sb; 48 // Important that it is 1! Part of protocol over wire, silly yes. 49 // Fix please. 50 int indent = 1; 51 52 public PubapiVisitor(StringBuffer sb) { 53 this.sb = sb; 54 } 55 56 String depth(int l) { 57 return " ".substring(0, l); 58 } 59 60 @Override 61 public Void visitType(TypeElement e, Void p) { 62 if (e.getModifiers().contains(Modifier.PUBLIC) 63 || e.getModifiers().contains(Modifier.PROTECTED)) 64 { 65 sb.append(depth(indent) + "TYPE " + e.getQualifiedName() + "\n"); 66 indent += 2; 67 Void v = super.visitType(e, p); 68 indent -= 2; 69 return v; 70 } 71 return null; 72 } 73 74 @Override 75 public Void visitVariable(VariableElement e, Void p) { 76 if (e.getModifiers().contains(Modifier.PUBLIC) 77 || e.getModifiers().contains(Modifier.PROTECTED)) { 78 sb.append(depth(indent)).append("VAR ") 79 .append(makeVariableString(e)).append("\n"); 80 } 81 // Safe to not recurse here, because the only thing 82 // to visit here is the constructor of a variable declaration. 83 // If it happens to contain an anonymous inner class (which it might) 84 // then this class is never visible outside of the package anyway, so 85 // we are allowed to ignore it here. 86 return null; 87 } 88 89 @Override 90 public Void visitExecutable(ExecutableElement e, Void p) { 91 if (e.getModifiers().contains(Modifier.PUBLIC) 92 || e.getModifiers().contains(Modifier.PROTECTED)) { 93 sb.append(depth(indent)).append("METHOD ") 94 .append(makeMethodString(e)).append("\n"); 95 } 96 return null; 97 } 98 99 /** 100 * Creates a String representation of a method element with everything 101 * necessary to track all public aspects of it in an API. 102 * @param e Element to create String for. 103 * @return String representation of element. 104 */ 105 protected String makeMethodString(ExecutableElement e) { 106 StringBuilder result = new StringBuilder(); 107 for (Modifier modifier : e.getModifiers()) { 108 result.append(modifier.toString()); 109 result.append(" "); 110 } 111 result.append(e.getReturnType().toString()); 112 result.append(" "); 113 result.append(e.toString()); 114 | 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 26 package com.sun.tools.sjavac.comp; 27 28 import java.util.ArrayList; 29 import java.util.Collections; 30 import java.util.Iterator; 31 import java.util.List; 32 import java.util.LinkedList; 33 import javax.lang.model.element.Modifier; 34 import javax.lang.model.element.ExecutableElement; 35 import javax.lang.model.element.TypeElement; 36 import javax.lang.model.element.VariableElement; 37 import javax.lang.model.type.TypeMirror; 38 import javax.lang.model.util.ElementScanner9; 39 40 /** Utility class that constructs a textual representation 41 * of the public api of a class. 42 * 43 * <p><b>This is NOT part of any supported API. 44 * If you write code that depends on this, you do so at your own 45 * risk. This code and its internal interfaces are subject to change 46 * or deletion without notice.</b></p> 47 */ 48 public class PubapiVisitor extends ElementScanner9<Void, Void> { 49 50 // The pubapi is stored here. 51 List<String> api = new LinkedList<String>(); 52 // The hash of the pubapi (excluding paths to jars/classes and their timestamp) 53 int hash; 54 // Indentation level. 55 int indent = 0; 56 // The class location info is for example: 57 // ZipFileIndexFileObject[/home/fredrik/bin/jdk1.8.0/lib/tools.jar(com/sun/tools/javac/comp/Resolve.class) 1396702502000 58 // ie the jfileobj.toString() + " " + jfileobj.getLastModified() 59 String class_loc_info = ""; 60 61 // If true, then store full public api information, not just the hash. 62 // Makes it much easier to debug any public api bugs. 63 boolean debugPubapi = false; 64 65 String depth(int l) { 66 return "________________________________".substring(0, l); 67 } 68 69 public void classLocInfo(String s) { 70 class_loc_info = " "+s; 71 } 72 73 public void construct(TypeElement e) { 74 visit(e); 75 hash = 0; 76 List<String> sorted_api = new ArrayList<>(); 77 sorted_api.addAll(api); 78 // Why sort here? Because we want the same pubapi hash to be generated 79 // for both a source compile and a classpath extraction. 80 Collections.sort(sorted_api); 81 82 for (String s : sorted_api) { 83 hash ^= s.hashCode(); 84 } 85 api = new LinkedList<String>(); 86 api.add(0, "PUBAPI "+e.getQualifiedName()+" "+Integer.toString(Math.abs(hash),16)+class_loc_info); 87 if (debugPubapi) { 88 api.addAll(sorted_api); 89 } 90 } 91 92 @Override 93 public Void visitType(TypeElement e, Void p) { 94 if (e.getModifiers().contains(Modifier.PUBLIC) 95 || e.getModifiers().contains(Modifier.PROTECTED)) 96 { 97 api.add(depth(indent) + "!TYPE " + e.getQualifiedName()); 98 indent += 2; 99 Void v = super.visitType(e, p); 100 indent -= 2; 101 return v; 102 } 103 return null; 104 } 105 106 @Override 107 public Void visitVariable(VariableElement e, Void p) { 108 if (e.getModifiers().contains(Modifier.PUBLIC) 109 || e.getModifiers().contains(Modifier.PROTECTED)) { 110 api.add(depth(indent)+"VAR "+makeVariableString(e)); 111 } 112 // Safe to not recurse here, because the only thing 113 // to visit here is the constructor of a variable declaration. 114 // If it happens to contain an anonymous inner class (which it might) 115 // then this class is never visible outside of the package anyway, so 116 // we are allowed to ignore it here. 117 return null; 118 } 119 120 @Override 121 public Void visitExecutable(ExecutableElement e, Void p) { 122 if (e.getModifiers().contains(Modifier.PUBLIC) 123 || e.getModifiers().contains(Modifier.PROTECTED)) { 124 api.add(depth(indent)+"METHOD "+makeMethodString(e)); 125 } 126 return null; 127 } 128 129 /** 130 * Creates a String representation of a method element with everything 131 * necessary to track all public aspects of it in an API. 132 * @param e Element to create String for. 133 * @return String representation of element. 134 */ 135 protected String makeMethodString(ExecutableElement e) { 136 StringBuilder result = new StringBuilder(); 137 for (Modifier modifier : e.getModifiers()) { 138 result.append(modifier.toString()); 139 result.append(" "); 140 } 141 result.append(e.getReturnType().toString()); 142 result.append(" "); 143 result.append(e.toString()); 144 |