Update everything in baksmali to use the new BaksmaliWriter functionality

This commit is contained in:
Ben Gruver 2021-02-26 11:21:45 -08:00
parent 9ce00aae9c
commit ecd68918ac
35 changed files with 140 additions and 923 deletions

View File

@ -28,21 +28,19 @@
package org.jf.baksmali.Adaptors;
import org.jf.baksmali.Adaptors.EncodedValue.AnnotationEncodedValueAdaptor;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.AnnotationVisibility;
import org.jf.dexlib2.iface.Annotation;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Collection;
public class AnnotationFormatter {
public static void writeTo(@Nonnull BaksmaliWriter writer,
@Nonnull Collection<? extends Annotation> annotations,
@Nullable String containingClass) throws IOException {
@Nonnull Collection<? extends Annotation> annotations) throws IOException {
boolean first = true;
for (Annotation annotation: annotations) {
if (!first) {
@ -50,19 +48,19 @@ public class AnnotationFormatter {
}
first = false;
writeTo(writer, annotation, containingClass);
writeTo(writer, annotation);
}
}
public static void writeTo(@Nonnull BaksmaliWriter writer, @Nonnull Annotation annotation,
@Nullable String containingClass) throws IOException {
public static void writeTo(
@Nonnull BaksmaliWriter writer, @Nonnull Annotation annotation) throws IOException {
writer.write(".annotation ");
writer.write(AnnotationVisibility.getVisibility(annotation.getVisibility()));
writer.write(' ');
writer.write(annotation.getType());
writer.write('\n');
AnnotationEncodedValueAdaptor.writeElementsTo(writer, annotation.getElements(), containingClass);
writer.writeAnnotationElements(annotation.getElements());
writer.write(".end annotation\n");
}

View File

@ -38,8 +38,6 @@ import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.formats.Instruction21c;
import org.jf.dexlib2.iface.reference.FieldReference;
import org.jf.dexlib2.iface.reference.Reference;
import org.jf.dexlib2.util.ReferenceUtil;
import org.jf.util.StringUtils;
import javax.annotation.Nonnull;
import java.io.IOException;
@ -68,7 +66,7 @@ public class ClassDefinition {
}
@Nonnull
private static HashSet<String> findFieldsSetInStaticConstructor(@Nonnull ClassDef classDef) {
private HashSet<String> findFieldsSetInStaticConstructor(@Nonnull ClassDef classDef) {
HashSet<String> fieldsSetInStaticConstructor = new HashSet<String>();
for (Method method: classDef.getDirectMethods()) {
@ -89,7 +87,8 @@ public class ClassDefinition {
try {
fieldRef.validateReference();
if (fieldRef.getDefiningClass().equals((classDef.getType()))) {
fieldsSetInStaticConstructor.add(ReferenceUtil.getShortFieldDescriptor(fieldRef));
fieldsSetInStaticConstructor.add(
formatter.getShortFieldDescriptor(fieldRef));
}
} catch (Reference.InvalidReferenceException ex) {
// Just ignore for now. We'll deal with it when processing the instruction
@ -119,7 +118,7 @@ public class ClassDefinition {
private void writeClass(BaksmaliWriter writer) throws IOException {
writer.write(".class ");
writeAccessFlags(writer);
writer.write(classDef.getType());
writer.writeType(classDef.getType());
writer.write('\n');
}
@ -134,7 +133,7 @@ public class ClassDefinition {
String superClass = classDef.getSuperclass();
if (superClass != null) {
writer.write(".super ");
writer.write(superClass);
writer.writeType(superClass);
writer.write('\n');
}
}
@ -142,9 +141,9 @@ public class ClassDefinition {
private void writeSourceFile(BaksmaliWriter writer) throws IOException {
String sourceFile = classDef.getSourceFile();
if (sourceFile != null) {
writer.write(".source \"");
StringUtils.writeEscapedString(writer, sourceFile);
writer.write("\"\n");
writer.write(".source ");
writer.writeQuotedString(sourceFile);
writer.write("\n");
}
}
@ -156,7 +155,7 @@ public class ClassDefinition {
writer.write("# interfaces\n");
for (String interfaceName: interfaces) {
writer.write(".implements ");
writer.write(interfaceName);
writer.writeType(interfaceName);
writer.write('\n');
}
}
@ -168,12 +167,7 @@ public class ClassDefinition {
writer.write("\n\n");
writer.write("# annotations\n");
String containingClass = null;
if (options.implicitReferences) {
containingClass = classDef.getType();
}
AnnotationFormatter.writeTo(writer, classAnnotations, containingClass);
AnnotationFormatter.writeTo(writer, classAnnotations);
}
}
@ -198,7 +192,7 @@ public class ClassDefinition {
boolean setInStaticConstructor;
BaksmaliWriter fieldWriter = writer;
String fieldString = ReferenceUtil.getShortFieldDescriptor(field);
String fieldString = formatter.getShortFieldDescriptor(field);
if (!writtenFields.add(fieldString)) {
writer.write("# duplicate field ignored\n");
fieldWriter = getCommentingWriter(writer);
@ -207,7 +201,7 @@ public class ClassDefinition {
} else {
setInStaticConstructor = fieldsSetInStaticConstructor.contains(fieldString);
}
FieldDefinition.writeTo(options, fieldWriter, field, setInStaticConstructor);
FieldDefinition.writeTo(fieldWriter, field, setInStaticConstructor);
}
return writtenFields;
}
@ -232,7 +226,7 @@ public class ClassDefinition {
writer.write('\n');
BaksmaliWriter fieldWriter = writer;
String fieldString = ReferenceUtil.getShortFieldDescriptor(field);
String fieldString = formatter.getShortFieldDescriptor(field);
if (!writtenFields.add(fieldString)) {
writer.write("# duplicate field ignored\n");
fieldWriter = getCommentingWriter(writer);
@ -245,7 +239,7 @@ public class ClassDefinition {
writer.write("# There is both a static and instance field with this signature.\n" +
"# You will need to rename one of these fields, including all references.\n");
}
FieldDefinition.writeTo(options, fieldWriter, field, false);
FieldDefinition.writeTo(fieldWriter, field, false);
}
}
@ -269,7 +263,7 @@ public class ClassDefinition {
writer.write('\n');
// TODO: check for method validation errors
String methodString = ReferenceUtil.getMethodDescriptor(method, true);
String methodString = formatter.getShortMethodDescriptor(method);
BaksmaliWriter methodWriter = writer;
if (!writtenMethods.add(methodString)) {
@ -279,7 +273,7 @@ public class ClassDefinition {
MethodImplementation methodImpl = method.getImplementation();
if (methodImpl == null) {
MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);
MethodDefinition.writeEmptyMethodTo(methodWriter, method, this);
} else {
MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
methodDefinition.writeTo(methodWriter);
@ -288,7 +282,8 @@ public class ClassDefinition {
return writtenMethods;
}
private void writeVirtualMethods(BaksmaliWriter writer, Set<String> directMethods) throws IOException {
private void writeVirtualMethods(BaksmaliWriter writer, Set<String> directMethods)
throws IOException {
boolean wroteHeader = false;
Set<String> writtenMethods = new HashSet<String>();
@ -308,7 +303,7 @@ public class ClassDefinition {
writer.write('\n');
// TODO: check for method validation errors
String methodString = ReferenceUtil.getMethodDescriptor(method, true);
String methodString = formatter.getShortMethodDescriptor(method);
BaksmaliWriter methodWriter = writer;
if (!writtenMethods.add(methodString)) {
@ -324,7 +319,7 @@ public class ClassDefinition {
MethodImplementation methodImpl = method.getImplementation();
if (methodImpl == null) {
MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);
MethodDefinition.writeEmptyMethodTo(methodWriter, method, this);
} else {
MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
methodDefinition.writeTo(methodWriter);

View File

@ -31,6 +31,7 @@
package org.jf.baksmali.Adaptors.Debug;
import org.jf.baksmali.Adaptors.ClassDefinition;
import org.jf.baksmali.Adaptors.MethodItem;
import org.jf.baksmali.Adaptors.RegisterFormatter;
import org.jf.dexlib2.DebugItemType;
@ -47,15 +48,18 @@ public abstract class DebugMethodItem extends MethodItem {
@Override public double getSortOrder() { return sortOrder; }
public static DebugMethodItem build(RegisterFormatter registerFormatter, DebugItem debugItem) {
public static DebugMethodItem build(
ClassDefinition classDef, RegisterFormatter registerFormatter, DebugItem debugItem) {
int codeAddress = debugItem.getCodeAddress();
switch (debugItem.getDebugItemType()) {
case DebugItemType.START_LOCAL:
return new StartLocalMethodItem(codeAddress, -1, registerFormatter, (StartLocal)debugItem);
return new StartLocalMethodItem(classDef, codeAddress, -1, registerFormatter, (StartLocal)debugItem);
case DebugItemType.END_LOCAL:
return new EndLocalMethodItem(codeAddress, -1, registerFormatter, (EndLocal)debugItem);
case DebugItemType.RESTART_LOCAL:
return new RestartLocalMethodItem(codeAddress, -1, registerFormatter, (RestartLocal)debugItem);
return new RestartLocalMethodItem(
classDef, codeAddress, -1, registerFormatter, (RestartLocal)debugItem);
case DebugItemType.EPILOGUE_BEGIN:
return new BeginEpilogueMethodItem(codeAddress, -4);
case DebugItemType.PROLOGUE_END:

View File

@ -43,7 +43,7 @@ public class EndLocalMethodItem extends DebugMethodItem {
@Nonnull private final RegisterFormatter registerFormatter;
public EndLocalMethodItem(int codeAddress, int sortOrder, @Nonnull RegisterFormatter registerFormatter,
@Nonnull EndLocal endLocal) {
@Nonnull EndLocal endLocal) {
super(codeAddress, sortOrder);
this.endLocal = endLocal;
this.registerFormatter = registerFormatter;

View File

@ -31,8 +31,8 @@
package org.jf.baksmali.Adaptors.Debug;
import org.jf.baksmali.Adaptors.ReferenceFormatter;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.immutable.value.ImmutableNullEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -52,22 +52,24 @@ public class LocalFormatter {
*
* One of name, type or signature must be non-null
*/
public static void writeLocal(@Nonnull BaksmaliWriter writer, @Nullable String name, @Nullable String type,
@Nullable String signature) throws IOException {
public static void writeLocal(@Nonnull BaksmaliWriter writer, @Nullable String name,
@Nullable String type, @Nullable String signature)
throws IOException {
if (name != null) {
ReferenceFormatter.writeStringReference(writer, name);
writer.writeQuotedString(name);
} else {
writer.write("null");
writer.writeEncodedValue(ImmutableNullEncodedValue.INSTANCE);
}
writer.write(':');
if (type != null) {
writer.write(type);
writer.writeType(type);
} else {
writer.write("V");
writer.writeType("V");
}
if (signature != null) {
writer.write(", ");
ReferenceFormatter.writeStringReference(writer, signature);
writer.writeQuotedString(signature);
}
}
}

View File

@ -31,6 +31,7 @@
package org.jf.baksmali.Adaptors.Debug;
import org.jf.baksmali.Adaptors.ClassDefinition;
import org.jf.baksmali.Adaptors.RegisterFormatter;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.iface.debug.RestartLocal;
@ -39,12 +40,14 @@ import javax.annotation.Nonnull;
import java.io.IOException;
public class RestartLocalMethodItem extends DebugMethodItem {
@Nonnull private final ClassDefinition classDef;
@Nonnull private final RestartLocal restartLocal;
@Nonnull private final RegisterFormatter registerFormatter;
public RestartLocalMethodItem(int codeAddress, int sortOrder, @Nonnull RegisterFormatter registerFormatter,
@Nonnull RestartLocal restartLocal) {
public RestartLocalMethodItem(@Nonnull ClassDefinition classDef, int codeAddress, int sortOrder,
@Nonnull RegisterFormatter registerFormatter, @Nonnull RestartLocal restartLocal) {
super(codeAddress, sortOrder);
this.classDef = classDef;
this.restartLocal = restartLocal;
this.registerFormatter = registerFormatter;
}

View File

@ -33,7 +33,6 @@ package org.jf.baksmali.Adaptors.Debug;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.iface.debug.SetSourceFile;
import org.jf.util.StringUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -52,9 +51,8 @@ public class SetSourceFileMethodItem extends DebugMethodItem {
writer.write(".source");
if (sourceFile != null) {
writer.write(" \"");
StringUtils.writeEscapedString(writer, sourceFile);
writer.write('"');
writer.write(" ");
writer.writeQuotedString(sourceFile);
}
return true;
}

View File

@ -31,6 +31,7 @@
package org.jf.baksmali.Adaptors.Debug;
import org.jf.baksmali.Adaptors.ClassDefinition;
import org.jf.baksmali.Adaptors.RegisterFormatter;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.iface.debug.StartLocal;
@ -39,12 +40,14 @@ import javax.annotation.Nonnull;
import java.io.IOException;
public class StartLocalMethodItem extends DebugMethodItem {
@Nonnull private final ClassDefinition classDef;
@Nonnull private final StartLocal startLocal;
@Nonnull private final RegisterFormatter registerFormatter;
public StartLocalMethodItem(int codeAddress, int sortOrder, @Nonnull RegisterFormatter registerFormatter,
@Nonnull StartLocal startLocal) {
public StartLocalMethodItem(@Nonnull ClassDefinition classDef, int codeAddress, int sortOrder,
@Nonnull RegisterFormatter registerFormatter, @Nonnull StartLocal startLocal) {
super(codeAddress, sortOrder);
this.classDef = classDef;
this.startLocal = startLocal;
this.registerFormatter = registerFormatter;
}

View File

@ -1,65 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver (JesusFreke)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Adaptors.EncodedValue;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.iface.AnnotationElement;
import org.jf.dexlib2.iface.value.AnnotationEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Collection;
public abstract class AnnotationEncodedValueAdaptor {
public static void writeTo(@Nonnull BaksmaliWriter writer,
@Nonnull AnnotationEncodedValue annotationEncodedValue,
@Nullable String containingClass) throws IOException {
writer.write(".subannotation ");
writer.write(annotationEncodedValue.getType());
writer.write('\n');
writeElementsTo(writer, annotationEncodedValue.getElements(), containingClass);
writer.write(".end subannotation");
}
public static void writeElementsTo(@Nonnull BaksmaliWriter writer,
@Nonnull Collection<? extends AnnotationElement> annotationElements,
@Nullable String containingClass) throws IOException {
writer.indent(4);
for (AnnotationElement annotationElement: annotationElements) {
writer.write(annotationElement.getName());
writer.write(" = ");
EncodedValueAdaptor.writeTo(writer, annotationElement.getValue(), containingClass);
writer.write('\n');
}
writer.deindent(4);
}
}

View File

@ -1,65 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver (JesusFreke)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Adaptors.EncodedValue;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.iface.value.ArrayEncodedValue;
import org.jf.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Collection;
public class ArrayEncodedValueAdaptor {
public static void writeTo(@Nonnull BaksmaliWriter writer,
@Nonnull ArrayEncodedValue arrayEncodedValue,
@Nullable String containingClass) throws IOException {
writer.write('{');
Collection<? extends EncodedValue> values = arrayEncodedValue.getValue();
if (values.size() == 0) {
writer.write('}');
return;
}
writer.write('\n');
writer.indent(4);
boolean first = true;
for (EncodedValue encodedValue: values) {
if (!first) {
writer.write(",\n");
}
first = false;
EncodedValueAdaptor.writeTo(writer, encodedValue, containingClass);
}
writer.deindent(4);
writer.write("\n}");
}
}

View File

@ -1,124 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver (JesusFreke)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Adaptors.EncodedValue;
import org.jf.baksmali.Adaptors.ReferenceFormatter;
import org.jf.baksmali.Renderers.*;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.*;
import org.jf.dexlib2.util.ReferenceUtil;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
public abstract class EncodedValueAdaptor {
public static void writeTo(@Nonnull BaksmaliWriter writer, @Nonnull EncodedValue encodedValue,
@Nullable String containingClass)
throws IOException {
switch (encodedValue.getValueType()) {
case ValueType.ANNOTATION:
AnnotationEncodedValueAdaptor.writeTo(writer, (AnnotationEncodedValue)encodedValue, containingClass);
return;
case ValueType.ARRAY:
ArrayEncodedValueAdaptor.writeTo(writer, (ArrayEncodedValue)encodedValue, containingClass);
return;
case ValueType.BOOLEAN:
BooleanRenderer.writeTo(writer, ((BooleanEncodedValue)encodedValue).getValue());
return;
case ValueType.BYTE:
ByteRenderer.writeTo(writer, ((ByteEncodedValue)encodedValue).getValue());
return;
case ValueType.CHAR:
CharRenderer.writeTo(writer, ((CharEncodedValue)encodedValue).getValue());
return;
case ValueType.DOUBLE:
DoubleRenderer.writeTo(writer, ((DoubleEncodedValue)encodedValue).getValue());
return;
case ValueType.ENUM:
EnumEncodedValue enumEncodedValue = (EnumEncodedValue)encodedValue;
boolean useImplicitReference = false;
if (enumEncodedValue.getValue().getDefiningClass().equals(containingClass)) {
useImplicitReference = true;
}
writer.write(".enum ");
ReferenceUtil.writeFieldDescriptor(writer, enumEncodedValue.getValue(), useImplicitReference);
return;
case ValueType.FIELD:
FieldEncodedValue fieldEncodedValue = (FieldEncodedValue)encodedValue;
useImplicitReference = false;
if (fieldEncodedValue.getValue().getDefiningClass().equals(containingClass)) {
useImplicitReference = true;
}
ReferenceUtil.writeFieldDescriptor(writer, fieldEncodedValue.getValue(), useImplicitReference);
return;
case ValueType.FLOAT:
FloatRenderer.writeTo(writer, ((FloatEncodedValue)encodedValue).getValue());
return;
case ValueType.INT:
IntegerRenderer.writeTo(writer, ((IntEncodedValue)encodedValue).getValue());
return;
case ValueType.LONG:
LongRenderer.writeTo(writer, ((LongEncodedValue)encodedValue).getValue());
return;
case ValueType.METHOD:
MethodEncodedValue methodEncodedValue = (MethodEncodedValue)encodedValue;
useImplicitReference = false;
if (methodEncodedValue.getValue().getDefiningClass().equals(containingClass)) {
useImplicitReference = true;
}
ReferenceUtil.writeMethodDescriptor(writer, methodEncodedValue.getValue(), useImplicitReference);
return;
case ValueType.NULL:
writer.write("null");
return;
case ValueType.SHORT:
ShortRenderer.writeTo(writer, ((ShortEncodedValue)encodedValue).getValue());
return;
case ValueType.STRING:
ReferenceFormatter.writeStringReference(writer, ((StringEncodedValue)encodedValue).getValue());
return;
case ValueType.TYPE:
writer.write(((TypeEncodedValue)encodedValue).getValue());
return;
case ValueType.METHOD_TYPE:
ReferenceFormatter.writeReference(writer, ReferenceType.METHOD_PROTO,
((MethodTypeEncodedValue)encodedValue).getValue());
return;
case ValueType.METHOD_HANDLE:
ReferenceFormatter.writeReference(writer, ReferenceType.METHOD_HANDLE,
((MethodHandleEncodedValue)encodedValue).getValue());
return;
default:
throw new IllegalArgumentException("Unknown encoded value type: " + encodedValue.getValueType());
}
}
}

View File

@ -28,8 +28,6 @@
package org.jf.baksmali.Adaptors;
import org.jf.baksmali.Adaptors.EncodedValue.EncodedValueAdaptor;
import org.jf.baksmali.BaksmaliOptions;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.HiddenApiRestriction;
@ -43,7 +41,7 @@ import java.util.Collection;
import java.util.Set;
public class FieldDefinition {
public static void writeTo(BaksmaliOptions options, BaksmaliWriter writer, Field field,
public static void writeTo(BaksmaliWriter writer, Field field,
boolean setInStaticConstructor) throws IOException {
EncodedValue initialValue = field.getInitialValue();
int accessFlags = field.getAccessFlags();
@ -63,18 +61,13 @@ public class FieldDefinition {
writer.write(".field ");
writeAccessFlagsAndRestrictions(writer, field.getAccessFlags(), field.getHiddenApiRestrictions());
writer.write(field.getName());
writer.writeSimpleName(field.getName());
writer.write(':');
writer.write(field.getType());
writer.writeType(field.getType());
if (initialValue != null) {
writer.write(" = ");
String containingClass = null;
if (options.implicitReferences) {
containingClass = field.getDefiningClass();
}
EncodedValueAdaptor.writeTo(writer, initialValue, containingClass);
writer.writeEncodedValue(initialValue);
}
writer.write('\n');
@ -83,12 +76,7 @@ public class FieldDefinition {
if (annotations.size() > 0) {
writer.indent(4);
String containingClass = null;
if (options.implicitReferences) {
containingClass = field.getDefiningClass();
}
AnnotationFormatter.writeTo(writer, annotations, containingClass);
AnnotationFormatter.writeTo(writer, annotations);
writer.deindent(4);
writer.write(".end field\n");
}

View File

@ -29,7 +29,6 @@
package org.jf.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.baksmali.Renderers.LongRenderer;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.iface.instruction.formats.ArrayPayload;
@ -63,7 +62,7 @@ public class ArrayDataMethodItem extends InstructionMethodItem<ArrayPayload> {
}
for (Number number: elements) {
LongRenderer.writeSignedIntOrLongTo(writer, number.longValue());
writer.writeSignedIntOrLongTo(number.longValue());
writer.write(suffix);
if (elementWidth == 8) {
writeCommentIfLikelyDouble(writer, number.longValue());

View File

@ -31,9 +31,7 @@ package org.jf.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.baksmali.Adaptors.MethodDefinition.InvalidSwitchPayload;
import org.jf.baksmali.Adaptors.MethodItem;
import org.jf.baksmali.Adaptors.ReferenceFormatter;
import org.jf.baksmali.BaksmaliOptions;
import org.jf.baksmali.Renderers.LongRenderer;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.VerificationError;
@ -41,9 +39,7 @@ import org.jf.dexlib2.iface.instruction.*;
import org.jf.dexlib2.iface.instruction.formats.Instruction20bc;
import org.jf.dexlib2.iface.instruction.formats.Instruction31t;
import org.jf.dexlib2.iface.instruction.formats.UnknownInstruction;
import org.jf.dexlib2.iface.reference.CallSiteReference;
import org.jf.dexlib2.iface.reference.Reference;
import org.jf.dexlib2.util.ReferenceUtil;
import org.jf.util.ExceptionWithContext;
import org.jf.util.NumberUtils;
@ -80,7 +76,7 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
}
private interface Writable {
void writeTo(BaksmaliWriter writer) throws IOException;
void write() throws IOException;
}
@Override
@ -105,41 +101,17 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
if (instruction instanceof ReferenceInstruction) {
ReferenceInstruction referenceInstruction = (ReferenceInstruction)instruction;
final String classContext;
if (methodDef.classDef.options.implicitReferences) {
classContext = methodDef.method.getDefiningClass();
} else {
classContext = null;
}
Reference reference = referenceInstruction.getReference();
try {
reference.validateReference();
if (reference instanceof CallSiteReference) {
referenceWritable = new Writable() {
@Override
public void writeTo(BaksmaliWriter indentingWriter) throws IOException {
ReferenceFormatter.writeCallSiteReference(indentingWriter, (CallSiteReference)reference);
}
};
} else {
referenceWritable = new Writable() {
@Override
public void writeTo(BaksmaliWriter indentingWriter) throws IOException {
indentingWriter.write(ReferenceUtil.getReferenceString(reference, classContext));
}
};
}
referenceWritable = () -> writer.writeReference(reference);
} catch (Reference.InvalidReferenceException ex) {
commentOutInstruction = true;
writer.write("#");
writer.write(ex.getMessage());
writer.write("\n");
referenceWritable = indentingWriter -> {
indentingWriter.write(ex.getInvalidReferenceRepresentation());
};
referenceWritable = () -> writer.write(ex.getInvalidReferenceRepresentation());
}
if (instruction instanceof DualReferenceInstruction) {
@ -148,18 +120,13 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
try {
Reference reference2 = dualReferenceInstruction.getReference2();
reference2.validateReference();
referenceWritable2 = indentingWriter -> {
indentingWriter.write(ReferenceUtil.getReferenceString(reference2, classContext));
};
referenceWritable2 = () -> writer.writeReference(reference2);
} catch (Reference.InvalidReferenceException ex) {
commentOutInstruction = true;
writer.write("#");
writer.write(ex.getMessage());
writer.write("\n");
referenceWritable = indentingWriter -> {
indentingWriter.write(ex.getInvalidReferenceRepresentation());
};
referenceWritable = () -> writer.write(ex.getInvalidReferenceRepresentation());
}
}
}
@ -213,6 +180,8 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
switch (instruction.getOpcode().format) {
case Format10t:
case Format20t:
case Format30t:
writeOpcode(writer);
writer.write(' ');
writeTargetLabel(writer);
@ -249,13 +218,8 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
writer.write(' ');
writer.write(verificationErrorName);
writer.write(", ");
referenceWritable.writeTo(writer);
break;
case Format20t:
case Format30t:
writeOpcode(writer);
writer.write(' ');
writeTargetLabel(writer);
assert referenceWritable != null;
referenceWritable.write();
break;
case Format21c:
case Format31c:
@ -263,7 +227,7 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
referenceWritable.writeTo(writer);
referenceWritable.write();
break;
case Format21ih:
case Format21lh:
@ -307,7 +271,8 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
writer.write(", ");
writeSecondRegister(writer);
writer.write(", ");
referenceWritable.writeTo(writer);
assert referenceWritable != null;
referenceWritable.write();
break;
case Format22cs:
writeOpcode(writer);
@ -349,7 +314,8 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
writer.write(' ');
writeInvokeRegisters(writer);
writer.write(", ");
referenceWritable.writeTo(writer);
assert referenceWritable != null;
referenceWritable.write();
break;
case Format35mi:
writeOpcode(writer);
@ -370,7 +336,8 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
writer.write(' ');
writeInvokeRangeRegisters(writer);
writer.write(", ");
referenceWritable.writeTo(writer);
assert referenceWritable != null;
referenceWritable.write();
break;
case Format3rmi:
writeOpcode(writer);
@ -391,18 +358,22 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
writer.write(' ');
writeInvokeRegisters(writer);
writer.write(", ");
referenceWritable.writeTo(writer);
assert referenceWritable != null;
referenceWritable.write();
writer.write(", ");
referenceWritable2.writeTo(writer);
assert referenceWritable2 != null;
referenceWritable2.write();
break;
case Format4rcc:
writeOpcode(writer);
writer.write(' ');
writeInvokeRangeRegisters(writer);
writer.write(", ");
referenceWritable.writeTo(writer);
assert referenceWritable != null;
referenceWritable.write();
writer.write(", ");
referenceWritable2.writeTo(writer);
assert referenceWritable2 != null;
referenceWritable2.write();
break;
default:
assert false;
@ -500,7 +471,7 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
}
protected void writeLiteral(BaksmaliWriter writer) throws IOException {
LongRenderer.writeSignedIntOrLongTo(writer, ((WideLiteralInstruction)instruction).getWideLiteral());
writer.writeSignedIntOrLongTo(((WideLiteralInstruction)instruction).getWideLiteral());
}
protected void writeCommentIfLikelyFloat(BaksmaliWriter writer) throws IOException {

View File

@ -30,10 +30,10 @@ package org.jf.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.LabelMethodItem;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.baksmali.Renderers.IntegerRenderer;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.iface.instruction.SwitchElement;
import org.jf.dexlib2.iface.instruction.formats.PackedSwitchPayload;
import org.jf.dexlib2.immutable.value.ImmutableIntEncodedValue;
import java.io.IOException;
import java.util.ArrayList;
@ -85,7 +85,7 @@ public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchPa
writer = methodDef.classDef.getCommentingWriter(writer);
}
writer.write(".packed-switch ");
IntegerRenderer.writeTo(writer, firstKey);
writer.writeEncodedValue(new ImmutableIntEncodedValue(firstKey));
writer.indent(4);
writer.write('\n');
int key = firstKey;

View File

@ -30,10 +30,10 @@ package org.jf.baksmali.Adaptors.Format;
import org.jf.baksmali.Adaptors.LabelMethodItem;
import org.jf.baksmali.Adaptors.MethodDefinition;
import org.jf.baksmali.Renderers.IntegerRenderer;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.iface.instruction.SwitchElement;
import org.jf.dexlib2.iface.instruction.formats.SparseSwitchPayload;
import org.jf.dexlib2.immutable.value.ImmutableIntEncodedValue;
import java.io.IOException;
import java.util.ArrayList;
@ -76,7 +76,7 @@ public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchPa
writer.write(".sparse-switch\n");
writer.indent(4);
for (SparseSwitchTarget target: targets) {
IntegerRenderer.writeTo(writer, target.getKey());
writer.writeEncodedValue(new ImmutableIntEncodedValue(target.getKey()));
writer.write(" -> ");
target.writeTargetTo(writer);
writeCommentIfResourceId(writer, target.getKey());

View File

@ -32,7 +32,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.jf.baksmali.Adaptors.Debug.DebugMethodItem;
import org.jf.baksmali.Adaptors.Format.InstructionMethodItemFactory;
import org.jf.baksmali.BaksmaliOptions;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.*;
import org.jf.dexlib2.analysis.AnalysisException;
@ -49,7 +48,6 @@ import org.jf.dexlib2.iface.reference.Reference;
import org.jf.dexlib2.immutable.instruction.ImmutableInstruction31t;
import org.jf.dexlib2.util.InstructionOffsetMap;
import org.jf.dexlib2.util.InstructionOffsetMap.InvalidInstructionOffset;
import org.jf.dexlib2.util.ReferenceUtil;
import org.jf.dexlib2.util.SyntheticAccessorResolver;
import org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember;
import org.jf.dexlib2.util.TypeUtils;
@ -57,7 +55,6 @@ import org.jf.util.ExceptionWithContext;
import org.jf.util.SparseIntArray;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.*;
@ -151,7 +148,7 @@ public class MethodDefinition {
} catch (Exception ex) {
String methodString;
try {
methodString = ReferenceUtil.getMethodDescriptor(method);
methodString = classDef.getFormatter().getMethodDescriptor(method);
} catch (Exception ex2) {
throw ExceptionWithContext.withContext(ex, "Error while processing method");
}
@ -160,27 +157,23 @@ public class MethodDefinition {
}
public static void writeEmptyMethodTo(BaksmaliWriter writer, Method method,
BaksmaliOptions options) throws IOException {
ClassDefinition classDef) throws IOException {
writer.write(".method ");
writeAccessFlagsAndRestrictions(writer, method.getAccessFlags(), method.getHiddenApiRestrictions());
writer.write(method.getName());
writer.write("(");
ImmutableList<MethodParameter> methodParameters = ImmutableList.copyOf(method.getParameters());
for (MethodParameter parameter: methodParameters) {
writer.write(parameter.getType());
writer.writeType(parameter.getType());
}
writer.write(")");
writer.write(method.getReturnType());
writer.write('\n');
writer.indent(4);
writeParameters(writer, method, methodParameters, options);
writeParameters(classDef, writer, method, methodParameters);
String containingClass = null;
if (options.implicitReferences) {
containingClass = method.getDefiningClass();
}
AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass);
AnnotationFormatter.writeTo(writer, method.getAnnotations());
writer.deindent(4);
writer.write(".end method\n");
@ -194,18 +187,18 @@ public class MethodDefinition {
writer.write(".method ");
writeAccessFlagsAndRestrictions(writer, method.getAccessFlags(), method.getHiddenApiRestrictions());
writer.write(method.getName());
writer.writeSimpleName(method.getName());
writer.write("(");
for (MethodParameter parameter: methodParameters) {
String type = parameter.getType();
writer.write(type);
writer.writeType(type);
parameterRegisterCount++;
if (TypeUtils.isWideType(type)) {
parameterRegisterCount++;
}
}
writer.write(")");
writer.write(method.getReturnType());
writer.writeType(method.getReturnType());
writer.write('\n');
writer.indent(4);
@ -217,18 +210,14 @@ public class MethodDefinition {
writer.writeSignedIntAsDec(methodImpl.getRegisterCount());
}
writer.write('\n');
writeParameters(writer, method, methodParameters, classDef.options);
writeParameters(classDef, writer, method, methodParameters);
if (registerFormatter == null) {
registerFormatter = new RegisterFormatter(classDef.options, methodImpl.getRegisterCount(),
parameterRegisterCount);
}
String containingClass = null;
if (classDef.options.implicitReferences) {
containingClass = method.getDefiningClass();
}
AnnotationFormatter.writeTo(writer, method.getAnnotations(), containingClass);
AnnotationFormatter.writeTo(writer, method.getAnnotations());
writer.write('\n');
@ -313,34 +302,30 @@ public class MethodDefinition {
}
}
private static void writeParameters(BaksmaliWriter writer, Method method,
List<? extends MethodParameter> parameters,
BaksmaliOptions options) throws IOException {
private static void writeParameters(ClassDefinition classDef, BaksmaliWriter writer, Method method,
List<? extends MethodParameter> parameters) throws IOException {
boolean isStatic = AccessFlags.STATIC.isSet(method.getAccessFlags());
int registerNumber = isStatic?0:1;
for (MethodParameter parameter: parameters) {
String parameterType = parameter.getType();
String parameterName = parameter.getName();
Collection<? extends Annotation> annotations = parameter.getAnnotations();
if ((options.debugInfo && parameterName != null) || annotations.size() != 0) {
if ((classDef.options.debugInfo && parameterName != null) || annotations.size() != 0) {
writer.write(".param p");
writer.writeSignedIntAsDec(registerNumber);
if (parameterName != null && options.debugInfo) {
if (parameterName != null && classDef.options.debugInfo) {
writer.write(", ");
ReferenceFormatter.writeStringReference(writer, parameterName);
writer.writeQuotedString(parameterName);
}
writer.write(" # ");
writer.write(parameterType);
writer.writeType(parameterType);
writer.write("\n");
if (annotations.size() > 0) {
writer.indent(4);
String containingClass = null;
if (options.implicitReferences) {
containingClass = method.getDefiningClass();
}
AnnotationFormatter.writeTo(writer, annotations, containingClass);
AnnotationFormatter.writeTo(writer, annotations);
writer.deindent(4);
writer.write(".end param\n");
}
@ -449,7 +434,8 @@ public class MethodDefinition {
AccessedMember accessedMember =
classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);
if (accessedMember != null) {
methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress));
methodItems.add(new SyntheticAccessCommentMethodItem(
classDef, accessedMember, currentCodeAddress));
}
}
} catch (Reference.InvalidReferenceException e) {
@ -577,7 +563,7 @@ public class MethodDefinition {
private void addDebugInfo(final List<MethodItem> methodItems) {
for (DebugItem debugItem: methodImpl.getDebugItems()) {
methodItems.add(DebugMethodItem.build(registerFormatter, debugItem));
methodItems.add(DebugMethodItem.build(classDef, registerFormatter, debugItem));
}
}
@ -598,14 +584,6 @@ public class MethodDefinition {
}
}
@Nullable
private String getContainingClassForImplicitReference() {
if (classDef.options.implicitReferences) {
return classDef.classDef.getType();
}
return null;
}
public static class LabelCache {
protected HashMap<LabelMethodItem, LabelMethodItem> labels = new HashMap<LabelMethodItem, LabelMethodItem>();

View File

@ -1,99 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Adaptors;
import org.jf.baksmali.Adaptors.EncodedValue.EncodedValueAdaptor;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.MethodHandleType;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.iface.reference.*;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.util.ReferenceUtil;
import org.jf.util.StringUtils;
import java.io.IOException;
public class ReferenceFormatter {
public static void writeStringReference(BaksmaliWriter writer, String item) throws IOException {
writer.write('"');
StringUtils.writeEscapedString(writer, item);
writer.write('"');
}
public static void writeCallSiteReference(BaksmaliWriter writer, CallSiteReference callSite) throws IOException {
writer.write(callSite.getName());
writer.write('(');
writer.write('"');
StringUtils.writeEscapedString(writer, callSite.getMethodName());
writer.write("\", ");
writeReference(writer, ReferenceType.METHOD_PROTO, callSite.getMethodProto());
for (EncodedValue encodedValue : callSite.getExtraArguments()) {
writer.write(", ");
EncodedValueAdaptor.writeTo(writer, encodedValue, null);
}
writer.write(")@");
MethodHandleReference methodHandle = callSite.getMethodHandle();
if (methodHandle.getMethodHandleType() != MethodHandleType.INVOKE_STATIC) {
throw new IllegalArgumentException("The linker method handle for a call site must be of type invoke-static");
}
writeReference(writer, ReferenceType.METHOD, callSite.getMethodHandle().getMemberReference());
}
public static void writeReference(BaksmaliWriter writer, int referenceType,
Reference reference) throws IOException {
switch (referenceType) {
case ReferenceType.STRING:
writeStringReference(writer, ((StringReference)reference).getString());
return;
case ReferenceType.TYPE:
writer.write(((TypeReference)reference).getType());
return;
case ReferenceType.METHOD:
ReferenceUtil.writeMethodDescriptor(writer, (MethodReference)reference);
return;
case ReferenceType.FIELD:
ReferenceUtil.writeFieldDescriptor(writer, (FieldReference)reference);
return;
case ReferenceType.METHOD_PROTO:
ReferenceUtil.writeMethodProtoDescriptor(writer, (MethodProtoReference)reference);
return;
case ReferenceType.METHOD_HANDLE:
ReferenceUtil.writeMethodHandle(writer, (MethodHandleReference)reference);
return;
case ReferenceType.CALL_SITE:
// We can't use ReferenceUtil.writeCallSite here, because it doesn't write encoded values out in the
// exact format we need here.
writeCallSiteReference(writer, (CallSiteReference)reference);
return;
default:
throw new IllegalStateException("Unknown reference type");
}
}
}

View File

@ -57,7 +57,8 @@ public class RegisterFormatter {
* @param startRegister the first register in the range
* @param lastRegister the last register in the range
*/
public void writeRegisterRange(BaksmaliWriter writer, int startRegister, int lastRegister) throws IOException {
public void writeRegisterRange(
BaksmaliWriter writer, int startRegister, int lastRegister) throws IOException {
if (options.parameterRegisters) {
assert startRegister <= lastRegister;

View File

@ -29,17 +29,19 @@
package org.jf.baksmali.Adaptors;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.util.SyntheticAccessorResolver;
import org.jf.util.ExceptionWithContext;
import java.io.IOException;
public class SyntheticAccessCommentMethodItem extends MethodItem {
private final ClassDefinition classDef;
private final SyntheticAccessorResolver.AccessedMember accessedMember;
public SyntheticAccessCommentMethodItem(SyntheticAccessorResolver.AccessedMember accessedMember, int codeAddress) {
public SyntheticAccessCommentMethodItem(
ClassDefinition classDef, SyntheticAccessorResolver.AccessedMember accessedMember, int codeAddress) {
super(codeAddress);
this.classDef = classDef;
this.accessedMember = accessedMember;
}
@ -109,13 +111,7 @@ public class SyntheticAccessCommentMethodItem extends MethodItem {
throw new ExceptionWithContext("Unknown access type: %d", accessedMember.accessedMemberType);
}
int referenceType;
if (accessedMember.accessedMemberType == SyntheticAccessorResolver.METHOD) {
referenceType = ReferenceType.METHOD;
} else {
referenceType = ReferenceType.FIELD;
}
ReferenceFormatter.writeReference(writer, referenceType, accessedMember.accessedMember);
writer.writeReference(accessedMember.accessedMember);
return true;
}
}

View File

@ -79,7 +79,7 @@ public class BaksmaliOptions {
/**
* Load the resource ids from a set of public.xml files.
*
* @param resourceFiles A map of resource prefixes -> public.xml files
* @param resourceFiles A map of resource prefixes -&gt; public.xml files
*/
public void loadResourceIds(Map<String, File> resourceFiles) throws SAXException, IOException {
for (Map.Entry<String, File> entry: resourceFiles.entrySet()) {

View File

@ -34,6 +34,7 @@ package org.jf.baksmali;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import org.jf.baksmali.formatter.BaksmaliFormatter;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.util.jcommander.ExtendedParameters;
@ -69,8 +70,10 @@ public class ListClassesCommand extends DexInputCommand {
String input = inputList.get(0);
loadDexFile(input);
BaksmaliFormatter formatter = new BaksmaliFormatter();
for (ClassDef classDef: dexFile.getClasses()) {
System.out.println(classDef.getType());
System.out.println(formatter.getType(classDef.getType()));
}
}
}

View File

@ -35,6 +35,7 @@ import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.beust.jcommander.ParametersDelegate;
import org.jf.baksmali.formatter.BaksmaliFormatter;
import org.jf.dexlib2.analysis.ClassProto;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.reference.FieldReference;
@ -78,11 +79,13 @@ public class ListFieldOffsetsCommand extends DexInputCommand {
loadDexFile(input);
BaksmaliOptions options = getOptions();
BaksmaliFormatter formatter = new BaksmaliFormatter();
try {
for (ClassDef classDef: dexFile.getClasses()) {
ClassProto classProto = (ClassProto) options.classPath.getClass(classDef);
SparseArray<FieldReference> fields = classProto.getInstanceFields();
String className = "Class " + classDef.getType() + " : " + fields.size() + " instance fields\n";
String className = "Class " + formatter.getType(classDef.getType()) + " : " + fields.size() + " instance fields\n";
System.out.write(className.getBytes());
for (int i=0;i<fields.size();i++) {
String field = fields.keyAt(i) + ":" + fields.valueAt(i).getType() + " " + fields.valueAt(i).getName() + "\n";

View File

@ -33,8 +33,8 @@ package org.jf.baksmali;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import org.jf.baksmali.formatter.BaksmaliFormatter;
import org.jf.dexlib2.iface.reference.Reference;
import org.jf.dexlib2.util.ReferenceUtil;
import javax.annotation.Nonnull;
import java.util.List;
@ -67,8 +67,10 @@ public abstract class ListReferencesCommand extends DexInputCommand {
String input = inputList.get(0);
loadDexFile(input);
BaksmaliFormatter formatter = new BaksmaliFormatter();
for (Reference reference: dexFile.getReferences(referenceType)) {
System.out.println(ReferenceUtil.getReferenceString(reference));
System.out.println(formatter.getReference(reference));
}
}
}

View File

@ -1,43 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Renderers;
import org.jf.baksmali.formatter.BaksmaliWriter;
import java.io.IOException;
public class BooleanRenderer {
public static void writeTo(BaksmaliWriter writer, boolean val) throws IOException {
if (val) {
writer.write("true");
} else {
writer.write("false");
}
}
}

View File

@ -1,53 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver (JesusFreke)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Renderers;
import org.jf.baksmali.formatter.BaksmaliWriter;
import java.io.IOException;
public class ByteRenderer {
public static void writeTo(BaksmaliWriter writer, byte val) throws IOException {
if (val<0) {
writer.write("-0x");
writer.writeUnsignedLongAsHex(-val);
writer.write('t');
} else {
writer.write("0x");
writer.writeUnsignedLongAsHex(val);
writer.write('t');
}
}
public static void writeUnsignedTo(BaksmaliWriter writer, byte val) throws IOException {
writer.write("0x");
writer.writeUnsignedLongAsHex(val & 0xFF);
writer.write('t');
}
}

View File

@ -1,42 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver (JesusFreke)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Renderers;
import org.jf.baksmali.formatter.BaksmaliWriter;
import org.jf.util.StringUtils;
import java.io.IOException;
public class CharRenderer {
public static void writeTo(BaksmaliWriter writer, char val) throws IOException {
writer.write('\'');
StringUtils.writeEscapedChar(writer, val);
writer.write('\'');
}
}

View File

@ -1,39 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Renderers;
import org.jf.baksmali.formatter.BaksmaliWriter;
import java.io.IOException;
public class DoubleRenderer {
public static void writeTo(BaksmaliWriter writer, double val) throws IOException {
writer.write(Double.toString(val));
}
}

View File

@ -1,40 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver (JesusFreke)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Renderers;
import org.jf.baksmali.formatter.BaksmaliWriter;
import java.io.IOException;
public class FloatRenderer {
public static void writeTo(BaksmaliWriter writer, float val) throws IOException {
writer.write(Float.toString(val));
writer.write('f');
}
}

View File

@ -1,50 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver (JesusFreke)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Renderers;
import org.jf.baksmali.formatter.BaksmaliWriter;
import java.io.IOException;
public class IntegerRenderer {
public static void writeTo(BaksmaliWriter writer, int val) throws IOException {
if (val<0) {
writer.write("-0x");
writer.writeUnsignedLongAsHex(-((long) val));
} else {
writer.write("0x");
writer.writeUnsignedLongAsHex(val);
}
}
public static void writeUnsignedTo(BaksmaliWriter writer, int val) throws IOException {
writer.write("0x");
writer.writeUnsignedLongAsHex(val & 0xFFFFFFFFL);
}
}

View File

@ -1,63 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver (JesusFreke)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Renderers;
import org.jf.baksmali.formatter.BaksmaliWriter;
import java.io.IOException;
public class LongRenderer {
public static void writeTo(BaksmaliWriter writer, long val) throws IOException {
if (val<0) {
writer.write("-0x");
writer.writeUnsignedLongAsHex(-val);
writer.write('L');
} else {
writer.write("0x");
writer.writeUnsignedLongAsHex(val);
writer.write('L');
}
}
public static void writeSignedIntOrLongTo(BaksmaliWriter writer, long val) throws IOException {
if (val<0) {
writer.write("-0x");
writer.writeUnsignedLongAsHex(-val);
if (val < Integer.MIN_VALUE) {
writer.write('L');
}
} else {
writer.write("0x");
writer.writeUnsignedLongAsHex(val);
if (val > Integer.MAX_VALUE) {
writer.write('L');
}
}
}
}

View File

@ -1,47 +0,0 @@
/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver (JesusFreke)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Renderers;
import org.jf.baksmali.formatter.BaksmaliWriter;
import java.io.IOException;
public class ShortRenderer {
public static void writeTo(BaksmaliWriter writer, short val) throws IOException {
if (val < 0) {
writer.write("-0x");
writer.writeUnsignedLongAsHex(-val);
writer.write('s');
} else {
writer.write("0x");
writer.writeUnsignedLongAsHex(val);
writer.write('s');
}
}
}

View File

@ -88,7 +88,9 @@ public class BaksmaliTestUtils {
boolean stripComments)
throws IOException {
StringWriter stringWriter = new StringWriter();
BaksmaliWriter writer = new BaksmaliWriter(stringWriter);
BaksmaliWriter writer = new BaksmaliWriter(
stringWriter,
options.implicitReferences ? classDef.getType() : null);
ClassDefinition classDefinition = new ClassDefinition(options, classDef);
classDefinition.writeTo(writer);
writer.close();

View File

@ -141,8 +141,8 @@ public class InstructionMethodItemTest {
InstructionMethodItem methodItem = new InstructionMethodItem<Instruction21c>(methodDefinition, 0, instruction);
StringWriter stringWriter = new StringWriter();
BaksmaliWriter indentingWriter = new BaksmaliWriter(stringWriter);
methodItem.writeTo(indentingWriter);
BaksmaliWriter writer = new BaksmaliWriter(stringWriter);
methodItem.writeTo(writer);
Assert.assertEquals("#Invalid reference\n#const-string v0, blahblahblah\nnop", stringWriter.toString());
}

View File

@ -38,6 +38,7 @@ public class InstructionRoundtripTest extends IdenticalRoundtripTest {
public void testConstMethodHandle() {
BaksmaliOptions options = new BaksmaliOptions();
options.apiLevel = 28;
options.implicitReferences = false;
runTest("ConstMethodHandle", options);
}