1 /* gnu.classpath.tools.gjdoc.ClassDocImpl
2 Copyright (C) 2001, 2012 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu.classpath.tools.gjdoc;
40 import com.sun.javadoc.*;
43 import gnu.classpath.tools.gjdoc.expr.EvaluatorEnvironment;
44 import gnu.classpath.tools.gjdoc.expr.CircularExpressionException;
45 import gnu.classpath.tools.gjdoc.expr.IllegalExpressionException;
46 import gnu.classpath.tools.gjdoc.expr.UnknownIdentifierException;
48 public class ClassDocImpl
49 extends ProgramElementDocImpl
50 implements ClassDoc, WritableType, EvaluatorEnvironment {
52 private ClassDoc baseClassDoc;
53 private ClassDoc[] importedClasses;
54 private PackageDoc[] importedPackages;
55 private boolean definesSerializableFields;
56 private FieldDoc[] serialPersistentField;
57 private MethodDoc[] serializationMethods;
58 private String dimension = "";
60 public ClassDocImpl(ClassDoc containingClass,
61 PackageDoc containingPackage,
65 SourcePosition position) {
66 super(containingClass, containingPackage, accessLevel, isFinal, isStatic,
68 this.baseClassDoc = this;
71 public ClassDocImpl(ClassDoc containingClass,
72 PackageDoc containingPackage,
73 ClassDoc[] importedClasses,
74 PackageDoc[] importedPackages,
75 SourcePosition position) {
76 super(containingClass, containingPackage,
78 this.importedClasses=importedClasses;
79 this.importedPackages=importedPackages;
80 this.baseClassDoc = this;
83 // Return constructors in class.
84 public ConstructorDoc[] constructors() {
85 return constructors(true);
88 public ConstructorDoc[] constructors(boolean filter) {
89 return filter ? filteredConstructors : unfilteredConstructors;
92 // Return true if Serializable fields are explicitly defined with the special class member serialPersistentFields.
93 public boolean definesSerializableFields() {
94 return definesSerializableFields;
97 // Return fields in class.
98 public FieldDoc[] fields() {
102 public FieldDoc[] fields(boolean filter) {
103 return filter ? filteredFields : unfilteredFields;
106 private static Set<String> primitiveNames;
108 primitiveNames = new HashSet<String>();
109 primitiveNames.add("int");
110 primitiveNames.add("long");
111 primitiveNames.add("char");
112 primitiveNames.add("short");
113 primitiveNames.add("byte");
114 primitiveNames.add("float");
115 primitiveNames.add("double");
116 primitiveNames.add("boolean");
119 private Map<String,ClassDoc> findClassCache = new HashMap<String,ClassDoc>();
121 public ClassDoc findClass(String className, String dimension)
123 ClassDoc cached = findClassCache.get(className + dimension);
124 if (null != cached) {
128 ClassDoc classDoc = findClass(className);
130 if (null!=classDoc) {
132 if (classDoc.dimension().equals(dimension)) {
136 ClassDoc rc = (ClassDoc) ((WritableType)classDoc).clone();
137 ((WritableType)rc).setDimension(dimension);
138 findClassCache.put(className + dimension, rc);
142 catch (CloneNotSupportedException e) {
143 throw new RuntimeException(e);
152 public ClassDoc findClass(String className)
154 String qualifiedName = Main.getRootDoc().resolveClassName(className, this);
155 ClassDoc rc=Main.getRootDoc().classNamed(qualifiedName);
158 for (ClassDoc cdi=this; cdi!=null; cdi=cdi.containingClass()) {
159 for (ClassDoc sdi=cdi; sdi!=null; sdi=sdi.superclass()) {
160 if (sdi instanceof ClassDocProxy) {
161 ClassDoc realClass = Main.getRootDoc().classNamed(sdi.qualifiedName());
162 if (null != realClass) {
166 rc=Main.getRootDoc().classNamed(sdi.qualifiedName()+"."+className);
167 if (rc!=null) return rc;
175 // Get the list of classes declared as imported.
176 public ClassDoc[] importedClasses() {
177 return importedClasses;
180 // Get the list of packages declared as imported.
181 public PackageDoc[] importedPackages() {
182 return importedPackages;
185 // Return inner classes within this class.
186 public ClassDoc[] innerClasses() {
187 return innerClasses(true);
190 public ClassDoc[] innerClasses(boolean filtered) {
191 return filtered ? filteredInnerClasses : unfilteredInnerClasses;
194 void setFilteredInnerClasses(ClassDoc[] filteredInnerClasses) {
195 this.filteredInnerClasses=filteredInnerClasses;
198 void setInnerClasses(ClassDoc[] unfilteredInnerClasses) {
199 this.unfilteredInnerClasses=unfilteredInnerClasses;
202 // Return interfaces implemented by this class or interfaces extended by this interface.
203 public ClassDoc[] interfaces() {
207 public void setInterfaces(ClassDoc[] interfaces) {
208 this.interfaces=interfaces;
211 // Return true if this class is abstract
212 public boolean isAbstract() {
213 return isAbstract || isInterface();
216 public boolean isInterface() {
220 public boolean isAnnotation() {
224 public boolean isEnum()
229 // Return true if this class is abstract
230 public void setIsAbstract(boolean b) {
234 // Return true if this class implements java.io.Externalizable.
235 public boolean isExternalizable() {
236 return implementsInterface("java.io.Externalizable");
239 // Return true if this class implements java.io.Serializable.
240 public boolean isSerializable() {
241 return implementsInterface("java.io.Serializable");
244 public boolean implementsInterface(String name) {
245 for (ClassDoc cdi=this; cdi!=null; cdi=(ClassDoc)cdi.superclass()) {
246 if (cdi instanceof ClassDocImpl) {
247 ClassDoc[] cdiInterfaces=(ClassDoc[])cdi.interfaces();
248 if (null != cdiInterfaces) {
249 for (int i=0; i<cdiInterfaces.length; ++i) {
250 if (cdiInterfaces[i].qualifiedName().equals(name))
256 //throw new RuntimeException("implementsInterface(\""+name+"\") failed: Not a ClassDocImpl:"+cdi);
262 // Return methods in class.
263 public MethodDoc[] methods() {
264 return methods(true);
267 // Return methods in class.
268 public MethodDoc[] methods(boolean filter) {
269 return filter ? filteredMethods : unfilteredMethods;
272 // Return the Serializable fields of class. Return either a list of default fields documented by serial tag or return a single FieldDoc for serialPersistentField member.
273 public FieldDoc[] serializableFields() {
274 if (serialPersistentField!=null) {
275 return serialPersistentField;
278 return serializableFields;
282 // Return the serialization methods for this class.
283 public MethodDoc[] serializationMethods() {
284 return serializationMethods;
287 // Test whether this class is a subclass of the specified class.
288 public boolean subclassOf(ClassDoc cd) {
289 for (ClassDocImpl cdi=(ClassDocImpl)superclass(); cdi!=null; cdi=(ClassDocImpl)cdi.superclass()) {
296 // Return the superclass of this class
297 public ClassDoc superclass() {
301 // Implementation of Interface Type
303 public ClassDoc asClassDoc() {
305 return (ClassDoc)this;
308 public String typeName() { return name(); }
310 public String qualifiedTypeName() {
311 return (containingPackage()!=null && !containingPackage().equals(PackageDocImpl.DEFAULT_PACKAGE))?(containingPackage().name()+"."+name()):(name());
314 public String qualifiedName() { return qualifiedTypeName(); }
316 public String dimension() { return dimension; }
318 public String toString() { return "ClassDoc{"+qualifiedTypeName()+"}"; }
320 public TypeVariable asTypeVariable() { return null; }
322 public static ClassDocImpl createInstance(ClassDoc containingClass,
323 PackageDoc containingPackage,
324 ClassDoc[] importedClasses,
325 PackageDoc[] importedPackages,
326 char[] source, int startIndex, int endIndex,
327 List<String> importStatementList) throws ParseException, IOException {
329 String superclassName = "java.lang.Object";
331 ClassDocImpl rc=new ClassDocImpl(containingClass,
336 rc.setImportStatementList(importStatementList);
337 List<String> implementedInterfaces = new ArrayList<String>();
342 final int STATE_NORMAL = 1;
343 final int STATE_SLASHC = 2;
344 final int STATE_STARC = 3;
345 final int STATE_ANNO = 4;
347 int state=STATE_NORMAL;
351 for (int ndx=startIndex; ndx<=endIndex; ++ndx) {
352 char c=(ndx==endIndex)?10:source[ndx];
353 boolean processWord=false;
354 if (state==STATE_SLASHC) {
360 else if (state==STATE_STARC) {
361 if (c=='/' && prev=='*') {
367 if (c=='/' && prev=='/') {
370 word=word.substring(0,word.length()-1);
373 else if (c=='*' && prev=='/') {
376 word=word.substring(0,word.length()-1);
383 else if (c=='(' && state==STATE_ANNO) {
387 else if (c==')' && state==STATE_ANNO) {
403 else if (c=='{' && parLevel == 0 ||
404 c==',' && varLevel == 0 && parLevel == 0 ||
405 Parser.WHITESPACE.indexOf(c)>=0 && parLevel == 0 && varLevel == 0) {
413 if (processWord && word.length()>0) {
415 if (rc.processModifier(word)) {
417 else if (word.equals("abstract")) {
418 rc.setIsAbstract(true);
420 else if (word.equals("class")) {
421 rc.setIsInterface(false);
424 else if (word.equals("enum"))
429 else if (word.equals("interface")) {
430 rc.setIsInterface(true);
433 else if (word.equals("@interface")) {
434 rc.setIsInterface(true);
435 rc.setIsAnnotation(true);
438 else if (word.equals("strictfp")) {
441 Main.getRootDoc().printWarning("unknown modifier '"+word+"'");
444 else if (word.equals("extends") && !rc.isAnnotation()) {
445 if (rc.isInterface()) {
452 else if (word.equals("implements") && !rc.isAnnotation()) {
456 int parameterIndex = word.indexOf("<");
457 if (parameterIndex == -1)
461 rc.setClass(word.substring(0, parameterIndex));
462 parseTypeVariables(rc,word.substring(parameterIndex,
467 //Debug.log(9,"setting baseclass of "+rc+" to "+word);
468 int parameterIndex = word.indexOf("<");
469 if (parameterIndex == -1)
473 /* FIXME: Parse type parameters */
474 superclassName=word.substring(0,parameterIndex);
478 int parameterIndex = word.indexOf("<");
479 if (parameterIndex == -1)
480 implementedInterfaces.add(word);
483 /* FIXME: Parse type parameters */
484 implementedInterfaces.add(word.substring(0,parameterIndex));
490 if (c=='{' && state==STATE_NORMAL) break;
495 if (null != containingClass
496 && containingClass.isInterface()) {
497 rc.accessLevel = ACCESS_PUBLIC;
500 if (rc.name()==null) {
501 throw new ParseException("No classdef found in expression \""+new String(source,startIndex,endIndex-startIndex)+"\"");
504 rc.setPosition(ClassDocImpl.getPosition(rc, source, startIndex));
506 ClassDoc superclassProxy=new ClassDocProxy(superclassName, rc);
508 if (!rc.qualifiedName().equals("java.lang.Object")) {
509 rc.setSuperclass(superclassProxy);
512 ClassDoc[] interfaces=new ClassDoc[implementedInterfaces.size()];
513 for (int i=0; i<interfaces.length; ++i) {
514 interfaces[i]=new ClassDocProxy(implementedInterfaces.get(i), rc);
516 rc.setInterfaces(interfaces);
518 if (rc.isInterface() && rc.containingClass()!=null) {
519 rc.setIsStatic(true);
524 public void setFields(FieldDoc[] fields) {
525 this.unfilteredFields=fields;
528 public void setFilteredFields(FieldDoc[] fields) {
529 this.filteredFields=fields;
532 public void setSerializableFields(FieldDoc[] sfields) {
533 this.serializableFields=sfields;
536 public void setMethods(MethodDoc[] methods) {
537 this.unfilteredMethods=methods;
540 public void setFilteredMethods(MethodDoc[] methods) {
541 this.filteredMethods=methods;
544 public void setConstructors(ConstructorDoc[] constructors) {
545 this.unfilteredConstructors=constructors;
548 public void setFilteredConstructors(ConstructorDoc[] constructors) {
549 this.filteredConstructors=constructors;
552 // Returns the name of this Doc item.
553 public String name() {
554 if (containingClass==null) {
558 return containingClass.name()+"."+className;
562 public String getClassName() {
566 public void setClass(String className) {
567 this.className=className;
570 void setSuperclass(ClassDoc superclass) {
571 this.superclass=superclass;
574 public void resolve() throws ParseException {
578 if (containingClass!=null)
579 ((ClassDocImpl)containingClass).resolve();
581 //Debug.log(9,"resolving class '"+qualifiedName()+"'");
583 for (int i=0; i<importedPackages.length; ++i) {
584 Debug.log(9,"class "+qualifiedName()+" imports "+importedPackages[i].name());
588 if (superclass instanceof ClassDocProxy) {
590 ClassDoc realClassDoc=findClass(superclass.qualifiedName());
592 if (realClassDoc==null) {
594 if (true) { // Main.recursiveClasses) {
595 throw new ParseException("In class '"+qualifiedName()+"': class '"+className+"' not found.");
600 superclass=realClassDoc;
604 if (null != interfaces) {
605 for (int i=0; i<interfaces.length; ++i) {
606 if (interfaces[i] instanceof ClassDocProxy) {
607 //Debug.log(9,"class "+qualifiedName()+" implements "+interfaces[i].qualifiedName());
608 ClassDoc realClassDoc=findClass(interfaces[i].qualifiedName());
609 if (realClassDoc==null) {
611 if (Main.recursiveClasses) {
612 throw new ParseException("In class '"+qualifiedName()+"': class '"+className+"' not found.");
617 //Debug.log(9,"found class '"+className+"': "+interfaces[i]);
618 interfaces[i]=realClassDoc;
624 if (unfilteredFields!=null) {
625 for (int i=0; i<unfilteredFields.length; ++i) {
626 ((FieldDocImpl)unfilteredFields[i]).resolve();
627 if (unfilteredFields[i].name().equals("serialPersistentField")) {
628 serialPersistentField=new FieldDoc[]{unfilteredFields[i]};
629 definesSerializableFields=true;
634 if (unfilteredMethods!=null) {
635 for (int i=0; i<unfilteredMethods.length; ++i) {
636 ((MethodDocImpl)unfilteredMethods[i]).resolve();
640 if (unfilteredConstructors!=null) {
641 for (int i=0; i<unfilteredConstructors.length; ++i) {
642 ((ConstructorDocImpl)unfilteredConstructors[i]).resolve();
646 List<MethodDoc> isSerMethodList = new ArrayList<MethodDoc>();
648 if (null != maybeSerMethodList) {
649 for (Iterator<MethodDoc> it = maybeSerMethodList.iterator(); it.hasNext(); ) {
650 MethodDocImpl method=(MethodDocImpl)it.next();
653 if (((method.name().equals("readObject")
654 && method.signature().equals("(java.io.ObjectInputStream)"))
655 || (method.name().equals("writeObject")
656 && method.signature().equals("(java.io.ObjectOutputStream)"))
657 || (method.name().equals("readExternal")
658 && method.signature().equals("(java.io.ObjectInput)"))
659 || (method.name().equals("writeExternal")
660 && method.signature().equals("(java.io.ObjectOutput)"))
661 || (method.name().equals("readResolve")
662 && method.signature().equals("()")))) {
664 isSerMethodList.add(method);
667 this.serializationMethods = isSerMethodList.toArray(new MethodDoc[isSerMethodList.size()]);
668 maybeSerMethodList=null;
673 public FieldDoc findFieldRec(String name) {
674 return findFieldRec(this, name);
677 private static FieldDoc findFieldRec(ClassDoc classDoc, String name)
679 FieldDoc field = findField(classDoc, name);
684 ClassDoc[] interfaces = classDoc.interfaces();
685 for (int i=0; i<interfaces.length; ++i) {
686 field = findFieldRec(interfaces[i], name);
691 if (null != classDoc.superclass()) {
692 return findFieldRec(classDoc.superclass(), name);
700 private static FieldDoc findField(ClassDoc classDoc, String name)
702 FieldDoc[] fields = classDoc.fields(false);
703 for (int i=0; i<fields.length; ++i) {
704 if (fields[i].name().equals(name)) {
711 public FieldDoc findField(String fieldName) {
712 for (int i=0; i<filteredFields.length; ++i) {
713 if (filteredFields[i].name().equals(fieldName)) {
714 return filteredFields[i];
720 public void resolveComments() {
722 super.resolveComments();
724 if (null != unfilteredFields) {
725 for (int i=0; i<unfilteredFields.length; ++i) {
726 ((FieldDocImpl)unfilteredFields[i]).resolveComments();
730 if (null != serializableFields) {
731 for (int i=0; i<serializableFields.length; ++i) {
732 ((FieldDocImpl)serializableFields[i]).resolveComments();
735 if (null != unfilteredMethods) {
736 for (int i=0; i<unfilteredMethods.length; ++i) {
737 ((MethodDocImpl)unfilteredMethods[i]).resolveComments();
740 if (null != unfilteredConstructors) {
741 for (int i=0; i<unfilteredConstructors.length; ++i) {
742 ((ConstructorDocImpl)unfilteredConstructors[i]).resolveComments();
750 private String className=null;
752 private boolean isAbstract;
753 private boolean isInterface;
754 private boolean isAnnotation;
755 private boolean isEnum;
756 private ClassDoc[] interfaces;
757 private ClassDoc[] filteredInnerClasses;
758 private ClassDoc[] unfilteredInnerClasses;
759 private FieldDoc[] filteredFields;
760 private FieldDoc[] unfilteredFields;
761 private FieldDoc[] serializableFields;
762 private MethodDoc[] filteredMethods;
763 private MethodDoc[] unfilteredMethods;
764 private ConstructorDoc[] filteredConstructors;
765 private ConstructorDoc[] unfilteredConstructors;
766 private TypeVariable[] typeParameters;
768 private boolean resolved=false;
770 private ClassDoc superclass;
772 // Is this Doc item a class.
773 public boolean isClass() {
777 // return true if this Doc is include in the active set.
778 public boolean isIncluded() {
779 if (this == baseClassDoc) {
781 || (null != containingClass && Main.getInstance().includeAccessLevel(accessLevel));
784 return baseClassDoc.isIncluded();
788 void setIsIncluded(boolean b) {
792 private boolean isIncluded=false;
794 void setImportedClasses(ClassDoc[] importedClasses) {
795 this.importedClasses=importedClasses;
798 private static Map<String,Type> typeMap = new HashMap<String,Type>();
800 Type typeForString(String typeName) throws ParseException {
801 //String orgTypename=typeName;
802 int ndx=typeName.indexOf('[');
805 for (int i=ndx; i<typeName.length(); ++i) {
806 if ("[]".indexOf(typeName.charAt(i))>=0) {
807 dim+=typeName.charAt(i);
810 typeName=typeName.substring(0,ndx).trim();
813 ClassDoc classDoc = findClass(typeName, dim);
814 if (null != classDoc) {
818 Type type = typeMap.get(typeName+dim);
821 if (type.dimension().equals(dim)) {
825 Type rc = (Type) ((WritableType)type).clone();
826 ((WritableType)rc).setDimension(dim);
830 catch (CloneNotSupportedException e) {
831 throw new ParseException(e.toString());
835 if ("boolean".equals(typeName)
836 || "char".equals(typeName)
837 || "byte".equals(typeName)
838 || "short".equals(typeName)
839 || "int".equals(typeName)
840 || "long".equals(typeName)
841 || "void".equals(typeName)
842 || "float".equals(typeName)
843 || "double".equals(typeName)) {
844 Type rc=new TypeImpl(null, typeName, dim);
845 typeMap.put(typeName+dim, rc);
849 if (Main.getInstance().isDocletRunning()) {
850 //System.err.println(findClass("java.lang.String"));
851 //throw new ParseException("Doclet running, class not found: "+typeName+" ("+orgTypename+")");
853 Type rc=new ClassDocProxy(typeName, this);
854 ((WritableType)rc).setDimension(dim);
858 public boolean isException() {
859 for (ClassDoc cdi=this;
861 cdi=cdi.superclass()) {
863 if ("java.lang.Exception".equals(cdi.qualifiedName()))
869 public boolean isError() {
870 for (ClassDoc cdi=this; cdi!=null; cdi=cdi.superclass()) {
871 if ("java.lang.Error".equals(cdi.qualifiedName()))
877 public boolean isOrdinaryClass() {
878 return !isException() && !isError() && !isInterface();
881 public void setIsInterface(boolean b) {
885 public void setIsAnnotation(boolean b) {
889 public void setIsEnum(boolean b)
894 public ExecutableMemberDoc findExecutableRec(String nameAndSignature) {
896 ExecutableMemberDoc rc;
897 for (ClassDoc cdi=this; cdi!=null; ) {
898 rc=findMethod(cdi, nameAndSignature);
899 if (rc!=null) return rc;
900 rc=findConstructor(cdi, nameAndSignature);
901 if (rc!=null) return rc;
903 ClassDoc _superclass = cdi.superclass();
904 if (null == _superclass) {
914 public static ConstructorDoc findConstructor(ClassDoc classDoc, String nameAndSignature) {
915 int ndx=nameAndSignature.indexOf('(');
919 String fullSignature = resolveSignature(classDoc, nameAndSignature.substring(ndx));
920 return findConstructor(classDoc,
921 nameAndSignature.substring(0,ndx),
926 public static ConstructorDoc findConstructor(ClassDoc classDoc, String name, String signature) {
927 ConstructorDoc[] filteredConstructors = classDoc.constructors(true);
928 if (null != filteredConstructors) {
929 for (int i=0; i<filteredConstructors.length; ++i) {
930 ConstructorDoc constructor = filteredConstructors[i];
931 if (constructor.name().equals(name) && constructor.signature().equals(signature))
938 public static MethodDoc findMethod(ClassDoc classDoc, String nameAndSignature) {
939 int ndx=nameAndSignature.indexOf('(');
944 String name = nameAndSignature.substring(0,ndx);
945 String fullSignature = resolveSignature(classDoc, nameAndSignature.substring(ndx));
946 return findMethod(classDoc, name, fullSignature);
950 private static String resolveSignature(ClassDoc classDoc, String signature)
952 signature = signature.substring(1, signature.length() - 1).trim();
953 if (0 == signature.length()) {
956 StringTokenizer st = new StringTokenizer(signature, ",");
957 StringBuffer fullSignature = new StringBuffer("(");
958 while (st.hasMoreTokens()) {
959 String type = st.nextToken().trim();
960 int ndx = type.length();
961 while (ndx > 0 && type.charAt(ndx - 1) == '[' || type.charAt(ndx - 1) == ']') {
964 String dim = type.substring(ndx);
965 type = type.substring(0, ndx);
966 ClassDoc typeClass = classDoc.findClass(type);
967 if (fullSignature.length() > 1) {
968 fullSignature.append(",");
970 if (null != typeClass) {
971 fullSignature.append(typeClass.qualifiedName());
974 fullSignature.append(type);
976 fullSignature.append(dim);
978 fullSignature.append(')');
979 return fullSignature.toString();
982 public static MethodDoc findMethod(ClassDoc classDoc, String name, String signature) {
983 MethodDoc[] filteredMethods = classDoc.methods(true);
984 if (null != filteredMethods) {
985 for (int i=0; i<filteredMethods.length; ++i) {
986 MethodDoc method = filteredMethods[i];
987 if (method.name().equals(name) && method.signature().equals(signature))
994 public boolean equals(Object o) {
995 return (o!=null) && (o instanceof ClassDoc) && ((ClassDoc)o).qualifiedName().equals(qualifiedName());
998 private List<MethodDoc> maybeSerMethodList;
1000 void setMaybeSerMethodList(List<MethodDoc> maybeSerMethodList) {
1001 this.maybeSerMethodList=maybeSerMethodList;
1004 public void setDimension(String dimension) {
1005 this.dimension = dimension;
1008 public Object clone() throws CloneNotSupportedException {
1009 ClassDocImpl result = (ClassDocImpl)super.clone();
1010 result.baseClassDoc = baseClassDoc;
1014 public int superHashCode()
1016 return super.hashCode();
1019 public int hashCode()
1021 return qualifiedTypeName().hashCode();
1024 public ClassDoc getBaseClassDoc()
1026 return baseClassDoc;
1029 public FieldDoc getFieldDoc(String name)
1031 for (int i=0; i<unfilteredFields.length; ++i) {
1032 if (name.equals(unfilteredFields[i].name())) {
1033 return unfilteredFields[i];
1039 public MethodDoc getMethodDoc(String name, String signature)
1041 for (int i=0; i<unfilteredMethods.length; ++i) {
1042 if (name.equals(unfilteredMethods[i].name())
1043 && signature.equals(unfilteredMethods[i].signature())) {
1044 return unfilteredMethods[i];
1051 public ConstructorDoc getConstructorDoc(String signature)
1053 for (int i=0; i<unfilteredConstructors.length; ++i) {
1054 if (signature.equals(unfilteredConstructors[i].signature())) {
1055 return unfilteredConstructors[i];
1061 private Object findFieldValue(String identifier,
1064 Set<FieldDoc> visitedFields)
1065 throws UnknownIdentifierException, IllegalExpressionException
1067 while (classDoc != null) {
1068 if (classDoc instanceof ClassDocImpl) {
1069 FieldDocImpl fieldDoc
1070 = (FieldDocImpl)((ClassDocImpl)classDoc).getFieldDoc(fieldName);
1071 if (visitedFields.contains(fieldDoc)) {
1072 throw new CircularExpressionException("Circular reference detected");
1074 else if (null != fieldDoc) {
1075 return fieldDoc.constantValue(visitedFields);
1079 ClassDoc[] _interfaces = classDoc.interfaces();
1080 if (null != _interfaces) {
1081 for (int i=0; i<_interfaces.length; ++i) {
1082 if (_interfaces[i] instanceof ClassDocImpl) {
1083 FieldDocImpl fieldDoc
1084 = (FieldDocImpl)((ClassDocImpl)_interfaces[i]).getFieldDoc(fieldName);
1085 if (visitedFields.contains(fieldDoc)) {
1086 throw new CircularExpressionException("Circular reference detected");
1088 else if (null != fieldDoc) {
1089 return fieldDoc.constantValue(visitedFields);
1095 classDoc = classDoc.superclass();
1097 throw new UnknownIdentifierException(identifier);
1100 public Object getValue(String identifier, Set<FieldDoc> visitedFields)
1101 throws UnknownIdentifierException, IllegalExpressionException
1103 int ndx = identifier.lastIndexOf('.');
1105 String _className = identifier.substring(0, ndx);
1106 String _fieldName = identifier.substring(ndx + 1);
1108 ClassDoc _classDoc = findClass(_className);
1109 if (null != _classDoc) {
1110 return findFieldValue(identifier, _classDoc, _fieldName, visitedFields);
1113 throw new UnknownIdentifierException(identifier);
1117 return findFieldValue(identifier, this, identifier, visitedFields);
1121 public boolean isPrimitive()
1126 // Compares this Object with the specified Object for order.
1127 public int compareTo(Doc d) {
1130 if (d instanceof ClassDocImpl) {
1132 ClassDocImpl c1 = this;
1133 ClassDocImpl c2 = (ClassDocImpl)d;
1135 if (null != c1.containingClass() && null == c2.containingClass()) {
1136 rc = c1.containingClass().compareTo(c2);
1142 else if (null == c1.containingClass() && null != c2.containingClass()) {
1143 rc = c1.compareTo(c2.containingClass());
1149 else if (null != c1.containingClass() && null != c2.containingClass()) {
1150 rc = c1.containingClass().compareTo(c2.containingClass());
1156 rc = super.compareTo(d);
1158 return Main.getInstance().getCollator().compare(containingPackage().name(),
1159 c2.containingPackage().name());
1170 private List<String> importStatementList;
1172 public void setImportStatementList(List<String> importStatementList)
1174 this.importStatementList = new LinkedList<String>();
1175 this.importStatementList.addAll(importStatementList);
1178 public List getImportSpecifierList()
1180 return importStatementList;
1183 public TypeVariable[] typeParameters()
1185 return typeParameters;
1190 * Parses the type variables declared in the class definition.
1195 * <dt>TypeParameters:</dt>
1196 * <dd><code>< <em>TypeParameter</em> { <em>, TypeParameter }</code></dd>
1197 * <dt>TypeParameter:</dt>
1198 * <dd><code><em>Identifier</em> { <strong>extends</strong> <em>Bound</em>
1201 * <dd><code><em>Type</em>{<strong>&</strong> <em>Type</em> } </dd>
1204 * @param rc the owning class.
1205 * @param typeVariables the string to be parsed.
1206 * @throws ParseException if parsing fails.
1208 public static void parseTypeVariables(ClassDocImpl rc,
1209 String typeVariables)
1210 throws ParseException
1212 List parsedBounds = null;
1213 StringTokenizer parameters = new StringTokenizer(typeVariables,
1216 List variables = new ArrayList();
1217 while (parameters.hasMoreTokens())
1219 String parameter = parameters.nextToken();
1220 StringTokenizer parts = new StringTokenizer(parameter,
1222 TypeVariableImpl variable = new TypeVariableImpl(rc.qualifiedName(),
1223 parts.nextToken(),"",
1225 if (parts.hasMoreTokens())
1227 if (!parts.nextToken().equals("extends"))
1228 throw new ParseException("Invalid type parameter: " + parameter);
1229 StringTokenizer bounds = new StringTokenizer(parts.nextToken(),
1232 parsedBounds = new ArrayList();
1233 while (bounds.hasMoreTokens())
1235 String bound = bounds.nextToken();
1236 int nameSep = bound.lastIndexOf(".");
1237 String packageName = bound.substring(0, nameSep);
1238 String boundName = bound.substring(nameSep, bound.length());
1239 parsedBounds.add(new TypeImpl(packageName,boundName,""));
1242 if (parsedBounds != null)
1243 variable.setBounds(parsedBounds);
1244 variables.add(variable);
1246 rc.setTypeParameters(variables);
1250 * Set the type parameters to the contents of the supplied list.
1252 * @param variables a list of type parameters.
1254 void setTypeParameters(List variables)
1257 (TypeVariable[]) variables.toArray(new TypeVariable[variables.size()]);