use of jadx.core.dex.visitors.typeinference.TypeCompareEnum in project jadx by skylot.
the class MethodInvokeVisitor method isMethodAcceptable.
private boolean isMethodAcceptable(IMethodDetails methodDetails, List<ArgType> types, Function<TypeCompareEnum, Boolean> acceptFunction) {
List<ArgType> mthTypes = methodDetails.getArgTypes();
int argCount = mthTypes.size();
if (argCount != types.size()) {
return false;
}
TypeCompare typeCompare = root.getTypeUpdate().getTypeCompare();
for (int i = 0; i < argCount; i++) {
ArgType mthType = mthTypes.get(i);
ArgType argType = types.get(i);
TypeCompareEnum result = typeCompare.compareTypes(argType, mthType);
if (!acceptFunction.apply(result)) {
return false;
}
}
return true;
}
use of jadx.core.dex.visitors.typeinference.TypeCompareEnum in project jadx by skylot.
the class OverrideMethodVisitor method updateReturnType.
private boolean updateReturnType(MethodNode mth, IMethodDetails baseMth, SuperTypesData superData) {
ArgType baseReturnType = baseMth.getReturnType();
if (mth.getReturnType().equals(baseReturnType)) {
return false;
}
if (!baseReturnType.containsTypeVariable()) {
return false;
}
TypeCompare typeCompare = mth.root().getTypeUpdate().getTypeCompare();
ArgType baseCls = baseMth.getMethodInfo().getDeclClass().getType();
for (ArgType superType : superData.getSuperTypes()) {
TypeCompareEnum compareResult = typeCompare.compareTypes(superType, baseCls);
if (compareResult == TypeCompareEnum.NARROW_BY_GENERIC) {
ArgType targetRetType = mth.root().getTypeUtils().replaceClassGenerics(superType, baseReturnType);
if (targetRetType != null && !targetRetType.containsTypeVariable() && !targetRetType.equals(mth.getReturnType())) {
mth.updateReturnType(targetRetType);
return true;
}
}
}
return false;
}
use of jadx.core.dex.visitors.typeinference.TypeCompareEnum in project jadx by skylot.
the class ModVisitor method fixFieldUsage.
/**
* If field is not visible from use site => cast to origin class
*/
private static void fixFieldUsage(MethodNode mth, IndexInsnNode insn) {
InsnArg instanceArg = insn.getArg(insn.getType() == InsnType.IGET ? 0 : 1);
if (instanceArg.contains(AFlag.SUPER)) {
return;
}
if (instanceArg.isInsnWrap() && ((InsnWrapArg) instanceArg).getWrapInsn().getType() == InsnType.CAST) {
return;
}
FieldInfo fieldInfo = (FieldInfo) insn.getIndex();
ArgType clsType = fieldInfo.getDeclClass().getType();
ArgType instanceType = instanceArg.getType();
if (Objects.equals(clsType, instanceType)) {
// cast not needed
return;
}
FieldNode fieldNode = mth.root().resolveField(fieldInfo);
if (fieldNode == null) {
// unknown field
TypeCompareEnum result = mth.root().getTypeCompare().compareTypes(instanceType, clsType);
if (result.isEqual() || (result == TypeCompareEnum.NARROW_BY_GENERIC && !instanceType.isGenericType())) {
return;
}
} else if (isFieldVisibleInMethod(fieldNode, mth)) {
return;
}
// insert cast
IndexInsnNode castInsn = new IndexInsnNode(InsnType.CAST, clsType, 1);
castInsn.addArg(instanceArg.duplicate());
castInsn.add(AFlag.SYNTHETIC);
castInsn.add(AFlag.EXPLICIT_CAST);
InsnArg castArg = InsnArg.wrapInsnIntoArg(castInsn);
castArg.setType(clsType);
insn.replaceArg(instanceArg, castArg);
InsnRemover.unbindArgUsage(mth, instanceArg);
}
use of jadx.core.dex.visitors.typeinference.TypeCompareEnum in project jadx by skylot.
the class SimplifyVisitor method shadowedByOuterCast.
private static boolean shadowedByOuterCast(RootNode root, ArgType castType, @Nullable InsnNode parentInsn) {
if (parentInsn != null && parentInsn.getType() == InsnType.CAST) {
ArgType parentCastType = (ArgType) ((IndexInsnNode) parentInsn).getIndex();
TypeCompareEnum result = root.getTypeCompare().compareTypes(parentCastType, castType);
return result.isNarrow();
}
return false;
}
use of jadx.core.dex.visitors.typeinference.TypeCompareEnum in project jadx by skylot.
the class ModVisitor method isFieldVisibleInMethod.
private static boolean isFieldVisibleInMethod(FieldNode field, MethodNode mth) {
AccessInfo accessFlags = field.getAccessFlags();
if (accessFlags.isPublic()) {
return true;
}
ClassNode useCls = mth.getParentClass();
ClassNode fieldCls = field.getParentClass();
boolean sameScope = Objects.equals(useCls, fieldCls) && !mth.getAccessFlags().isStatic();
if (sameScope) {
return true;
}
if (accessFlags.isPrivate()) {
return false;
}
// package-private or protected
if (Objects.equals(useCls.getClassInfo().getPackage(), fieldCls.getClassInfo().getPackage())) {
// same package
return true;
}
if (accessFlags.isPackagePrivate()) {
return false;
}
// protected
TypeCompareEnum result = mth.root().getTypeCompare().compareTypes(useCls, fieldCls);
// true if use class is subclass of field class
return result == TypeCompareEnum.NARROW;
}
Aggregations