Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code comments #1127

Merged
merged 8 commits into from
Mar 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 190 additions & 0 deletions WrapLayout.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import java.awt.*;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

/**
* FlowLayout subclass that fully supports wrapping of components.
*/
public class WrapLayout extends FlowLayout
{
private Dimension preferredLayoutSize;

/**
* Constructs a new <code>WrapLayout</code> with a left
* alignment and a default 5-unit horizontal and vertical gap.
*/
public WrapLayout()
{
super();
}

/**
* Constructs a new <code>FlowLayout</code> with the specified
* alignment and a default 5-unit horizontal and vertical gap.
* The value of the alignment argument must be one of
* <code>WrapLayout</code>, <code>WrapLayout</code>,
* or <code>WrapLayout</code>.
* @param align the alignment value
*/
public WrapLayout(int align)
{
super(align);
}

/**
* Creates a new flow layout manager with the indicated alignment
* and the indicated horizontal and vertical gaps.
* <p>
* The value of the alignment argument must be one of
* <code>WrapLayout</code>, <code>WrapLayout</code>,
* or <code>WrapLayout</code>.
* @param align the alignment value
* @param hgap the horizontal gap between components
* @param vgap the vertical gap between components
*/
public WrapLayout(int align, int hgap, int vgap)
{
super(align, hgap, vgap);
}

/**
* Returns the preferred dimensions for this layout given the
* <i>visible</i> components in the specified target container.
* @param target the component which needs to be laid out
* @return the preferred dimensions to lay out the
* subcomponents of the specified container
*/
@Override
public Dimension preferredLayoutSize(Container target)
{
return layoutSize(target, true);
}

/**
* Returns the minimum dimensions needed to layout the <i>visible</i>
* components contained in the specified target container.
* @param target the component which needs to be laid out
* @return the minimum dimensions to lay out the
* subcomponents of the specified container
*/
@Override
public Dimension minimumLayoutSize(Container target)
{
Dimension minimum = layoutSize(target, false);
minimum.width -= (getHgap() + 1);
return minimum;
}

/**
* Returns the minimum or preferred dimension needed to layout the target
* container.
*
* @param target target to get layout size for
* @param preferred should preferred size be calculated
* @return the dimension to layout the target container
*/
private Dimension layoutSize(Container target, boolean preferred)
{
synchronized (target.getTreeLock())
{
// Each row must fit with the width allocated to the containter.
// When the container width = 0, the preferred width of the container
// has not yet been calculated so lets ask for the maximum.

int targetWidth = target.getSize().width;
Container container = target;

while (container.getSize().width == 0 && container.getParent() != null)
{
container = container.getParent();
}

targetWidth = container.getSize().width;

if (targetWidth == 0)
targetWidth = Integer.MAX_VALUE;

int hgap = getHgap();
int vgap = getVgap();
Insets insets = target.getInsets();
int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
int maxWidth = targetWidth - horizontalInsetsAndGap;

// Fit components into the allowed width

Dimension dim = new Dimension(0, 0);
int rowWidth = 0;
int rowHeight = 0;

int nmembers = target.getComponentCount();

for (int i = 0; i < nmembers; i++)
{
Component m = target.getComponent(i);

if (m.isVisible())
{
Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();

// Can't add the component to current row. Start a new row.

if (rowWidth + d.width > maxWidth)
{
addRow(dim, rowWidth, rowHeight);
rowWidth = 0;
rowHeight = 0;
}

// Add a horizontal gap for all components after the first

if (rowWidth != 0)
{
rowWidth += hgap;
}

rowWidth += d.width;
rowHeight = Math.max(rowHeight, d.height);
}
}

addRow(dim, rowWidth, rowHeight);

dim.width += horizontalInsetsAndGap;
dim.height += insets.top + insets.bottom + vgap * 2;

// When using a scroll pane or the DecoratedLookAndFeel we need to
// make sure the preferred size is less than the size of the
// target containter so shrinking the container size works
// correctly. Removing the horizontal gap is an easy way to do this.

Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);

if (scrollPane != null && target.isValid())
{
dim.width -= (hgap + 1);
}

return dim;
}
}

/*
* A new row has been completed. Use the dimensions of this row
* to update the preferred size for the container.
*
* @param dim update the width and height when appropriate
* @param rowWidth the width of the row to add
* @param rowHeight the height of the row to add
*/
private void addRow(Dimension dim, int rowWidth, int rowHeight)
{
dim.width = Math.max(dim.width, rowWidth);

if (dim.height > 0)
{
dim.height += getVgap();
}

dim.height += rowHeight;
}
}
39 changes: 12 additions & 27 deletions jadx-core/src/main/java/jadx/api/CodePosition.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,27 @@

