- Revision
- 1292
- Author
- rfscholte
- Date
- 2011-08-13 17:23:49 -0500 (Sat, 13 Aug 2011)
Log Message
Start explaining how Type.resolve works, in order to move it to a separate class. Small simplifying code fragment.
Modified Paths
Diff
Modified: trunk/qdox/src/main/java/com/thoughtworks/qdox/model/Type.java (1291 => 1292)
--- trunk/qdox/src/main/java/com/thoughtworks/qdox/model/Type.java 2011-08-11 20:07:39 UTC (rev 1291) +++ trunk/qdox/src/main/java/com/thoughtworks/qdox/model/Type.java 2011-08-13 22:23:49 UTC (rev 1292) @@ -373,30 +373,70 @@ return "void".equals(getValue()); } - protected Type resolve( JavaClass parentClass, JavaClass subclass ) +// String superSource = "public abstract class Test<T> {\n" + +// " private T me;\n" + +// " public Test(T me) {\n" + +// " this.me = me;\n" + +// " }\n" + +// " public T getValue() {\n" + +// " return me;\n" + +// " }\n" + +// " }"; +//String subSource = "public class StringTest extends Test<String> {\n" + +// " public StringTest(String s) {\n" + +// " super(s);\n" + +// " }\n" + +// " }"; + + /** + * Consider the following example + * + * <pre> + * public abstract class AbstractClass<T> + * { + * private T value; + * + * public AbstractClass( T value ) { this.value = value; } + * + * public T getValue() { return value; } + * } + * + * public class ConcreteClass extends AbstractClass<String> + * { + * public ConcreteClass( String s ) { super( s ); } + * } + * </pre> + * <p> + * We want to know the resolved returnType when calling <code>ConcreteClass.getValue()</code>. + * The expected type is String. + * </p> + * + * <ul> + * <li>{@code this} would be T</li> + * <li>{@code declaringClass} would be AbstractClass</li> + * <li>{@code callingClass} would be ConcreteClass</li> + * </ul> + * + * @param declaringClass + * @param callingClass + * @return + */ + protected Type resolve( JavaClass declaringClass, JavaClass callingClass ) { Type result = this; - int typeIndex = -1; - for ( ListIterator<TypeVariable> iter = parentClass.getTypeParameters().listIterator(); iter.hasNext(); ) - { - if ( iter.next().getFullyQualifiedName().equals( getFullyQualifiedName() ) ) - { - typeIndex = iter.previousIndex(); - break; - } - } + int typeIndex = getTypeVariableIndex( declaringClass, this.getFullyQualifiedName() ); if ( typeIndex >= 0 ) { - String fqn = parentClass.getFullyQualifiedName(); - if ( subclass.getSuperClass() != null && fqn.equals( subclass.getSuperClass().getFullyQualifiedName() ) ) + String fqn = declaringClass.getFullyQualifiedName(); + if ( callingClass.getSuperClass() != null && fqn.equals( callingClass.getSuperClass().getFullyQualifiedName() ) ) { - result = subclass.getSuperClass().getActualTypeArguments().get( typeIndex ); + result = callingClass.getSuperClass().getActualTypeArguments().get( typeIndex ); } else { - for ( Type implement : subclass.getImplements() ) + for ( Type implement : callingClass.getImplements() ) { if ( fqn.equals( implement.getFullyQualifiedName() ) ) { @@ -414,12 +454,26 @@ result.actualArgumentTypes = new LinkedList<Type>(); for (Type actualArgType : getActualTypeArguments()) { - result.actualArgumentTypes.add(actualArgType.resolve( parentClass, subclass )); + result.actualArgumentTypes.add(actualArgType.resolve( declaringClass, callingClass )); } } return result; } + private static int getTypeVariableIndex( JavaClass declaringClass, String fqn ) + { + int typeIndex = -1; + for ( TypeVariable typeVariable : declaringClass.getTypeParameters() ) + { + typeIndex++; + if ( typeVariable.getFullyQualifiedName().equals( fqn ) ) + { + return typeIndex; + } + } + return -1; + } + /** * * @return a generic string representation of this type with fully qualified names.
To unsubscribe from this list please visit:
