Index: ChangeLog =================================================================== RCS file: /cvsroot/classpath/gjdoc/ChangeLog,v retrieving revision 1.180 diff -u -3 -p -u -r1.180 ChangeLog --- ChangeLog 8 Apr 2005 17:36:34 -0000 1.180 +++ ChangeLog 17 Apr 2005 13:50:15 -0000 @@ -1,3 +1,43 @@ +2005-04-17 Andrew John Hughes + + * src/com/sun/javadoc/ClassDoc.java: + (typeParameters()): New method for retrieving type variables. + * src/com/sun/javadoc/Type.java: + (asTypeVariable()): New method for casting to a type variable. + * src/com/sun/javadoc/TypeVariable.java: + New class to handle type variables. + (bounds()): New method to retrieve variable bounds. + (owner()): New method to retrieve owning class. + * src/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.java: + (printIndexEntry(HtmlPage,Doc)): Add type variables to class name. + (printClassPage(File,String,ClassDoc,ClassDoc,ClassDoc)): + Likewise. + (createTypeHref(HtmlPage,Type,boolean)): Likewise. + (getTypeParameters(ClassDoc)): New method to construct a String + containing the type parameters. + * src/gnu/classpath/tools/gjdoc/ClassDocImpl.java: + (asTypeVariable()): New method. + (createInstance(ClassDoc,PackageDoc,ClassDoc[],PackageDoc[],char[], + int,int,List)): Add parsing of type variables, which may contain ','. + (typeParameters()): New method to return the type parameters. + (parseTypeVariables(ClassDocImpl, String)): New method to parse + the type variables. + * src/gnu/classpath/tools/gjdoc/ClassDocProxy.java: + (asTypeVariable()): New method. + (typeParameters()): New method. + * src/gnu/classpath/tools/gjdoc/ClassDocReflectedImpl.java: + (asTypeVariable()): New method. + (typeParameters()): New method. + * src/gnu/classpath/tools/gjdoc/TypeImpl.java: + (asTypeVariable()): New variable to cast type variables. + * src/gnu/classpath/tools/gjdoc/TypeVariableImpl.java: + New class to represent type variables. + (TypeVariableImpl(String,String,String,ProgramElementDoc)): + New constructor, which also handles owning class. + (setBounds(List)): New method to set bounds. + (bounds()): New method to retrieve bounds. + (owner()): New method to retrieve owner. + 2005-04-08 Julian Scheid * src/gnu/classpath/tools/gjdoc/FieldDocImpl.java Index: src/com/sun/javadoc/ClassDoc.java =================================================================== RCS file: /cvsroot/classpath/gjdoc/src/com/sun/javadoc/ClassDoc.java,v retrieving revision 1.3 diff -u -3 -p -u -r1.3 ClassDoc.java --- src/com/sun/javadoc/ClassDoc.java 17 Dec 2004 17:54:21 -0000 1.3 +++ src/com/sun/javadoc/ClassDoc.java 17 Apr 2005 13:50:15 -0000 @@ -287,5 +287,18 @@ importedClasses(); public abstract PackageDoc[] importedPackages(); +/*************************************************************************/ + +/** + * This method returns the formal type parameters of this class. + * The returned array is empty if the class does not represent a + * parameterized type. + * + * @return The list of type parameters. + * @since 1.5 + */ +TypeVariable[] +typeParameters(); + } // interface ClassDoc Index: src/com/sun/javadoc/Type.java =================================================================== RCS file: /cvsroot/classpath/gjdoc/src/com/sun/javadoc/Type.java,v retrieving revision 1.2 diff -u -3 -p -u -r1.2 Type.java --- src/com/sun/javadoc/Type.java 13 Dec 2004 17:39:51 -0000 1.2 +++ src/com/sun/javadoc/Type.java 17 Apr 2005 13:50:15 -0000 @@ -87,5 +87,16 @@ asClassDoc(); public abstract boolean isPrimitive(); +/** + * Returns this type as a TypeVariable, if it is an + * instance of the TypeVariable class. Otherwise, + * it returns null. + * + * @return this cast to a TypeVariable instance, or null + * if this is not a type variable. + */ +TypeVariable +asTypeVariable(); + } // interface Type Index: src/com/sun/javadoc/TypeVariable.java =================================================================== RCS file: src/com/sun/javadoc/TypeVariable.java diff -N src/com/sun/javadoc/TypeVariable.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/com/sun/javadoc/TypeVariable.java 17 Apr 2005 13:50:15 -0000 @@ -0,0 +1,55 @@ +/* TypeVariable.java -- Document a Java type variable. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of the com.sun.javadoc implementation of GNU Classpath. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published +by the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software Foundation +Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA. */ + + +package com.sun.javadoc; + +/** + * This class represents a type variable, which is used to parameterize + * the types used in a method or class. For example, + * List<E> has the type variable, E. Type + * variables may have explicit bounds, such as <T extends + * Book>, which specifies that the type is a sub-class of + * Book. + * + * @since 1.5 + * @author Andrew John Hughes (address@hidden) + */ +public interface TypeVariable + extends Type +{ + + /** + * Returns the bounds of this type variable. These are the types + * represented in the extends clause. + * + * @return an array of types which specify the bounds of this variable. + * The array is empty if there are no explicit bounds. + */ + Type[] bounds(); + + /** + * Returns the class, interface, method or constructor in which this + * type variable was declared. + * + * @return the owning program element for this type variable. + */ + ProgramElementDoc owner(); + +} Index: src/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.java =================================================================== RCS file: /cvsroot/classpath/gjdoc/src/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.java,v retrieving revision 1.46 diff -u -3 -p -u -r1.46 HtmlDoclet.java --- src/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.java 8 Apr 2005 17:36:33 -0000 1.46 +++ src/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.java 17 Apr 2005 13:50:16 -0000 @@ -954,7 +954,7 @@ public class HtmlDoclet else if (entry instanceof ClassDoc) { ClassDoc classDoc = (ClassDoc)entry; output.beginAnchor(getClassURL(classDoc)); - output.print(entry.name()); + output.print(entry.name() + getTypeParameters(classDoc)); output.endAnchor(); output.print(" - "); if (entry.isInterface()) { @@ -1942,7 +1942,7 @@ public class HtmlDoclet printType(output, cd, true); } else { - output.print(cd.qualifiedName()); + output.print(cd.qualifiedName() + getTypeParameters(cd)); } output.endElement("code"); output.endElement("li"); @@ -2014,7 +2014,8 @@ public class HtmlDoclet keywords.add(methodDoc.name() + "()"); } } - + String parameters = getTypeParameters(classDoc); + output.beginPage(getPageTitle(classDoc.name()), getOutputCharset(), keywords, getStylesheets()); output.beginBody(CssClass.BODY_CONTENT_CLASS); @@ -2025,7 +2026,8 @@ public class HtmlDoclet classDoc.containingPackage().name()); output.div(CssClass.CLASS_TITLE_CLASS, getClassTypeName(classDoc) - + " " + classDoc.name()); + + " " + classDoc.name() + + parameters); output.endDiv(CssClass.CLASS_TITLE); boolean needSep = false; @@ -2113,11 +2115,11 @@ public class HtmlDoclet output.beginSpan(CssClass.CLASS_SYNOPSIS_NAME); if (optionLinkSource.getValue() && null != classDoc.position()) { output.beginAnchor(getOuterClassDoc(classDoc).name() + "-source" + filenameExtension + "#line." + classDoc.position()); - output.print(classDoc.name()); + output.print(classDoc.name() + parameters); output.endAnchor(); } else { - output.print(classDoc.name()); + output.print(classDoc.name() + parameters); } output.endSpan(CssClass.CLASS_SYNOPSIS_NAME); output.endDiv(CssClass.CLASS_SYNOPSIS_DECLARATION); @@ -2883,15 +2885,16 @@ public class HtmlDoclet StringBuffer result = new StringBuffer(); if (null != url && null != asClassDoc) { + String parameters = getTypeParameters(asClassDoc); if (fullyQualified) { - result.append(output.createHrefString(url, possiblyQualifiedName(asClassDoc))); + result.append(output.createHrefString(url,possiblyQualifiedName(asClassDoc) + parameters)); } else { StringBuffer title = new StringBuffer(); title.append(getClassTypeName(asClassDoc)); title.append(" in "); title.append(asClassDoc.containingPackage().name()); - result.append(output.createHrefString(url, asClassDoc.name(), title.toString())); + result.append(output.createHrefString(url, asClassDoc.name() + parameters, title.toString())); } } else { @@ -3628,4 +3631,34 @@ public class HtmlDoclet return super.isSinglePackage(); } } + + private String getTypeParameters(ClassDoc classDoc) + { + String parameters = ""; + TypeVariable[] params = classDoc.typeParameters(); + if (params != null) + { + parameters = "<"; + for (int a = 0; a < params.length; ++a) + { + parameters += params[a].typeName(); + Type[] bounds = params[a].bounds(); + if (bounds != null) + { + parameters += " extends "; + for (int b = 0; a < bounds.length; ++b) + { + parameters += bounds[a]; + if (b != bounds.length - 1) + parameters += " & "; + } + } + if (a != params.length - 1) + parameters += ","; + } + parameters += ">"; + } + return parameters; + } + } Index: src/gnu/classpath/tools/gjdoc/ClassDocImpl.java =================================================================== RCS file: /cvsroot/classpath/gjdoc/src/gnu/classpath/tools/gjdoc/ClassDocImpl.java,v retrieving revision 1.22 diff -u -3 -p -u -r1.22 ClassDocImpl.java --- src/gnu/classpath/tools/gjdoc/ClassDocImpl.java 8 Apr 2005 17:36:33 -0000 1.22 +++ src/gnu/classpath/tools/gjdoc/ClassDocImpl.java 17 Apr 2005 13:50:16 -0000 @@ -258,6 +258,7 @@ public class ClassDocImpl public String toString() { return "ClassDoc{"+qualifiedTypeName()+"}"; } + public TypeVariable asTypeVariable() { return null; } public static ClassDocImpl createInstance(ClassDoc containingClass, PackageDoc containingPackage, @@ -315,7 +316,8 @@ public class ClassDocImpl word=word.substring(0,word.length()-1); processWord=true; } - else if (c=='{' || c==',' || Parser.WHITESPACE.indexOf(c)>=0) { + else if (c=='{' || c==',' && item > 1 || + Parser.WHITESPACE.indexOf(c)>=0) { processWord=true; } else { @@ -355,7 +357,15 @@ public class ClassDocImpl item=3; } else if (item==1) { - rc.setClass(word); + int parameterIndex = word.indexOf("<"); + if (parameterIndex == -1) + rc.setClass(word); + else + { + rc.setClass(word.substring(0, parameterIndex)); + parseTypeVariables(rc,word.substring(parameterIndex, + word.length())); + } } else if (item==2) { //Debug.log(9,"setting baseclass of "+rc+" to "+word); @@ -603,6 +613,7 @@ public class ClassDocImpl private MethodDoc[] unfilteredMethods; private ConstructorDoc[] filteredConstructors; private ConstructorDoc[] unfilteredConstructors; + private TypeVariable[] typeParameters; private boolean resolved=false; @@ -1014,5 +1025,83 @@ public class ClassDocImpl { return importStatementList; } + + public TypeVariable[] typeParameters() + { + return typeParameters; + } + + /** + *

