Search in sources :

Example 1 with TypeCompareEnum

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;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) TypeCompare(jadx.core.dex.visitors.typeinference.TypeCompare) TypeCompareEnum(jadx.core.dex.visitors.typeinference.TypeCompareEnum)

Example 2 with TypeCompareEnum

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;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) TypeCompare(jadx.core.dex.visitors.typeinference.TypeCompare) TypeCompareEnum(jadx.core.dex.visitors.typeinference.TypeCompareEnum)

Example 3 with TypeCompareEnum

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);
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) FieldNode(jadx.core.dex.nodes.FieldNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) TypeCompareEnum(jadx.core.dex.visitors.typeinference.TypeCompareEnum) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) FieldInfo(jadx.core.dex.info.FieldInfo)

Example 4 with TypeCompareEnum

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;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) TypeCompareEnum(jadx.core.dex.visitors.typeinference.TypeCompareEnum)

Example 5 with TypeCompareEnum

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;
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) ConstClassNode(jadx.core.dex.instructions.ConstClassNode) TypeCompareEnum(jadx.core.dex.visitors.typeinference.TypeCompareEnum) AccessInfo(jadx.core.dex.info.AccessInfo)

Aggregations

TypeCompareEnum (jadx.core.dex.visitors.typeinference.TypeCompareEnum)8 ArgType (jadx.core.dex.instructions.args.ArgType)7 TypeCompare (jadx.core.dex.visitors.typeinference.TypeCompare)5 AccessInfo (jadx.core.dex.info.AccessInfo)1 FieldInfo (jadx.core.dex.info.FieldInfo)1 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)1 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)1 CodeVar (jadx.core.dex.instructions.args.CodeVar)1 InsnArg (jadx.core.dex.instructions.args.InsnArg)1 ClassNode (jadx.core.dex.nodes.ClassNode)1 FieldNode (jadx.core.dex.nodes.FieldNode)1 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)1