1920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson/* 2920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Copyright (C) 2010 Google Inc. 3920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * 4920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Licensed under the Apache License, Version 2.0 (the "License"); 5920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * you may not use this file except in compliance with the License. 6920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * You may obtain a copy of the License at 7920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * 8920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * http://www.apache.org/licenses/LICENSE-2.0 9920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * 10920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Unless required by applicable law or agreed to in writing, software 11920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * distributed under the License is distributed on an "AS IS" BASIS, 12920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * See the License for the specific language governing permissions and 14920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * limitations under the License. 15920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 16920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 17920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpackage com.google.doclava; 18920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 19ed8f79791885c3ac15401d88a147aee551e1039eBrian Carlstromimport java.io.BufferedOutputStream; 20920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.io.File; 21920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.io.FileNotFoundException; 22ed8f79791885c3ac15401d88a147aee551e1039eBrian Carlstromimport java.io.FileOutputStream; 23920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.io.PrintStream; 24d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.ArrayList; 25d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.Arrays; 26d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.Collection; 27d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.Collections; 28d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.HashMap; 29d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.HashSet; 30d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.List; 31d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.Set; 32920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 33920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpublic class Stubs { 34970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton public static void writeStubsAndApi(String stubsDir, String apiFile, String keepListFile, 35920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson HashSet<String> stubPackages) { 36920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // figure out which classes we need 37040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final HashSet<ClassInfo> notStrippable = new HashSet<ClassInfo>(); 38920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo[] all = Converter.allClasses(); 39040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato PrintStream apiWriter = null; 40970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton PrintStream keepListWriter = null; 41040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (apiFile != null) { 42920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson try { 43040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato File xml = new File(apiFile); 44920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xml.getParentFile().mkdirs(); 45ed8f79791885c3ac15401d88a147aee551e1039eBrian Carlstrom apiWriter = new PrintStream(new BufferedOutputStream(new FileOutputStream(xml))); 46920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } catch (FileNotFoundException e) { 47040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Errors.error(Errors.IO_ERROR, new SourcePositionInfo(apiFile, 0, 0), 48920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson "Cannot open file for write."); 49920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 50920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 51970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (keepListFile != null) { 52970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton try { 53970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton File keepList = new File(keepListFile); 54970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepList.getParentFile().mkdirs(); 55970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter = new PrintStream(new BufferedOutputStream(new FileOutputStream(keepList))); 56970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } catch (FileNotFoundException e) { 57970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Errors.error(Errors.IO_ERROR, new SourcePositionInfo(keepListFile, 0, 0), 58970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton "Cannot open file for write."); 59970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 60970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 61920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // If a class is public or protected, not hidden, and marked as included, 62920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // then we can't strip it 63920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo cl : all) { 64920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.checkLevel() && cl.isIncluded()) { 65920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(cl, notStrippable, "0:0"); 66920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 67920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 68920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 69920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // complain about anything that looks includeable but is not supposed to 70920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // be written, e.g. hidden things 71920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo cl : notStrippable) { 72920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!cl.isHidden()) { 73d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (MethodInfo m : cl.selfMethods()) { 74920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (m.isHidden()) { 75920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(), "Reference to hidden method " 76920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + m.name()); 77920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else if (m.isDeprecated()) { 78920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // don't bother reporting deprecated methods 79920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // unless they are public 80920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.DEPRECATED, m.position(), "Method " + cl.qualifiedName() + "." 81920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + m.name() + " is deprecated"); 82920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 83920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 84920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo returnClass = m.returnType().asClassInfo(); 85920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (returnClass != null && returnClass.isHidden()) { 86920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(), "Method " + cl.qualifiedName() 87920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "." + m.name() + " returns unavailable type " + returnClass.name()); 88920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 89920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 90d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (ParameterInfo p : m.parameters()) { 91920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson TypeInfo t = p.type(); 92920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!t.isPrimitive()) { 93920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (t.asClassInfo().isHidden()) { 94920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(), "Parameter of hidden type " 95920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + t.fullName() + " in " + cl.qualifiedName() + "." + m.name() + "()"); 96920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 97920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 98920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 99920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 100920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 101920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // annotations are handled like methods 102d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (MethodInfo m : cl.annotationElements()) { 103920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (m.isHidden()) { 104920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(), "Reference to hidden annotation " 105920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + m.name()); 106920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 107920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 108920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo returnClass = m.returnType().asClassInfo(); 109920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (returnClass != null && returnClass.isHidden()) { 110920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(), "Annotation '" + m.name() 111920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "' returns unavailable type " + returnClass.name()); 112920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 114d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (ParameterInfo p : m.parameters()) { 115920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson TypeInfo t = p.type(); 116920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!t.isPrimitive()) { 117920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (t.asClassInfo().isHidden()) { 118920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.UNAVAILABLE_SYMBOL, p.position(), 119920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson "Reference to unavailable annotation class " + t.fullName()); 120920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 121920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 122920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 123920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else if (cl.isDeprecated()) { 125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // not hidden, but deprecated 126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.DEPRECATED, cl.position(), "Class " + cl.qualifiedName() 127920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " is deprecated"); 128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 130920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson HashMap<PackageInfo, List<ClassInfo>> packages = new HashMap<PackageInfo, List<ClassInfo>>(); 132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo cl : notStrippable) { 133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!cl.isDocOnly()) { 134920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (stubPackages == null || stubPackages.contains(cl.containingPackage().name())) { 135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // write out the stubs 136920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (stubsDir != null) { 137040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeClassFile(stubsDir, notStrippable, cl); 138920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 139970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton // build class list for api file or keep list file 140970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (apiWriter != null || keepListWriter != null) { 141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (packages.containsKey(cl.containingPackage())) { 142920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson packages.get(cl.containingPackage()).add(cl); 143920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 144920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ArrayList<ClassInfo> classes = new ArrayList<ClassInfo>(); 145920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson classes.add(cl); 146920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson packages.put(cl.containingPackage(), classes); 147920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 148920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 149920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 150920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 151920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 152920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 153040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // write out the Api 154040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (apiWriter != null) { 155040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeApi(apiWriter, packages, notStrippable); 156040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.close(); 157920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 158970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 159970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton // write out the keep list 160970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (keepListWriter != null) { 161970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeKeepList(keepListWriter, packages, notStrippable); 162970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.close(); 163970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 164920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 165920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 166920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson public static void cantStripThis(ClassInfo cl, HashSet<ClassInfo> notStrippable, String why) { 167920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 168920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!notStrippable.add(cl)) { 169920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // slight optimization: if it already contains cl, it already contains 170920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // all of cl's parents 171920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return; 172920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 173920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cl.setReasonIncluded(why); 174920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 175920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cant strip annotations 176920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /* 177920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * if (cl.annotations() != null){ for (AnnotationInstanceInfo ai : cl.annotations()){ if 178920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * (ai.type() != null){ cantStripThis(ai.type(), notStrippable, "1:" + cl.qualifiedName()); } } 179920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * } 180920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 181920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cant strip any public fields or their generics 182920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.allSelfFields() != null) { 183920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FieldInfo fInfo : cl.allSelfFields()) { 184920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fInfo.type() != null) { 185920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fInfo.type().asClassInfo() != null) { 186920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(fInfo.type().asClassInfo(), notStrippable, "2:" + cl.qualifiedName()); 187920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 188920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fInfo.type().typeArguments() != null) { 189920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo tTypeInfo : fInfo.type().typeArguments()) { 190920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (tTypeInfo.asClassInfo() != null) { 191920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(tTypeInfo.asClassInfo(), notStrippable, "3:" + cl.qualifiedName()); 192920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 193920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 194920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 195920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 196920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 197920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 198920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cant strip any of the type's generics 199920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.asTypeInfo() != null) { 200920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.asTypeInfo().typeArguments() != null) { 201920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo tInfo : cl.asTypeInfo().typeArguments()) { 202920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (tInfo.asClassInfo() != null) { 203920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(tInfo.asClassInfo(), notStrippable, "4:" + cl.qualifiedName()); 204920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 205920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 206920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 207920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 208920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cant strip any of the annotation elements 209920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cantStripThis(cl.annotationElements(), notStrippable); 210920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // take care of methods 211920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(cl.allSelfMethods(), notStrippable); 212920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(cl.allConstructors(), notStrippable); 213920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // blow the outer class open if this is an inner class 214920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.containingClass() != null) { 215920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(cl.containingClass(), notStrippable, "5:" + cl.qualifiedName()); 216920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 217920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // blow open super class and interfaces 218920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo supr = cl.realSuperclass(); 219920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (supr != null) { 220920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (supr.isHidden()) { 221920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cl is a public class declared as extending a hidden superclass. 222920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // this is not a desired practice but it's happened, so we deal 223920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // with it by stripping off the superclass relation for purposes of 224920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // generating the doc & stub information, and proceeding normally. 225920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cl.init(cl.asTypeInfo(), cl.realInterfaces(), cl.realInterfaceTypes(), cl.innerClasses(), 226920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cl.allConstructors(), cl.allSelfMethods(), cl.annotationElements(), cl.allSelfFields(), 227920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cl.enumConstants(), cl.containingPackage(), cl.containingClass(), null, null, cl 228920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson .annotations()); 229920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.HIDDEN_SUPERCLASS, cl.position(), "Public class " + cl.qualifiedName() 230920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " stripped of unavailable superclass " + supr.qualifiedName()); 231920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 232920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(supr, notStrippable, "6:" + cl.realSuperclass().name() + cl.qualifiedName()); 233920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 234920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 235920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 236920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 237d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private static void cantStripThis(ArrayList<MethodInfo> mInfos, HashSet<ClassInfo> notStrippable) { 238920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // for each method, blow open the parameters, throws and return types. also blow open their 239920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // generics 240920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mInfos != null) { 241920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo mInfo : mInfos) { 242920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mInfo.getTypeParameters() != null) { 243920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo tInfo : mInfo.getTypeParameters()) { 244920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (tInfo.asClassInfo() != null) { 245920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(tInfo.asClassInfo(), notStrippable, "8:" 246920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); 247920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 248920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 249920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 250920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mInfo.parameters() != null) { 251920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ParameterInfo pInfo : mInfo.parameters()) { 252920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pInfo.type() != null && pInfo.type().asClassInfo() != null) { 253920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(pInfo.type().asClassInfo(), notStrippable, "9:" 254920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); 255920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pInfo.type().typeArguments() != null) { 256920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo tInfoType : pInfo.type().typeArguments()) { 257920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (tInfoType.asClassInfo() != null) { 258920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo tcl = tInfoType.asClassInfo(); 259920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (tcl.isHidden()) { 260920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors 261920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson .error(Errors.UNAVAILABLE_SYMBOL, mInfo.position(), 262920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson "Parameter of hidden type " + tInfoType.fullName() + " in " 263920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.containingClass().qualifiedName() + '.' + mInfo.name() 264920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "()"); 265920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 266920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(tcl, notStrippable, "10:" 267920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); 268920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 269920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 270920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 271920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 272920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 273920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 274920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 275920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo thrown : mInfo.thrownExceptions()) { 276920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(thrown, notStrippable, "11:" + mInfo.realContainingClass().qualifiedName() 277920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ":" + mInfo.name()); 278920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 279920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mInfo.returnType() != null && mInfo.returnType().asClassInfo() != null) { 280920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(mInfo.returnType().asClassInfo(), notStrippable, "12:" 281920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); 282920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mInfo.returnType().typeArguments() != null) { 283920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo tyInfo : mInfo.returnType().typeArguments()) { 284920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (tyInfo.asClassInfo() != null) { 285920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(tyInfo.asClassInfo(), notStrippable, "13:" 286920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); 287920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 288920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 289920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 290920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 291920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 292920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 293920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 294920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 295920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static String javaFileName(ClassInfo cl) { 296920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String dir = ""; 297920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson PackageInfo pkg = cl.containingPackage(); 298920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pkg != null) { 299920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson dir = pkg.name(); 300920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson dir = dir.replace('.', '/') + '/'; 301920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 302920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return dir + cl.name() + ".java"; 303920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 304920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 305040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeClassFile(String stubsDir, HashSet<ClassInfo> notStrippable, ClassInfo cl) { 306920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // inner classes are written by their containing class 307920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.containingClass() != null) { 308920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return; 309920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 310920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 311920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Work around the bogus "Array" class we invent for 312920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505) 313920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.containingPackage() != null 314920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson && cl.containingPackage().name().equals(PackageInfo.DEFAULT_PACKAGE)) { 315920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return; 316920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 317920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 318920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String filename = stubsDir + '/' + javaFileName(cl); 319920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson File file = new File(filename); 320920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClearPage.ensureDirectory(file); 321920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 322920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson PrintStream stream = null; 323920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson try { 324ed8f79791885c3ac15401d88a147aee551e1039eBrian Carlstrom stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(file))); 325040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeClassFile(stream, notStrippable, cl); 326920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } catch (FileNotFoundException e) { 327920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson System.err.println("error writing file: " + filename); 328920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } finally { 329920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (stream != null) { 330920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.close(); 331920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 332920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 333920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 334920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 335040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeClassFile(PrintStream stream, HashSet<ClassInfo> notStrippable, ClassInfo cl) { 336920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson PackageInfo pkg = cl.containingPackage(); 337920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pkg != null) { 338920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println("package " + pkg.name() + ";"); 339920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 340040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeClass(stream, notStrippable, cl); 341920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 342920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 343040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeClass(PrintStream stream, HashSet<ClassInfo> notStrippable, ClassInfo cl) { 34473934887ea87fca353449f0fd476d6c07b349521Tor Norbye writeAnnotations(stream, cl.annotations(), cl.isDeprecated()); 345920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 346920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(cl.scope() + " "); 347920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isAbstract() && !cl.isAnnotation() && !cl.isInterface()) { 348920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("abstract "); 349920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 350920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isStatic()) { 351920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("static "); 352920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 353920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isFinal() && !cl.isEnum()) { 354920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("final "); 355920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 356920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (false) { 357920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("strictfp "); 358920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 359920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 360920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson HashSet<String> classDeclTypeVars = new HashSet(); 361920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String leafName = cl.asTypeInfo().fullName(classDeclTypeVars); 362920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int bracket = leafName.indexOf('<'); 363920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (bracket < 0) bracket = leafName.length() - 1; 364920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int period = leafName.lastIndexOf('.', bracket); 365920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (period < 0) period = -1; 366920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson leafName = leafName.substring(period + 1); 367920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 368920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String kind = cl.kind(); 369920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(kind + " " + leafName); 370920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 371920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson TypeInfo base = cl.superclassType(); 372920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 373920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!"enum".equals(kind)) { 374920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (base != null && !"java.lang.Object".equals(base.qualifiedTypeName())) { 375920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(" extends " + base.fullName(classDeclTypeVars)); 376920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 377920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 378920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 379920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<TypeInfo> usedInterfaces = new ArrayList<TypeInfo>(); 380d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (TypeInfo iface : cl.realInterfaceTypes()) { 381920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (notStrippable.contains(iface.asClassInfo()) && !iface.asClassInfo().isDocOnly()) { 382920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson usedInterfaces.add(iface); 383920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 384920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 385920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (usedInterfaces.size() > 0 && !cl.isAnnotation()) { 386920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // can java annotations extend other ones? 387920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isInterface() || cl.isAnnotation()) { 388920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" extends "); 389920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 390920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" implements "); 391920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 392920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String comma = ""; 393920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo iface : usedInterfaces) { 394920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(comma + iface.fullName(classDeclTypeVars)); 395920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson comma = ", "; 396920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 397920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(); 398920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 399920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 400920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println("{"); 401920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 402d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<FieldInfo> enumConstants = cl.enumConstants(); 403d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int N = enumConstants.size(); 404d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int i = 0; 405d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (FieldInfo field : enumConstants) { 406920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!field.constantLiteralValue().equals("null")) { 407920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(field.name() + "(" + field.constantLiteralValue() 408920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + (i == N - 1 ? ");" : "),")); 409920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 410920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(field.name() + "(" + (i == N - 1 ? ");" : "),")); 411920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 412d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein i++; 413920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 414920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 415920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo inner : cl.getRealInnerClasses()) { 416920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (notStrippable.contains(inner) && !inner.isDocOnly()) { 417040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeClass(stream, notStrippable, inner); 418920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 419920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 420920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 421920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 422920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo method : cl.constructors()) { 423920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!method.isDocOnly()) { 424920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeMethod(stream, method, true); 425920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 426920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 427920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 428920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson boolean fieldNeedsInitialization = false; 429920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson boolean staticFieldNeedsInitialization = false; 430920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FieldInfo field : cl.allSelfFields()) { 431920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!field.isDocOnly()) { 432920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!field.isStatic() && field.isFinal() && !fieldIsInitialized(field)) { 433920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson fieldNeedsInitialization = true; 434920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 435920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (field.isStatic() && field.isFinal() && !fieldIsInitialized(field)) { 436920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson staticFieldNeedsInitialization = true; 437920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 438920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 439920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 440920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 441920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // The compiler includes a default public constructor that calls the super classes 442920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // default constructor in the case where there are no written constructors. 443920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // So, if we hide all the constructors, java may put in a constructor 444920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // that calls a nonexistent super class constructor. So, if there are no constructors, 445920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // and the super class doesn't have a default constructor, write in a private constructor 446920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // that works. TODO -- we generate this as protected, but we really should generate 447920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // it as private unless it also exists in the real code. 448d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if ((cl.constructors().isEmpty() && (!cl.getNonWrittenConstructors().isEmpty() || fieldNeedsInitialization)) 449920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson && !cl.isAnnotation() && !cl.isInterface() && !cl.isEnum()) { 450920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Errors.error(Errors.HIDDEN_CONSTRUCTOR, 451920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cl.position(), "No constructors " + 452920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // "found and superclass has no parameterless constructor. A constructor " + 453920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // "that calls an appropriate superclass constructor " + 454920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // "was automatically written to stubs.\n"); 455920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(cl.leafName() + "() { " + superCtorCall(cl, null) + "throw new" 456920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " RuntimeException(\"Stub!\"); }"); 457920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 458920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 459920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo method : cl.allSelfMethods()) { 460920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isEnum()) { 461920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (("values".equals(method.name()) && "()".equals(method.signature())) 462920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson || ("valueOf".equals(method.name()) && "(java.lang.String)".equals(method.signature()))) { 463920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // skip these two methods on enums, because they're synthetic, 464920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // although for some reason javadoc doesn't mark them as synthetic, 465920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // maybe because they still want them documented 466920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 467920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 468920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 469920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!method.isDocOnly()) { 470920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeMethod(stream, method, false); 471920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 472920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 473920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Write all methods that are hidden, but override abstract methods or interface methods. 474920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // These can't be hidden. 475920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo method : cl.getHiddenMethods()) { 476920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson MethodInfo overriddenMethod = 477920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson method.findRealOverriddenMethod(method.name(), method.signature(), notStrippable); 478920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo classContainingMethod = 479920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson method.findRealOverriddenClass(method.name(), method.signature()); 480920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (overriddenMethod != null && !overriddenMethod.isHidden() && !overriddenMethod.isDocOnly() 481920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson && (overriddenMethod.isAbstract() || overriddenMethod.containingClass().isInterface())) { 482920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson method.setReason("1:" + classContainingMethod.qualifiedName()); 483920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cl.addMethod(method); 484920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeMethod(stream, method, false); 485920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 486920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 487920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 488920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo element : cl.annotationElements()) { 489920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!element.isDocOnly()) { 490920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeAnnotationElement(stream, element); 491920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 492920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 493920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 494920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FieldInfo field : cl.allSelfFields()) { 495920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!field.isDocOnly()) { 496920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeField(stream, field); 497920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 498920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 499920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 500920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (staticFieldNeedsInitialization) { 501920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("static { "); 502920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FieldInfo field : cl.allSelfFields()) { 503920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!field.isDocOnly() && field.isStatic() && field.isFinal() && !fieldIsInitialized(field) 504920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson && field.constantValue() == null) { 505920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(field.name() + " = " + field.type().defaultValue() + "; "); 506920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 507920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 508920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println("}"); 509920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 510920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 511920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println("}"); 512920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 513920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 514920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 515920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeMethod(PrintStream stream, MethodInfo method, boolean isConstructor) { 516920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String comma; 517920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 51873934887ea87fca353449f0fd476d6c07b349521Tor Norbye writeAnnotations(stream, method.annotations(), method.isDeprecated()); 51973934887ea87fca353449f0fd476d6c07b349521Tor Norbye 520920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(method.scope() + " "); 521920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isStatic()) { 522920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("static "); 523920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 524920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isFinal()) { 525920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("final "); 526920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 527920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isAbstract()) { 528920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("abstract "); 529920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 530920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isSynchronized()) { 531920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("synchronized "); 532920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 533920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isNative()) { 534920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("native "); 535920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 536920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (false /* method.isStictFP() */) { 537920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("strictfp "); 538920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 539920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 540920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(method.typeArgumentsName(new HashSet()) + " "); 541920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 542920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!isConstructor) { 543920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(method.returnType().fullName(method.typeVariables()) + " "); 544920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 545920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String n = method.name(); 546920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int pos = n.lastIndexOf('.'); 547920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pos >= 0) { 548920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson n = n.substring(pos + 1); 549920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 550920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(n + "("); 551920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson comma = ""; 552920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int count = 1; 553d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int size = method.parameters().size(); 554920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ParameterInfo param : method.parameters()) { 555920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(comma + fullParameterTypeName(method, param.type(), count == size) + " " 556920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + param.name()); 557920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson comma = ", "; 558920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson count++; 559920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 560920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(")"); 561920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 562920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson comma = ""; 563d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (method.thrownExceptions().size() > 0) { 564920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" throws "); 565920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo thrown : method.thrownExceptions()) { 566920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(comma + thrown.qualifiedName()); 567920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson comma = ", "; 568920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 569920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 570920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isAbstract() || method.isNative() || method.containingClass().isInterface()) { 571920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(";"); 572920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 573920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" { "); 574920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (isConstructor) { 575920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(superCtorCall(method.containingClass(), method.thrownExceptions())); 576920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 577920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println("throw new RuntimeException(\"Stub!\"); }"); 578920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 579920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 580920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 581920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeField(PrintStream stream, FieldInfo field) { 58273934887ea87fca353449f0fd476d6c07b349521Tor Norbye writeAnnotations(stream, field.annotations(), field.isDeprecated()); 58373934887ea87fca353449f0fd476d6c07b349521Tor Norbye 584920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(field.scope() + " "); 585920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (field.isStatic()) { 586920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("static "); 587920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 588920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (field.isFinal()) { 589920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("final "); 590920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 591920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (field.isTransient()) { 592920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("transient "); 593920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 594920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (field.isVolatile()) { 595920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("volatile "); 596920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 597920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 598920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(field.type().fullName()); 599920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" "); 600920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(field.name()); 601920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 602920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fieldIsInitialized(field)) { 603920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" = " + field.constantLiteralValue()); 604920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 605920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 606920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(";"); 607920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 608920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 609920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static boolean fieldIsInitialized(FieldInfo field) { 610920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return (field.isFinal() && field.constantValue() != null) 611920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson || !field.type().dimension().equals("") || field.containingClass().isInterface(); 612920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 613920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 614920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Returns 'true' if the method is an @Override of a visible parent 615920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // method implementation, and thus does not affect the API. 616040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static boolean methodIsOverride(HashSet<ClassInfo> notStrippable, MethodInfo mi) { 617920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Abstract/static/final methods are always listed in the API description 618920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mi.isAbstract() || mi.isStatic() || mi.isFinal()) { 619920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return false; 620920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 621920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 622920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Find any relevant ancestor declaration and inspect it 623920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson MethodInfo om = mi.findSuperclassImplementation(notStrippable); 624920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (om != null) { 625920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Visibility mismatch is an API change, so check for it 626920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mi.mIsPrivate == om.mIsPrivate && mi.mIsPublic == om.mIsPublic 627920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson && mi.mIsProtected == om.mIsProtected) { 628920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Look only for overrides of an ancestor class implementation, 629920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // not of e.g. an abstract or interface method declaration 630920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!om.isAbstract()) { 631920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // If the parent is hidden, we can't rely on it to provide 632920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // the API 633920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!om.isHidden()) { 634920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // If the only "override" turns out to be in our own class 635920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // (which sometimes happens in concrete subclasses of 636920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // abstract base classes), it's not really an override 637920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!mi.mContainingClass.equals(om.mContainingClass)) { 638920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return true; 639920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 640920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 641920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 642920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 643920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 644920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return false; 645920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 646920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 647920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static boolean canCallMethod(ClassInfo from, MethodInfo m) { 648920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (m.isPublic() || m.isProtected()) { 649920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return true; 650920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 651920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (m.isPackagePrivate()) { 652920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String fromPkg = from.containingPackage().name(); 653920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String pkg = m.containingClass().containingPackage().name(); 654920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fromPkg.equals(pkg)) { 655920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return true; 656920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 657920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 658920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return false; 659920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 660920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 661920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // call a constructor, any constructor on this class's superclass. 662d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein static String superCtorCall(ClassInfo cl, ArrayList<ClassInfo> thrownExceptions) { 663920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo base = cl.realSuperclass(); 664920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (base == null) { 665920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return ""; 666920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 667920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson HashSet<String> exceptionNames = new HashSet<String>(); 668920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (thrownExceptions != null) { 669920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo thrown : thrownExceptions) { 670920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson exceptionNames.add(thrown.name()); 671920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 672920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 673d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<MethodInfo> ctors = base.constructors(); 674920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson MethodInfo ctor = null; 675920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // bad exception indicates that the exceptions thrown by the super constructor 676920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // are incompatible with the constructor we're using for the sub class. 677920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Boolean badException = false; 678920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo m : ctors) { 679920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (canCallMethod(cl, m)) { 680920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (m.thrownExceptions() != null) { 681920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo thrown : m.thrownExceptions()) { 682920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!exceptionNames.contains(thrown.name())) { 683920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson badException = true; 684920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 685920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 686920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 687920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (badException) { 688920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson badException = false; 689920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 690920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 691920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // if it has no args, we're done 692d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (m.parameters().isEmpty()) { 693920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return ""; 694920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 695920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ctor = m; 696920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 697920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 698920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (ctor != null) { 699920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String result = ""; 700920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "super("; 701d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ParameterInfo> params = ctor.parameters(); 702d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (ParameterInfo param : params) { 703d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein TypeInfo t = param.type(); 704920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (t.isPrimitive() && t.dimension().equals("")) { 705920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String n = t.simpleTypeName(); 706920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (("byte".equals(n) || "short".equals(n) || "int".equals(n) || "long".equals(n) 707920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson || "float".equals(n) || "double".equals(n)) 708920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson && t.dimension().equals("")) { 709920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "0"; 710920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else if ("char".equals(n)) { 711920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "'\\0'"; 712920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else if ("boolean".equals(n)) { 713920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "false"; 714920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 715920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "<<unknown-" + n + ">>"; 716920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 717920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 718920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // put null in each super class method. Cast null to the correct type 719920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // to avoid collisions with other constructors. If the type is generic 720920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // don't cast it 721920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += 722920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson (!t.isTypeVariable() ? "(" + t.qualifiedTypeName() + t.dimension() + ")" : "") 723920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "null"; 724920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 725d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (param != params.get(params.size()-1)) { 726920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += ","; 727920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 728920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 729920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "); "; 730920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return result; 731920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 732920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return ""; 733920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 734920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 735920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 73673934887ea87fca353449f0fd476d6c07b349521Tor Norbye /** 73773934887ea87fca353449f0fd476d6c07b349521Tor Norbye * Write out the given list of annotations. If the {@code isDeprecated} 73873934887ea87fca353449f0fd476d6c07b349521Tor Norbye * flag is true also write out a {@code @Deprecated} annotation if it did not 73973934887ea87fca353449f0fd476d6c07b349521Tor Norbye * already appear in the list of annotations. (This covers APIs that mention 74073934887ea87fca353449f0fd476d6c07b349521Tor Norbye * {@code @deprecated} in their documentation but fail to add 74173934887ea87fca353449f0fd476d6c07b349521Tor Norbye * {@code @Deprecated} as an annotation. 74273934887ea87fca353449f0fd476d6c07b349521Tor Norbye * <p> 74373934887ea87fca353449f0fd476d6c07b349521Tor Norbye * {@code @Override} annotations are deliberately skipped. 74473934887ea87fca353449f0fd476d6c07b349521Tor Norbye */ 74573934887ea87fca353449f0fd476d6c07b349521Tor Norbye static void writeAnnotations(PrintStream stream, List<AnnotationInstanceInfo> annotations, 74673934887ea87fca353449f0fd476d6c07b349521Tor Norbye boolean isDeprecated) { 74773934887ea87fca353449f0fd476d6c07b349521Tor Norbye assert annotations != null; 748920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (AnnotationInstanceInfo ann : annotations) { 74973934887ea87fca353449f0fd476d6c07b349521Tor Norbye // Skip @Override annotations: the stubs do not need it and in some cases it leads 75073934887ea87fca353449f0fd476d6c07b349521Tor Norbye // to compilation errors with the way the stubs are generated 75173934887ea87fca353449f0fd476d6c07b349521Tor Norbye if (ann.type() != null && ann.type().qualifiedName().equals("java.lang.Override")) { 75273934887ea87fca353449f0fd476d6c07b349521Tor Norbye continue; 75373934887ea87fca353449f0fd476d6c07b349521Tor Norbye } 754920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!ann.type().isHidden()) { 755920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(ann.toString()); 75673934887ea87fca353449f0fd476d6c07b349521Tor Norbye if (isDeprecated && ann.type() != null 75773934887ea87fca353449f0fd476d6c07b349521Tor Norbye && ann.type().qualifiedName().equals("java.lang.Deprecated")) { 75873934887ea87fca353449f0fd476d6c07b349521Tor Norbye isDeprecated = false; // Prevent duplicate annotations 75973934887ea87fca353449f0fd476d6c07b349521Tor Norbye } 760920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 761920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 76273934887ea87fca353449f0fd476d6c07b349521Tor Norbye if (isDeprecated) { 76373934887ea87fca353449f0fd476d6c07b349521Tor Norbye stream.println("@Deprecated"); 76473934887ea87fca353449f0fd476d6c07b349521Tor Norbye } 765920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 766920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 767920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeAnnotationElement(PrintStream stream, MethodInfo ann) { 768920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(ann.returnType().fullName()); 769920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" "); 770920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(ann.name()); 771920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("()"); 772920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson AnnotationValueInfo def = ann.defaultAnnotationElementValue(); 773920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (def != null) { 774920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" default "); 775920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(def.valueString()); 776920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 777920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(";"); 778920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 779920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 780920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeXML(PrintStream xmlWriter, HashMap<PackageInfo, List<ClassInfo>> allClasses, 781040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato HashSet<ClassInfo> notStrippable) { 782920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // extract the set of packages, sort them by name, and write them out in that order 783920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Set<PackageInfo> allClassKeys = allClasses.keySet(); 784920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson PackageInfo[] allPackages = allClassKeys.toArray(new PackageInfo[allClassKeys.size()]); 785920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Arrays.sort(allPackages, PackageInfo.comparator); 786920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 787920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<api>"); 788920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (PackageInfo pack : allPackages) { 789920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writePackageXML(xmlWriter, pack, allClasses.get(pack), notStrippable); 790920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 791920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</api>"); 792920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 793920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 794040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public static void writeXml(PrintStream xmlWriter, Collection<PackageInfo> pkgs) { 795040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final PackageInfo[] packages = pkgs.toArray(new PackageInfo[pkgs.size()]); 796040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Arrays.sort(packages, PackageInfo.comparator); 797040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 798040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato HashSet<ClassInfo> notStrippable = new HashSet(); 799040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (PackageInfo pkg: packages) { 800040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (ClassInfo cl: pkg.allClasses().values()) { 801040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato notStrippable.add(cl); 802040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 803040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 804040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato xmlWriter.println("<api>"); 805040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (PackageInfo pkg: packages) { 806040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writePackageXML(xmlWriter, pkg, pkg.allClasses().values(), notStrippable); 807040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 808040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato xmlWriter.println("</api>"); 809040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 810040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 811040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writePackageXML(PrintStream xmlWriter, PackageInfo pack, 812040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Collection<ClassInfo> classList, HashSet<ClassInfo> notStrippable) { 813920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo[] classes = classList.toArray(new ClassInfo[classList.size()]); 814920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Arrays.sort(classes, ClassInfo.comparator); 815920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Work around the bogus "Array" class we invent for 816920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505) 817920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pack.name().equals(PackageInfo.DEFAULT_PACKAGE)) { 818920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return; 819920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 820920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<package name=\"" + pack.name() + "\"\n" 821920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // + " source=\"" + pack.position() + "\"\n" 822920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ">"); 823920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo cl : classes) { 824920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeClassXML(xmlWriter, cl, notStrippable); 825920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 826920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</package>"); 827920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 828920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 829920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 830920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 831040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeClassXML(PrintStream xmlWriter, ClassInfo cl, HashSet<ClassInfo> notStrippable) { 832920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String scope = cl.scope(); 833920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String deprecatedString = ""; 834920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String declString = (cl.isInterface()) ? "interface" : "class"; 835920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isDeprecated()) { 836920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "deprecated"; 837920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 838920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "not deprecated"; 839920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 840920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<" + declString + " name=\"" + cl.name() + "\""); 841920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!cl.isInterface() && !cl.qualifiedName().equals("java.lang.Object")) { 842920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println(" extends=\"" 843920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ((cl.realSuperclass() == null) ? "java.lang.Object" : cl.realSuperclass() 844920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson .qualifiedName()) + "\""); 845920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 846920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println(" abstract=\"" + cl.isAbstract() + "\"\n" + " static=\"" + cl.isStatic() 847920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "\"\n" + " final=\"" + cl.isFinal() + "\"\n" + " deprecated=\"" + deprecatedString 848920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "\"\n" + " visibility=\"" + scope + "\"\n" 849920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // + " source=\"" + cl.position() + "\"\n" 850920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ">"); 851920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 852d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ClassInfo> interfaces = cl.realInterfaces(); 853d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(interfaces, ClassInfo.comparator); 854920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo iface : interfaces) { 855920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (notStrippable.contains(iface)) { 856920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<implements name=\"" + iface.qualifiedName() + "\">"); 857920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</implements>"); 858920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 859920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 860920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 861d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<MethodInfo> constructors = cl.constructors(); 862d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(constructors, MethodInfo.comparator); 863920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo mi : constructors) { 864920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeConstructorXML(xmlWriter, mi); 865920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 866920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 867d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<MethodInfo> methods = cl.allSelfMethods(); 868d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(methods, MethodInfo.comparator); 869920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo mi : methods) { 870040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!methodIsOverride(notStrippable, mi)) { 871920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeMethodXML(xmlWriter, mi); 872920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 873920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 874920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 875d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<FieldInfo> fields = cl.allSelfFields(); 876d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(fields, FieldInfo.comparator); 877920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FieldInfo fi : fields) { 878920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeFieldXML(xmlWriter, fi); 879920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 880920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</" + declString + ">"); 881920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 882920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 883920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 884920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeMethodXML(PrintStream xmlWriter, MethodInfo mi) { 885920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String scope = mi.scope(); 886920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 887920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String deprecatedString = ""; 888920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mi.isDeprecated()) { 889920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "deprecated"; 890920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 891920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "not deprecated"; 892920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 893920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<method name=\"" 894920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mi.name() 895920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "\"\n" 896920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ((mi.returnType() != null) ? " return=\"" 897920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + makeXMLcompliant(fullParameterTypeName(mi, mi.returnType(), false)) + "\"\n" : "") 898920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " abstract=\"" + mi.isAbstract() + "\"\n" + " native=\"" + mi.isNative() + "\"\n" 899920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " synchronized=\"" + mi.isSynchronized() + "\"\n" + " static=\"" + mi.isStatic() + "\"\n" 900920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " final=\"" + mi.isFinal() + "\"\n" + " deprecated=\"" + deprecatedString + "\"\n" 901920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " visibility=\"" + scope + "\"\n" 902920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // + " source=\"" + mi.position() + "\"\n" 903920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ">"); 904920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 905920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // write parameters in declaration order 906d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int numParameters = mi.parameters().size(); 907920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int count = 0; 908920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ParameterInfo pi : mi.parameters()) { 909920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson count++; 910920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeParameterXML(xmlWriter, mi, pi, count == numParameters); 911920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 912920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 913920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // but write exceptions in canonicalized order 914d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ClassInfo> exceptions = mi.thrownExceptions(); 915d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(exceptions, ClassInfo.comparator); 916920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo pi : exceptions) { 917920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<exception name=\"" + pi.name() + "\" type=\"" + pi.qualifiedName() 918920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "\">"); 919920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</exception>"); 920920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 921920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</method>"); 922920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 923920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 924920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeConstructorXML(PrintStream xmlWriter, MethodInfo mi) { 925920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String scope = mi.scope(); 926920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String deprecatedString = ""; 927920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mi.isDeprecated()) { 928920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "deprecated"; 929920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 930920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "not deprecated"; 931920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 932920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<constructor name=\"" + mi.name() + "\"\n" + " type=\"" 933920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mi.containingClass().qualifiedName() + "\"\n" + " static=\"" + mi.isStatic() + "\"\n" 934920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " final=\"" + mi.isFinal() + "\"\n" + " deprecated=\"" + deprecatedString + "\"\n" 935920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " visibility=\"" + scope + "\"\n" 936920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // + " source=\"" + mi.position() + "\"\n" 937920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ">"); 938920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 939d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int numParameters = mi.parameters().size(); 940920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int count = 0; 941920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ParameterInfo pi : mi.parameters()) { 942920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson count++; 943920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeParameterXML(xmlWriter, mi, pi, count == numParameters); 944920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 945920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 946d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ClassInfo> exceptions = mi.thrownExceptions(); 947d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(exceptions, ClassInfo.comparator); 948920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo pi : exceptions) { 949920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<exception name=\"" + pi.name() + "\" type=\"" + pi.qualifiedName() 950920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "\">"); 951920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</exception>"); 952920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 953920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</constructor>"); 954920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 955920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 956920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeParameterXML(PrintStream xmlWriter, MethodInfo method, ParameterInfo pi, 957920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson boolean isLast) { 958920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<parameter name=\"" + pi.name() + "\" type=\"" 959920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + makeXMLcompliant(fullParameterTypeName(method, pi.type(), isLast)) + "\">"); 960920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</parameter>"); 961920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 962920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 963920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeFieldXML(PrintStream xmlWriter, FieldInfo fi) { 964920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String scope = fi.scope(); 965920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String deprecatedString = ""; 966920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fi.isDeprecated()) { 967920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "deprecated"; 968920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 969920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "not deprecated"; 970920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 971920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // need to make sure value is valid XML 972920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String value = makeXMLcompliant(fi.constantLiteralValue()); 973920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 974920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String fullTypeName = makeXMLcompliant(fi.type().qualifiedTypeName()) + fi.type().dimension(); 975920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 976920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<field name=\"" + fi.name() + "\"\n" + " type=\"" + fullTypeName + "\"\n" 977920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " transient=\"" + fi.isTransient() + "\"\n" + " volatile=\"" + fi.isVolatile() + "\"\n" 978920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + (fieldIsInitialized(fi) ? " value=\"" + value + "\"\n" : "") + " static=\"" 979920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + fi.isStatic() + "\"\n" + " final=\"" + fi.isFinal() + "\"\n" + " deprecated=\"" 980920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + deprecatedString + "\"\n" + " visibility=\"" + scope + "\"\n" 981920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // + " source=\"" + fi.position() + "\"\n" 982920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ">"); 983920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</field>"); 984920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 985920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 986920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static String makeXMLcompliant(String s) { 987920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String returnString = ""; 988920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson returnString = s.replaceAll("&", "&"); 989920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson returnString = returnString.replaceAll("<", "<"); 990920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson returnString = returnString.replaceAll(">", ">"); 991920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson returnString = returnString.replaceAll("\"", """); 992920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson returnString = returnString.replaceAll("'", "&pos;"); 993920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return returnString; 994920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 995920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 996040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public static void writeApi(PrintStream apiWriter, Collection<PackageInfo> pkgs) { 997040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final PackageInfo[] packages = pkgs.toArray(new PackageInfo[pkgs.size()]); 998040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Arrays.sort(packages, PackageInfo.comparator); 999040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1000040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato HashSet<ClassInfo> notStrippable = new HashSet(); 1001040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (PackageInfo pkg: packages) { 1002040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (ClassInfo cl: pkg.allClasses().values()) { 1003040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato notStrippable.add(cl); 1004040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1005040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1006040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (PackageInfo pkg: packages) { 1007040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writePackageApi(apiWriter, pkg, pkg.allClasses().values(), notStrippable); 1008040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1009040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1010040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1011040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeApi(PrintStream apiWriter, HashMap<PackageInfo, List<ClassInfo>> allClasses, 1012040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato HashSet<ClassInfo> notStrippable) { 1013040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // extract the set of packages, sort them by name, and write them out in that order 1014040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Set<PackageInfo> allClassKeys = allClasses.keySet(); 1015040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato PackageInfo[] allPackages = allClassKeys.toArray(new PackageInfo[allClassKeys.size()]); 1016040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Arrays.sort(allPackages, PackageInfo.comparator); 1017040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1018040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (PackageInfo pack : allPackages) { 1019040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writePackageApi(apiWriter, pack, allClasses.get(pack), notStrippable); 1020040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1021040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1022040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1023040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writePackageApi(PrintStream apiWriter, PackageInfo pack, 1024040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Collection<ClassInfo> classList, HashSet<ClassInfo> notStrippable) { 1025040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // Work around the bogus "Array" class we invent for 1026040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505) 1027040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (pack.name().equals(PackageInfo.DEFAULT_PACKAGE)) { 1028040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return; 1029040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1030040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1031040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print("package "); 1032040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(pack.qualifiedName()); 1033040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" {\n\n"); 1034040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1035040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato ClassInfo[] classes = classList.toArray(new ClassInfo[classList.size()]); 1036040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Arrays.sort(classes, ClassInfo.comparator); 1037040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (ClassInfo cl : classes) { 1038040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeClassApi(apiWriter, cl, notStrippable); 1039040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1040040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1041040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print("}\n\n"); 1042040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1043040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1044040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeClassApi(PrintStream apiWriter, ClassInfo cl, HashSet<ClassInfo> notStrippable) { 1045040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean first; 1046040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1047040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1048040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(cl.scope()); 1049040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (cl.isStatic()) { 1050040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" static"); 1051040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1052040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (cl.isFinal()) { 1053040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" final"); 1054040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1055040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (cl.isAbstract()) { 1056040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" abstract"); 1057040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1058040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (cl.isDeprecated()) { 1059040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" deprecated"); 1060040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1061040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1062040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(cl.isInterface() ? "interface" : "class"); 1063040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1064040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(cl.name()); 1065040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1066040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!cl.isInterface() 1067040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato && !"java.lang.Object".equals(cl.qualifiedName()) 1068040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato && cl.realSuperclass() != null 1069040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato && !"java.lang.Object".equals(cl.realSuperclass().qualifiedName())) { 1070040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" extends "); 1071040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(cl.realSuperclass().qualifiedName()); 1072040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1073040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1074d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ClassInfo> interfaces = cl.realInterfaces(); 1075d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(interfaces, ClassInfo.comparator); 1076040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato first = true; 1077040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (ClassInfo iface : interfaces) { 1078040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (notStrippable.contains(iface)) { 1079040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (first) { 1080040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" implements"); 1081040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato first = false; 1082040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1083040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1084040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(iface.qualifiedName()); 1085040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1086040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1087040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1088040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" {\n"); 1089040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1090d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<MethodInfo> constructors = cl.constructors(); 1091d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(constructors, MethodInfo.comparator); 1092040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (MethodInfo mi : constructors) { 1093040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeConstructorApi(apiWriter, mi); 1094040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1095040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1096d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<MethodInfo> methods = cl.allSelfMethods(); 1097d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(methods, MethodInfo.comparator); 1098040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (MethodInfo mi : methods) { 1099040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!methodIsOverride(notStrippable, mi)) { 1100040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeMethodApi(apiWriter, mi); 1101040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1102040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1103040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1104d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<FieldInfo> enums = cl.enumConstants(); 1105d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(enums, FieldInfo.comparator); 1106132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato for (FieldInfo fi : enums) { 1107132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato writeFieldApi(apiWriter, fi, "enum_constant"); 1108132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato } 1109132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato 1110d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<FieldInfo> fields = cl.allSelfFields(); 1111d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(fields, FieldInfo.comparator); 1112040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (FieldInfo fi : fields) { 1113132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato writeFieldApi(apiWriter, fi, "field"); 1114040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1115040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1116040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" }\n\n"); 1117040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1118040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1119040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeConstructorApi(PrintStream apiWriter, MethodInfo mi) { 1120040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" ctor "); 1121040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(mi.scope()); 1122040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isDeprecated()) { 1123040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" deprecated"); 1124040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1125040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1126040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(mi.name()); 1127040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1128040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeParametersApi(apiWriter, mi, mi.parameters()); 1129040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeThrowsApi(apiWriter, mi.thrownExceptions()); 1130040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(";\n"); 1131040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1132040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1133040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeMethodApi(PrintStream apiWriter, MethodInfo mi) { 1134040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" method "); 1135040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(mi.scope()); 1136040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isStatic()) { 1137040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" static"); 1138040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1139040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isFinal()) { 1140040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" final"); 1141040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1142040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isAbstract()) { 1143040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" abstract"); 1144040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1145040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isDeprecated()) { 1146040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" deprecated"); 1147040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1148040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isSynchronized()) { 1149040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" synchronized"); 1150040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1151040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1152040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.returnType() == null) { 1153040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print("void"); 1154040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 1155040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(fullParameterTypeName(mi, mi.returnType(), false)); 1156040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1157040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1158040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(mi.name()); 1159040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1160040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeParametersApi(apiWriter, mi, mi.parameters()); 1161040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeThrowsApi(apiWriter, mi.thrownExceptions()); 1162040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1163040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(";\n"); 1164040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1165040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1166d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein static void writeParametersApi(PrintStream apiWriter, MethodInfo method, ArrayList<ParameterInfo> params) { 1167040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print("("); 1168040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1169d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (ParameterInfo pi : params) { 1170d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (pi != params.get(0)) { 1171040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(", "); 1172040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1173d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein apiWriter.print(fullParameterTypeName(method, pi.type(), pi == params.get(params.size()-1))); 1174040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // turn on to write the names too 1175040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (false) { 1176040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1177040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(pi.name()); 1178040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1179040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1180040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1181040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(")"); 1182040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1183040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1184d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein static void writeThrowsApi(PrintStream apiWriter, ArrayList<ClassInfo> exceptions) { 1185040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // write in a canonical order 1186d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein exceptions = (ArrayList<ClassInfo>) exceptions.clone(); 1187d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(exceptions, ClassInfo.comparator); 1188d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein //final int N = exceptions.length; 1189040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean first = true; 1190d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (ClassInfo ex : exceptions) { 1191040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // Turn this off, b/c we need to regenrate the old xml files. 1192040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (true || !"java.lang.RuntimeException".equals(ex.qualifiedName()) 1193040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato && !ex.isDerivedFrom("java.lang.RuntimeException")) { 1194040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (first) { 1195040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" throws "); 1196040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato first = false; 1197040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 1198040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(", "); 1199040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1200040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(ex.qualifiedName()); 1201040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1202040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1203040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1204040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1205132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato static void writeFieldApi(PrintStream apiWriter, FieldInfo fi, String label) { 1206132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato apiWriter.print(" "); 1207132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato apiWriter.print(label); 1208132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato apiWriter.print(" "); 1209040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(fi.scope()); 1210040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isStatic()) { 1211040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" static"); 1212040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1213040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isFinal()) { 1214040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" final"); 1215040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1216040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isDeprecated()) { 1217040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" deprecated"); 1218040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1219040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isTransient()) { 1220040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" transient"); 1221040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1222040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isVolatile()) { 1223040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" volatile"); 1224040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1225040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1226040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1227040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(fi.type().qualifiedTypeName() + fi.type().dimension()); 1228040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1229040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1230040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(fi.name()); 1231040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1232040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Object val = null; 1233040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isConstant() && fieldIsInitialized(fi)) { 1234040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" = "); 1235040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(fi.constantLiteralValue()); 1236040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato val = fi.constantValue(); 1237040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1238040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1239040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(";"); 1240040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1241040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (val != null) { 1242040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (val instanceof Integer && "char".equals(fi.type().qualifiedTypeName())) { 1243040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.format(" // 0x%04x '%s'", val, 1244040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato FieldInfo.javaEscapeString("" + ((char)((Integer)val).intValue()))); 1245040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if (val instanceof Byte || val instanceof Short || val instanceof Integer) { 1246040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.format(" // 0x%x", val); 1247040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if (val instanceof Long) { 1248040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.format(" // 0x%xL", val); 1249040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1250040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1251040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1252040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print("\n"); 1253040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1254040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1255970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeKeepList(PrintStream keepListWriter, 1256970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton HashMap<PackageInfo, List<ClassInfo>> allClasses, HashSet<ClassInfo> notStrippable) { 1257970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton // extract the set of packages, sort them by name, and write them out in that order 1258970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Set<PackageInfo> allClassKeys = allClasses.keySet(); 1259970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton PackageInfo[] allPackages = allClassKeys.toArray(new PackageInfo[allClassKeys.size()]); 1260970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Arrays.sort(allPackages, PackageInfo.comparator); 1261970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1262970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (PackageInfo pack : allPackages) { 1263970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writePackageKeepList(keepListWriter, pack, allClasses.get(pack), notStrippable); 1264970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1265970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1266970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1267970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writePackageKeepList(PrintStream keepListWriter, PackageInfo pack, 1268970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Collection<ClassInfo> classList, HashSet<ClassInfo> notStrippable) { 1269970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton // Work around the bogus "Array" class we invent for 1270970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505) 1271970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (pack.name().equals(PackageInfo.DEFAULT_PACKAGE)) { 1272970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton return; 1273970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1274970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1275970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton ClassInfo[] classes = classList.toArray(new ClassInfo[classList.size()]); 1276970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Arrays.sort(classes, ClassInfo.comparator); 1277970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (ClassInfo cl : classes) { 1278970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeClassKeepList(keepListWriter, cl, notStrippable); 1279970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1280970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1281970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1282970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeClassKeepList(PrintStream keepListWriter, ClassInfo cl, 1283970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton HashSet<ClassInfo> notStrippable) { 1284970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("-keep class "); 1285970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(to$Class(cl.qualifiedName())); 1286970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1287970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" {\n"); 1288970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1289970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton ArrayList<MethodInfo> constructors = cl.constructors(); 1290970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Collections.sort(constructors, MethodInfo.comparator); 1291970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (MethodInfo mi : constructors) { 1292970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeConstructorKeepList(keepListWriter, mi); 1293970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1294970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1295970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("\n"); 1296970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1297970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton ArrayList<MethodInfo> methods = cl.allSelfMethods(); 1298970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Collections.sort(methods, MethodInfo.comparator); 1299970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (MethodInfo mi : methods) { 1300970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (!methodIsOverride(notStrippable, mi)) { 1301970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeMethodKeepList(keepListWriter, mi); 1302970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1303970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1304970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1305970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("\n"); 1306970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1307970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton ArrayList<FieldInfo> enums = cl.enumConstants(); 1308970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Collections.sort(enums, FieldInfo.comparator); 1309970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (FieldInfo fi : enums) { 1310970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeFieldKeepList(keepListWriter, fi); 1311970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1312970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1313970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("\n"); 1314970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1315970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton ArrayList<FieldInfo> fields = cl.allSelfFields(); 1316970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Collections.sort(fields, FieldInfo.comparator); 1317970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (FieldInfo fi : fields) { 1318970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeFieldKeepList(keepListWriter, fi); 1319970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1320970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1321970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("}\n\n"); 1322970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1323970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1324970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeConstructorKeepList(PrintStream keepListWriter, MethodInfo mi) { 1325970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1326970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton String name = mi.name(); 1327970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton name = name.replace(".", "$"); 1328970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(name); 1329970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1330970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeParametersKeepList(keepListWriter, mi, mi.parameters()); 1331970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(";\n"); 1332970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1333970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1334970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeMethodKeepList(PrintStream keepListWriter, MethodInfo mi) { 1335970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1336970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(mi.scope()); 1337970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (mi.isStatic()) { 1338970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" static"); 1339970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1340970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (mi.isAbstract()) { 1341970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" abstract"); 1342970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1343970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (mi.isSynchronized()) { 1344970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" synchronized"); 1345970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1346970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1347970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (mi.returnType() == null) { 1348970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("void"); 1349970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } else { 1350970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(getCleanTypeName(mi.returnType())); 1351970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1352970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1353970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(mi.name()); 1354970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1355970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeParametersKeepList(keepListWriter, mi, mi.parameters()); 1356970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1357970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(";\n"); 1358970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1359970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1360970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeParametersKeepList(PrintStream keepListWriter, MethodInfo method, 1361970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton ArrayList<ParameterInfo> params) { 1362970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("("); 1363970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1364970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (ParameterInfo pi : params) { 1365970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (pi != params.get(0)) { 1366970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(", "); 1367970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1368550a9de05d89f19d1f824fbbb04ba7cd8a1ff86eJeff Hamilton keepListWriter.print(getCleanTypeName(pi.type())); 1369970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1370970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1371970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(")"); 1372970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1373970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1374970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeFieldKeepList(PrintStream keepListWriter, FieldInfo fi) { 1375970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1376970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(fi.scope()); 1377970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (fi.isStatic()) { 1378970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" static"); 1379970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1380970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (fi.isTransient()) { 1381970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" transient"); 1382970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1383970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (fi.isVolatile()) { 1384970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" volatile"); 1385970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1386970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1387970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1388970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(getCleanTypeName(fi.type()) + fi.type().dimension()); 1389970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1390970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1391970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(fi.name()); 1392970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1393970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(";\n"); 1394970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1395970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1396920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static String fullParameterTypeName(MethodInfo method, TypeInfo type, boolean isLast) { 1397920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String fullTypeName = type.fullName(method.typeVariables()); 1398920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (isLast && method.isVarArgs()) { 1399920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // TODO: note that this does not attempt to handle hypothetical 1400920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // vararg methods whose last parameter is a list of arrays, e.g. 1401920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // "Object[]...". 1402920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson fullTypeName = type.fullNameNoDimension(method.typeVariables()) + "..."; 1403920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 1404920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return fullTypeName; 1405920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 1406970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1407970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static String to$Class(String name) { 1408970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton int pos = 0; 1409970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton while ((pos = name.indexOf('.', pos)) > 0) { 1410970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton String n = name.substring(0, pos); 1411970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (Converter.obtainClass(n) != null) { 1412970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton return n + (name.substring(pos).replace('.', '$')); 1413970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1414970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton pos = pos + 1; 1415970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1416970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton return name; 1417970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1418970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1419970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static String getCleanTypeName(TypeInfo t) { 1420d6f2c2b6edce46c86581be1f508981742e20fb51Jeff Hamilton return t.isPrimitive() ? t.simpleTypeName() + t.dimension() : 14211e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton to$Class(t.asClassInfo().qualifiedName() + t.dimension()); 1422970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1423920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson} 1424