+ * Parses the type variables declared in the class definition. + * The syntax is: + *

+ *

+ *

+ *
TypeParameters:
+ *
< TypeParameter { , TypeParameter }
+ *
TypeParameter:
+ *
Identifier { extends Bound + * }
+ *
Bound:
+ *
Type{& Type }
+ *
+ * + * @param rc the owning class. + * @param typeVariables the string to be parsed. + * @throws ParseException if parsing fails. + */ + public static void parseTypeVariables(ClassDocImpl rc, + String typeVariables) + throws ParseException + { + List parsedBounds = null; + StringTokenizer parameters = new StringTokenizer(typeVariables, + Parser.WHITESPACE + + "<>,"); + List variables = new ArrayList(); + while (parameters.hasMoreTokens()) + { + String parameter = parameters.nextToken(); + StringTokenizer parts = new StringTokenizer(parameter, + Parser.WHITESPACE); + TypeVariableImpl variable = new TypeVariableImpl(rc.qualifiedName(), + parts.nextToken(),"", + rc); + if (parts.hasMoreTokens()) + { + if (!parts.nextToken().equals("extends")) + throw new ParseException("Invalid type parameter: " + parameter); + StringTokenizer bounds = new StringTokenizer(parts.nextToken(), + Parser.WHITESPACE + + "&"); + parsedBounds = new ArrayList(); + while (bounds.hasMoreTokens()) + { + String bound = bounds.nextToken(); + int nameSep = bound.lastIndexOf("."); + String packageName = bound.substring(0, nameSep); + String boundName = bound.substring(nameSep, bound.length()); + parsedBounds.add(new TypeImpl(packageName,boundName,"")); + } + } + if (parsedBounds != null) + variable.setBounds(parsedBounds); + variables.add(variable); + } + rc.setTypeParameters(variables); + } + + /** + * Set the type parameters to the contents of the supplied list. + * + * @param variables a list of type parameters. + */ + void setTypeParameters(List variables) + { + typeParameters = + (TypeVariable[]) variables.toArray(new TypeVariable[variables.size()]); + } + } Index: src/gnu/classpath/tools/gjdoc/ClassDocProxy.java =================================================================== RCS file: /cvsroot/classpath/gjdoc/src/gnu/classpath/tools/gjdoc/ClassDocProxy.java,v retrieving revision 1.10 diff -u -3 -p -u -r1.10 ClassDocProxy.java --- src/gnu/classpath/tools/gjdoc/ClassDocProxy.java 20 Dec 2004 21:27:52 -0000 1.10 +++ src/gnu/classpath/tools/gjdoc/ClassDocProxy.java 17 Apr 2005 13:50:16 -0000 @@ -124,6 +124,7 @@ public class ClassDocProxy implements Cl public String qualifiedTypeName() { return qualifiedName; } public String dimension() { return dimension; } public ClassDoc asClassDoc() { return this; } + public TypeVariable asTypeVariable() { return null; } public boolean isPrimitive() { return false; } public String toString() { return "ClassDocProxy{"+qualifiedName+", context="+classContext+"}"; } @@ -145,4 +146,7 @@ public class ClassDocProxy implements Cl return 0; } } + + public TypeVariable[] typeParameters() { return new TypeVariable[0]; } + } Index: src/gnu/classpath/tools/gjdoc/ClassDocReflectedImpl.java =================================================================== RCS file: /cvsroot/classpath/gjdoc/src/gnu/classpath/tools/gjdoc/ClassDocReflectedImpl.java,v retrieving revision 1.2 diff -u -3 -p -u -r1.2 ClassDocReflectedImpl.java --- src/gnu/classpath/tools/gjdoc/ClassDocReflectedImpl.java 21 Dec 2004 13:34:33 -0000 1.2 +++ src/gnu/classpath/tools/gjdoc/ClassDocReflectedImpl.java 17 Apr 2005 13:50:16 -0000 @@ -173,6 +173,7 @@ public class ClassDocReflectedImpl public String typeName() { return name; } public String qualifiedTypeName() { return qualifiedName(); } public ClassDoc asClassDoc() { return this; } + public TypeVariable asTypeVariable() { return null; } public boolean isPrimitive() { return false; } public String toString() { return "ClassDocReflectedImpl{"+qualifiedName()+"}"; } @@ -195,4 +196,7 @@ public class ClassDocReflectedImpl public Object clone() throws CloneNotSupportedException { return super.clone(); } + + public TypeVariable[] typeParameters() { return new TypeVariable[0]; } + } Index: src/gnu/classpath/tools/gjdoc/TypeImpl.java =================================================================== RCS file: /cvsroot/classpath/gjdoc/src/gnu/classpath/tools/gjdoc/TypeImpl.java,v retrieving revision 1.5 diff -u -3 -p -u -r1.5 TypeImpl.java --- src/gnu/classpath/tools/gjdoc/TypeImpl.java 13 Dec 2004 17:39:51 -0000 1.5 +++ src/gnu/classpath/tools/gjdoc/TypeImpl.java 17 Apr 2005 13:50:16 -0000 @@ -80,4 +80,13 @@ public class TypeImpl implements Type, W _primitiveNames.add("double"); primitiveNames = Collections.unmodifiableSet(_primitiveNames); } + + public TypeVariable asTypeVariable() + { + if (this instanceof TypeVariable) + return (TypeVariable) this; + else + return null; + } + } Index: src/gnu/classpath/tools/gjdoc/TypeVariableImpl.java =================================================================== RCS file: src/gnu/classpath/tools/gjdoc/TypeVariableImpl.java diff -N src/gnu/classpath/tools/gjdoc/TypeVariableImpl.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/gnu/classpath/tools/gjdoc/TypeVariableImpl.java 17 Apr 2005 13:50:16 -0000 @@ -0,0 +1,91 @@ +/* gnu.classpath.tools.gjdoc.TypeVariableImpl + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. */ + +package gnu.classpath.tools.gjdoc; + +import com.sun.javadoc.ProgramElementDoc; +import com.sun.javadoc.Type; +import com.sun.javadoc.TypeVariable; + +import java.util.List; + +public class TypeVariableImpl + extends TypeImpl + implements TypeVariable, WritableType +{ + + /** + * The bounds of this particular type variable. + */ + Type[] bounds; + + /** + * The owning program element of this type variable. + */ + ProgramElementDoc owner; + + /** + * Constructs a new type variable with the supplied name and owner. + * + * @param packageName the name of the package containing the type variable. + * @param typeName the name of the type variable. + * @param dimension the dimensions of the type variable (always ""). + * @param owner the owning program element of the type variable. + */ + TypeVariableImpl(String packageName, String typeName, String dimension, + ProgramElementDoc owner) + { + super(packageName, typeName, dimension); + this.owner = owner; + } + + /** + * Set the bounds to the contents of the supplied list. + * + * @param parsedBounds a list of type bounds. + */ + void setBounds(List parsedBounds) + { + bounds = (Type[]) parsedBounds.toArray(new Type[parsedBounds.size()]); + } + + /** + * Returns the bounds of this type variable. + * + * @return the bounds of the variable. + */ + public Type[] bounds() + { + return bounds; + } + + /** + * Returns the owning program element for this type variable. + * + * @return the owning program element, whether a class, interface, + * constructor or method. + */ + public ProgramElementDoc owner() + { + return owner; + } + + +}