package com.sora.util.akatsuki.analyzers;
import java.util.Arrays;
import javax.lang.model.type.DeclaredType;
import com.sora.util.akatsuki.AndroidTypes;
import com.sora.util.akatsuki.TransformationContext;
import com.sora.util.akatsuki.analyzers.CascadingTypeAnalyzer.DefaultAnalysis;
public class ObjectTypeAnalyzer
extends CascadingTypeAnalyzer<ObjectTypeAnalyzer, DeclaredType, DefaultAnalysis> {
public ObjectTypeAnalyzer(TransformationContext context) {
super(context);
}
@Override
protected ObjectTypeAnalyzer createInstance(TransformationContext context) {
return new ObjectTypeAnalyzer(context);
}
@Override
public DefaultAnalysis createAnalysis(InvocationContext<DeclaredType> context)
throws UnknownTypeException {
// handle SparseArray
if (utils().isSameType(context.field.fieldMirror(),
utils().of(AndroidTypes.SparseArray.className), true)) {
final DeclaredType sparseArrayMirror = (DeclaredType) context.field.fieldMirror();
if (utils().isAssignable(sparseArrayMirror.getTypeArguments().get(0),
utils().of(AndroidTypes.Parcelable.className), true)) {
// SparseArray<? extends Parcelable>
return DefaultAnalysis.of(this, "SparseParcelableArray", context);
} else {
// SparseArray<? extends Object>
return null;
}
}
final AndroidTypes found = Arrays.stream(AndroidTypes.values())
.filter(t -> utils().isAssignable(context.field.refinedMirror(),
utils().of(t.className), true))
.findFirst().orElseThrow(() -> new UnknownTypeException(context.field));
String methodName = found.typeAlias != null ? found.typeAlias.toString()
: found.asMirror(this).asElement().getSimpleName().toString();
methodName += suffix;
// we use field mirror here because we don't want to screw up other
// types the cascades to this type
if (utils().isAssignable(context.field.fieldMirror(),
utils().of(AndroidTypes.Parcelable.className), true)) {
// parcelable has a getter of <T> T getParcelable(String) so no
// casting is needed
// return cascade(target(null), Function.identity(), context);
return DefaultAnalysis.of(cast(TypeCastStrategy.NO_CAST), methodName, context);
}
return DefaultAnalysis.of(target(targetOrElse(found.asMirror(this))), methodName, context);
}
}