diff options
author | Jeff Arneson <jarneson@google.com> | 2014-12-02 21:11:42 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-12-02 21:11:42 +0000 |
commit | f2aaefa64d6f026c68872cd4eb41432492a64114 (patch) | |
tree | b40b5581c7c42c79ef2f2359b457eb1601e34d89 /src | |
parent | a2769edc45485149708af8eaa08156623ba72313 (diff) | |
parent | d6570b0b7f66519ba50c18d9e08db423bdf1341e (diff) | |
download | android_external_doclava-f2aaefa64d6f026c68872cd4eb41432492a64114.tar.gz android_external_doclava-f2aaefa64d6f026c68872cd4eb41432492a64114.tar.bz2 android_external_doclava-f2aaefa64d6f026c68872cd4eb41432492a64114.zip |
am d6570b0b: Fix docs for classes that implement or extend generics with type parameters
* commit 'd6570b0b7f66519ba50c18d9e08db423bdf1341e':
Fix docs for classes that implement or extend generics with type parameters
Diffstat (limited to 'src')
-rw-r--r-- | src/com/google/doclava/ClassInfo.java | 280 | ||||
-rw-r--r-- | src/com/google/doclava/MethodInfo.java | 24 | ||||
-rw-r--r-- | src/com/google/doclava/ParameterInfo.java | 30 | ||||
-rw-r--r-- | src/com/google/doclava/TypeInfo.java | 68 |
4 files changed, 334 insertions, 68 deletions
diff --git a/src/com/google/doclava/ClassInfo.java b/src/com/google/doclava/ClassInfo.java index 466c22b..14cd99c 100644 --- a/src/com/google/doclava/ClassInfo.java +++ b/src/com/google/doclava/ClassInfo.java @@ -19,20 +19,50 @@ package com.google.doclava; import com.google.clearsilver.jsilver.data.Data; import com.sun.javadoc.ClassDoc; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Queue; import java.util.Set; import java.util.TreeMap; -import java.util.TreeSet; -import java.util.Vector; public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Scoped, Resolvable { + + /** + * Contains a ClassInfo and a TypeInfo. + * <p> + * This is used to match a ClassInfo, which doesn't keep track of its type parameters + * and a type which does. + */ + private class ClassTypePair { + private final ClassInfo mClassInfo; + private final TypeInfo mTypeInfo; + + public ClassTypePair(ClassInfo cl, TypeInfo t) { + mClassInfo = cl; + mTypeInfo = t; + } + + public ClassInfo classInfo() { + return mClassInfo; + } + + public TypeInfo typeInfo() { + return mTypeInfo; + } + + public Map<String, TypeInfo> getTypeArgumentMapping() { + return TypeInfo.getTypeArgumentMapping(classInfo(), typeInfo()); + } + } + public static final Comparator<ClassInfo> comparator = new Comparator<ClassInfo>() { public int compare(ClassInfo a, ClassInfo b) { return a.name().compareTo(b.name()); @@ -148,6 +178,9 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco mSelfFields = null; mSelfAttributes = null; mDeprecatedKnown = false; + mSuperclassesWithTypes = null; + mInterfacesWithTypes = null; + mAllInterfacesWithTypes = null; Collections.sort(mEnumConstants, FieldInfo.comparator); Collections.sort(mInnerClasses, ClassInfo.comparator); @@ -279,6 +312,130 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco return result; } + /** + * List of only direct interface's classes, without worrying about type param mapping. + * This can't be lazy loaded, because its overloads depend on changing type parameters + * passed in from the callers. + */ + private List<ClassTypePair> justMyInterfacesWithTypes() { + return justMyInterfacesWithTypes(Collections.<String, TypeInfo>emptyMap()); + } + + /** + * List of only direct interface's classes and their parameterized types. + * This can't be lazy loaded, because of the passed in typeArgumentsMap. + */ + private List<ClassTypePair> justMyInterfacesWithTypes(Map<String, TypeInfo> typeArgumentsMap) { + if (mRealInterfaces == null || mRealInterfaceTypes == null) { + return Collections.<ClassTypePair>emptyList(); + } + + List<ClassTypePair> list = new ArrayList<ClassTypePair>(); + for (int i = 0; i < mRealInterfaces.size(); i++) { + ClassInfo iface = mRealInterfaces.get(i); + TypeInfo type = mRealInterfaceTypes.get(i); + if (iface != null && type != null) { + type = type.getTypeWithArguments(typeArgumentsMap); + if (iface.checkLevel()) { + list.add(new ClassTypePair(iface, type)); + } else { + // add the interface's interfaces + Map<String, TypeInfo> map = TypeInfo.getTypeArgumentMapping(iface.asTypeInfo(), type); + list.addAll(iface.justMyInterfacesWithTypes(map)); + } + } + } + return list; + } + + /** + * List of only direct interface's classes, and any hidden superclass's direct interfaces + * between this class and the first visible superclass and those interface class's parameterized types. + */ + private ArrayList<ClassTypePair> interfacesWithTypes() { + if (mInterfacesWithTypes == null) { + mInterfacesWithTypes = new ArrayList<ClassTypePair>(); + + Iterator<ClassTypePair> itr = superClassesWithTypes().iterator(); + // skip the first one, which is this class + itr.next(); + while (itr.hasNext()) { + ClassTypePair ctp = itr.next(); + if (ctp.classInfo().checkLevel()) { + break; + } else { + // fill mInterfacesWithTypes from the hidden superclass + mInterfacesWithTypes.addAll( + ctp.classInfo().justMyInterfacesWithTypes(ctp.getTypeArgumentMapping())); + } + } + mInterfacesWithTypes.addAll( + justMyInterfacesWithTypes()); + } + return mInterfacesWithTypes; + } + + /** + * List of all interface's classes reachable in this class's inheritance hierarchy + * and those interface class's parameterized types. + */ + private ArrayList<ClassTypePair> allInterfacesWithTypes() { + if (mAllInterfacesWithTypes == null) { + mAllInterfacesWithTypes = new ArrayList<ClassTypePair>(); + Queue<ClassTypePair> toParse = new ArrayDeque<ClassTypePair>(); + Set<String> visited = new HashSet<String>(); + + Iterator<ClassTypePair> itr = superClassesWithTypes().iterator(); + // skip the first one, which is this class + itr.next(); + while (itr.hasNext()) { + ClassTypePair ctp = itr.next(); + toParse.addAll( + ctp.classInfo().justMyInterfacesWithTypes(ctp.getTypeArgumentMapping())); + } + toParse.addAll(justMyInterfacesWithTypes()); + while (!toParse.isEmpty()) { + ClassTypePair ctp = toParse.remove(); + if (!visited.contains(ctp.typeInfo().fullName())) { + mAllInterfacesWithTypes.add(ctp); + visited.add(ctp.typeInfo().fullName()); + toParse.addAll(ctp.classInfo().justMyInterfacesWithTypes(ctp.getTypeArgumentMapping())); + } + } + } + return mAllInterfacesWithTypes; + } + + /** + * A list of ClassTypePairs that contain all superclasses + * and their corresponding types. The types will have type parameters + * cascaded upwards so they match, if any classes along the way set them. + * The list includes the current class, and is an ascending order up the + * heirarchy tree. + * */ + private ArrayList<ClassTypePair> superClassesWithTypes() { + if (mSuperclassesWithTypes == null) { + mSuperclassesWithTypes = new ArrayList<ClassTypePair>(); + + ClassTypePair lastCtp = new ClassTypePair(this, this.asTypeInfo()); + mSuperclassesWithTypes.add(lastCtp); + + Map<String, TypeInfo> typeArgumentsMap; + ClassInfo superclass = mRealSuperclass; + TypeInfo supertype = mRealSuperclassType; + TypeInfo nextType; + while (superclass != null && supertype != null) { + typeArgumentsMap = lastCtp.getTypeArgumentMapping(); + lastCtp = new ClassTypePair(superclass, supertype.getTypeWithArguments(typeArgumentsMap)); + mSuperclassesWithTypes.add(lastCtp); + + supertype = superclass.mRealSuperclassType; + superclass = superclass.mRealSuperclass; + } + } + return mSuperclassesWithTypes; + } + private static void gatherHiddenInterfaces(ClassInfo cl, HashSet<ClassInfo> interfaces) { for (ClassInfo iface : cl.mRealInterfaces) { if (iface.checkLevel()) { @@ -526,10 +683,10 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco return mAllSelfFields; } - private void gatherMethods(ClassInfo owner, ClassInfo cl, HashMap<String, MethodInfo> methods) { - for (MethodInfo m : cl.selfMethods()) { + private void gatherMethods(ClassInfo owner, ClassTypePair ctp, HashMap<String, MethodInfo> methods) { + for (MethodInfo m : ctp.classInfo().selfMethods()) { if (m.checkLevel()) { - methods.put(m.name() + m.signature(), m.cloneForClass(owner)); + methods.put(m.name() + m.signature(), m.cloneForClass(owner, ctp.getTypeArgumentMapping())); } } } @@ -538,12 +695,18 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco if (mSelfMethods == null) { HashMap<String, MethodInfo> methods = new HashMap<String, MethodInfo>(); // our hidden parents - if (mRealSuperclass != null && !mRealSuperclass.checkLevel()) { - gatherMethods(this, mRealSuperclass, methods); + for (ClassTypePair ctp : superClassesWithTypes()) { + // this class is included in this list, so skip it! + if (ctp.classInfo() != this) { + if (ctp.classInfo().checkLevel()) { + break; + } + gatherMethods(this, ctp, methods); + } } - for (ClassInfo iface : mRealInterfaces) { - if (!iface.checkLevel()) { - gatherMethods(this, iface, methods); + for (ClassTypePair ctp : justMyInterfacesWithTypes(Collections.<String, TypeInfo>emptyMap())) { + if (!ctp.classInfo().checkLevel()) { + gatherMethods(this, ctp, methods); } } // mine @@ -1093,23 +1256,19 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco containingPackage().makeClassLinkListHDF(data, "class.package"); // inheritance hierarchy - Vector<ClassInfo> superClasses = new Vector<ClassInfo>(); - superClasses.add(this); - ClassInfo supr = superclass(); - while (supr != null) { - superClasses.add(supr); - supr = supr.superclass(); - } - n = superClasses.size(); - for (i = 0; i < n; i++) { - supr = superClasses.elementAt(n - i - 1); - - supr.asTypeInfo().makeQualifiedHDF(data, "class.inheritance." + i + ".class"); - supr.asTypeInfo().makeHDF(data, "class.inheritance." + i + ".short_class"); - j = 0; - for (TypeInfo t : supr.interfaceTypes()) { - t.makeHDF(data, "class.inheritance." + i + ".interfaces." + j); - j++; + List<ClassTypePair> ctplist = superClassesWithTypes(); + n = ctplist.size(); + for (i = 0; i < ctplist.size(); i++) { + // go in reverse order + ClassTypePair ctp = ctplist.get(n - i - 1); + if (ctp.classInfo().checkLevel()) { + ctp.typeInfo().makeQualifiedHDF(data, "class.inheritance." + i + ".class"); + ctp.typeInfo().makeHDF(data, "class.inheritance." + i + ".short_class"); + j = 0; + for (ClassTypePair t : ctp.classInfo().interfacesWithTypes()) { + t.typeInfo().makeHDF(data, "class.inheritance." + i + ".interfaces." + j); + j++; + } } } @@ -1281,70 +1440,68 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco } // inherited methods - Set<ClassInfo> interfaces = new TreeSet<ClassInfo>(); - addInterfaces(interfaces(), interfaces); - ClassInfo cl = superclass(); + Iterator<ClassTypePair> superclassesItr = superClassesWithTypes().iterator(); + superclassesItr.next(); // skip the first one, which is the current class + ClassTypePair superCtp; i = 0; - while (cl != null) { - addInterfaces(cl.interfaces(), interfaces); - makeInheritedHDF(data, i, cl); - cl = cl.superclass(); - i++; - } - for (ClassInfo iface : interfaces) { - makeInheritedHDF(data, i, iface); - i++; + while (superclassesItr.hasNext()) { + superCtp = superclassesItr.next(); + if (superCtp.classInfo().checkLevel()) { + makeInheritedHDF(data, i, superCtp); + i++; + } } - } - - private static void addInterfaces(ArrayList<ClassInfo> ifaces, Set<ClassInfo> out) { - for (ClassInfo cl : ifaces) { - out.add(cl); - addInterfaces(cl.interfaces(), out); + Iterator<ClassTypePair> interfacesItr = allInterfacesWithTypes().iterator(); + while (interfacesItr.hasNext()) { + superCtp = interfacesItr.next(); + if (superCtp.classInfo().checkLevel()) { + makeInheritedHDF(data, i, superCtp); + i++; + } } } - private static void makeInheritedHDF(Data data, int index, ClassInfo cl) { + private static void makeInheritedHDF(Data data, int index, ClassTypePair ctp) { int i; String base = "class.inherited." + index; - data.setValue(base + ".qualified", cl.qualifiedName()); - if (cl.checkLevel()) { - data.setValue(base + ".link", cl.htmlPage()); + data.setValue(base + ".qualified", ctp.classInfo().qualifiedName()); + if (ctp.classInfo().checkLevel()) { + data.setValue(base + ".link", ctp.classInfo().htmlPage()); } - String kind = cl.kind(); + String kind = ctp.classInfo().kind(); if (kind != null) { data.setValue(base + ".kind", kind); } - if (cl.mIsIncluded) { + if (ctp.classInfo().mIsIncluded) { data.setValue(base + ".included", "true"); } else { - Doclava.federationTagger.tagAll(new ClassInfo[] {cl}); - if (!cl.getFederatedReferences().isEmpty()) { - FederatedSite site = cl.getFederatedReferences().iterator().next(); - data.setValue(base + ".link", site.linkFor(cl.htmlPage())); + Doclava.federationTagger.tagAll(new ClassInfo[] {ctp.classInfo()}); + if (!ctp.classInfo().getFederatedReferences().isEmpty()) { + FederatedSite site = ctp.classInfo().getFederatedReferences().iterator().next(); + data.setValue(base + ".link", site.linkFor(ctp.classInfo().htmlPage())); data.setValue(base + ".federated", site.name()); } } // xml attributes i = 0; - for (AttributeInfo attr : cl.selfAttributes()) { + for (AttributeInfo attr : ctp.classInfo().selfAttributes()) { attr.makeHDF(data, base + ".attrs." + i); i++; } // methods i = 0; - for (MethodInfo method : cl.selfMethods()) { - method.makeHDF(data, base + ".methods." + i); + for (MethodInfo method : ctp.classInfo().selfMethods()) { + method.makeHDF(data, base + ".methods." + i, ctp.getTypeArgumentMapping()); i++; } // fields i = 0; - for (FieldInfo field : cl.selfFields()) { + for (FieldInfo field : ctp.classInfo().selfFields()) { if (!field.isConstant()) { field.makeHDF(data, base + ".fields." + i); i++; @@ -1353,7 +1510,7 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco // constants i = 0; - for (FieldInfo field : cl.selfFields()) { + for (FieldInfo field : ctp.classInfo().selfFields()) { if (field.isConstant()) { field.makeHDF(data, base + ".constants." + i); i++; @@ -1727,6 +1884,9 @@ public class ClassInfo extends DocInfo implements ContainerInfo, Comparable, Sco private boolean mDeprecatedKnown; // lazy + private ArrayList<ClassTypePair> mSuperclassesWithTypes; + private ArrayList<ClassTypePair> mInterfacesWithTypes; + private ArrayList<ClassTypePair> mAllInterfacesWithTypes; private ArrayList<MethodInfo> mConstructors; private ArrayList<ClassInfo> mRealInnerClasses; private ArrayList<MethodInfo> mSelfMethods; diff --git a/src/com/google/doclava/MethodInfo.java b/src/com/google/doclava/MethodInfo.java index 8c5e271..eb360cd 100644 --- a/src/com/google/doclava/MethodInfo.java +++ b/src/com/google/doclava/MethodInfo.java @@ -237,13 +237,23 @@ public class MethodInfo extends MemberInfo implements AbstractMethodInfo, Resolv return mTypeParameters; } - public MethodInfo cloneForClass(ClassInfo newContainingClass) { + /** + * Clone this MethodInfo as if it belonged to the specified ClassInfo and apply the + * typeArgumentMapping to the parameters and return types. + */ + public MethodInfo cloneForClass(ClassInfo newContainingClass, + Map<String, TypeInfo> typeArgumentMapping) { + TypeInfo returnType = mReturnType.getTypeWithArguments(typeArgumentMapping); + ArrayList<ParameterInfo> parameters = new ArrayList<ParameterInfo>(); + for (ParameterInfo pi : mParameters) { + parameters.add(pi.cloneWithTypeArguments(typeArgumentMapping)); + } MethodInfo result = new MethodInfo(getRawCommentText(), mTypeParameters, name(), signature(), newContainingClass, realContainingClass(), isPublic(), isProtected(), isPackagePrivate(), isPrivate(), isFinal(), isStatic(), isSynthetic(), mIsAbstract, mIsSynchronized, mIsNative, mIsAnnotationElement, kind(), mFlatSignature, - mOverriddenMethod, mReturnType, mParameters, mThrownExceptions, position(), + mOverriddenMethod, returnType, mParameters, mThrownExceptions, position(), annotations()); result.init(mDefaultAnnotationElementValue); return result; @@ -539,13 +549,18 @@ public class MethodInfo extends MemberInfo implements AbstractMethodInfo, Resolv } public void makeHDF(Data data, String base) { + makeHDF(data, base, Collections.<String, TypeInfo>emptyMap()); + } + + public void makeHDF(Data data, String base, Map<String, TypeInfo> typeMapping) { data.setValue(base + ".kind", kind()); data.setValue(base + ".name", name()); data.setValue(base + ".href", htmlPage()); data.setValue(base + ".anchor", anchor()); if (mReturnType != null) { - returnType().makeHDF(data, base + ".returnType", false, typeVariables()); + returnType().getTypeWithArguments(typeMapping).makeHDF( + data, base + ".returnType", false, typeVariables()); data.setValue(base + ".abstract", mIsAbstract ? "abstract" : ""); } @@ -564,7 +579,8 @@ public class MethodInfo extends MemberInfo implements AbstractMethodInfo, Resolv ParamTagInfo.makeHDF(data, base + ".paramTags", paramTags()); AttrTagInfo.makeReferenceHDF(data, base + ".attrRefs", comment().attrTags()); ThrowsTagInfo.makeHDF(data, base + ".throws", throwsTags()); - ParameterInfo.makeHDF(data, base + ".params", mParameters.toArray(new ParameterInfo[mParameters.size()]), isVarArgs(), typeVariables()); + ParameterInfo.makeHDF(data, base + ".params", mParameters.toArray( + new ParameterInfo[mParameters.size()]), isVarArgs(), typeVariables(), typeMapping); if (isProtected()) { data.setValue(base + ".scope", "protected"); } else if (isPublic()) { diff --git a/src/com/google/doclava/ParameterInfo.java b/src/com/google/doclava/ParameterInfo.java index f4e39f0..b911283 100644 --- a/src/com/google/doclava/ParameterInfo.java +++ b/src/com/google/doclava/ParameterInfo.java @@ -18,7 +18,9 @@ package com.google.doclava; import com.google.clearsilver.jsilver.data.Data; +import java.util.Collections; import java.util.HashSet; +import java.util.Map; public class ParameterInfo { public ParameterInfo(String name, String typeName, TypeInfo type, boolean isVarArg, @@ -30,6 +32,14 @@ public class ParameterInfo { mPosition = position; } + /** + * Clone this Parameter, but replace the type according to the typeArgumentMapping provided. + */ + public ParameterInfo cloneWithTypeArguments(Map<String, TypeInfo> typeArgumentMapping) { + return new ParameterInfo( + mName, mTypeName, mType.getTypeWithArguments(typeArgumentMapping), mIsVarArg, mPosition); + } + TypeInfo type() { return mType; } @@ -45,23 +55,35 @@ public class ParameterInfo { SourcePositionInfo position() { return mPosition; } - + boolean isVarArg() { return mIsVarArg; } public void makeHDF(Data data, String base, boolean isLastVararg, HashSet<String> typeVariables) { + makeHDF(data, base, isLastVararg, typeVariables, Collections.<String, TypeInfo>emptyMap()); + } + + public void makeHDF(Data data, String base, boolean isLastVararg, HashSet<String> typeVariables, + Map<String, TypeInfo> typeMapping) { data.setValue(base + ".name", this.name()); - type().makeHDF(data, base + ".type", isLastVararg, typeVariables); + type().getTypeWithArguments(typeMapping).makeHDF( + data, base + ".type", isLastVararg, typeVariables); } public static void makeHDF(Data data, String base, ParameterInfo[] params, boolean isVararg, HashSet<String> typeVariables) { + makeHDF(data, base, params, isVararg, typeVariables, Collections.<String, TypeInfo>emptyMap()); + } + + public static void makeHDF(Data data, String base, ParameterInfo[] params, boolean isVararg, + HashSet<String> typeVariables, Map<String, TypeInfo> typeMapping) { for (int i = 0; i < params.length; i++) { - params[i].makeHDF(data, base + "." + i, isVararg && (i == params.length - 1), typeVariables); + params[i].makeHDF( + data, base + "." + i, isVararg && (i == params.length - 1), typeVariables, typeMapping); } } - + /** * Returns true if this parameter's dimension information agrees * with the represented callee's dimension information. diff --git a/src/com/google/doclava/TypeInfo.java b/src/com/google/doclava/TypeInfo.java index 36d9634..567415b 100644 --- a/src/com/google/doclava/TypeInfo.java +++ b/src/com/google/doclava/TypeInfo.java @@ -98,6 +98,29 @@ public class TypeInfo implements Resolvable { } } + /** + * Copy Constructor. + */ + private TypeInfo(TypeInfo other) { + mIsPrimitive = other.isPrimitive(); + mIsTypeVariable = other.isTypeVariable(); + mIsWildcard = other.isWildcard(); + mDimension = other.dimension(); + mSimpleTypeName = other.simpleTypeName(); + mQualifiedTypeName = other.qualifiedTypeName(); + mClass = other.asClassInfo(); + if (other.typeArguments() != null) { + mTypeArguments = new ArrayList<TypeInfo>(other.typeArguments()); + } + if (other.superBounds() != null) { + mSuperBounds = new ArrayList<TypeInfo>(other.superBounds()); + } + if (other.extendsBounds() != null) { + mExtendsBounds = new ArrayList<TypeInfo>(other.extendsBounds()); + } + mFullName = other.fullName(); + } + public ClassInfo asClassInfo() { return mClass; } @@ -423,6 +446,51 @@ public class TypeInfo implements Resolvable { return allResolved; } + /** + * Copy this TypeInfo, but replace type arguments with those defined in the + * typeArguments mapping. + * <p> + * If the current type is one of the base types in the mapping (i.e. a parameter itself) + * then this returns the mapped type. + */ + public TypeInfo getTypeWithArguments(Map<String, TypeInfo> typeArguments) { + if (typeArguments.containsKey(fullName())) { + return typeArguments.get(fullName()); + } + + TypeInfo ti = new TypeInfo(this); + if (typeArguments() != null) { + ArrayList<TypeInfo> newArgs = new ArrayList<TypeInfo>(); + for (TypeInfo t : typeArguments()) { + newArgs.add(t.getTypeWithArguments(typeArguments)); + } + ti.setTypeArguments(newArgs); + } + return ti; + } + + /** + * Given two TypeInfos that reference the same type, take the first one's type parameters + * and generate a mapping from their names to the type parameters defined in the second. + */ + public static Map<String, TypeInfo> getTypeArgumentMapping(TypeInfo generic, TypeInfo typed) { + Map<String, TypeInfo> map = new HashMap<String, TypeInfo>(); + for (int i = 0; i < generic.typeArguments().size(); i++) { + if (typed.typeArguments() != null && typed.typeArguments().size() > i) { + map.put(generic.typeArguments().get(i).fullName(), typed.typeArguments().get(i)); + } + } + return map; + } + + /** + * Given a ClassInfo and a parameterized TypeInfo, take the class's raw type's type parameters + * and generate a mapping from their names to the type parameters defined in the TypeInfo. + */ + public static Map<String, TypeInfo> getTypeArgumentMapping(ClassInfo cls, TypeInfo typed) { + return getTypeArgumentMapping(cls.asTypeInfo(), typed); + } + private ArrayList<Resolution> mResolutions; private boolean mIsPrimitive; |