public final class CodePosition {

private final JavaNode node;
private final int line;
private final int offset;
private int usagePosition = -1;
private final int pos;

public CodePosition(JavaNode node, int line, int offset) {
this.node = node;
public CodePosition(int line, int offset, int pos) {
this.line = line;
this.offset = offset;
this.pos = pos;
}

public CodePosition(int line, int offset) {
this.node = null;
this.line = line;
this.offset = offset;
}

public int getUsagePosition() {
return usagePosition;
public CodePosition(int line) {
this(line, 0, -1);
}

public CodePosition setUsagePosition(int usagePosition) {
this.usagePosition = usagePosition;
return this;
}

public JavaNode getNode() {
return node;
@Deprecated
public CodePosition(int line, int offset) {
this(line, offset, -1);
}

public JavaClass getJavaClass() {
JavaClass parent = node.getDeclaringClass();
if (parent == null && node instanceof JavaClass) {
return (JavaClass) node;
}
return parent;
public int getPos() {
return pos;
}

public int getLine() {
Expand Down Expand Up @@ -72,8 +57,8 @@ public String toString() {
if (offset != 0) {
sb.append(':').append(offset);
}
if (node != null) {
sb.append(' ').append(node);
if (pos > 0) {
sb.append('@').append(pos);
}
return sb.toString();
}
Expand Down
6 changes: 6 additions & 0 deletions jadx-core/src/main/java/jadx/api/ICodeWriter.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package jadx.api;

import java.util.Map;

import jadx.core.dex.attributes.nodes.LineAttrNode;

public interface ICodeWriter {
Expand Down Expand Up @@ -51,4 +53,8 @@ public interface ICodeWriter {
String getCodeStr();

int getLength();

StringBuilder getRawBuf();

Map<CodePosition, Object> getRawAnnotations();
}
11 changes: 11 additions & 0 deletions jadx-core/src/main/java/jadx/api/JadxArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.function.Function;
import java.util.function.Predicate;

import jadx.api.data.ICodeData;
import jadx.api.impl.AnnotatedCodeWriter;
import jadx.api.impl.InMemoryCodeCache;

Expand Down Expand Up @@ -78,6 +79,8 @@ public enum OutputFormatEnum {

private OutputFormatEnum outputFormat = OutputFormatEnum.JAVA;

private ICodeData codeData;

public JadxArgs() {
// use default options
}
Expand Down Expand Up @@ -384,6 +387,14 @@ public void setCodeWriterProvider(Function<JadxArgs, ICodeWriter> codeWriterProv
this.codeWriterProvider = codeWriterProvider;
}

public ICodeData getCodeData() {
return codeData;
}

public void setCodeData(ICodeData codeData) {
this.codeData = codeData;
}

@Override
public String toString() {
return "JadxArgs{" + "inputFiles=" + inputFiles
Expand Down
17 changes: 15 additions & 2 deletions jadx-core/src/main/java/jadx/api/JadxDecompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
import jadx.core.Jadx;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.nodes.LineAttrNode;
import jadx.core.dex.nodes.*;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.dex.nodes.VariableNode;
import jadx.core.dex.visitors.SaveCode;
import jadx.core.export.ExportGradleProject;
import jadx.core.utils.Utils;
Expand Down Expand Up @@ -428,6 +432,15 @@ private JavaField getJavaFieldByNode(FieldNode fld) {
throw new JadxRuntimeException("JavaField not found by FieldNode: " + fld);
}

@Nullable
public JavaClass searchJavaClassByOrigFullName(String fullName) {
return getRoot().getClasses().stream()
.filter(cls -> cls.getClassInfo().getFullName().equals(fullName))
.findFirst()
.map(this::getJavaClassByNode)
.orElse(null);
}

@Nullable
JavaNode convertNode(Object obj) {
if (!(obj instanceof LineAttrNode)) {
Expand Down Expand Up @@ -481,7 +494,7 @@ public CodePosition getDefinitionPosition(JavaNode javaNode) {
if (defLine == 0) {
return null;
}
return new CodePosition(jCls, defLine, 0);
return new CodePosition(defLine, 0, javaNode.getDefPos());
}

public JadxArgs getArgs() {
Expand Down
11 changes: 10 additions & 1 deletion jadx-core/src/main/java/jadx/api/JavaClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,18 @@ protected JadxDecompiler getRootDecompiler() {
return decompiler;
}

private Map<CodePosition, Object> getCodeAnnotations() {
public Map<CodePosition, Object> getCodeAnnotations() {
ICodeInfo code = getCodeInfo();
if (code == null) {
return Collections.emptyMap();
}
return code.getAnnotations();
}

public Object getAnnotationAt(CodePosition pos) {
return getCodeAnnotations().get(pos);
}

public Map<CodePosition, JavaNode> getUsageMap() {
Map<CodePosition, Object> map = getCodeAnnotations();
if (map.isEmpty() || decompiler == null) {
Expand Down Expand Up @@ -229,6 +233,11 @@ public int getDecompiledLine() {
return cls.getDecompiledLine();
}

@Override
public int getDefPos() {
return cls.getDefPosition();
}

@Override
public boolean equals(Object o) {
return this == o || o instanceof JavaClass && cls.equals(((JavaClass) o).cls);
Expand Down
5 changes: 5 additions & 0 deletions jadx-core/src/main/java/jadx/api/JavaField.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public int getDecompiledLine() {
return field.getDecompiledLine();
}

@Override
public int getDefPos() {
return field.getDefPosition();
}

@Override
public List<JavaNode> getUseIn() {
return getDeclaringClass().getRootDecompiler().convertNodes(field.getUseIn());
Expand Down
5 changes: 5 additions & 0 deletions jadx-core/src/main/java/jadx/api/JavaMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ public int getDecompiledLine() {
return mth.getDecompiledLine();
}

@Override
public int getDefPos() {
return mth.getDefPosition();
}

/**
* Internal API. Not Stable!
*/
Expand Down
Loading