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, 355118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu String removedApiFile, 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; 415118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu PrintStream removedApiWriter = null; 425118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 43040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (apiFile != null) { 44920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson try { 45040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato File xml = new File(apiFile); 46920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xml.getParentFile().mkdirs(); 47ed8f79791885c3ac15401d88a147aee551e1039eBrian Carlstrom apiWriter = new PrintStream(new BufferedOutputStream(new FileOutputStream(xml))); 48920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } catch (FileNotFoundException e) { 49040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Errors.error(Errors.IO_ERROR, new SourcePositionInfo(apiFile, 0, 0), 50920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson "Cannot open file for write."); 51920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 52920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 53970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (keepListFile != null) { 54970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton try { 55970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton File keepList = new File(keepListFile); 56970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepList.getParentFile().mkdirs(); 57970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter = new PrintStream(new BufferedOutputStream(new FileOutputStream(keepList))); 58970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } catch (FileNotFoundException e) { 59970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Errors.error(Errors.IO_ERROR, new SourcePositionInfo(keepListFile, 0, 0), 60970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton "Cannot open file for write."); 61970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 62970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 635118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (removedApiFile != null) { 645118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu try { 655118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu File removedApi = new File(removedApiFile); 665118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu removedApi.getParentFile().mkdirs(); 675118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu removedApiWriter = new PrintStream( 685118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu new BufferedOutputStream(new FileOutputStream(removedApi))); 695118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } catch (FileNotFoundException e) { 705118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu Errors.error(Errors.IO_ERROR, new SourcePositionInfo(removedApiFile, 0, 0), 715118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu "Cannot open file for write"); 725118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 735118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 74920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // If a class is public or protected, not hidden, and marked as included, 75920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // then we can't strip it 76920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo cl : all) { 77920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.checkLevel() && cl.isIncluded()) { 78920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(cl, notStrippable, "0:0"); 79920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 80920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 81920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 82920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // complain about anything that looks includeable but is not supposed to 83920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // be written, e.g. hidden things 84920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo cl : notStrippable) { 855118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (!cl.isHiddenOrRemoved()) { 86d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (MethodInfo m : cl.selfMethods()) { 875118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (m.isHiddenOrRemoved()) { 885118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(), "Reference to unavailable method " 89920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + m.name()); 90920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else if (m.isDeprecated()) { 91920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // don't bother reporting deprecated methods 92920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // unless they are public 93920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.DEPRECATED, m.position(), "Method " + cl.qualifiedName() + "." 94920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + m.name() + " is deprecated"); 95920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 96920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 97920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo returnClass = m.returnType().asClassInfo(); 985118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (returnClass != null && returnClass.isHiddenOrRemoved()) { 99920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(), "Method " + cl.qualifiedName() 100920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "." + m.name() + " returns unavailable type " + returnClass.name()); 101920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 102920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 103d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (ParameterInfo p : m.parameters()) { 104920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson TypeInfo t = p.type(); 105920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!t.isPrimitive()) { 1065118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (t.asClassInfo().isHiddenOrRemoved()) { 1075118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(), "Parameter of unavailable type " 108920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + t.fullName() + " in " + cl.qualifiedName() + "." + m.name() + "()"); 109920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 110920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 111920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 112920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 114920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // annotations are handled like methods 115d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (MethodInfo m : cl.annotationElements()) { 1165118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (m.isHiddenOrRemoved()) { 1175118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(), "Reference to unavailable annotation " 118920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + m.name()); 119920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 120920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 121920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo returnClass = m.returnType().asClassInfo(); 1225118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (returnClass != null && returnClass.isHiddenOrRemoved()) { 123920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(), "Annotation '" + m.name() 124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "' returns unavailable type " + returnClass.name()); 125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 127d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (ParameterInfo p : m.parameters()) { 128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson TypeInfo t = p.type(); 129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!t.isPrimitive()) { 1305118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (t.asClassInfo().isHiddenOrRemoved()) { 131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.UNAVAILABLE_SYMBOL, p.position(), 132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson "Reference to unavailable annotation class " + t.fullName()); 133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 134920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 136920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 137920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else if (cl.isDeprecated()) { 138920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // not hidden, but deprecated 139920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.DEPRECATED, cl.position(), "Class " + cl.qualifiedName() 140920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " is deprecated"); 141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 142920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 143920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 1445118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu // packages contains all the notStrippable classes mapped by their containing packages 145920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson HashMap<PackageInfo, List<ClassInfo>> packages = new HashMap<PackageInfo, List<ClassInfo>>(); 146920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo cl : notStrippable) { 147920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!cl.isDocOnly()) { 148920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (stubPackages == null || stubPackages.contains(cl.containingPackage().name())) { 149920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // write out the stubs 150920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (stubsDir != null) { 151040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeClassFile(stubsDir, notStrippable, cl); 152920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 153970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton // build class list for api file or keep list file 154970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (apiWriter != null || keepListWriter != null) { 155920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (packages.containsKey(cl.containingPackage())) { 156920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson packages.get(cl.containingPackage()).add(cl); 157920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 158920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ArrayList<ClassInfo> classes = new ArrayList<ClassInfo>(); 159920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson classes.add(cl); 160920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson packages.put(cl.containingPackage(), classes); 161920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 162920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 163920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 164920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 165920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 166040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // write out the Api 167040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (apiWriter != null) { 168040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeApi(apiWriter, packages, notStrippable); 169040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.close(); 170920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 171970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 172970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton // write out the keep list 173970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (keepListWriter != null) { 174970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeKeepList(keepListWriter, packages, notStrippable); 175970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.close(); 176970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1775118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 1785118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu HashMap<PackageInfo, List<ClassInfo>> allPackageClassMap = 1795118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu new HashMap<PackageInfo, List<ClassInfo>>(); 1805118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu for (ClassInfo cl : Converter.allClasses()) { 1815118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (allPackageClassMap.containsKey(cl.containingPackage())) { 1825118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu allPackageClassMap.get(cl.containingPackage()).add(cl); 1835118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } else { 1845118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu ArrayList<ClassInfo> classes = new ArrayList<ClassInfo>(); 1855118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu classes.add(cl); 1865118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu allPackageClassMap.put(cl.containingPackage(), classes); 1875118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 1885118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 1895118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu // write out the removed Api 1905118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (removedApiWriter != null) { 1915118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu writeRemovedApi(removedApiWriter, allPackageClassMap, notStrippable); 1925118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu removedApiWriter.close(); 1935118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 194920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 195920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 196920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson public static void cantStripThis(ClassInfo cl, HashSet<ClassInfo> notStrippable, String why) { 197920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 198920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!notStrippable.add(cl)) { 199920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // slight optimization: if it already contains cl, it already contains 200920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // all of cl's parents 201920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return; 202920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 203920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cl.setReasonIncluded(why); 204920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 205920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cant strip annotations 206920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /* 207920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * if (cl.annotations() != null){ for (AnnotationInstanceInfo ai : cl.annotations()){ if 208920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * (ai.type() != null){ cantStripThis(ai.type(), notStrippable, "1:" + cl.qualifiedName()); } } 209920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * } 210920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 211920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cant strip any public fields or their generics 212ae8cb832ba8239534b7529292065936bdb85b1e3Ying Wang if (cl.selfFields() != null) { 213ae8cb832ba8239534b7529292065936bdb85b1e3Ying Wang for (FieldInfo fInfo : cl.selfFields()) { 214920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fInfo.type() != null) { 215920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fInfo.type().asClassInfo() != null) { 216920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(fInfo.type().asClassInfo(), notStrippable, "2:" + cl.qualifiedName()); 217920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 218920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fInfo.type().typeArguments() != null) { 219920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo tTypeInfo : fInfo.type().typeArguments()) { 220920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (tTypeInfo.asClassInfo() != null) { 221920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(tTypeInfo.asClassInfo(), notStrippable, "3:" + cl.qualifiedName()); 222920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 223920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 224920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 225920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 226920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 227920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 228920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cant strip any of the type's generics 229920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.asTypeInfo() != null) { 230920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.asTypeInfo().typeArguments() != null) { 231920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo tInfo : cl.asTypeInfo().typeArguments()) { 232920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (tInfo.asClassInfo() != null) { 233920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(tInfo.asClassInfo(), notStrippable, "4:" + cl.qualifiedName()); 234920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 235920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 236920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 237920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 238920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cant strip any of the annotation elements 239920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cantStripThis(cl.annotationElements(), notStrippable); 240920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // take care of methods 241920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(cl.allSelfMethods(), notStrippable); 242920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(cl.allConstructors(), notStrippable); 243920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // blow the outer class open if this is an inner class 244920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.containingClass() != null) { 245920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(cl.containingClass(), notStrippable, "5:" + cl.qualifiedName()); 246920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 247920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // blow open super class and interfaces 248920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo supr = cl.realSuperclass(); 249920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (supr != null) { 2505118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (supr.isHiddenOrRemoved()) { 251920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cl is a public class declared as extending a hidden superclass. 252920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // this is not a desired practice but it's happened, so we deal 2532da2d64196a401f664644619160f8a33eda77d9aMathieu Chartier // with it by finding the first super class which passes checklevel for purposes of 254920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // generating the doc & stub information, and proceeding normally. 255920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cl.init(cl.asTypeInfo(), cl.realInterfaces(), cl.realInterfaceTypes(), cl.innerClasses(), 256920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cl.allConstructors(), cl.allSelfMethods(), cl.annotationElements(), cl.allSelfFields(), 2572da2d64196a401f664644619160f8a33eda77d9aMathieu Chartier cl.enumConstants(), cl.containingPackage(), cl.containingClass(), 258bf322c1b64a9a7f2aade8ba499fcec4bd141a688Elliott Hughes supr.superclass(), supr.superclassType(), cl.annotations()); 259920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors.error(Errors.HIDDEN_SUPERCLASS, cl.position(), "Public class " + cl.qualifiedName() 260920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " stripped of unavailable superclass " + supr.qualifiedName()); 261920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 262920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(supr, notStrippable, "6:" + cl.realSuperclass().name() + cl.qualifiedName()); 263920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 264920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 265920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 266920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 267d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein private static void cantStripThis(ArrayList<MethodInfo> mInfos, HashSet<ClassInfo> notStrippable) { 268920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // for each method, blow open the parameters, throws and return types. also blow open their 269920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // generics 270920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mInfos != null) { 271920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo mInfo : mInfos) { 272920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mInfo.getTypeParameters() != null) { 273920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo tInfo : mInfo.getTypeParameters()) { 274920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (tInfo.asClassInfo() != null) { 275920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(tInfo.asClassInfo(), notStrippable, "8:" 276920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); 277920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 278920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 279920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 280920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mInfo.parameters() != null) { 281920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ParameterInfo pInfo : mInfo.parameters()) { 282920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pInfo.type() != null && pInfo.type().asClassInfo() != null) { 283920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(pInfo.type().asClassInfo(), notStrippable, "9:" 284920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); 285920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pInfo.type().typeArguments() != null) { 286920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo tInfoType : pInfo.type().typeArguments()) { 287920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (tInfoType.asClassInfo() != null) { 288920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo tcl = tInfoType.asClassInfo(); 2895118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (tcl.isHiddenOrRemoved()) { 290920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Errors 291920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson .error(Errors.UNAVAILABLE_SYMBOL, mInfo.position(), 292920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson "Parameter of hidden type " + tInfoType.fullName() + " in " 293920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.containingClass().qualifiedName() + '.' + mInfo.name() 294920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "()"); 295920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 296920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(tcl, notStrippable, "10:" 297920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); 298920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 299920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 300920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 301920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 302920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 303920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 304920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 305920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo thrown : mInfo.thrownExceptions()) { 306920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(thrown, notStrippable, "11:" + mInfo.realContainingClass().qualifiedName() 307920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ":" + mInfo.name()); 308920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 309920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mInfo.returnType() != null && mInfo.returnType().asClassInfo() != null) { 310920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(mInfo.returnType().asClassInfo(), notStrippable, "12:" 311920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); 312920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mInfo.returnType().typeArguments() != null) { 313920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo tyInfo : mInfo.returnType().typeArguments()) { 314920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (tyInfo.asClassInfo() != null) { 315920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cantStripThis(tyInfo.asClassInfo(), notStrippable, "13:" 316920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mInfo.realContainingClass().qualifiedName() + ":" + mInfo.name()); 317920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 318920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 319920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 320920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 321920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 322920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 323920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 324920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 325920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static String javaFileName(ClassInfo cl) { 326920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String dir = ""; 327920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson PackageInfo pkg = cl.containingPackage(); 328920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pkg != null) { 329920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson dir = pkg.name(); 330920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson dir = dir.replace('.', '/') + '/'; 331920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 332920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return dir + cl.name() + ".java"; 333920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 334920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 335040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeClassFile(String stubsDir, HashSet<ClassInfo> notStrippable, ClassInfo cl) { 336920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // inner classes are written by their containing class 337920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.containingClass() != null) { 338920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return; 339920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 340920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 341920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Work around the bogus "Array" class we invent for 342920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505) 343920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.containingPackage() != null 344920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson && cl.containingPackage().name().equals(PackageInfo.DEFAULT_PACKAGE)) { 345920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return; 346920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 347920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 348920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String filename = stubsDir + '/' + javaFileName(cl); 349920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson File file = new File(filename); 350920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClearPage.ensureDirectory(file); 351920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 352920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson PrintStream stream = null; 353920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson try { 354ed8f79791885c3ac15401d88a147aee551e1039eBrian Carlstrom stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(file))); 355040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeClassFile(stream, notStrippable, cl); 356920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } catch (FileNotFoundException e) { 357920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson System.err.println("error writing file: " + filename); 358920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } finally { 359920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (stream != null) { 360920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.close(); 361920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 362920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 363920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 364920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 365040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeClassFile(PrintStream stream, HashSet<ClassInfo> notStrippable, ClassInfo cl) { 366920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson PackageInfo pkg = cl.containingPackage(); 367920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pkg != null) { 368920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println("package " + pkg.name() + ";"); 369920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 370040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeClass(stream, notStrippable, cl); 371920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 372920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 373040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeClass(PrintStream stream, HashSet<ClassInfo> notStrippable, ClassInfo cl) { 37473934887ea87fca353449f0fd476d6c07b349521Tor Norbye writeAnnotations(stream, cl.annotations(), cl.isDeprecated()); 375920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 376920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(cl.scope() + " "); 377920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isAbstract() && !cl.isAnnotation() && !cl.isInterface()) { 378920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("abstract "); 379920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 380920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isStatic()) { 381920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("static "); 382920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 383920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isFinal() && !cl.isEnum()) { 384920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("final "); 385920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 386920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (false) { 387920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("strictfp "); 388920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 389920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 390920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson HashSet<String> classDeclTypeVars = new HashSet(); 391920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String leafName = cl.asTypeInfo().fullName(classDeclTypeVars); 392920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int bracket = leafName.indexOf('<'); 393920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (bracket < 0) bracket = leafName.length() - 1; 394920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int period = leafName.lastIndexOf('.', bracket); 395920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (period < 0) period = -1; 396920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson leafName = leafName.substring(period + 1); 397920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 398920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String kind = cl.kind(); 399920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(kind + " " + leafName); 400920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 401920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson TypeInfo base = cl.superclassType(); 402920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 403920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!"enum".equals(kind)) { 404920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (base != null && !"java.lang.Object".equals(base.qualifiedTypeName())) { 405920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(" extends " + base.fullName(classDeclTypeVars)); 406920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 407920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 408920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 409920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<TypeInfo> usedInterfaces = new ArrayList<TypeInfo>(); 410d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (TypeInfo iface : cl.realInterfaceTypes()) { 411920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (notStrippable.contains(iface.asClassInfo()) && !iface.asClassInfo().isDocOnly()) { 412920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson usedInterfaces.add(iface); 413920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 414920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 415920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (usedInterfaces.size() > 0 && !cl.isAnnotation()) { 416920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // can java annotations extend other ones? 417920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isInterface() || cl.isAnnotation()) { 418920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" extends "); 419920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 420920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" implements "); 421920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 422920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String comma = ""; 423920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (TypeInfo iface : usedInterfaces) { 424920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(comma + iface.fullName(classDeclTypeVars)); 425920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson comma = ", "; 426920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 427920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(); 428920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 429920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 430920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println("{"); 431920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 432d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<FieldInfo> enumConstants = cl.enumConstants(); 433d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int N = enumConstants.size(); 434d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int i = 0; 435d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (FieldInfo field : enumConstants) { 436920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!field.constantLiteralValue().equals("null")) { 437920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(field.name() + "(" + field.constantLiteralValue() 438920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + (i == N - 1 ? ");" : "),")); 439920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 440920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(field.name() + "(" + (i == N - 1 ? ");" : "),")); 441920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 442d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein i++; 443920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 444920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 445920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo inner : cl.getRealInnerClasses()) { 446920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (notStrippable.contains(inner) && !inner.isDocOnly()) { 447040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeClass(stream, notStrippable, inner); 448920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 449920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 450920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 451920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 452920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo method : cl.constructors()) { 453920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!method.isDocOnly()) { 454920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeMethod(stream, method, true); 455920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 456920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 457920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 458920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson boolean fieldNeedsInitialization = false; 459920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson boolean staticFieldNeedsInitialization = false; 460ae8cb832ba8239534b7529292065936bdb85b1e3Ying Wang for (FieldInfo field : cl.selfFields()) { 461920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!field.isDocOnly()) { 462920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!field.isStatic() && field.isFinal() && !fieldIsInitialized(field)) { 463920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson fieldNeedsInitialization = true; 464920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 465920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (field.isStatic() && field.isFinal() && !fieldIsInitialized(field)) { 466920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson staticFieldNeedsInitialization = true; 467920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 468920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 469920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 470920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 471920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // The compiler includes a default public constructor that calls the super classes 472920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // default constructor in the case where there are no written constructors. 473920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // So, if we hide all the constructors, java may put in a constructor 474920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // that calls a nonexistent super class constructor. So, if there are no constructors, 475920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // and the super class doesn't have a default constructor, write in a private constructor 476920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // that works. TODO -- we generate this as protected, but we really should generate 477920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // it as private unless it also exists in the real code. 4785118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if ((cl.constructors().isEmpty() && (!cl.getNonWrittenConstructors().isEmpty() || 4795118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu fieldNeedsInitialization)) && !cl.isAnnotation() && !cl.isInterface() && !cl.isEnum()) { 480920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Errors.error(Errors.HIDDEN_CONSTRUCTOR, 481920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // cl.position(), "No constructors " + 482920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // "found and superclass has no parameterless constructor. A constructor " + 483920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // "that calls an appropriate superclass constructor " + 484920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // "was automatically written to stubs.\n"); 485920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(cl.leafName() + "() { " + superCtorCall(cl, null) + "throw new" 486920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " RuntimeException(\"Stub!\"); }"); 487920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 488920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 489920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo method : cl.allSelfMethods()) { 490920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isEnum()) { 4915118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (("values".equals(method.name()) && "()".equals(method.signature())) || 4925118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu ("valueOf".equals(method.name()) && 4935118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu "(java.lang.String)".equals(method.signature()))) { 494920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // skip these two methods on enums, because they're synthetic, 495920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // although for some reason javadoc doesn't mark them as synthetic, 496920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // maybe because they still want them documented 497920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 498920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 499920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 500920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!method.isDocOnly()) { 501920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeMethod(stream, method, false); 502920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 503920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 5045118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu // Write all methods that are hidden or removed, but override abstract methods or interface methods. 505920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // These can't be hidden. 5065118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu List<MethodInfo> hiddenAndRemovedMethods = cl.getHiddenMethods(); 5075118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu hiddenAndRemovedMethods.addAll(cl.getRemovedMethods()); 5085118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu for (MethodInfo method : hiddenAndRemovedMethods) { 509920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson MethodInfo overriddenMethod = 510920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson method.findRealOverriddenMethod(method.name(), method.signature(), notStrippable); 511920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo classContainingMethod = 512920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson method.findRealOverriddenClass(method.name(), method.signature()); 5135118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (overriddenMethod != null && !overriddenMethod.isHiddenOrRemoved() && 5145118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu !overriddenMethod.isDocOnly() && 5155118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu (overriddenMethod.isAbstract() || overriddenMethod.containingClass().isInterface())) { 516920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson method.setReason("1:" + classContainingMethod.qualifiedName()); 517920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson cl.addMethod(method); 518920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeMethod(stream, method, false); 519920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 520920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 521920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 522920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo element : cl.annotationElements()) { 523920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!element.isDocOnly()) { 524920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeAnnotationElement(stream, element); 525920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 526920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 527920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 528ae8cb832ba8239534b7529292065936bdb85b1e3Ying Wang for (FieldInfo field : cl.selfFields()) { 529920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!field.isDocOnly()) { 530920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeField(stream, field); 531920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 532920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 533920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 534920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (staticFieldNeedsInitialization) { 535920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("static { "); 536ae8cb832ba8239534b7529292065936bdb85b1e3Ying Wang for (FieldInfo field : cl.selfFields()) { 537920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!field.isDocOnly() && field.isStatic() && field.isFinal() && !fieldIsInitialized(field) 538920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson && field.constantValue() == null) { 539920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(field.name() + " = " + field.type().defaultValue() + "; "); 540920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 541920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 542920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println("}"); 543920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 544920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 545920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println("}"); 546920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 547920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 548920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 549920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeMethod(PrintStream stream, MethodInfo method, boolean isConstructor) { 550920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String comma; 551920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 55273934887ea87fca353449f0fd476d6c07b349521Tor Norbye writeAnnotations(stream, method.annotations(), method.isDeprecated()); 55373934887ea87fca353449f0fd476d6c07b349521Tor Norbye 554920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(method.scope() + " "); 555920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isStatic()) { 556920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("static "); 557920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 558920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isFinal()) { 559920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("final "); 560920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 561920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isAbstract()) { 562920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("abstract "); 563920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 564920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isSynchronized()) { 565920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("synchronized "); 566920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 567920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isNative()) { 568920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("native "); 569920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 570920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (false /* method.isStictFP() */) { 571920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("strictfp "); 572920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 573920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 574920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(method.typeArgumentsName(new HashSet()) + " "); 575920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 576920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!isConstructor) { 577920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(method.returnType().fullName(method.typeVariables()) + " "); 578920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 579920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String n = method.name(); 580920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int pos = n.lastIndexOf('.'); 581920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pos >= 0) { 582920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson n = n.substring(pos + 1); 583920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 584920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(n + "("); 585920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson comma = ""; 586920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int count = 1; 587d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int size = method.parameters().size(); 588920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ParameterInfo param : method.parameters()) { 589920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(comma + fullParameterTypeName(method, param.type(), count == size) + " " 590920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + param.name()); 591920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson comma = ", "; 592920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson count++; 593920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 594920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(")"); 595920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 596920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson comma = ""; 597d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (method.thrownExceptions().size() > 0) { 598920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" throws "); 599920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo thrown : method.thrownExceptions()) { 600920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(comma + thrown.qualifiedName()); 601920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson comma = ", "; 602920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 603920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 604920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (method.isAbstract() || method.isNative() || method.containingClass().isInterface()) { 605920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(";"); 606920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 607920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" { "); 608920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (isConstructor) { 609920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(superCtorCall(method.containingClass(), method.thrownExceptions())); 610920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 611920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println("throw new RuntimeException(\"Stub!\"); }"); 612920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 613920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 614920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 615920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeField(PrintStream stream, FieldInfo field) { 61673934887ea87fca353449f0fd476d6c07b349521Tor Norbye writeAnnotations(stream, field.annotations(), field.isDeprecated()); 61773934887ea87fca353449f0fd476d6c07b349521Tor Norbye 618920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(field.scope() + " "); 619920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (field.isStatic()) { 620920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("static "); 621920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 622920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (field.isFinal()) { 623920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("final "); 624920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 625920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (field.isTransient()) { 626920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("transient "); 627920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 628920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (field.isVolatile()) { 629920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("volatile "); 630920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 631920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 632920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(field.type().fullName()); 633920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" "); 634920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(field.name()); 635920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 636920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fieldIsInitialized(field)) { 637920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" = " + field.constantLiteralValue()); 638920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 639920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 640920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(";"); 641920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 642920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 643920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static boolean fieldIsInitialized(FieldInfo field) { 644920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return (field.isFinal() && field.constantValue() != null) 645920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson || !field.type().dimension().equals("") || field.containingClass().isInterface(); 646920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 647920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 648920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Returns 'true' if the method is an @Override of a visible parent 649920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // method implementation, and thus does not affect the API. 650040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static boolean methodIsOverride(HashSet<ClassInfo> notStrippable, MethodInfo mi) { 651920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Abstract/static/final methods are always listed in the API description 652920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mi.isAbstract() || mi.isStatic() || mi.isFinal()) { 653920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return false; 654920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 655920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 656920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Find any relevant ancestor declaration and inspect it 657920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson MethodInfo om = mi.findSuperclassImplementation(notStrippable); 658920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (om != null) { 659920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Visibility mismatch is an API change, so check for it 660920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mi.mIsPrivate == om.mIsPrivate && mi.mIsPublic == om.mIsPublic 661920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson && mi.mIsProtected == om.mIsProtected) { 662920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Look only for overrides of an ancestor class implementation, 663920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // not of e.g. an abstract or interface method declaration 664920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!om.isAbstract()) { 6655118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu // If the parent is hidden or removed, we can't rely on it to provide 666920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // the API 6675118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (!om.isHiddenOrRemoved()) { 668920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // If the only "override" turns out to be in our own class 669920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // (which sometimes happens in concrete subclasses of 670920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // abstract base classes), it's not really an override 671920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!mi.mContainingClass.equals(om.mContainingClass)) { 672920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return true; 673920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 674920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 675920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 676920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 677920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 678920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return false; 679920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 680920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 681920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static boolean canCallMethod(ClassInfo from, MethodInfo m) { 682920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (m.isPublic() || m.isProtected()) { 683920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return true; 684920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 685920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (m.isPackagePrivate()) { 686920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String fromPkg = from.containingPackage().name(); 687920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String pkg = m.containingClass().containingPackage().name(); 688920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fromPkg.equals(pkg)) { 689920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return true; 690920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 691920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 692920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return false; 693920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 694920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 695920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // call a constructor, any constructor on this class's superclass. 696d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein static String superCtorCall(ClassInfo cl, ArrayList<ClassInfo> thrownExceptions) { 697920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo base = cl.realSuperclass(); 698920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (base == null) { 699920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return ""; 700920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 701920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson HashSet<String> exceptionNames = new HashSet<String>(); 702920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (thrownExceptions != null) { 703920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo thrown : thrownExceptions) { 704920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson exceptionNames.add(thrown.name()); 705920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 706920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 707d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<MethodInfo> ctors = base.constructors(); 708920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson MethodInfo ctor = null; 709920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // bad exception indicates that the exceptions thrown by the super constructor 710920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // are incompatible with the constructor we're using for the sub class. 711920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Boolean badException = false; 712920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo m : ctors) { 713920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (canCallMethod(cl, m)) { 714920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (m.thrownExceptions() != null) { 715920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo thrown : m.thrownExceptions()) { 716920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!exceptionNames.contains(thrown.name())) { 717920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson badException = true; 718920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 719920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 720920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 721920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (badException) { 722920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson badException = false; 723920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 724920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 725920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // if it has no args, we're done 726d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (m.parameters().isEmpty()) { 727920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return ""; 728920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 729920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ctor = m; 730920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 731920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 732920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (ctor != null) { 733920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String result = ""; 734920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "super("; 735d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ParameterInfo> params = ctor.parameters(); 736d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (ParameterInfo param : params) { 737d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein TypeInfo t = param.type(); 738920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (t.isPrimitive() && t.dimension().equals("")) { 739920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String n = t.simpleTypeName(); 740920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (("byte".equals(n) || "short".equals(n) || "int".equals(n) || "long".equals(n) 741920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson || "float".equals(n) || "double".equals(n)) 742920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson && t.dimension().equals("")) { 743920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "0"; 744920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else if ("char".equals(n)) { 745920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "'\\0'"; 746920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else if ("boolean".equals(n)) { 747920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "false"; 748920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 749920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "<<unknown-" + n + ">>"; 750920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 751920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 752920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // put null in each super class method. Cast null to the correct type 753920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // to avoid collisions with other constructors. If the type is generic 754920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // don't cast it 755920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += 756920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson (!t.isTypeVariable() ? "(" + t.qualifiedTypeName() + t.dimension() + ")" : "") 757920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "null"; 758920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 759d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (param != params.get(params.size()-1)) { 760920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += ","; 761920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 762920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 763920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson result += "); "; 764920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return result; 765920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 766920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return ""; 767920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 768920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 769920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 77073934887ea87fca353449f0fd476d6c07b349521Tor Norbye /** 77173934887ea87fca353449f0fd476d6c07b349521Tor Norbye * Write out the given list of annotations. If the {@code isDeprecated} 77273934887ea87fca353449f0fd476d6c07b349521Tor Norbye * flag is true also write out a {@code @Deprecated} annotation if it did not 77373934887ea87fca353449f0fd476d6c07b349521Tor Norbye * already appear in the list of annotations. (This covers APIs that mention 77473934887ea87fca353449f0fd476d6c07b349521Tor Norbye * {@code @deprecated} in their documentation but fail to add 77573934887ea87fca353449f0fd476d6c07b349521Tor Norbye * {@code @Deprecated} as an annotation. 77673934887ea87fca353449f0fd476d6c07b349521Tor Norbye * <p> 77773934887ea87fca353449f0fd476d6c07b349521Tor Norbye * {@code @Override} annotations are deliberately skipped. 77873934887ea87fca353449f0fd476d6c07b349521Tor Norbye */ 77973934887ea87fca353449f0fd476d6c07b349521Tor Norbye static void writeAnnotations(PrintStream stream, List<AnnotationInstanceInfo> annotations, 78073934887ea87fca353449f0fd476d6c07b349521Tor Norbye boolean isDeprecated) { 78173934887ea87fca353449f0fd476d6c07b349521Tor Norbye assert annotations != null; 782920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (AnnotationInstanceInfo ann : annotations) { 78373934887ea87fca353449f0fd476d6c07b349521Tor Norbye // Skip @Override annotations: the stubs do not need it and in some cases it leads 78473934887ea87fca353449f0fd476d6c07b349521Tor Norbye // to compilation errors with the way the stubs are generated 78573934887ea87fca353449f0fd476d6c07b349521Tor Norbye if (ann.type() != null && ann.type().qualifiedName().equals("java.lang.Override")) { 78673934887ea87fca353449f0fd476d6c07b349521Tor Norbye continue; 78773934887ea87fca353449f0fd476d6c07b349521Tor Norbye } 7885118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (!ann.type().isHiddenOrRemoved()) { 789920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(ann.toString()); 79073934887ea87fca353449f0fd476d6c07b349521Tor Norbye if (isDeprecated && ann.type() != null 79173934887ea87fca353449f0fd476d6c07b349521Tor Norbye && ann.type().qualifiedName().equals("java.lang.Deprecated")) { 79273934887ea87fca353449f0fd476d6c07b349521Tor Norbye isDeprecated = false; // Prevent duplicate annotations 79373934887ea87fca353449f0fd476d6c07b349521Tor Norbye } 794920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 795920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 79673934887ea87fca353449f0fd476d6c07b349521Tor Norbye if (isDeprecated) { 79773934887ea87fca353449f0fd476d6c07b349521Tor Norbye stream.println("@Deprecated"); 79873934887ea87fca353449f0fd476d6c07b349521Tor Norbye } 799920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 800920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 801920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeAnnotationElement(PrintStream stream, MethodInfo ann) { 802920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(ann.returnType().fullName()); 803920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" "); 804920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(ann.name()); 805920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print("()"); 806920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson AnnotationValueInfo def = ann.defaultAnnotationElementValue(); 807920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (def != null) { 808920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(" default "); 809920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.print(def.valueString()); 810920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 811920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.println(";"); 812920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 813920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 814920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeXML(PrintStream xmlWriter, HashMap<PackageInfo, List<ClassInfo>> allClasses, 815040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato HashSet<ClassInfo> notStrippable) { 816920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // extract the set of packages, sort them by name, and write them out in that order 817920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Set<PackageInfo> allClassKeys = allClasses.keySet(); 818920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson PackageInfo[] allPackages = allClassKeys.toArray(new PackageInfo[allClassKeys.size()]); 819920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Arrays.sort(allPackages, PackageInfo.comparator); 820920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 821920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<api>"); 822920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (PackageInfo pack : allPackages) { 823920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writePackageXML(xmlWriter, pack, allClasses.get(pack), notStrippable); 824920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 825920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</api>"); 826920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 827920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 828040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public static void writeXml(PrintStream xmlWriter, Collection<PackageInfo> pkgs) { 829040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final PackageInfo[] packages = pkgs.toArray(new PackageInfo[pkgs.size()]); 830040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Arrays.sort(packages, PackageInfo.comparator); 831040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 832040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato HashSet<ClassInfo> notStrippable = new HashSet(); 833040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (PackageInfo pkg: packages) { 834040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (ClassInfo cl: pkg.allClasses().values()) { 835040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato notStrippable.add(cl); 836040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 837040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 838040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato xmlWriter.println("<api>"); 839040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (PackageInfo pkg: packages) { 840040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writePackageXML(xmlWriter, pkg, pkg.allClasses().values(), notStrippable); 841040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 842040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato xmlWriter.println("</api>"); 843040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 844040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 845040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writePackageXML(PrintStream xmlWriter, PackageInfo pack, 846040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Collection<ClassInfo> classList, HashSet<ClassInfo> notStrippable) { 847920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo[] classes = classList.toArray(new ClassInfo[classList.size()]); 848920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Arrays.sort(classes, ClassInfo.comparator); 849920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Work around the bogus "Array" class we invent for 850920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505) 851920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (pack.name().equals(PackageInfo.DEFAULT_PACKAGE)) { 852920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return; 853920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 854920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<package name=\"" + pack.name() + "\"\n" 855920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // + " source=\"" + pack.position() + "\"\n" 856920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ">"); 857920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo cl : classes) { 858920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeClassXML(xmlWriter, cl, notStrippable); 859920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 860920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</package>"); 861920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 862920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 863920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 864920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 865040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeClassXML(PrintStream xmlWriter, ClassInfo cl, HashSet<ClassInfo> notStrippable) { 866920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String scope = cl.scope(); 867920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String deprecatedString = ""; 868920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String declString = (cl.isInterface()) ? "interface" : "class"; 869920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (cl.isDeprecated()) { 870920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "deprecated"; 871920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 872920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "not deprecated"; 873920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 874920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<" + declString + " name=\"" + cl.name() + "\""); 875920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!cl.isInterface() && !cl.qualifiedName().equals("java.lang.Object")) { 876920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println(" extends=\"" 877920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ((cl.realSuperclass() == null) ? "java.lang.Object" : cl.realSuperclass() 878920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson .qualifiedName()) + "\""); 879920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 880920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println(" abstract=\"" + cl.isAbstract() + "\"\n" + " static=\"" + cl.isStatic() 881920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "\"\n" + " final=\"" + cl.isFinal() + "\"\n" + " deprecated=\"" + deprecatedString 882920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "\"\n" + " visibility=\"" + scope + "\"\n" 883920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // + " source=\"" + cl.position() + "\"\n" 884920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ">"); 885920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 886d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ClassInfo> interfaces = cl.realInterfaces(); 887d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(interfaces, ClassInfo.comparator); 888920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo iface : interfaces) { 889920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (notStrippable.contains(iface)) { 890920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<implements name=\"" + iface.qualifiedName() + "\">"); 891920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</implements>"); 892920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 893920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 894920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 895d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<MethodInfo> constructors = cl.constructors(); 896d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(constructors, MethodInfo.comparator); 897920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo mi : constructors) { 898920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeConstructorXML(xmlWriter, mi); 899920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 900920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 901d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<MethodInfo> methods = cl.allSelfMethods(); 902d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(methods, MethodInfo.comparator); 903920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo mi : methods) { 904040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!methodIsOverride(notStrippable, mi)) { 905920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeMethodXML(xmlWriter, mi); 906920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 907920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 908920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 909ae8cb832ba8239534b7529292065936bdb85b1e3Ying Wang ArrayList<FieldInfo> fields = cl.selfFields(); 910d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(fields, FieldInfo.comparator); 911920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FieldInfo fi : fields) { 912920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeFieldXML(xmlWriter, fi); 913920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 914920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</" + declString + ">"); 915920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 916920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 917920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 918920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeMethodXML(PrintStream xmlWriter, MethodInfo mi) { 919920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String scope = mi.scope(); 920920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 921920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String deprecatedString = ""; 922920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mi.isDeprecated()) { 923920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "deprecated"; 924920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 925920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "not deprecated"; 926920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 927920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<method name=\"" 928920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mi.name() 929920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "\"\n" 930920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ((mi.returnType() != null) ? " return=\"" 931920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + makeXMLcompliant(fullParameterTypeName(mi, mi.returnType(), false)) + "\"\n" : "") 932920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " abstract=\"" + mi.isAbstract() + "\"\n" + " native=\"" + mi.isNative() + "\"\n" 933920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " synchronized=\"" + mi.isSynchronized() + "\"\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 939920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // write parameters in declaration order 940d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int numParameters = mi.parameters().size(); 941920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int count = 0; 942920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ParameterInfo pi : mi.parameters()) { 943920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson count++; 944920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeParameterXML(xmlWriter, mi, pi, count == numParameters); 945920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 946920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 947920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // but write exceptions in canonicalized order 948d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ClassInfo> exceptions = mi.thrownExceptions(); 949d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(exceptions, ClassInfo.comparator); 950920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo pi : exceptions) { 951920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<exception name=\"" + pi.name() + "\" type=\"" + pi.qualifiedName() 952920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "\">"); 953920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</exception>"); 954920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 955920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</method>"); 956920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 957920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 958920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeConstructorXML(PrintStream xmlWriter, MethodInfo mi) { 959920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String scope = mi.scope(); 960920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String deprecatedString = ""; 961920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (mi.isDeprecated()) { 962920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "deprecated"; 963920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 964920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "not deprecated"; 965920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 966920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<constructor name=\"" + mi.name() + "\"\n" + " type=\"" 967920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + mi.containingClass().qualifiedName() + "\"\n" + " static=\"" + mi.isStatic() + "\"\n" 968920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " final=\"" + mi.isFinal() + "\"\n" + " deprecated=\"" + deprecatedString + "\"\n" 969920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " visibility=\"" + scope + "\"\n" 970920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // + " source=\"" + mi.position() + "\"\n" 971920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ">"); 972920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 973d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein int numParameters = mi.parameters().size(); 974920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int count = 0; 975920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ParameterInfo pi : mi.parameters()) { 976920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson count++; 977920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson writeParameterXML(xmlWriter, mi, pi, count == numParameters); 978920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 979920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 980d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ClassInfo> exceptions = mi.thrownExceptions(); 981d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(exceptions, ClassInfo.comparator); 982920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo pi : exceptions) { 983920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<exception name=\"" + pi.name() + "\" type=\"" + pi.qualifiedName() 984920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + "\">"); 985920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</exception>"); 986920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 987920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</constructor>"); 988920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 989920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 990920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeParameterXML(PrintStream xmlWriter, MethodInfo method, ParameterInfo pi, 991920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson boolean isLast) { 992920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<parameter name=\"" + pi.name() + "\" type=\"" 993920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + makeXMLcompliant(fullParameterTypeName(method, pi.type(), isLast)) + "\">"); 994920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</parameter>"); 995920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 996920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 997920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static void writeFieldXML(PrintStream xmlWriter, FieldInfo fi) { 998920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String scope = fi.scope(); 999920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String deprecatedString = ""; 1000920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (fi.isDeprecated()) { 1001920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "deprecated"; 1002920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 1003920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson deprecatedString = "not deprecated"; 1004920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 1005920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // need to make sure value is valid XML 1006920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String value = makeXMLcompliant(fi.constantLiteralValue()); 1007920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 10087751817561b5fea6ffaee8cad497ab6876deca0eYing Wang String fullTypeName = makeXMLcompliant(fi.type().fullName()); 1009920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 1010920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("<field name=\"" + fi.name() + "\"\n" + " type=\"" + fullTypeName + "\"\n" 1011920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + " transient=\"" + fi.isTransient() + "\"\n" + " volatile=\"" + fi.isVolatile() + "\"\n" 1012920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + (fieldIsInitialized(fi) ? " value=\"" + value + "\"\n" : "") + " static=\"" 1013920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + fi.isStatic() + "\"\n" + " final=\"" + fi.isFinal() + "\"\n" + " deprecated=\"" 1014920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + deprecatedString + "\"\n" + " visibility=\"" + scope + "\"\n" 1015920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // + " source=\"" + fi.position() + "\"\n" 1016920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson + ">"); 1017920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson xmlWriter.println("</field>"); 1018920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 1019920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 1020920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static String makeXMLcompliant(String s) { 1021920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String returnString = ""; 1022920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson returnString = s.replaceAll("&", "&"); 1023920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson returnString = returnString.replaceAll("<", "<"); 1024920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson returnString = returnString.replaceAll(">", ">"); 1025920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson returnString = returnString.replaceAll("\"", """); 1026920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson returnString = returnString.replaceAll("'", "&pos;"); 1027920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return returnString; 1028920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 1029920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 10305118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu static void writeRemovedApi(PrintStream apiWriter, HashMap<PackageInfo, 10315118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu List<ClassInfo>> allPackageClassMap, Set<ClassInfo> notStrippable) { 10325118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu final PackageInfo[] packages = allPackageClassMap.keySet().toArray(new PackageInfo[0]); 10335118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu Arrays.sort(packages, PackageInfo.comparator); 10345118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu for (PackageInfo pkg : packages) { 10355118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu // beware that pkg.allClasses() has no class in it at the moment 10365118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu final List<ClassInfo> classes = allPackageClassMap.get(pkg); 10375118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu Collections.sort(classes, ClassInfo.comparator); 10385118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu boolean hasWrittenPackageHead = false; 10395118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu for (ClassInfo cl : classes) { 10405118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (cl.hasRemovedSelfMembers()) { 10415118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (!hasWrittenPackageHead) { 10425118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu hasWrittenPackageHead = true; 10435118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print("package "); 10445118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(pkg.qualifiedName()); 10455118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" {\n\n"); 10465118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10475118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu writeClassRemovedSelfMembers(apiWriter, cl, notStrippable); 10485118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10495118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10505118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 10515118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu // the package contains some classes with some removed members 10525118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (hasWrittenPackageHead) { 10535118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print("}\n\n"); 10545118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10555118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10565118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10575118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 10585118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu /** 10595118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu * Write the removed members of the class to removed.txt 10605118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu */ 10615118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu private static void writeClassRemovedSelfMembers(PrintStream apiWriter, ClassInfo cl, 10625118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu Set<ClassInfo> notStrippable) { 10635118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" "); 10645118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(cl.scope()); 10655118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (cl.isStatic()) { 10665118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" static"); 10675118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10685118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (cl.isFinal()) { 10695118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" final"); 10705118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10715118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (cl.isAbstract()) { 10725118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" abstract"); 10735118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10745118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (cl.isDeprecated()) { 10755118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" deprecated"); 10765118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10775118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" "); 10785118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(cl.isInterface() ? "interface" : "class"); 10795118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" "); 10805118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(cl.name()); 10815118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 10825118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (!cl.isInterface() 10835118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu && !"java.lang.Object".equals(cl.qualifiedName()) 10845118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu && cl.realSuperclass() != null 10855118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu && !"java.lang.Object".equals(cl.realSuperclass().qualifiedName())) { 10865118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" extends "); 10875118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(cl.realSuperclass().qualifiedName()); 10885118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10895118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 10905118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu ArrayList<ClassInfo> interfaces = cl.realInterfaces(); 10915118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu Collections.sort(interfaces, ClassInfo.comparator); 10925118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu boolean first = true; 10935118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu for (ClassInfo iface : interfaces) { 10945118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (notStrippable.contains(iface)) { 10955118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu if (first) { 10965118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" implements"); 10975118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu first = false; 10985118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 10995118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" "); 11005118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(iface.qualifiedName()); 11015118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 11025118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 11035118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 11045118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" {\n"); 11055118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 11065118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu List<MethodInfo> constructors = cl.getRemovedConstructors(); 11075118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu for (MethodInfo mi : constructors) { 11085118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu writeConstructorApi(apiWriter, mi); 11095118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 11105118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 11115118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu List<MethodInfo> methods = cl.getRemovedSelfMethods(); 11125118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu for (MethodInfo mi : methods) { 11135118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu writeMethodApi(apiWriter, mi); 11145118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 11155118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 11165118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu List<FieldInfo> enums = cl.getRemovedSelfEnumConstants(); 11175118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu for (FieldInfo fi : enums) { 11185118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu writeFieldApi(apiWriter, fi, "enum_constant"); 11195118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 11205118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 11215118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu List<FieldInfo> fields = cl.getRemovedSelfFields(); 11225118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu for (FieldInfo fi : fields) { 11235118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu writeFieldApi(apiWriter, fi, "field"); 11245118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 11255118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 11265118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu apiWriter.print(" }\n\n"); 11275118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu } 11285118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu 1129040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato public static void writeApi(PrintStream apiWriter, Collection<PackageInfo> pkgs) { 1130040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato final PackageInfo[] packages = pkgs.toArray(new PackageInfo[pkgs.size()]); 1131040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Arrays.sort(packages, PackageInfo.comparator); 1132040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1133040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato HashSet<ClassInfo> notStrippable = new HashSet(); 1134040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (PackageInfo pkg: packages) { 1135040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (ClassInfo cl: pkg.allClasses().values()) { 1136040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato notStrippable.add(cl); 1137040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1138040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1139040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (PackageInfo pkg: packages) { 1140040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writePackageApi(apiWriter, pkg, pkg.allClasses().values(), notStrippable); 1141040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1142040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1143040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1144040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeApi(PrintStream apiWriter, HashMap<PackageInfo, List<ClassInfo>> allClasses, 1145040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato HashSet<ClassInfo> notStrippable) { 1146040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // extract the set of packages, sort them by name, and write them out in that order 1147040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Set<PackageInfo> allClassKeys = allClasses.keySet(); 1148040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato PackageInfo[] allPackages = allClassKeys.toArray(new PackageInfo[allClassKeys.size()]); 1149040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Arrays.sort(allPackages, PackageInfo.comparator); 1150040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1151040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (PackageInfo pack : allPackages) { 1152040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writePackageApi(apiWriter, pack, allClasses.get(pack), notStrippable); 1153040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1154040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1155040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1156040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writePackageApi(PrintStream apiWriter, PackageInfo pack, 1157040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Collection<ClassInfo> classList, HashSet<ClassInfo> notStrippable) { 1158040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // Work around the bogus "Array" class we invent for 1159040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505) 1160040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (pack.name().equals(PackageInfo.DEFAULT_PACKAGE)) { 1161040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato return; 1162040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1163040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1164040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print("package "); 1165040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(pack.qualifiedName()); 1166040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" {\n\n"); 1167040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1168040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato ClassInfo[] classes = classList.toArray(new ClassInfo[classList.size()]); 1169040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Arrays.sort(classes, ClassInfo.comparator); 1170040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (ClassInfo cl : classes) { 1171040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeClassApi(apiWriter, cl, notStrippable); 1172040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1173040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1174040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print("}\n\n"); 1175040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1176040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1177040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeClassApi(PrintStream apiWriter, ClassInfo cl, HashSet<ClassInfo> notStrippable) { 1178040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean first; 1179040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1180040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1181040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(cl.scope()); 1182040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (cl.isStatic()) { 1183040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" static"); 1184040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1185040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (cl.isFinal()) { 1186040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" final"); 1187040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1188040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (cl.isAbstract()) { 1189040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" abstract"); 1190040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1191040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (cl.isDeprecated()) { 1192040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" deprecated"); 1193040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1194040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1195040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(cl.isInterface() ? "interface" : "class"); 1196040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1197040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(cl.name()); 1198040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1199040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!cl.isInterface() 1200040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato && !"java.lang.Object".equals(cl.qualifiedName()) 1201040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato && cl.realSuperclass() != null 1202040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato && !"java.lang.Object".equals(cl.realSuperclass().qualifiedName())) { 1203040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" extends "); 1204040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(cl.realSuperclass().qualifiedName()); 1205040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1206040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1207d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<ClassInfo> interfaces = cl.realInterfaces(); 1208d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(interfaces, ClassInfo.comparator); 1209040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato first = true; 1210040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (ClassInfo iface : interfaces) { 1211040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (notStrippable.contains(iface)) { 1212040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (first) { 1213040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" implements"); 1214040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato first = false; 1215040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1216040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1217040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(iface.qualifiedName()); 1218040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1219040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1220040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1221040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" {\n"); 1222040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1223d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<MethodInfo> constructors = cl.constructors(); 1224d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(constructors, MethodInfo.comparator); 1225040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (MethodInfo mi : constructors) { 1226040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeConstructorApi(apiWriter, mi); 1227040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1228040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1229d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<MethodInfo> methods = cl.allSelfMethods(); 1230d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(methods, MethodInfo.comparator); 1231040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (MethodInfo mi : methods) { 1232040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (!methodIsOverride(notStrippable, mi)) { 1233040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeMethodApi(apiWriter, mi); 1234040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1235040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1236040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1237d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein ArrayList<FieldInfo> enums = cl.enumConstants(); 1238d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(enums, FieldInfo.comparator); 1239132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato for (FieldInfo fi : enums) { 1240132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato writeFieldApi(apiWriter, fi, "enum_constant"); 1241132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato } 1242132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato 1243ae8cb832ba8239534b7529292065936bdb85b1e3Ying Wang ArrayList<FieldInfo> fields = cl.selfFields(); 1244d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(fields, FieldInfo.comparator); 1245040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato for (FieldInfo fi : fields) { 1246132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato writeFieldApi(apiWriter, fi, "field"); 1247040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1248040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1249040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" }\n\n"); 1250040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1251040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1252040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeConstructorApi(PrintStream apiWriter, MethodInfo mi) { 1253040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" ctor "); 1254040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(mi.scope()); 1255040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isDeprecated()) { 1256040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" deprecated"); 1257040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1258040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1259040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(mi.name()); 1260040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1261040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeParametersApi(apiWriter, mi, mi.parameters()); 1262040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeThrowsApi(apiWriter, mi.thrownExceptions()); 1263040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(";\n"); 1264040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1265040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1266040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato static void writeMethodApi(PrintStream apiWriter, MethodInfo mi) { 1267040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" method "); 1268040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(mi.scope()); 1269040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isStatic()) { 1270040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" static"); 1271040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1272040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isFinal()) { 1273040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" final"); 1274040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1275040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isAbstract()) { 1276040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" abstract"); 1277040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1278040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isDeprecated()) { 1279040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" deprecated"); 1280040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1281040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.isSynchronized()) { 1282040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" synchronized"); 1283040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1284040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1285040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (mi.returnType() == null) { 1286040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print("void"); 1287040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 1288040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(fullParameterTypeName(mi, mi.returnType(), false)); 1289040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1290040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1291040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(mi.name()); 1292040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1293040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeParametersApi(apiWriter, mi, mi.parameters()); 1294040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato writeThrowsApi(apiWriter, mi.thrownExceptions()); 1295040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1296040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(";\n"); 1297040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1298040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 12995118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu static void writeParametersApi(PrintStream apiWriter, MethodInfo method, 13005118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu ArrayList<ParameterInfo> params) { 1301040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print("("); 1302040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1303d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (ParameterInfo pi : params) { 1304d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein if (pi != params.get(0)) { 1305040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(", "); 1306040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1307d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein apiWriter.print(fullParameterTypeName(method, pi.type(), pi == params.get(params.size()-1))); 1308040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // turn on to write the names too 1309040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (false) { 1310040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1311040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(pi.name()); 1312040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1313040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1314040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1315040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(")"); 1316040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1317040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1318d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein static void writeThrowsApi(PrintStream apiWriter, ArrayList<ClassInfo> exceptions) { 1319040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // write in a canonical order 1320d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein exceptions = (ArrayList<ClassInfo>) exceptions.clone(); 1321d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein Collections.sort(exceptions, ClassInfo.comparator); 1322d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein //final int N = exceptions.length; 1323040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato boolean first = true; 1324d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein for (ClassInfo ex : exceptions) { 1325040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato // Turn this off, b/c we need to regenrate the old xml files. 1326040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (true || !"java.lang.RuntimeException".equals(ex.qualifiedName()) 1327040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato && !ex.isDerivedFrom("java.lang.RuntimeException")) { 1328040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (first) { 1329040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" throws "); 1330040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato first = false; 1331040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else { 1332040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(", "); 1333040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1334040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(ex.qualifiedName()); 1335040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1336040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1337040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1338040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1339132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato static void writeFieldApi(PrintStream apiWriter, FieldInfo fi, String label) { 1340132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato apiWriter.print(" "); 1341132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato apiWriter.print(label); 1342132afe44b3b7963e47d4c32948b2667ddc00062cJoe Onorato apiWriter.print(" "); 1343040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(fi.scope()); 1344040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isStatic()) { 1345040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" static"); 1346040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1347040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isFinal()) { 1348040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" final"); 1349040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1350040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isDeprecated()) { 1351040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" deprecated"); 1352040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1353040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isTransient()) { 1354040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" transient"); 1355040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1356040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isVolatile()) { 1357040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" volatile"); 1358040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1359040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1360040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 13617751817561b5fea6ffaee8cad497ab6876deca0eYing Wang apiWriter.print(fi.type().fullName()); 1362040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1363040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" "); 1364040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(fi.name()); 1365040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1366040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato Object val = null; 1367040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (fi.isConstant() && fieldIsInitialized(fi)) { 1368040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(" = "); 1369040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(fi.constantLiteralValue()); 1370040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato val = fi.constantValue(); 1371040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1372040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1373040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print(";"); 1374040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1375040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (val != null) { 1376040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato if (val instanceof Integer && "char".equals(fi.type().qualifiedTypeName())) { 1377040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.format(" // 0x%04x '%s'", val, 1378040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato FieldInfo.javaEscapeString("" + ((char)((Integer)val).intValue()))); 1379040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if (val instanceof Byte || val instanceof Short || val instanceof Integer) { 1380040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.format(" // 0x%x", val); 1381040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } else if (val instanceof Long) { 1382040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.format(" // 0x%xL", val); 1383040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1384040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1385040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1386040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato apiWriter.print("\n"); 1387040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato } 1388040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato 1389970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeKeepList(PrintStream keepListWriter, 1390970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton HashMap<PackageInfo, List<ClassInfo>> allClasses, HashSet<ClassInfo> notStrippable) { 1391970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton // extract the set of packages, sort them by name, and write them out in that order 1392970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Set<PackageInfo> allClassKeys = allClasses.keySet(); 1393970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton PackageInfo[] allPackages = allClassKeys.toArray(new PackageInfo[allClassKeys.size()]); 1394970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Arrays.sort(allPackages, PackageInfo.comparator); 1395970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1396970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (PackageInfo pack : allPackages) { 1397970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writePackageKeepList(keepListWriter, pack, allClasses.get(pack), notStrippable); 1398970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1399970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1400970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1401970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writePackageKeepList(PrintStream keepListWriter, PackageInfo pack, 1402970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Collection<ClassInfo> classList, HashSet<ClassInfo> notStrippable) { 1403970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton // Work around the bogus "Array" class we invent for 1404970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton // Arrays.copyOf's Class<? extends T[]> newType parameter. (http://b/2715505) 1405970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (pack.name().equals(PackageInfo.DEFAULT_PACKAGE)) { 1406970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton return; 1407970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1408970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1409970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton ClassInfo[] classes = classList.toArray(new ClassInfo[classList.size()]); 1410970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Arrays.sort(classes, ClassInfo.comparator); 1411970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (ClassInfo cl : classes) { 1412970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeClassKeepList(keepListWriter, cl, notStrippable); 1413970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1414970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1415970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1416970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeClassKeepList(PrintStream keepListWriter, ClassInfo cl, 1417970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton HashSet<ClassInfo> notStrippable) { 1418970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("-keep class "); 1419970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(to$Class(cl.qualifiedName())); 1420970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1421970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" {\n"); 1422970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1423970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton ArrayList<MethodInfo> constructors = cl.constructors(); 1424970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Collections.sort(constructors, MethodInfo.comparator); 1425970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (MethodInfo mi : constructors) { 1426970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeConstructorKeepList(keepListWriter, mi); 1427970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1428970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1429970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("\n"); 1430970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1431970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton ArrayList<MethodInfo> methods = cl.allSelfMethods(); 1432970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Collections.sort(methods, MethodInfo.comparator); 1433970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (MethodInfo mi : methods) { 143437abe68eddab604d66d9d7c6eaeed5b0e2b2fc33Adam Metcalf // allSelfMethods is the non-hidden and visible methods. See Doclava.checkLevel. 143537abe68eddab604d66d9d7c6eaeed5b0e2b2fc33Adam Metcalf writeMethodKeepList(keepListWriter, mi); 1436970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1437970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1438970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("\n"); 1439970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1440970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton ArrayList<FieldInfo> enums = cl.enumConstants(); 1441970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Collections.sort(enums, FieldInfo.comparator); 1442970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (FieldInfo fi : enums) { 1443970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeFieldKeepList(keepListWriter, fi); 1444970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1445970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1446970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("\n"); 1447970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1448ae8cb832ba8239534b7529292065936bdb85b1e3Ying Wang ArrayList<FieldInfo> fields = cl.selfFields(); 1449970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton Collections.sort(fields, FieldInfo.comparator); 1450970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (FieldInfo fi : fields) { 1451970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeFieldKeepList(keepListWriter, fi); 1452970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1453970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1454970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("}\n\n"); 1455970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1456970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1457970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeConstructorKeepList(PrintStream keepListWriter, MethodInfo mi) { 1458970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1459970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton String name = mi.name(); 1460970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton name = name.replace(".", "$"); 1461970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(name); 1462970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1463970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeParametersKeepList(keepListWriter, mi, mi.parameters()); 1464970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(";\n"); 1465970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1466970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1467970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeMethodKeepList(PrintStream keepListWriter, MethodInfo mi) { 1468970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1469970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(mi.scope()); 1470970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (mi.isStatic()) { 1471970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" static"); 1472970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1473970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (mi.isAbstract()) { 1474970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" abstract"); 1475970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1476970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (mi.isSynchronized()) { 1477970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" synchronized"); 1478970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1479970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1480970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (mi.returnType() == null) { 1481970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("void"); 1482970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } else { 1483970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(getCleanTypeName(mi.returnType())); 1484970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1485970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1486970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(mi.name()); 1487970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1488970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton writeParametersKeepList(keepListWriter, mi, mi.parameters()); 1489970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1490970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(";\n"); 1491970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1492970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1493970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeParametersKeepList(PrintStream keepListWriter, MethodInfo method, 1494970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton ArrayList<ParameterInfo> params) { 1495970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print("("); 1496970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1497970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton for (ParameterInfo pi : params) { 1498970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (pi != params.get(0)) { 1499970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(", "); 1500970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1501550a9de05d89f19d1f824fbbb04ba7cd8a1ff86eJeff Hamilton keepListWriter.print(getCleanTypeName(pi.type())); 1502970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1503970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1504970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(")"); 1505970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1506970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1507970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static void writeFieldKeepList(PrintStream keepListWriter, FieldInfo fi) { 1508970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1509970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(fi.scope()); 1510970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (fi.isStatic()) { 1511970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" static"); 1512970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1513970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (fi.isTransient()) { 1514970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" transient"); 1515970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1516970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (fi.isVolatile()) { 1517970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" volatile"); 1518970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1519970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1520970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1521e64dc94c3548aba038c89438fc9fb492dc678c48Sergei Datsenko keepListWriter.print(getCleanTypeName(fi.type())); 1522970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1523970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(" "); 1524970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(fi.name()); 1525970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1526970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton keepListWriter.print(";\n"); 1527970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1528970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1529920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson static String fullParameterTypeName(MethodInfo method, TypeInfo type, boolean isLast) { 1530920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String fullTypeName = type.fullName(method.typeVariables()); 1531920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (isLast && method.isVarArgs()) { 1532920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // TODO: note that this does not attempt to handle hypothetical 1533920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // vararg methods whose last parameter is a list of arrays, e.g. 1534920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // "Object[]...". 1535920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson fullTypeName = type.fullNameNoDimension(method.typeVariables()) + "..."; 1536920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 1537920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return fullTypeName; 1538920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 1539970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1540970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static String to$Class(String name) { 1541970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton int pos = 0; 1542970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton while ((pos = name.indexOf('.', pos)) > 0) { 1543970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton String n = name.substring(0, pos); 1544970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton if (Converter.obtainClass(n) != null) { 1545970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton return n + (name.substring(pos).replace('.', '$')); 1546970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1547970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton pos = pos + 1; 1548970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1549970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton return name; 1550970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1551970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton 1552970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton static String getCleanTypeName(TypeInfo t) { 1553d6f2c2b6edce46c86581be1f508981742e20fb51Jeff Hamilton return t.isPrimitive() ? t.simpleTypeName() + t.dimension() : 15541e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton to$Class(t.asClassInfo().qualifiedName() + t.dimension()); 1555970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton } 1556920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson} 1557