1 /* 2 * Copyright (c) 2011, 2014, 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 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 import com.sun.tools.javac.util.DefinedBy; 38 import com.sun.tools.javac.util.DefinedBy.Api; 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 risk. 45 * This code and its internal interfaces are subject to change or 46 * deletion without notice.</b> 47 */ 48 public class PubapiVisitor extends ElementScanner9<Void, Void> { 49 50 StringBuffer sb; 51 // Important that it is 1! Part of protocol over wire, silly yes. 52 // Fix please. 53 int indent = 1; 54 55 public PubapiVisitor(StringBuffer sb) { 56 this.sb = sb; 57 } 58 59 String depth(int l) { 60 return " ".substring(0, l); 61 } 62 63 @Override @DefinedBy(Api.LANGUAGE_MODEL) 64 public Void visitType(TypeElement e, Void p) { 65 if (e.getModifiers().contains(Modifier.PUBLIC) 66 || e.getModifiers().contains(Modifier.PROTECTED)) 67 { 68 sb.append(depth(indent) + "TYPE " + e.getQualifiedName() + "\n"); 69 indent += 2; 70 Void v = super.visitType(e, p); 71 indent -= 2; 72 return v; 73 } 74 return null; 75 } 76 77 @Override @DefinedBy(Api.LANGUAGE_MODEL) 78 public Void visitVariable(VariableElement e, Void p) { 79 if (e.getModifiers().contains(Modifier.PUBLIC) 80 || e.getModifiers().contains(Modifier.PROTECTED)) { 81 sb.append(depth(indent)).append("VAR ") 82 .append(makeVariableString(e)).append("\n"); 83 } 84 // Safe to not recurse here, because the only thing 85 // to visit here is the constructor of a variable declaration. 86 // If it happens to contain an anonymous inner class (which it might) 87 // then this class is never visible outside of the package anyway, so 88 // we are allowed to ignore it here. 89 return null; 90 } 91 92 @Override @DefinedBy(Api.LANGUAGE_MODEL) 93 public Void visitExecutable(ExecutableElement e, Void p) { 94 if (e.getModifiers().contains(Modifier.PUBLIC) 95 || e.getModifiers().contains(Modifier.PROTECTED)) { 96 sb.append(depth(indent)).append("METHOD ") 97 .append(makeMethodString(e)).append("\n"); 98 } 99 return null; 100 } 101 102 /** 103 * Creates a String representation of a method element with everything 104 * necessary to track all public aspects of it in an API. 105 * @param e Element to create String for. 106 * @return String representation of element. 107 */ 108 protected String makeMethodString(ExecutableElement e) { 109 StringBuilder result = new StringBuilder(); 110 for (Modifier modifier : e.getModifiers()) { 111 result.append(modifier.toString()); 112 result.append(" "); 113 } 114 result.append(e.getReturnType().toString()); 115 result.append(" "); 116 result.append(e.toString()); 117 118 List<? extends TypeMirror> thrownTypes = e.getThrownTypes(); 119 if (!thrownTypes.isEmpty()) { 120 result.append(" throws "); 121 for (Iterator<? extends TypeMirror> iterator = thrownTypes 122 .iterator(); iterator.hasNext();) { 123 TypeMirror typeMirror = iterator.next(); 124 result.append(typeMirror.toString()); 125 if (iterator.hasNext()) { 126 result.append(", "); 127 } 128 } 129 } 130 return result.toString(); 131 } 132 133 /** 134 * Creates a String representation of a variable element with everything 135 * necessary to track all public aspects of it in an API. 136 * @param e Element to create String for. 137 * @return String representation of element. 138 */ 139 protected String makeVariableString(VariableElement e) { 140 StringBuilder result = new StringBuilder(); 141 for (Modifier modifier : e.getModifiers()) { 142 result.append(modifier.toString()); 143 result.append(" "); 144 } 145 result.append(e.asType().toString()); 146 result.append(" "); 147 result.append(e.toString()); 148 Object value = e.getConstantValue(); 149 if (value != null) { 150 result.append(" = "); 151 if (e.asType().toString().equals("char")) { 152 int v = (int)value.toString().charAt(0); 153 result.append("'\\u"+Integer.toString(v,16)+"'"); 154 } else { 155 result.append(value.toString()); 156 } 157 } 158 return result.toString(); 159 } 160 }