mirror of
https://github.com/revanced/smali.git
synced 2025-05-09 10:54:29 +02:00
Added support for parameter names and annotations
git-svn-id: https://smali.googlecode.com/svn/trunk@172 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
b6547e8fd5
commit
3c9013f9c0
@ -40,6 +40,7 @@ public class ClassDefinition {
|
||||
|
||||
private HashMap<Integer, AnnotationSetItem> methodAnnotations = new HashMap<Integer, AnnotationSetItem>();
|
||||
private HashMap<Integer, AnnotationSetItem> fieldAnnotations = new HashMap<Integer, AnnotationSetItem>();
|
||||
private HashMap<Integer, AnnotationSetRefList> parameterAnnotations = new HashMap<Integer, AnnotationSetRefList>();
|
||||
|
||||
public ClassDefinition(ClassDefItem classDefItem) {
|
||||
this.classDefItem = classDefItem;
|
||||
@ -54,18 +55,26 @@ public class ClassDefinition {
|
||||
}
|
||||
|
||||
List<AnnotationDirectoryItem.MethodAnnotation> methodAnnotationList = annotationDirectory.getMethodAnnotations();
|
||||
if (methodAnnotations != null) {
|
||||
if (methodAnnotationList != null) {
|
||||
for (AnnotationDirectoryItem.MethodAnnotation methodAnnotation: methodAnnotationList) {
|
||||
methodAnnotations.put(methodAnnotation.getMethod().getIndex(), methodAnnotation.getAnnotationSet());
|
||||
}
|
||||
}
|
||||
|
||||
List<AnnotationDirectoryItem.FieldAnnotation> fieldAnnotationList = annotationDirectory.getFieldAnnotations();
|
||||
if (fieldAnnotations != null) {
|
||||
if (fieldAnnotationList != null) {
|
||||
for (AnnotationDirectoryItem.FieldAnnotation fieldAnnotation: fieldAnnotationList) {
|
||||
fieldAnnotations.put(fieldAnnotation.getField().getIndex(), fieldAnnotation.getAnnotationSet());
|
||||
}
|
||||
}
|
||||
|
||||
List<AnnotationDirectoryItem.ParameterAnnotation> parameterAnnotationList =
|
||||
annotationDirectory.getParameterAnnotations();
|
||||
if (parameterAnnotationList != null) {
|
||||
for (AnnotationDirectoryItem.ParameterAnnotation parameterAnnotation: parameterAnnotationList) {
|
||||
parameterAnnotations.put(parameterAnnotation.getMethod().getIndex(), parameterAnnotation.getParameterAnnotations());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getAccessFlags() {
|
||||
@ -151,7 +160,8 @@ public class ClassDefinition {
|
||||
if (classDataItem != null) {
|
||||
for (ClassDataItem.EncodedMethod method: classDataItem.getDirectMethods()) {
|
||||
AnnotationSetItem annotationSet = methodAnnotations.get(method.getMethod().getIndex());
|
||||
directMethods.add(new MethodDefinition(method, annotationSet));
|
||||
AnnotationSetRefList parameterAnnotationList = parameterAnnotations.get(method.getMethod().getIndex());
|
||||
directMethods.add(new MethodDefinition(method, annotationSet, parameterAnnotationList));
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,7 +174,8 @@ public class ClassDefinition {
|
||||
if (classDataItem != null) {
|
||||
for (ClassDataItem.EncodedMethod method: classDataItem.getVirtualMethods()) {
|
||||
AnnotationSetItem annotationSet = methodAnnotations.get(method.getMethod().getIndex());
|
||||
virtualMethods.add(new MethodDefinition(method, annotationSet));
|
||||
AnnotationSetRefList parameterAnnotationList = parameterAnnotations.get(method.getMethod().getIndex());
|
||||
virtualMethods.add(new MethodDefinition(method, annotationSet, parameterAnnotationList));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,12 +44,15 @@ public class MethodDefinition {
|
||||
private MethodIdItem methodIdItem;
|
||||
private CodeItem codeItem;
|
||||
private AnnotationSetItem annotationSet;
|
||||
private AnnotationSetRefList parameterAnnotations;
|
||||
|
||||
public MethodDefinition(ClassDataItem.EncodedMethod encodedMethod, AnnotationSetItem annotationSet) {
|
||||
public MethodDefinition(ClassDataItem.EncodedMethod encodedMethod, AnnotationSetItem annotationSet,
|
||||
AnnotationSetRefList parameterAnnotations) {
|
||||
this.encodedMethod = encodedMethod;
|
||||
this.methodIdItem = encodedMethod.getMethod();
|
||||
this.codeItem = encodedMethod.getCodeItem();
|
||||
this.annotationSet = annotationSet;
|
||||
this.parameterAnnotations = parameterAnnotations;
|
||||
}
|
||||
|
||||
private String methodName = null;
|
||||
@ -113,6 +116,86 @@ public class MethodDefinition {
|
||||
return annotationAdaptors;
|
||||
}
|
||||
|
||||
public List<ParameterAdaptor> getParameters() {
|
||||
DebugInfoItem debugInfoItem = null;
|
||||
if (codeItem != null) {
|
||||
debugInfoItem = codeItem.getDebugInfo();
|
||||
}
|
||||
|
||||
int parameterCount = 0;
|
||||
|
||||
List<AnnotationSetItem> annotations = new ArrayList<AnnotationSetItem>();
|
||||
if (parameterAnnotations != null) {
|
||||
List<AnnotationSetItem> _annotations = parameterAnnotations.getAnnotationSets();
|
||||
if (_annotations != null) {
|
||||
annotations.addAll(_annotations);
|
||||
}
|
||||
|
||||
parameterCount = annotations.size();
|
||||
}
|
||||
|
||||
List<String> parameterNames = new ArrayList<String>();
|
||||
if (debugInfoItem != null) {
|
||||
List<String> _parameterNames = debugInfoItem.getParameterNames();
|
||||
if (_parameterNames != null) {
|
||||
parameterNames.addAll(_parameterNames);
|
||||
}
|
||||
|
||||
if (parameterCount < parameterNames.size()) {
|
||||
parameterCount = parameterNames.size();
|
||||
}
|
||||
}
|
||||
|
||||
List<ParameterAdaptor> parameterAdaptors = new ArrayList<ParameterAdaptor>();
|
||||
for (int i=0; i<parameterCount; i++) {
|
||||
AnnotationSetItem annotationSet = null;
|
||||
if (i < annotations.size()) {
|
||||
annotationSet = annotations.get(i);
|
||||
}
|
||||
|
||||
String parameterName = null;
|
||||
if (i < parameterNames.size()) {
|
||||
parameterName = parameterNames.get(i);
|
||||
}
|
||||
|
||||
parameterAdaptors.add(new ParameterAdaptor(parameterName, annotationSet));
|
||||
}
|
||||
|
||||
return parameterAdaptors;
|
||||
}
|
||||
|
||||
private List<List<AnnotationAdaptor>> getParameterAnnotations() {
|
||||
if (parameterAnnotations == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<List<AnnotationAdaptor>> parameterAnnotationList = new ArrayList<List<AnnotationAdaptor>>();
|
||||
|
||||
List<AnnotationSetItem> annotationSets = parameterAnnotations.getAnnotationSets();
|
||||
|
||||
for (AnnotationSetItem annotationSet: annotationSets) {
|
||||
List<AnnotationAdaptor> parameterAnnotationAdaptors = new ArrayList<AnnotationAdaptor>();
|
||||
for (AnnotationItem annotationItem: annotationSet.getAnnotationItems()) {
|
||||
parameterAnnotationAdaptors.add(new AnnotationAdaptor(annotationItem));
|
||||
}
|
||||
parameterAnnotationList.add(parameterAnnotationAdaptors);
|
||||
}
|
||||
|
||||
return parameterAnnotationList;
|
||||
}
|
||||
|
||||
public List<String> getParameterNames() {
|
||||
if (codeItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DebugInfoItem debugInfoItem = codeItem.getDebugInfo();
|
||||
if (debugInfoItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return debugInfoItem.getParameterNames();
|
||||
}
|
||||
|
||||
private List<MethodItem> methodItems = null;
|
||||
public List<MethodItem> getMethodItems() {
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* [The "BSD licence"]
|
||||
* Copyright (c) 2009 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.dexlib.AnnotationSetItem;
|
||||
import org.jf.dexlib.AnnotationItem;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ParameterAdaptor {
|
||||
private String parameterName;
|
||||
private AnnotationSetItem parameterAnnotations;
|
||||
|
||||
public ParameterAdaptor(String parameterName, AnnotationSetItem parameterAnnotations) {
|
||||
this.parameterName = parameterName;
|
||||
this.parameterAnnotations = parameterAnnotations;
|
||||
}
|
||||
|
||||
public String getParameterName() {
|
||||
return parameterName;
|
||||
}
|
||||
|
||||
public List<AnnotationAdaptor> getAnnotations() {
|
||||
if (parameterAnnotations == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<AnnotationAdaptor> annotations = new ArrayList<AnnotationAdaptor>();
|
||||
for (AnnotationItem annotationItem: parameterAnnotations.getAnnotationItems()) {
|
||||
annotations.add(new AnnotationAdaptor(annotationItem));
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
}
|
@ -93,6 +93,9 @@ method(methodDef) ::=
|
||||
.method <methodDef.AccessFlags; separator=" "> <methodDef.MethodName><methodDef.Prototype>
|
||||
<if(methodDef.hasCode)>
|
||||
.registers <methodDef.RegisterCount>
|
||||
<if(methodDef.Parameters)>
|
||||
<methodDef.Parameters: Parameter(it); separator="\n">
|
||||
<endif>
|
||||
<if(methodDef.Annotations)>
|
||||
<methodDef.Annotations: annotation(it); separator="\n\n">
|
||||
<endif>
|
||||
@ -111,6 +114,15 @@ MethodItem(MethodItem) ::=
|
||||
<MethodItem: (MethodItem.Template)(MethodItem)>
|
||||
>>
|
||||
|
||||
Parameter(Parameter) ::=
|
||||
<<
|
||||
.parameter<if(Parameter.ParameterName)> "<Parameter.ParameterName>"<endif><if(Parameter.Annotations)>
|
||||
|
||||
<Parameter.Annotations: annotation(it); separator="\n\n">
|
||||
.end parameter
|
||||
<endif>
|
||||
>>
|
||||
|
||||
|
||||
|
||||
Format31tLabelMap ::= [
|
||||
|
@ -166,9 +166,27 @@
|
||||
.end method
|
||||
|
||||
|
||||
.method public debugTest()V
|
||||
.method public debugTest(IIIII)V
|
||||
.registers 10
|
||||
|
||||
.parameter "Blah"
|
||||
.parameter
|
||||
.parameter "BlahWithAnnotations"
|
||||
.annotation runtime Lsome/annotation;
|
||||
something = "some value"
|
||||
somethingelse = 1234
|
||||
.end annotation
|
||||
.annotation runtime La/second/annotation;
|
||||
.end annotation
|
||||
.end parameter
|
||||
.parameter
|
||||
.annotation runtime Lsome/annotation;
|
||||
something = "some value"
|
||||
somethingelse = 1234
|
||||
.end annotation
|
||||
.end parameter
|
||||
.parameter "LastParam"
|
||||
|
||||
.prologue
|
||||
|
||||
nop
|
||||
|
@ -131,6 +131,9 @@ public class AnnotationDirectoryItem extends OffsettedItem<AnnotationDirectoryIt
|
||||
return (List<FieldAnnotation>)fieldAnnotationList.clone();
|
||||
}
|
||||
|
||||
public List<ParameterAnnotation> getParameterAnnotations() {
|
||||
return (List<ParameterAnnotation>)parameterAnnotationList.clone();
|
||||
}
|
||||
|
||||
|
||||
public static class FieldAnnotation extends CompositeField<FieldAnnotation>
|
||||
@ -204,27 +207,36 @@ public class AnnotationDirectoryItem extends OffsettedItem<AnnotationDirectoryIt
|
||||
|
||||
public static class ParameterAnnotation extends CompositeField<ParameterAnnotation>
|
||||
implements Comparable<ParameterAnnotation> {
|
||||
private final IndexedItemReference<MethodIdItem> method;
|
||||
private final OffsettedItemReference<AnnotationSetRefList> parameterAnnotations;
|
||||
private final IndexedItemReference<MethodIdItem> methodReferenceField;
|
||||
private final OffsettedItemReference<AnnotationSetRefList> parameterAnnotationsReferenceField;
|
||||
|
||||
public ParameterAnnotation(DexFile dexFile) {
|
||||
super("parameter_annotation");
|
||||
fields = new Field[] {
|
||||
method = new IndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection,
|
||||
methodReferenceField = new IndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection,
|
||||
new IntegerField(null), "method_idx"),
|
||||
parameterAnnotations = new OffsettedItemReference<AnnotationSetRefList>(
|
||||
parameterAnnotationsReferenceField = new OffsettedItemReference<AnnotationSetRefList>(
|
||||
dexFile.AnnotationSetRefListsSection, new IntegerField(null), "annotations_off")
|
||||
};
|
||||
}
|
||||
|
||||
public ParameterAnnotation(DexFile dexFile, MethodIdItem method, AnnotationSetRefList parameterAnnotations) {
|
||||
this(dexFile);
|
||||
this.method.setReference(method);
|
||||
this.parameterAnnotations.setReference(parameterAnnotations);
|
||||
this.methodReferenceField.setReference(method);
|
||||
this.parameterAnnotationsReferenceField.setReference(parameterAnnotations);
|
||||
}
|
||||
|
||||
public int compareTo(ParameterAnnotation o) {
|
||||
return ((Integer)method.getReference().getIndex()).compareTo(o.method.getReference().getIndex());
|
||||
return ((Integer) methodReferenceField.getReference().getIndex()).compareTo(o.methodReferenceField.getReference().getIndex());
|
||||
}
|
||||
|
||||
public MethodIdItem getMethod() {
|
||||
return methodReferenceField.getReference();
|
||||
}
|
||||
|
||||
public AnnotationSetRefList getParameterAnnotations() {
|
||||
return parameterAnnotationsReferenceField.getReference();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -74,4 +74,18 @@ public class AnnotationSetRefList extends OffsettedItem<AnnotationSetRefList> {
|
||||
public String getConciseIdentity() {
|
||||
return "annotation_set_item @0x" + Integer.toHexString(getOffset());
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return annotationSetReferences.size();
|
||||
}
|
||||
|
||||
public List<AnnotationSetItem> getAnnotationSets() {
|
||||
List<AnnotationSetItem> annotationSets = new ArrayList<AnnotationSetItem>();
|
||||
|
||||
for (OffsettedItemReference<AnnotationSetItem> annotationSetReference: annotationSetReferences) {
|
||||
annotationSets.add(annotationSetReference.getReference());
|
||||
}
|
||||
|
||||
return annotationSets;
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,20 @@ public class DebugInfoItem extends OffsettedItem<DebugInfoItem> {
|
||||
return (List<DebugInstruction>)instructionFields.clone();
|
||||
}
|
||||
|
||||
public List<String> getParameterNames() {
|
||||
List<String> parameterNamesList = new ArrayList<String>();
|
||||
|
||||
for (IndexedItemReference<StringIdItem> parameterNameReference: parameterNames) {
|
||||
StringIdItem parameterNameItem = parameterNameReference.getReference();
|
||||
if (parameterNameItem == null) {
|
||||
parameterNamesList.add(null);
|
||||
} else {
|
||||
parameterNamesList.add(parameterNameItem.getStringValue());
|
||||
}
|
||||
}
|
||||
return parameterNamesList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class DebugInstructionList implements Field<DebugInstructionList> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user