use of jadx.core.dex.attributes.nodes.MethodOverrideAttr in project jadx by skylot.
the class MethodGen method addOverrideAnnotation.
private void addOverrideAnnotation(ICodeWriter code, MethodNode mth) {
MethodOverrideAttr overrideAttr = mth.get(AType.METHOD_OVERRIDE);
if (overrideAttr == null) {
return;
}
if (!overrideAttr.getBaseMethods().contains(mth)) {
code.startLine("@Override");
if (mth.checkCommentsLevel(CommentsLevel.INFO)) {
code.add(" // ");
code.add(Utils.listToString(overrideAttr.getOverrideList(), ", ", md -> md.getMethodInfo().getDeclClass().getAliasFullName()));
}
}
if (Consts.DEBUG) {
code.startLine("// related by override: ");
code.add(Utils.listToString(overrideAttr.getRelatedMthNodes(), ", ", m -> m.getParentClass().getFullName()));
}
}
use of jadx.core.dex.attributes.nodes.MethodOverrideAttr in project jadx by skylot.
the class JavaMethod method getOverrideRelatedMethods.
public List<JavaMethod> getOverrideRelatedMethods() {
MethodOverrideAttr ovrdAttr = mth.get(AType.METHOD_OVERRIDE);
if (ovrdAttr == null) {
return Collections.emptyList();
}
JadxDecompiler decompiler = getDeclaringClass().getRootDecompiler();
return ovrdAttr.getRelatedMthNodes().stream().map(m -> ((JavaMethod) decompiler.convertNode(m))).collect(Collectors.toList());
}
use of jadx.core.dex.attributes.nodes.MethodOverrideAttr in project jadx by skylot.
the class OverrideMethodVisitor method processOverrideMethods.
private MethodOverrideAttr processOverrideMethods(MethodNode mth, SuperTypesData superData) {
MethodOverrideAttr result = mth.get(AType.METHOD_OVERRIDE);
if (result != null) {
return result;
}
ClassNode cls = mth.getParentClass();
String signature = mth.getMethodInfo().makeSignature(false);
List<IMethodDetails> overrideList = new ArrayList<>();
Set<IMethodDetails> baseMethods = new HashSet<>();
for (ArgType superType : superData.getSuperTypes()) {
ClassNode classNode = mth.root().resolveClass(superType);
if (classNode != null) {
MethodNode ovrdMth = searchOverriddenMethod(classNode, signature);
if (ovrdMth != null) {
if (isMethodVisibleInCls(ovrdMth, cls)) {
overrideList.add(ovrdMth);
MethodOverrideAttr attr = ovrdMth.get(AType.METHOD_OVERRIDE);
if (attr != null) {
addBaseMethod(superData, overrideList, baseMethods, superType);
return buildOverrideAttr(mth, overrideList, baseMethods, attr);
}
}
}
} else {
ClspClass clsDetails = mth.root().getClsp().getClsDetails(superType);
if (clsDetails != null) {
Map<String, ClspMethod> methodsMap = clsDetails.getMethodsMap();
for (Map.Entry<String, ClspMethod> entry : methodsMap.entrySet()) {
String mthShortId = entry.getKey();
if (mthShortId.startsWith(signature)) {
overrideList.add(entry.getValue());
break;
}
}
}
}
addBaseMethod(superData, overrideList, baseMethods, superType);
}
return buildOverrideAttr(mth, overrideList, baseMethods, null);
}
use of jadx.core.dex.attributes.nodes.MethodOverrideAttr in project jadx by skylot.
the class OverrideMethodVisitor method applyOverrideAttr.
private MethodOverrideAttr applyOverrideAttr(MethodNode mth, List<IMethodDetails> overrideList, Set<IMethodDetails> baseMethods, boolean update) {
// don't rename method if override list contains not resolved method
boolean dontRename = overrideList.stream().anyMatch(m -> !(m instanceof MethodNode));
SortedSet<MethodNode> relatedMethods = null;
List<MethodNode> mthNodes = getMethodNodes(mth, overrideList);
if (update) {
// merge related methods from all override attributes
for (MethodNode mthNode : mthNodes) {
MethodOverrideAttr ovrdAttr = mthNode.get(AType.METHOD_OVERRIDE);
if (ovrdAttr != null) {
// use one of already allocated sets
relatedMethods = ovrdAttr.getRelatedMthNodes();
break;
}
}
if (relatedMethods != null) {
relatedMethods.addAll(mthNodes);
} else {
relatedMethods = new TreeSet<>(mthNodes);
}
for (MethodNode mthNode : mthNodes) {
MethodOverrideAttr ovrdAttr = mthNode.get(AType.METHOD_OVERRIDE);
if (ovrdAttr != null) {
SortedSet<MethodNode> set = ovrdAttr.getRelatedMthNodes();
if (relatedMethods != set) {
relatedMethods.addAll(set);
}
}
}
} else {
relatedMethods = new TreeSet<>(mthNodes);
}
int depth = 0;
for (MethodNode mthNode : mthNodes) {
if (dontRename) {
mthNode.add(AFlag.DONT_RENAME);
}
if (depth == 0) {
// skip current (first) method
depth = 1;
continue;
}
if (update) {
MethodOverrideAttr ovrdAttr = mthNode.get(AType.METHOD_OVERRIDE);
if (ovrdAttr != null) {
ovrdAttr.setRelatedMthNodes(relatedMethods);
continue;
}
}
mthNode.addAttr(new MethodOverrideAttr(Utils.listTail(overrideList, depth), relatedMethods, baseMethods));
depth++;
}
return new MethodOverrideAttr(overrideList, relatedMethods, baseMethods);
}
use of jadx.core.dex.attributes.nodes.MethodOverrideAttr in project jadx by skylot.
the class FixAccessModifiers method fixMethodVisibility.
private static int fixMethodVisibility(MethodNode mth) {
AccessInfo accessFlags = mth.getAccessFlags();
if (accessFlags.isPublic()) {
return -1;
}
MethodOverrideAttr overrideAttr = mth.get(AType.METHOD_OVERRIDE);
if (overrideAttr != null && !overrideAttr.getOverrideList().isEmpty()) {
// visibility can't be weaker
IMethodDetails parentMD = overrideAttr.getOverrideList().get(0);
AccessInfo parentAccInfo = new AccessInfo(parentMD.getRawAccessFlags(), AccessInfo.AFType.METHOD);
if (accessFlags.isVisibilityWeakerThan(parentAccInfo)) {
return parentAccInfo.getVisibility().rawValue();
}
}
if (mth.getUseIn().isEmpty()) {
return -1;
}
ClassNode thisTopParentCls = mth.getParentClass().getTopParentClass();
for (MethodNode useMth : mth.getUseIn()) {
ClassNode useInTPCls = useMth.getParentClass().getTopParentClass();
if (!useInTPCls.equals(thisTopParentCls)) {
return AccessFlags.PUBLIC;
}
}
return -1;
}
Aggregations