This is a microoptimization, which remove unnecessary values.put() and
values.remove() pair of operations if ValueStorage.put() is called for a
known duplicated value.
This may happen because MethodNode.unloadInsnArr() call from BlockSplitter.visit() - after it instructions[] become null.
So, try to reload method before processing its instructions array and bail if insnArr still null even after reloading method.
There is a duplicate control in the ConstStorage.ValueStorage.add() method,
so each constant should be added only once, and not be added on class refresh.
Fixes "Replace constants" failure after renaming any node.
checkInstructions() may fail with NPE:
ERROR - NullPointerException in pass: BlockSplitter in method: com.google.common.primitives.Ints.IntArrayAsList.<init>(int[], int, int):void, dex: out.dex
java.lang.NullPointerException: null
at jadx.core.dex.nodes.MethodNode.checkInstructions(MethodNode.java:159)
at jadx.core.dex.visitors.blocksmaker.BlockSplitter.visit(BlockSplitter.java:49)
at jadx.core.dex.visitors.DepthTraversal.visit(DepthTraversal.java:31)
at jadx.core.dex.visitors.DepthTraversal.lambda$visit$1(DepthTraversal.java:16)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at jadx.core.dex.visitors.DepthTraversal.visit(DepthTraversal.java:16)
at jadx.core.dex.visitors.DepthTraversal.lambda$visit$0(DepthTraversal.java:15)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at jadx.core.dex.visitors.DepthTraversal.visit(DepthTraversal.java:15)
at jadx.core.ProcessClass.process(ProcessClass.java:41)
at jadx.core.ProcessClass.generateCode(ProcessClass.java:58)
at jadx.core.dex.nodes.ClassNode.decompile(ClassNode.java:292)
at jadx.core.dex.nodes.ClassNode.decompile(ClassNode.java:271)
at jadx.core.dex.nodes.ClassNode.refresh(ClassNode.java:303)
at jadx.api.JavaClass.refresh(JavaClass.java:61)
at jadx.gui.treemodel.JClass.refresh(JClass.java:63)
...
This happens because MethodNode.unloadInsnArr() call from BlockSplitter.visit() - after it instructions[] become null.
So, try to reload method before processing its instructions array.
After renaming some classes needs to be redecompiled to reflect new state.
Move recompilation of non-displayed classes to background thread.
This should improve performance on weak machines.
* Add getRealFullName() to ClassNode and JavaClass and searchJavaClassByRealName() to JadxWrapper
Those methods is like getFullName() and searchJavaClassByClassName(), but for class names without aliases.
It is necessary for renaming classes/methods/fields.
* core: Make getFieldNode(), getMethodNode() and getRoot() public
This is necessary for renaming functionality
* jadx-gui: Add Rename popup menu entry (renames classes, methods and fields)
It allows user to rename classes, methods and fields.
It updates deobfuscation map and reload file.
This may be suboptimal, and maybe some RenameVisitor should be added.
Deobfuscation should be enabled in order to allow this.