ohrstrom@1504: /* ohrstrom@1504: * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. ohrstrom@1504: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohrstrom@1504: * ohrstrom@1504: * This code is free software; you can redistribute it and/or modify it ohrstrom@1504: * under the terms of the GNU General Public License version 2 only, as ohrstrom@1504: * published by the Free Software Foundation. Oracle designates this ohrstrom@1504: * particular file as subject to the "Classpath" exception as provided ohrstrom@1504: * by Oracle in the LICENSE file that accompanied this code. ohrstrom@1504: * ohrstrom@1504: * This code is distributed in the hope that it will be useful, but WITHOUT ohrstrom@1504: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohrstrom@1504: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohrstrom@1504: * version 2 for more details (a copy is included in the LICENSE file that ohrstrom@1504: * accompanied this code). ohrstrom@1504: * ohrstrom@1504: * You should have received a copy of the GNU General Public License version ohrstrom@1504: * 2 along with this work; if not, write to the Free Software Foundation, ohrstrom@1504: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohrstrom@1504: * ohrstrom@1504: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohrstrom@1504: * or visit www.oracle.com if you need additional information or have any ohrstrom@1504: * questions. ohrstrom@1504: */ ohrstrom@1504: ohrstrom@1504: package com.sun.tools.sjavac.comp; ohrstrom@1504: ohrstrom@1504: import java.util.Iterator; ohrstrom@1504: import java.util.List; ohrstrom@1504: import javax.lang.model.element.Modifier; ohrstrom@1504: import javax.lang.model.element.ExecutableElement; ohrstrom@1504: import javax.lang.model.element.TypeElement; ohrstrom@1504: import javax.lang.model.element.VariableElement; ohrstrom@1504: import javax.lang.model.type.TypeMirror; ohrstrom@1504: import javax.lang.model.util.ElementScanner6; ohrstrom@1504: ohrstrom@1504: /** Utility class that constructs a textual representation ohrstrom@1504: * of the public api of a class. ohrstrom@1504: * ohrstrom@1504: *

This is NOT part of any supported API. ohrstrom@1504: * If you write code that depends on this, you do so at your own ohrstrom@1504: * risk. This code and its internal interfaces are subject to change ohrstrom@1504: * or deletion without notice.

ohrstrom@1504: */ ohrstrom@1504: public class PubapiVisitor extends ElementScanner6 { ohrstrom@1504: ohrstrom@1504: StringBuffer sb; ohrstrom@1504: // Important that it is 1! Part of protocol over wire, silly yes. ohrstrom@1504: // Fix please. ohrstrom@1504: int indent = 1; ohrstrom@1504: ohrstrom@1504: public PubapiVisitor(StringBuffer sb) { ohrstrom@1504: this.sb = sb; ohrstrom@1504: } ohrstrom@1504: ohrstrom@1504: String depth(int l) { ohrstrom@1504: return " ".substring(0, l); ohrstrom@1504: } ohrstrom@1504: ohrstrom@1504: @Override ohrstrom@1504: public Void visitType(TypeElement e, Void p) { ohrstrom@1504: if (e.getModifiers().contains(Modifier.PUBLIC) ohrstrom@1504: || e.getModifiers().contains(Modifier.PROTECTED)) ohrstrom@1504: { ohrstrom@1504: sb.append(depth(indent) + "TYPE " + e.getQualifiedName() + "\n"); ohrstrom@1504: indent += 2; ohrstrom@1504: Void v = super.visitType(e, p); ohrstrom@1504: indent -= 2; ohrstrom@1504: return v; ohrstrom@1504: } ohrstrom@1504: return null; ohrstrom@1504: } ohrstrom@1504: ohrstrom@1504: @Override ohrstrom@1504: public Void visitVariable(VariableElement e, Void p) { ohrstrom@1504: if (e.getModifiers().contains(Modifier.PUBLIC) ohrstrom@1504: || e.getModifiers().contains(Modifier.PROTECTED)) { ohrstrom@1504: sb.append(depth(indent)).append("VAR ") ohrstrom@1504: .append(makeVariableString(e)).append("\n"); ohrstrom@1504: } ohrstrom@1504: // Safe to not recurse here, because the only thing ohrstrom@1504: // to visit here is the constructor of a variable declaration. ohrstrom@1504: // If it happens to contain an anonymous inner class (which it might) ohrstrom@1504: // then this class is never visible outside of the package anyway, so ohrstrom@1504: // we are allowed to ignore it here. ohrstrom@1504: return null; ohrstrom@1504: } ohrstrom@1504: ohrstrom@1504: @Override ohrstrom@1504: public Void visitExecutable(ExecutableElement e, Void p) { ohrstrom@1504: if (e.getModifiers().contains(Modifier.PUBLIC) ohrstrom@1504: || e.getModifiers().contains(Modifier.PROTECTED)) { ohrstrom@1504: sb.append(depth(indent)).append("METHOD ") ohrstrom@1504: .append(makeMethodString(e)).append("\n"); ohrstrom@1504: } ohrstrom@1504: return null; ohrstrom@1504: } ohrstrom@1504: ohrstrom@1504: /** ohrstrom@1504: * Creates a String representation of a method element with everything ohrstrom@1504: * necessary to track all public aspects of it in an API. ohrstrom@1504: * @param e Element to create String for. ohrstrom@1504: * @return String representation of element. ohrstrom@1504: */ ohrstrom@1504: protected String makeMethodString(ExecutableElement e) { ohrstrom@1504: StringBuilder result = new StringBuilder(); ohrstrom@1504: for (Modifier modifier : e.getModifiers()) { ohrstrom@1504: result.append(modifier.toString()); ohrstrom@1504: result.append(" "); ohrstrom@1504: } ohrstrom@1504: result.append(e.getReturnType().toString()); ohrstrom@1504: result.append(" "); ohrstrom@1504: result.append(e.toString()); ohrstrom@1504: ohrstrom@1504: List thrownTypes = e.getThrownTypes(); ohrstrom@1504: if (!thrownTypes.isEmpty()) { ohrstrom@1504: result.append(" throws "); ohrstrom@1504: for (Iterator iterator = thrownTypes ohrstrom@1504: .iterator(); iterator.hasNext();) { ohrstrom@1504: TypeMirror typeMirror = iterator.next(); ohrstrom@1504: result.append(typeMirror.toString()); ohrstrom@1504: if (iterator.hasNext()) { ohrstrom@1504: result.append(", "); ohrstrom@1504: } ohrstrom@1504: } ohrstrom@1504: } ohrstrom@1504: return result.toString(); ohrstrom@1504: } ohrstrom@1504: ohrstrom@1504: /** ohrstrom@1504: * Creates a String representation of a variable element with everything ohrstrom@1504: * necessary to track all public aspects of it in an API. ohrstrom@1504: * @param e Element to create String for. ohrstrom@1504: * @return String representation of element. ohrstrom@1504: */ ohrstrom@1504: protected String makeVariableString(VariableElement e) { ohrstrom@1504: StringBuilder result = new StringBuilder(); ohrstrom@1504: for (Modifier modifier : e.getModifiers()) { ohrstrom@1504: result.append(modifier.toString()); ohrstrom@1504: result.append(" "); ohrstrom@1504: } ohrstrom@1504: result.append(e.asType().toString()); ohrstrom@1504: result.append(" "); ohrstrom@1504: result.append(e.toString()); ohrstrom@1504: Object value = e.getConstantValue(); ohrstrom@1504: if (value != null) { ohrstrom@1504: result.append(" = "); ohrstrom@1504: if (e.asType().toString().equals("char")) { ohrstrom@1504: int v = (int)value.toString().charAt(0); ohrstrom@1504: result.append("'\\u"+Integer.toString(v,16)+"'"); ohrstrom@1504: } else { ohrstrom@1504: result.append(value.toString()); ohrstrom@1504: } ohrstrom@1504: } ohrstrom@1504: return result.toString(); ohrstrom@1504: } ohrstrom@1504: }