src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java

Print this page
rev 2819 : imported patch my-classpath-deps-00

*** 23,43 **** * questions. */ package com.sun.tools.sjavac.comp; ! import java.util.Iterator; import java.util.List; ! import javax.lang.model.element.Modifier; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementScanner9; import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy.Api; /** Utility class that constructs a textual representation * of the public api of a class. * * <p><b>This is NOT part of any supported API. --- 23,53 ---- * questions. */ package com.sun.tools.sjavac.comp; ! import static javax.lang.model.element.Modifier.PRIVATE; ! import java.util.List; ! import java.util.stream.Collectors; ! ! import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; + import javax.lang.model.element.TypeParameterElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementScanner9; import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy.Api; + import com.sun.tools.sjavac.pubapi.PubApi; + import com.sun.tools.sjavac.pubapi.PubApiTypeParam; + import com.sun.tools.sjavac.pubapi.PubMethod; + import com.sun.tools.sjavac.pubapi.PubType; + import com.sun.tools.sjavac.pubapi.PubVar; + import com.sun.tools.sjavac.pubapi.TypeDesc; /** Utility class that constructs a textual representation * of the public api of a class. * * <p><b>This is NOT part of any supported API.
*** 45,160 **** * This code and its internal interfaces are subject to change or * deletion without notice.</b> */ public class PubapiVisitor extends ElementScanner9<Void, Void> { ! StringBuffer sb; ! // Important that it is 1! Part of protocol over wire, silly yes. ! // Fix please. ! int indent = 1; ! ! public PubapiVisitor(StringBuffer sb) { ! this.sb = sb; ! } ! String depth(int l) { ! return " ".substring(0, l); } @Override @DefinedBy(Api.LANGUAGE_MODEL) public Void visitType(TypeElement e, Void p) { ! if (e.getModifiers().contains(Modifier.PUBLIC) ! || e.getModifiers().contains(Modifier.PROTECTED)) ! { ! sb.append(depth(indent) + "TYPE " + e.getQualifiedName() + "\n"); ! indent += 2; ! Void v = super.visitType(e, p); ! indent -= 2; ! return v; } return null; } @Override @DefinedBy(Api.LANGUAGE_MODEL) public Void visitVariable(VariableElement e, Void p) { ! if (e.getModifiers().contains(Modifier.PUBLIC) ! || e.getModifiers().contains(Modifier.PROTECTED)) { ! sb.append(depth(indent)).append("VAR ") ! .append(makeVariableString(e)).append("\n"); } // Safe to not recurse here, because the only thing // to visit here is the constructor of a variable declaration. // If it happens to contain an anonymous inner class (which it might) // then this class is never visible outside of the package anyway, so // we are allowed to ignore it here. return null; } @Override @DefinedBy(Api.LANGUAGE_MODEL) public Void visitExecutable(ExecutableElement e, Void p) { ! if (e.getModifiers().contains(Modifier.PUBLIC) ! || e.getModifiers().contains(Modifier.PROTECTED)) { ! sb.append(depth(indent)).append("METHOD ") ! .append(makeMethodString(e)).append("\n"); } return null; } ! /** ! * Creates a String representation of a method element with everything ! * necessary to track all public aspects of it in an API. ! * @param e Element to create String for. ! * @return String representation of element. ! */ ! protected String makeMethodString(ExecutableElement e) { ! StringBuilder result = new StringBuilder(); ! for (Modifier modifier : e.getModifiers()) { ! result.append(modifier.toString()); ! result.append(" "); ! } ! result.append(e.getReturnType().toString()); ! result.append(" "); ! result.append(e.toString()); ! ! List<? extends TypeMirror> thrownTypes = e.getThrownTypes(); ! if (!thrownTypes.isEmpty()) { ! result.append(" throws "); ! for (Iterator<? extends TypeMirror> iterator = thrownTypes ! .iterator(); iterator.hasNext();) { ! TypeMirror typeMirror = iterator.next(); ! result.append(typeMirror.toString()); ! if (iterator.hasNext()) { ! result.append(", "); ! } } } ! return result.toString(); ! } ! ! /** ! * Creates a String representation of a variable element with everything ! * necessary to track all public aspects of it in an API. ! * @param e Element to create String for. ! * @return String representation of element. ! */ ! protected String makeVariableString(VariableElement e) { ! StringBuilder result = new StringBuilder(); ! for (Modifier modifier : e.getModifiers()) { ! result.append(modifier.toString()); ! result.append(" "); ! } ! result.append(e.asType().toString()); ! result.append(" "); ! result.append(e.toString()); ! Object value = e.getConstantValue(); ! if (value != null) { ! result.append(" = "); ! if (e.asType().toString().equals("char")) { ! int v = (int)value.toString().charAt(0); ! result.append("'\\u"+Integer.toString(v,16)+"'"); ! } else { ! result.append(value.toString()); ! } } ! return result.toString(); } } --- 55,157 ---- * This code and its internal interfaces are subject to change or * deletion without notice.</b> */ public class PubapiVisitor extends ElementScanner9<Void, Void> { ! private PubApi collectedApi = new PubApi(); ! private boolean isNonPrivate(Element e) { ! return !e.getModifiers().contains(PRIVATE); } @Override @DefinedBy(Api.LANGUAGE_MODEL) public Void visitType(TypeElement e, Void p) { ! if (isNonPrivate(e)) { ! PubApi prevApi = collectedApi; ! collectedApi = new PubApi(); ! super.visitType(e, p); ! PubType t = new PubType(e.getModifiers(), ! e.getQualifiedName().toString(), ! collectedApi); ! prevApi.types.put(t.fqName, t); ! collectedApi = prevApi; } return null; } + private static String encodeChar(int c) { + return String.format("\\u%04x", c); + } + @Override @DefinedBy(Api.LANGUAGE_MODEL) public Void visitVariable(VariableElement e, Void p) { ! if (isNonPrivate(e)) { ! Object constVal = e.getConstantValue(); ! String constValStr = null; ! // TODO: This doesn't seem to be entirely accurate. What if I change ! // from, say, 0 to 0L? (And the field is public final static so that ! // it could get inlined.) ! if (constVal != null) { ! if (e.asType().toString().equals("char")) { ! // What type is 'value'? Is it already a char? ! char c = constVal.toString().charAt(0); ! constValStr = "'" + encodeChar(c) + "'"; ! } else { ! constValStr = constVal.toString() ! .chars() ! .mapToObj(PubapiVisitor::encodeChar) ! .collect(Collectors.joining("", "\"", "\"")); ! } ! } ! ! PubVar v = new PubVar(e.getModifiers(), ! TypeDesc.fromType(e.asType()), ! e.toString(), ! constValStr); ! collectedApi.variables.put(v.identifier, v); } + // Safe to not recurse here, because the only thing // to visit here is the constructor of a variable declaration. // If it happens to contain an anonymous inner class (which it might) // then this class is never visible outside of the package anyway, so // we are allowed to ignore it here. return null; } @Override @DefinedBy(Api.LANGUAGE_MODEL) public Void visitExecutable(ExecutableElement e, Void p) { ! if (isNonPrivate(e)) { ! PubMethod m = new PubMethod(e.getModifiers(), ! getTypeParameters(e.getTypeParameters()), ! TypeDesc.fromType(e.getReturnType()), ! e.getSimpleName().toString(), ! getTypeDescs(getParamTypes(e)), ! getTypeDescs(e.getThrownTypes())); ! collectedApi.methods.put(m.asSignatureString(), m); } return null; } ! private List<PubApiTypeParam> getTypeParameters(List<? extends TypeParameterElement> elements) { ! return elements.stream() ! .map(e -> new PubApiTypeParam(e.getSimpleName().toString(), getTypeDescs(e.getBounds()))) ! .collect(Collectors.toList()); } + + private List<TypeMirror> getParamTypes(ExecutableElement e) { + return e.getParameters() + .stream() + .map(VariableElement::asType) + .collect(Collectors.toList()); } ! ! private List<TypeDesc> getTypeDescs(List<? extends TypeMirror> list) { ! return list.stream() ! .map(TypeDesc::fromType) ! .collect(Collectors.toList()); } ! ! public PubApi getCollectedPubApi() { ! return collectedApi; } }