// We must first add every type param, before we resolve the bounds, which can
// refer to type params.
String selfTypeName = getSelfTypeFromAnnotations(mirror);
int i=0;
for(AnnotationMirror typeParamAnnotation : typeParameterAnnotations){
TypeParameter param = new TypeParameter();
param.setUnit(((Element)scope).getUnit());
param.setContainer(scope);
param.setScope(scope);
DeclarationVisitor.setVisibleScope(param);
param.setDeclaration((Declaration) scope);
// let's not trigger the lazy-loading if we're completing a LazyClass/LazyInterface
if(scope instanceof LazyContainer)
((LazyContainer)scope).addMember(param);
else // must be a method
scope.getMembers().add(param);
param.setName((String)typeParamAnnotation.getValue("value"));
param.setExtendedType(typeFactory.getAnythingDeclaration().getType());
if(i < typeParameterMirrors.size()){
TypeParameterMirror typeParameterMirror = typeParameterMirrors.get(i);
param.setNonErasedBounds(hasNonErasedBounds(typeParameterMirror));
}
String varianceName = (String) typeParamAnnotation.getValue("variance");
if(varianceName != null){
if(varianceName.equals("IN")){
param.setContravariant(true);
}else if(varianceName.equals("OUT"))
param.setCovariant(true);
}
// If this is a self type param then link it to its type's declaration
if (param.getName().equals(selfTypeName)) {
param.setSelfTypedDeclaration((TypeDeclaration)scope);
}
params.add(param);
i++;
}
Module moduleScope = Decl.getModuleContainer(scope);
// Now all type params have been set, we can resolve the references parts
Iterator<TypeParameter> paramsIterator = params.iterator();
for(AnnotationMirror typeParamAnnotation : typeParameterAnnotations){
TypeParameter param = paramsIterator.next();
@SuppressWarnings("unchecked")
List<String> satisfiesAttribute = (List<String>)typeParamAnnotation.getValue("satisfies");
setListOfTypes(param.getSatisfiedTypes(), satisfiesAttribute, scope, moduleScope,
"type parameter '"+param.getName()+"' satisfied types");
@SuppressWarnings("unchecked")
List<String> caseTypesAttribute = (List<String>)typeParamAnnotation.getValue("caseTypes");
if(caseTypesAttribute != null && !caseTypesAttribute.isEmpty())
param.setCaseTypes(new LinkedList<ProducedType>());
setListOfTypes(param.getCaseTypes(), caseTypesAttribute, scope, moduleScope,
"type parameter '"+param.getName()+"' case types");
String defaultValueAttribute = (String)typeParamAnnotation.getValue("defaultValue");
if(defaultValueAttribute != null && !defaultValueAttribute.isEmpty()){
ProducedType decodedType = decodeType(defaultValueAttribute, scope, moduleScope,
"type parameter '"+param.getName()+"' defaultValue");
param.setDefaultTypeArgument(decodedType);
param.setDefaulted(true);
}
}
}