}
private static BuildMetaClass cloneToBuildMetaClass(final MetaClass clazz,
final MetaParameterizedType parameterizedType,
final boolean reifyRecursively) {
final BuildMetaClass buildMetaClass = new BuildMetaClass(Context.create(), clazz.getFullyQualifiedName());
buildMetaClass.setReifiedFormOf(clazz);
buildMetaClass.setAbstract(clazz.isAbstract());
buildMetaClass.setFinal(clazz.isFinal());
buildMetaClass.setStatic(clazz.isStatic());
buildMetaClass.setInterface(clazz.isInterface());
buildMetaClass.setInterfaces(Arrays.asList(clazz.getInterfaces()));
buildMetaClass.setScope(GenUtil.scopeOf(clazz));
buildMetaClass.setSuperClass(clazz.getSuperClass());
for (final MetaTypeVariable typeVariable : clazz.getTypeParameters()) {
buildMetaClass.addTypeVariable(typeVariable);
}
if (parameterizedType != null) {
buildMetaClass.setParameterizedType(parameterizedType);
}
else {
buildMetaClass.setParameterizedType(clazz.getParameterizedType());
}
for (final MetaField field : clazz.getDeclaredFields()) {
final BuildMetaField bmf = new ShadowBuildMetaField(buildMetaClass, EmptyStatement.INSTANCE,
GenUtil.scopeOf(field), field.getType(), field.getName(), field);
bmf.setFinal(field.isFinal());
bmf.setStatic(field.isStatic());
bmf.setVolatile(field.isVolatile());
bmf.setTransient(field.isTransient());
buildMetaClass.addField(bmf);
}
for (final MetaConstructor c : clazz.getDeclaredConstructors()) {
final BuildMetaConstructor newConstructor = new BuildMetaConstructor(buildMetaClass, EmptyStatement.INSTANCE,
GenUtil.scopeOf(c),
DefParameters.from(c));
newConstructor.setReifiedFormOf(c);
buildMetaClass.addConstructor(newConstructor);
}
for (final MetaMethod method : clazz.getDeclaredMethods()) {
MetaClass returnType = method.getReturnType();
if (method.getGenericReturnType() instanceof MetaTypeVariable) {
final MetaTypeVariable typeVariable = (MetaTypeVariable) method.getGenericReturnType();
final MetaClass tVarVal = getTypeVariableValue(typeVariable, buildMetaClass);
if (tVarVal != null) {
returnType = tVarVal;
}
}
else if (method.getGenericReturnType() instanceof MetaParameterizedType) {
final MetaParameterizedType metaParameterizedType
= (MetaParameterizedType) method.getGenericReturnType();
final List<MetaType> typeVarValues = new ArrayList<MetaType>();
boolean defaultOnly = true;
for (final MetaType metaType : metaParameterizedType.getTypeParameters()) {
if (metaType instanceof MetaTypeVariable) {
final MetaTypeVariable typeVariable = (MetaTypeVariable) metaType;
final MetaClass tVarVar = getTypeVariableValue(typeVariable, buildMetaClass);
if (tVarVar != null) {
defaultOnly = false;
typeVarValues.add(tVarVar);
}
else {
typeVarValues.add(MetaClassFactory.get(Object.class));
}
}
}
if (reifyRecursively && !defaultOnly) {
returnType = parameterizedAs(returnType, typeParametersOf(typeVarValues.toArray(new MetaType[typeVarValues.size()])), false);
}
}
final List<Parameter> parameters = new ArrayList<Parameter>();
int i = 0;
for (final MetaParameter parm : method.getParameters()) {
MetaClass parmType = null;
if (method.getGenericParameterTypes() != null) {
if (method.getGenericParameterTypes()[i] instanceof MetaTypeVariable) {
final MetaTypeVariable typeVariable = (MetaTypeVariable) method.getGenericParameterTypes()[i];
final MetaClass tVarVal = getTypeVariableValue(typeVariable, buildMetaClass);
if (tVarVal != null) {
parmType = tVarVal;
}
}
}
if (parmType == null) {
parmType = parm.getType();
}
parameters.add(Parameter.of(parmType, parm.getName()));
i++;
}
final BuildMetaMethod newMethod = new ShadowBuildMetaMethod(buildMetaClass, BlockStatement.EMPTY_BLOCK,
GenUtil.scopeOf(method), GenUtil.modifiersOf(method), method.getName(), returnType,
DefParameters.fromParameters(parameters), ThrowsDeclaration.of(method.getCheckedExceptions()), method);
newMethod.setReifiedFormOf(method);
buildMetaClass.addMethod(newMethod);
}
return buildMetaClass;
}