WorkArounds.java revision 3294:9adfb22ff08f
138061Smsmith/* 255939Snsouch * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 370608Snsouch * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 438061Smsmith * 538061Smsmith * This code is free software; you can redistribute it and/or modify it 638061Smsmith * under the terms of the GNU General Public License version 2 only, as 738061Smsmith * published by the Free Software Foundation. Oracle designates this 838061Smsmith * particular file as subject to the "Classpath" exception as provided 938061Smsmith * by Oracle in the LICENSE file that accompanied this code. 1038061Smsmith * 1138061Smsmith * This code is distributed in the hope that it will be useful, but WITHOUT 1238061Smsmith * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1338061Smsmith * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1438061Smsmith * version 2 for more details (a copy is included in the LICENSE file that 1538061Smsmith * accompanied this code). 1638061Smsmith * 1738061Smsmith * You should have received a copy of the GNU General Public License version 1838061Smsmith * 2 along with this work; if not, write to the Free Software Foundation, 1938061Smsmith * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2038061Smsmith * 2138061Smsmith * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2238061Smsmith * or visit www.oracle.com if you need additional information or have any 2338061Smsmith * questions. 2438061Smsmith */ 2538061Smsmith 2638061Smsmithpackage jdk.javadoc.internal.doclets.toolkit; 2738061Smsmith 2838061Smsmithimport java.util.ArrayList; 2938061Smsmithimport java.util.Arrays; 30119418Sobrienimport java.util.Collection; 31119418Sobrienimport java.util.Collections; 32119418Sobrienimport java.util.HashMap; 3355205Speterimport java.util.List; 3438061Smsmithimport java.util.Map; 3538061Smsmithimport java.util.SortedSet; 3655939Snsouchimport java.util.TreeSet; 3755939Snsouch 3838061Smsmithimport javax.lang.model.element.AnnotationMirror; 3938061Smsmithimport javax.lang.model.element.Element; 4038061Smsmithimport javax.lang.model.element.ExecutableElement; 4155205Speterimport javax.lang.model.element.ModuleElement; 4238061Smsmithimport javax.lang.model.element.PackageElement; 4342475Snsouchimport javax.lang.model.element.TypeElement; 4442475Snsouchimport javax.lang.model.element.VariableElement; 4555939Snsouchimport javax.lang.model.type.TypeMirror; 4638061Smsmithimport javax.lang.model.util.Elements; 4738061Smsmithimport javax.tools.JavaFileObject; 4838061Smsmith 4938061Smsmithimport com.sun.source.tree.CompilationUnitTree; 5055939Snsouchimport com.sun.source.util.JavacTask; 5155939Snsouchimport com.sun.source.util.TreePath; 5238061Smsmithimport com.sun.tools.doclint.DocLint; 5338061Smsmithimport com.sun.tools.javac.api.BasicJavacTask; 5438061Smsmithimport com.sun.tools.javac.code.Attribute; 5538061Smsmithimport com.sun.tools.javac.code.Flags; 5638061Smsmithimport com.sun.tools.javac.code.Scope; 5738061Smsmithimport com.sun.tools.javac.code.Symbol; 5838061Smsmithimport com.sun.tools.javac.code.Symbol.ClassSymbol; 5938061Smsmithimport com.sun.tools.javac.code.Symbol.MethodSymbol; 6038061Smsmithimport com.sun.tools.javac.code.Symbol.VarSymbol; 6138061Smsmithimport com.sun.tools.javac.comp.AttrContext; 6238061Smsmithimport com.sun.tools.javac.comp.Env; 6338061Smsmithimport com.sun.tools.javac.model.JavacElements; 6438061Smsmithimport com.sun.tools.javac.model.JavacTypes; 6538061Smsmithimport com.sun.tools.javac.util.Names; 6638061Smsmith 6738061Smsmithimport jdk.javadoc.internal.doclets.toolkit.util.Utils; 6838061Smsmithimport jdk.javadoc.internal.tool.DocEnv; 6938061Smsmithimport jdk.javadoc.internal.tool.RootDocImpl; 7038061Smsmith 7138061Smsmithimport static com.sun.tools.javac.code.Kinds.Kind.*; 7238061Smsmithimport static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; 7338061Smsmith 7438061Smsmithimport static javax.lang.model.element.ElementKind.*; 7538061Smsmith 7638061Smsmith/** 7738061Smsmith * A quarantine class to isolate all the workarounds and bridges to 7838061Smsmith * a locality. This class should eventually disappear once all the 7938061Smsmith * standard APIs support the needed interfaces. 8038061Smsmith * 8138061Smsmith * 8238061Smsmith * <p><b>This is NOT part of any supported API. 8338061Smsmith * If you write code that depends on this, you do so at your own risk. 8439134Snsouch * This code and its internal interfaces are subject to change or 8539134Snsouch * deletion without notice.</b> 8638061Smsmith */ 8738061Smsmithpublic class WorkArounds { 8838061Smsmith 8938061Smsmith public final Configuration configuration; 9038061Smsmith public final DocEnv env; 9138061Smsmith public final Utils utils; 9238061Smsmith 9338061Smsmith private DocLint doclint; 9438061Smsmith 9538061Smsmith public WorkArounds(Configuration configuration) { 9638061Smsmith this.configuration = configuration; 9738061Smsmith this.utils = this.configuration.utils; 9838061Smsmith this.env = ((RootDocImpl)this.configuration.root).env; 9978645Snsouch } 10078645Snsouch 10178645Snsouch Map<CompilationUnitTree, Boolean> shouldCheck = new HashMap<>(); 10278645Snsouch // TODO: fix this up correctly 10378645Snsouch public void runDocLint(TreePath path) { 10478645Snsouch CompilationUnitTree unit = path.getCompilationUnit(); 10578645Snsouch if (doclint != null && shouldCheck.computeIfAbsent(unit, doclint::shouldCheck)) { 10678645Snsouch doclint.scan(path); 10778645Snsouch } 10878645Snsouch } 10978645Snsouch 11078645Snsouch // TODO: fix this up correctly 11178645Snsouch public void initDocLint(Collection<String> opts, Collection<String> customTagNames, String htmlVersion) { 11278645Snsouch ArrayList<String> doclintOpts = new ArrayList<>(); 11378645Snsouch boolean msgOptionSeen = false; 11439134Snsouch 11539134Snsouch for (String opt : opts) { 11639134Snsouch if (opt.startsWith(DocLint.XMSGS_OPTION)) { 11739134Snsouch if (opt.equals(DocLint.XMSGS_CUSTOM_PREFIX + "none")) 11845342Speter return; 11939134Snsouch msgOptionSeen = true; 12045342Speter } 12139134Snsouch doclintOpts.add(opt); 12239134Snsouch } 12339134Snsouch 12439134Snsouch if (!msgOptionSeen) { 12539134Snsouch doclintOpts.add(DocLint.XMSGS_OPTION); 12638061Smsmith } 12738061Smsmith 12838061Smsmith String sep = ""; 12938061Smsmith StringBuilder customTags = new StringBuilder(); 13038061Smsmith for (String customTag : customTagNames) { 13138061Smsmith customTags.append(sep); 13238061Smsmith customTags.append(customTag); 13339134Snsouch sep = DocLint.SEPARATOR; 13439134Snsouch } 13538061Smsmith doclintOpts.add(DocLint.XCUSTOM_TAGS_PREFIX + customTags.toString()); 13638061Smsmith doclintOpts.add(DocLint.XHTML_VERSION_PREFIX + htmlVersion); 13738061Smsmith 13838061Smsmith JavacTask t = BasicJavacTask.instance(env.context); 13938061Smsmith doclint = new DocLint(); 14038061Smsmith // standard doclet normally generates H1, H2 14138061Smsmith doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2"); 14239134Snsouch doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false); 14338061Smsmith } 14438061Smsmith 14538061Smsmith // TODO: fix this up correctly 14638061Smsmith public boolean haveDocLint() { 14739134Snsouch return (doclint == null); 14838061Smsmith } 14938061Smsmith 15038061Smsmith // TODO: jx.l.m directSuperTypes don't work for things like Enum, 15138061Smsmith // so we use javac directly, investigate why jx.l.m is not cutting it. 15239134Snsouch public List<TypeMirror> interfaceTypesOf(TypeMirror type) { 15338061Smsmith com.sun.tools.javac.util.List<com.sun.tools.javac.code.Type> interfaces = 15438061Smsmith ((RootDocImpl)configuration.root).env.getTypes().interfaces((com.sun.tools.javac.code.Type)type); 15538061Smsmith if (interfaces.isEmpty()) { 15638061Smsmith return Collections.emptyList(); 15738061Smsmith } 15838061Smsmith List<TypeMirror> list = new ArrayList<>(interfaces.size()); 15938061Smsmith for (com.sun.tools.javac.code.Type t : interfaces) { 16038061Smsmith list.add((TypeMirror)t); 16138061Smsmith } 16238061Smsmith return list; 16338061Smsmith } 16438061Smsmith 16538061Smsmith /* 16638061Smsmith * TODO: This method exists because of a bug in javac which does not 16738061Smsmith * handle "@deprecated tag in package-info.java", when this issue 16838061Smsmith * is fixed this method and its uses must be jettisoned. 16938061Smsmith */ 17038061Smsmith public boolean isDeprecated0(Element e) { 17138061Smsmith if (!utils.getDeprecatedTrees(e).isEmpty()) { 17238061Smsmith return true; 17378645Snsouch } 17478645Snsouch JavacTypes jctypes = ((RootDocImpl)configuration.root).env.typeutils; 17578645Snsouch TypeMirror deprecatedType = utils.getDeprecatedType(); 17678645Snsouch for (AnnotationMirror anno : e.getAnnotationMirrors()) { 17738061Smsmith if (jctypes.isSameType(anno.getAnnotationType().asElement().asType(), deprecatedType)) 17838061Smsmith return true; 17938061Smsmith } 18038061Smsmith return false; 18138061Smsmith } 18238061Smsmith 18338061Smsmith // TODO: fix jx.l.m add this method. 18478645Snsouch public boolean isSynthesized(AnnotationMirror aDesc) { 18578645Snsouch return ((Attribute)aDesc).isSynthesized(); 18678645Snsouch } 18778645Snsouch 18878645Snsouch // TODO: implement using jx.l.model 18978645Snsouch public boolean isVisible(TypeElement te) { 19078645Snsouch return env.isVisible((ClassSymbol)te); 19178645Snsouch } 19278645Snsouch 19378645Snsouch // TODO: fix the caller 19478645Snsouch public Object getConstValue(VariableElement ve) { 19578645Snsouch return ((VarSymbol)ve).getConstValue(); 19678645Snsouch } 19778645Snsouch 19838061Smsmith //TODO: DocTrees: Trees.getPath(Element e) is slow a factor 4-5 times. 19938061Smsmith public Map<Element, TreePath> getElementToTreePath() { 20038061Smsmith return env.elementToTreePath; 20138061Smsmith } 20239134Snsouch 20338061Smsmith // TODO: needs to ported to jx.l.m. 20438061Smsmith public TypeElement searchClass(TypeElement klass, String className) { 20538061Smsmith // search by qualified name first 20638061Smsmith TypeElement te = configuration.root.getElementUtils().getTypeElement(className); 20738061Smsmith if (te != null) { 20838061Smsmith return te; 20943433Snsouch } 21038061Smsmith 21138061Smsmith // search inner classes 21238061Smsmith for (TypeElement ite : utils.getClasses(klass)) { 21338061Smsmith TypeElement innerClass = searchClass(ite, className); 21438061Smsmith if (innerClass != null) { 21538061Smsmith return innerClass; 21638061Smsmith } 21738061Smsmith } 21839134Snsouch 21938061Smsmith // check in this package 22038061Smsmith te = utils.findClassInPackageElement(utils.containingPackage(klass), className); 221185003Sjhb if (te != null) { 22238061Smsmith return te; 22338061Smsmith } 22438061Smsmith 22543433Snsouch ClassSymbol tsym = (ClassSymbol)klass; 22638061Smsmith // make sure that this symbol has been completed 22738061Smsmith // TODO: do we need this anymore ? 22838061Smsmith if (tsym.completer != null) { 22938061Smsmith tsym.complete(); 23038061Smsmith } 23138061Smsmith 23239134Snsouch // search imports 23338061Smsmith if (tsym.sourcefile != null) { 23438061Smsmith 23538061Smsmith //### This information is available only for source classes. 236185003Sjhb Env<AttrContext> compenv = env.getEnv(tsym); 23743433Snsouch if (compenv == null) { 23843433Snsouch return null; 23938061Smsmith } 24038061Smsmith Names names = tsym.name.table.names; 24138061Smsmith Scope s = compenv.toplevel.namedImportScope; 24238061Smsmith for (Symbol sym : s.getSymbolsByName(names.fromString(className))) { 24338061Smsmith if (sym.kind == TYP) { 24438061Smsmith return (TypeElement)sym; 24538061Smsmith } 24638061Smsmith } 24739134Snsouch 24838061Smsmith s = compenv.toplevel.starImportScope; 24938061Smsmith for (Symbol sym : s.getSymbolsByName(names.fromString(className))) { 25038061Smsmith if (sym.kind == TYP) { 251185003Sjhb return (TypeElement)sym; 25243433Snsouch } 25343433Snsouch } 25438061Smsmith } 25538061Smsmith 25638061Smsmith return null; // not found 25738061Smsmith } 25838061Smsmith 25938061Smsmith // TODO: need to re-implement this using j.l.m. correctly!, this has 26038061Smsmith // implications on testInterface, the note here is that javac's supertype 26138061Smsmith // does the right thing returning Parameters in scope. 26239134Snsouch /** 26339134Snsouch * Return the type containing the method that this method overrides. 26439134Snsouch * It may be a <code>TypeElement</code> or a <code>TypeParameterElement</code>. 26539134Snsouch * @param method target 26643433Snsouch * @return a type 26739134Snsouch */ 26843433Snsouch public TypeMirror overriddenType(ExecutableElement method) { 26939134Snsouch if (utils.isStatic(method)) { 27039520Snsouch return null; 27139134Snsouch } 27239520Snsouch MethodSymbol sym = (MethodSymbol)method; 27339134Snsouch ClassSymbol origin = (ClassSymbol) sym.owner; 27439134Snsouch for (com.sun.tools.javac.code.Type t = env.getTypes().supertype(origin.type); 27538061Smsmith t.hasTag(com.sun.tools.javac.code.TypeTag.CLASS); 27638061Smsmith t = env.getTypes().supertype(t)) { 27738061Smsmith ClassSymbol c = (ClassSymbol) t.tsym; 27855939Snsouch for (com.sun.tools.javac.code.Symbol sym2 : c.members().getSymbolsByName(sym.name)) { 27938061Smsmith if (sym.overrides(sym2, origin, env.getTypes(), true)) { 28038061Smsmith return t; 28155939Snsouch } 28255939Snsouch } 28338061Smsmith } 28438061Smsmith return null; 28538061Smsmith } 28638061Smsmith 28738061Smsmith // TODO: investigate and reimplement without javac dependencies. 28838061Smsmith public boolean shouldDocument(Element e) { 28938061Smsmith return env.shouldDocument(e); 29038061Smsmith } 29155939Snsouch 29238061Smsmith //------------------Start of Serializable Implementation---------------------// 29338061Smsmith private final static Map<TypeElement, NewSerializedForm> serializedForms = new HashMap<>(); 29438061Smsmith 29555939Snsouch public SortedSet<VariableElement> getSerializableFields(Utils utils, TypeElement klass) { 29642475Snsouch NewSerializedForm sf = serializedForms.get(klass); 29742475Snsouch if (sf == null) { 29887599Sobrien sf = new NewSerializedForm(utils, configuration.root.getElementUtils(), klass); 29942475Snsouch serializedForms.put(klass, sf); 300185003Sjhb } 30142475Snsouch return sf.fields; 30238061Smsmith } 30355939Snsouch 30455939Snsouch public SortedSet<ExecutableElement> getSerializationMethods(Utils utils, TypeElement klass) { 30538061Smsmith NewSerializedForm sf = serializedForms.get(klass); 30655939Snsouch if (sf == null) { 30738061Smsmith sf = new NewSerializedForm(utils, configuration.root.getElementUtils(), klass); 30838061Smsmith serializedForms.put(klass, sf); 30938061Smsmith } 31038061Smsmith return sf.methods; 31138061Smsmith } 31239134Snsouch 31338061Smsmith public boolean definesSerializableFields(Utils utils, TypeElement klass) { 31439134Snsouch if (!utils.isSerializable(klass) || utils.isExternalizable(klass)) { 31538061Smsmith return false; 31639134Snsouch } else { 317185003Sjhb NewSerializedForm sf = serializedForms.get(klass); 31838061Smsmith if (sf == null) { 31955939Snsouch sf = new NewSerializedForm(utils, configuration.root.getElementUtils(), klass); 32039134Snsouch serializedForms.put(klass, sf); 32138061Smsmith } 32239134Snsouch return sf.definesSerializableFields; 32338061Smsmith } 32439134Snsouch } 32538061Smsmith 32639134Snsouch /* TODO we need a clean port to jx.l.m 32739134Snsouch * The serialized form is the specification of a class' serialization state. 32839134Snsouch * <p> 32939134Snsouch * 33039134Snsouch * It consists of the following information: 33139134Snsouch * <p> 33238061Smsmith * 33339134Snsouch * <pre> 33455939Snsouch * 1. Whether class is Serializable or Externalizable. 33539134Snsouch * 2. Javadoc for serialization methods. 33639134Snsouch * a. For Serializable, the optional readObject, writeObject, 33738061Smsmith * readResolve and writeReplace. 33838061Smsmith * serialData tag describes, in prose, the sequence and type 33938061Smsmith * of optional data written by writeObject. 34039134Snsouch * b. For Externalizable, writeExternal and readExternal. 34138061Smsmith * serialData tag describes, in prose, the sequence and type 34239134Snsouch * of optional data written by writeExternal. 34339134Snsouch * 3. Javadoc for serialization data layout. 34438061Smsmith * a. For Serializable, the name,type and description 34555939Snsouch * of each Serializable fields. 34639134Snsouch * b. For Externalizable, data layout is described by 2(b). 34738061Smsmith * </pre> 34855939Snsouch * 34938061Smsmith */ 35039134Snsouch static class NewSerializedForm { 35138061Smsmith 35238061Smsmith final Utils utils; 35338061Smsmith final Elements elements; 35438061Smsmith 35538061Smsmith final SortedSet<ExecutableElement> methods; 35638061Smsmith 35738061Smsmith /* List of FieldDocImpl - Serializable fields. 35839134Snsouch * Singleton list if class defines Serializable fields explicitly. 35938061Smsmith * Otherwise, list of default serializable fields. 36038061Smsmith * 0 length list for Externalizable. 36155939Snsouch */ 36239520Snsouch final SortedSet<VariableElement> fields; 36338061Smsmith 36439520Snsouch /* True if class specifies serializable fields explicitly. 36555939Snsouch * using special static member, serialPersistentFields. 366185003Sjhb */ 36739520Snsouch boolean definesSerializableFields = false; 36878645Snsouch 36955939Snsouch // Specially treated field/method names defined by Serialization. 37039520Snsouch private static final String SERIALIZABLE_FIELDS = "serialPersistentFields"; 37170608Snsouch private static final String READOBJECT = "readObject"; 37270608Snsouch private static final String WRITEOBJECT = "writeObject"; 37370608Snsouch private static final String READRESOLVE = "readResolve"; 37470608Snsouch private static final String WRITEREPLACE = "writeReplace"; 37555939Snsouch private static final String READOBJECTNODATA = "readObjectNoData"; 37670608Snsouch 37739520Snsouch NewSerializedForm(Utils utils, Elements elements, TypeElement te) { 37870608Snsouch this.utils = utils; 37970608Snsouch this.elements = elements; 38070608Snsouch methods = new TreeSet<>(utils.makeGeneralPurposeComparator()); 38139520Snsouch fields = new TreeSet<>(utils.makeGeneralPurposeComparator()); 38270608Snsouch if (utils.isExternalizable(te)) { 38370608Snsouch /* look up required public accessible methods, 38470608Snsouch * writeExternal and readExternal. 38570608Snsouch */ 38670608Snsouch String[] readExternalParamArr = {"java.io.ObjectInput"}; 38739520Snsouch String[] writeExternalParamArr = {"java.io.ObjectOutput"}; 38870608Snsouch 38970608Snsouch ExecutableElement md = findMethod(te, "readExternal", Arrays.asList(readExternalParamArr)); 39070608Snsouch if (md != null) { 39170608Snsouch methods.add(md); 39270608Snsouch } 39370608Snsouch md = findMethod((ClassSymbol) te, "writeExternal", Arrays.asList(writeExternalParamArr)); 39470608Snsouch if (md != null) { 39570608Snsouch methods.add(md); 39670608Snsouch } 39770608Snsouch } else if (utils.isSerializable(te)) { 39855939Snsouch VarSymbol dsf = getDefinedSerializableFields((ClassSymbol) te); 39970608Snsouch if (dsf != null) { 40070608Snsouch /* Define serializable fields with array of ObjectStreamField. 40139520Snsouch * Each ObjectStreamField should be documented by a 402184130Sjhb * serialField tag. 403184130Sjhb */ 40439520Snsouch definesSerializableFields = true; 40539520Snsouch fields.add((VariableElement) dsf); 40655939Snsouch } else { 40739520Snsouch 40839520Snsouch /* Calculate default Serializable fields as all 40939520Snsouch * non-transient, non-static fields. 41070608Snsouch * Fields should be documented by serial tag. 41170608Snsouch */ 41238061Smsmith computeDefaultSerializableFields((ClassSymbol) te); 41338061Smsmith } 41438061Smsmith 41538061Smsmith /* Check for optional customized readObject, writeObject, 41638061Smsmith * readResolve and writeReplace, which can all contain 41755939Snsouch * the serialData tag. */ 41838061Smsmith addMethodIfExist((ClassSymbol) te, READOBJECT); 419185003Sjhb addMethodIfExist((ClassSymbol) te, WRITEOBJECT); 42039134Snsouch addMethodIfExist((ClassSymbol) te, READRESOLVE); 42170608Snsouch addMethodIfExist((ClassSymbol) te, WRITEREPLACE); 42239520Snsouch addMethodIfExist((ClassSymbol) te, READOBJECTNODATA); 423184130Sjhb } 424184130Sjhb } 42539520Snsouch 42639520Snsouch private VarSymbol getDefinedSerializableFields(ClassSymbol def) { 42738061Smsmith Names names = def.name.table.names; 42855939Snsouch 42938061Smsmith /* SERIALIZABLE_FIELDS can be private, 43039520Snsouch */ 43139520Snsouch for (Symbol sym : def.members().getSymbolsByName(names.fromString(SERIALIZABLE_FIELDS))) { 43255939Snsouch if (sym.kind == VAR) { 43339520Snsouch VarSymbol f = (VarSymbol) sym; 43438061Smsmith if ((f.flags() & Flags.STATIC) != 0 43538061Smsmith && (f.flags() & Flags.PRIVATE) != 0) { 43638061Smsmith return f; 43738061Smsmith } 43838061Smsmith } 43938061Smsmith } 44038061Smsmith return null; 44138061Smsmith } 44255939Snsouch 44338061Smsmith /* 44438061Smsmith * Catalog Serializable method if it exists in current ClassSymbol. 44555939Snsouch * Do not look for method in superclasses. 44645342Speter * 44738061Smsmith * Serialization requires these methods to be non-static. 44855939Snsouch * 44938061Smsmith * @param method should be an unqualified Serializable method 45038061Smsmith * name either READOBJECT, WRITEOBJECT, READRESOLVE 45138061Smsmith * or WRITEREPLACE. 45238061Smsmith * @param visibility the visibility flag for the given method. 45338061Smsmith */ 45438061Smsmith private void addMethodIfExist(ClassSymbol def, String methodName) { 45538061Smsmith Names names = def.name.table.names; 45638061Smsmith 45738061Smsmith for (Symbol sym : def.members().getSymbolsByName(names.fromString(methodName))) { 45838061Smsmith if (sym.kind == MTH) { 45955939Snsouch MethodSymbol md = (MethodSymbol) sym; 46038061Smsmith if ((md.flags() & Flags.STATIC) == 0) { 46138061Smsmith /* 46255939Snsouch * WARNING: not robust if unqualifiedMethodName is overloaded 46345342Speter * method. Signature checking could make more robust. 46438061Smsmith * READOBJECT takes a single parameter, java.io.ObjectInputStream. 46555939Snsouch * WRITEOBJECT takes a single parameter, java.io.ObjectOutputStream. 46638061Smsmith */ 46738061Smsmith methods.add(md); 46838061Smsmith } 46938061Smsmith } 47038061Smsmith } 47138061Smsmith } 47238061Smsmith 47355939Snsouch /* 47438061Smsmith * Compute default Serializable fields from all members of ClassSymbol. 47538061Smsmith * 47638061Smsmith * must walk over all members of ClassSymbol. 47738061Smsmith */ 47838061Smsmith private void computeDefaultSerializableFields(ClassSymbol te) { 47938061Smsmith for (Symbol sym : te.members().getSymbols(NON_RECURSIVE)) { 48038061Smsmith if (sym != null && sym.kind == VAR) { 48138061Smsmith VarSymbol f = (VarSymbol) sym; 48238061Smsmith if ((f.flags() & Flags.STATIC) == 0 48338061Smsmith && (f.flags() & Flags.TRANSIENT) == 0) { 48438061Smsmith //### No modifier filtering applied here. 48538061Smsmith //### Add to beginning. 48638061Smsmith //### Preserve order used by old 'javadoc'. 48738061Smsmith fields.add(f); 48838061Smsmith } 48938061Smsmith } 49038061Smsmith } 49138061Smsmith } 49243433Snsouch 49343433Snsouch /** 49438061Smsmith * Find a method in this class scope. Search order: this class, interfaces, superclasses, 49538061Smsmith * outerclasses. Note that this is not necessarily what the compiler would do! 49638061Smsmith * 49738061Smsmith * @param methodName the unqualified name to search for. 49838061Smsmith * @param paramTypes the array of Strings for method parameter types. 49938061Smsmith * @return the first MethodDocImpl which matches, null if not found. 50038061Smsmith */ 50138061Smsmith public ExecutableElement findMethod(TypeElement te, String methodName, 502185003Sjhb List<String> paramTypes) { 50355939Snsouch List<? extends Element> allMembers = this.elements.getAllMembers(te); 50438061Smsmith loop: 50538061Smsmith for (Element e : allMembers) { 50638061Smsmith if (e.getKind() != METHOD) { 50738061Smsmith continue; 50838061Smsmith } 50938061Smsmith ExecutableElement ee = (ExecutableElement) e; 51038061Smsmith if (!ee.getSimpleName().contentEquals(methodName)) { 51138061Smsmith continue; 51238061Smsmith } 51338061Smsmith List<? extends VariableElement> parameters = ee.getParameters(); 51438061Smsmith if (paramTypes.size() != parameters.size()) { 51538061Smsmith continue; 51638061Smsmith } 51738061Smsmith for (int i = 0; i < parameters.size(); i++) { 51838061Smsmith VariableElement ve = parameters.get(i); 51938061Smsmith if (!ve.asType().toString().equals(paramTypes.get(i))) { 52038061Smsmith break loop; 52178645Snsouch } 52278645Snsouch } 52355939Snsouch return ee; 52478645Snsouch } 52538061Smsmith TypeElement encl = utils.getEnclosingTypeElement(te); 52638061Smsmith if (encl == null) { 52755939Snsouch return null; 52838061Smsmith } 52938061Smsmith return findMethod(encl, methodName, paramTypes); 53055939Snsouch } 53138061Smsmith } 53238061Smsmith 53338061Smsmith // TODO: this is a fast way to get the JavaFileObject for 53438061Smsmith // a package.html file, however we need to eliminate this. 53538061Smsmith public JavaFileObject getJavaFileObject(PackageElement pe) { 53638061Smsmith return env.pkgToJavaFOMap.get(pe); 53738061Smsmith } 53838061Smsmith 53938061Smsmith // TODO: we need to eliminate this, as it is hacky. 54038061Smsmith /** 54178645Snsouch * Returns a representation of the package truncated to two levels. 54278645Snsouch * For instance if the given package represents foo.bar.baz will return 54378645Snsouch * a representation of foo.bar 54478645Snsouch * @param pkg the PackageElement 54578645Snsouch * @return an abbreviated PackageElement 54678645Snsouch */ 54778645Snsouch public PackageElement getAbbreviatedPackageElement(PackageElement pkg) { 548185003Sjhb String parsedPackageName = utils.parsePackageName(pkg); 54978645Snsouch ModuleElement encl = (ModuleElement) pkg.getEnclosingElement(); 55078645Snsouch PackageElement abbrevPkg = encl == null 55138061Smsmith ? utils.elementUtils.getPackageElement(parsedPackageName) 55238061Smsmith : ((JavacElements) utils.elementUtils).getPackageElement(encl, parsedPackageName); 55338061Smsmith return abbrevPkg; 55438061Smsmith } 55538061Smsmith} 55638061Smsmith