mirror of
https://github.com/revanced/smali.git
synced 2025-05-15 21:57:05 +02:00
Add support to dexlib2 for parameter names
This commit is contained in:
parent
005690e855
commit
bfe20a295d
@ -36,7 +36,6 @@ import org.jf.dexlib2.dexbacked.util.AnnotationsDirectory;
|
||||
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
||||
import org.jf.dexlib2.iface.Annotation;
|
||||
import org.jf.dexlib2.iface.Method;
|
||||
import org.jf.dexlib2.iface.MethodImplementation;
|
||||
import org.jf.dexlib2.iface.MethodParameter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@ -99,6 +98,18 @@ public class DexBackedMethod implements Method {
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<? extends MethodParameter> getParameters() {
|
||||
if (parametersOffset > 0) {
|
||||
DexBackedMethodImplementation methodImpl = getImplementation();
|
||||
if (methodImpl != null) {
|
||||
return methodImpl.getParametersWithNames();
|
||||
}
|
||||
return getParametersWithoutNames();
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<? extends MethodParameter> getParametersWithoutNames() {
|
||||
if (parametersOffset > 0) {
|
||||
final int size = dexBuf.readSmallUint(parametersOffset);
|
||||
|
||||
@ -122,6 +133,10 @@ public class DexBackedMethod implements Method {
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Nullable @Override public String getName() { return null; }
|
||||
//TODO: iterate over the annotations to get the signature
|
||||
@Nullable @Override public String getSignature() { return null; }
|
||||
};
|
||||
}
|
||||
|
||||
@ -140,7 +155,7 @@ public class DexBackedMethod implements Method {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MethodImplementation getImplementation() {
|
||||
public DexBackedMethodImplementation getImplementation() {
|
||||
if (codeOffset > 0) {
|
||||
return new DexBackedMethodImplementation(dexBuf, this, codeOffset);
|
||||
}
|
||||
|
@ -35,17 +35,20 @@ import com.google.common.collect.ImmutableList;
|
||||
import org.jf.dexlib2.dexbacked.instruction.DexBackedInstruction;
|
||||
import org.jf.dexlib2.dexbacked.util.DebugItemList;
|
||||
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
||||
import org.jf.dexlib2.dexbacked.util.VariableSizeList;
|
||||
import org.jf.dexlib2.iface.Annotation;
|
||||
import org.jf.dexlib2.iface.MethodImplementation;
|
||||
import org.jf.dexlib2.iface.MethodParameter;
|
||||
import org.jf.dexlib2.iface.TryBlock;
|
||||
import org.jf.dexlib2.iface.debug.DebugItem;
|
||||
import org.jf.dexlib2.iface.instruction.Instruction;
|
||||
import org.jf.util.AlignmentUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
//TODO: consider making this extends DexBackedMethod, rather than passing in the associated DexBackedMethod
|
||||
public class DexBackedMethodImplementation implements MethodImplementation {
|
||||
@Nonnull public final DexBuffer dexBuf;
|
||||
@Nonnull public final DexBackedMethod method;
|
||||
@ -131,4 +134,40 @@ public class DexBackedMethodImplementation implements MethodImplementation {
|
||||
|
||||
return ImmutableList.copyOf(instructions);
|
||||
}
|
||||
|
||||
public List<MethodParameter> getParametersWithNames() {
|
||||
final int debugInfoOffset = dexBuf.readSmallUint(codeOffset + DEBUG_OFFSET_OFFSET);
|
||||
if (debugInfoOffset > 0) {
|
||||
DexReader reader = dexBuf.readerAt(debugInfoOffset);
|
||||
reader.skipUleb128();
|
||||
final int parameterNameCount = reader.readSmallUleb128();
|
||||
final List<? extends MethodParameter> methodParametersWithoutNames = method.getParametersWithoutNames();
|
||||
//TODO: make sure dalvik doesn't allow more parameter names than we have parameters
|
||||
|
||||
return new VariableSizeList<MethodParameter>(dexBuf, reader.getOffset()) {
|
||||
@Nonnull
|
||||
@Override
|
||||
protected MethodParameter readItem(@Nonnull DexReader reader, int index) {
|
||||
final MethodParameter methodParameter = methodParametersWithoutNames.get(index);
|
||||
String _name = null;
|
||||
if (index < parameterNameCount) {
|
||||
_name = reader.getOptionalString(reader.readSmallUleb128() - 1);
|
||||
}
|
||||
final String name = _name;
|
||||
|
||||
return new MethodParameter() {
|
||||
@Nonnull @Override public String getType() { return methodParameter.getType(); }
|
||||
@Nullable @Override public String getName() { return name; }
|
||||
@Nullable @Override public String getSignature() { return methodParameter.getSignature();}
|
||||
@Nonnull @Override public List<? extends Annotation> getAnnotations() {
|
||||
return methodParameter.getAnnotations();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override public int size() { return methodParametersWithoutNames.size(); }
|
||||
};
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,6 @@ import org.jf.util.ExceptionWithContext;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class DebugItemList extends VariableSizeListWithContext<DebugItem> {
|
||||
@ -86,24 +85,17 @@ public class DebugItemList extends VariableSizeListWithContext<DebugItem> {
|
||||
final LocalInfo[] locals = new LocalInfo[registerCount];
|
||||
Arrays.fill(locals, EMPTY_LOCAL_INFO);
|
||||
|
||||
List<? extends MethodParameter> parameters = method.getParameters();
|
||||
// getParameters returns a VariableSizeList when a method implementation is present. Since we're reading debug
|
||||
// information, the method obviously has an implementation.
|
||||
VariableSizeList<? extends MethodParameter> parameters =
|
||||
(VariableSizeList<? extends MethodParameter>)method.getParameters();
|
||||
VariableSizeList<? extends MethodParameter>.Iterator parameterIterator = parameters.listIterator();
|
||||
|
||||
//TODO: need to add parameter info to MethodParameter. Is there some way we could use the same reader for that?
|
||||
int debugParametersSize = initialReader.readSmallUleb128();
|
||||
if (debugParametersSize > parameters.size()) {
|
||||
//TODO: make sure that dalvik doesn't allow this
|
||||
throw new ExceptionWithContext("DebugInfoItem has more parameters than the method itself does. WTF?");
|
||||
}
|
||||
for (int i=0; i<parameters.size(); i++) {
|
||||
// TODO: look for a signature annotation on the... method? parameter?, and get the parameter signature
|
||||
final MethodParameter methodParameter = parameters.get(i);
|
||||
final String parameterName = dexBuf.getOptionalString(initialReader.readSmallUleb128() - 1);
|
||||
|
||||
locals[i] = new LocalInfo() {
|
||||
@Nullable @Override public String getName() { return parameterName; }
|
||||
@Nullable @Override public String getType() { return methodParameter.getType(); }
|
||||
@Nullable @Override public String getSignature() { return null; }
|
||||
};
|
||||
{ // local scope for i
|
||||
int i=0;
|
||||
while (parameterIterator.hasNext()) {
|
||||
locals[i++] = parameterIterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
if (parameters.size() < registerCount) {
|
||||
@ -121,7 +113,7 @@ public class DebugItemList extends VariableSizeListWithContext<DebugItem> {
|
||||
}
|
||||
}
|
||||
|
||||
return new Iterator(dexBuf, initialReader.getOffset()) {
|
||||
return new Iterator(dexBuf, parameterIterator.getReaderOffset()) {
|
||||
private boolean finished = false;
|
||||
private int codeAddress = 0;
|
||||
private int lineNumber = lineNumberStart;
|
||||
|
@ -102,5 +102,9 @@ public abstract class VariableSizeList<T> extends AbstractSequentialList<T> {
|
||||
checkBounds(index);
|
||||
skipItem(reader, index++);
|
||||
}
|
||||
|
||||
public int getReaderOffset() {
|
||||
return reader.getOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,10 +31,15 @@
|
||||
|
||||
package org.jf.dexlib2.iface;
|
||||
|
||||
import org.jf.dexlib2.iface.debug.LocalInfo;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public interface MethodParameter {
|
||||
public interface MethodParameter extends LocalInfo {
|
||||
@Nonnull String getType();
|
||||
@Nonnull List<? extends Annotation> getAnnotations();
|
||||
@Nullable String getName();
|
||||
@Nullable String getSignature();
|
||||
}
|
||||
|
@ -44,17 +44,22 @@ import java.util.List;
|
||||
public class ImmutableMethodParameter implements MethodParameter {
|
||||
@Nonnull public final String type;
|
||||
@Nonnull public final ImmutableList<? extends ImmutableAnnotation> annotations;
|
||||
@Nullable public final String name;
|
||||
|
||||
public ImmutableMethodParameter(@Nonnull String type,
|
||||
@Nullable List<? extends Annotation> annotations) {
|
||||
@Nullable List<? extends Annotation> annotations,
|
||||
@Nullable String name) {
|
||||
this.type = type;
|
||||
this.annotations = ImmutableAnnotation.immutableListOf(annotations);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ImmutableMethodParameter(@Nonnull String type,
|
||||
@Nullable ImmutableList<? extends ImmutableAnnotation> annotations) {
|
||||
@Nullable ImmutableList<? extends ImmutableAnnotation> annotations,
|
||||
@Nullable String name) {
|
||||
this.type = type;
|
||||
this.annotations = Objects.firstNonNull(annotations, ImmutableList.<ImmutableAnnotation>of());
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static ImmutableMethodParameter of(MethodParameter methodParameter) {
|
||||
@ -63,11 +68,16 @@ public class ImmutableMethodParameter implements MethodParameter {
|
||||
}
|
||||
return new ImmutableMethodParameter(
|
||||
methodParameter.getType(),
|
||||
methodParameter.getAnnotations());
|
||||
methodParameter.getAnnotations(),
|
||||
methodParameter.getName());
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getType() { return type; }
|
||||
@Nonnull @Override public List<? extends Annotation> getAnnotations() { return annotations; }
|
||||
@Nullable @Override public String getName() { return name; }
|
||||
|
||||
//TODO: iterate over the annotations to get the signature
|
||||
@Nullable @Override public String getSignature() { return null; }
|
||||
|
||||
@Nonnull
|
||||
public static ImmutableList<ImmutableMethodParameter> immutableListOf(List<? extends MethodParameter> list) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user