mirror of
https://github.com/revanced/smali.git
synced 2025-05-02 15:44:30 +02:00
- Added support for enum literals
- added "Enums" example, that shows how to construct an enum class - added an enum value to the AnnotationValues example, to show how enum values are specified in an annotation git-svn-id: https://smali.googlecode.com/svn/trunk@71 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
361fa2548e
commit
d54c635f84
@ -841,7 +841,8 @@ fragment LITERAL_EMITCHILD
|
||||
| BOOL_LITERAL_EMIT
|
||||
| ARRAY_LITERAL_EMITCHILDREN
|
||||
| SUBANNOTATION_EMITCHILDREN
|
||||
| TYPE_FIELD_METHOD_LITERAL_EMITCHILDREN;
|
||||
| TYPE_FIELD_METHOD_LITERAL_EMITCHILDREN
|
||||
| ENUM_LITERAL_EMITCHILDREN;
|
||||
|
||||
fragment SUBANNOTATION_EMITCHILDREN
|
||||
: SUBANNOTATION_START_EMIT
|
||||
@ -895,6 +896,20 @@ fragment TYPE_FIELD_METHOD_LITERAL_EMITCHILDREN
|
||||
//TODO: allow void and primitive type here?
|
||||
| PRIMITIVE_TYPE_EMIT
|
||||
| VOID_TYPE_EMIT;
|
||||
|
||||
fragment ENUM_EMIT
|
||||
: ENUM {emit($ENUM, ENUM);};
|
||||
fragment ENUM
|
||||
: '.enum';
|
||||
|
||||
fragment ENUM_LITERAL_EMITCHILDREN
|
||||
: ENUM_EMIT
|
||||
WS
|
||||
REFERENCE_TYPE_DESCRIPTOR_EMITCHILD
|
||||
ARROW_EMIT
|
||||
MEMBER_NAME_EMIT
|
||||
COLON_EMIT
|
||||
REFERENCE_TYPE_DESCRIPTOR_EMITCHILD;
|
||||
|
||||
fragment ARRAY_LITERAL_EMITCHILDREN
|
||||
: ARRAY_START_EMIT
|
||||
|
@ -58,6 +58,7 @@ tokens {
|
||||
I_SUBANNOTATION;
|
||||
I_ENCODED_FIELD;
|
||||
I_ENCODED_METHOD;
|
||||
I_ENCODED_ENUM;
|
||||
I_ENCODED_ARRAY;
|
||||
I_ARRAY_ELEMENT_SIZE;
|
||||
I_ARRAY_ELEMENTS;
|
||||
@ -545,7 +546,8 @@ literal
|
||||
| BOOL_LITERAL
|
||||
| array_literal
|
||||
| subannotation
|
||||
| type_field_method;
|
||||
| type_field_method_literal
|
||||
| enum_literal;
|
||||
|
||||
array_literal
|
||||
: ARRAY_START literal* ARRAY_END
|
||||
@ -564,7 +566,7 @@ subannotation
|
||||
: SUBANNOTATION_START CLASS_DESCRIPTOR annotation_element* SUBANNOTATION_END
|
||||
-> ^(I_SUBANNOTATION[$start, "I_SUBANNOTATION"] CLASS_DESCRIPTOR annotation_element*);
|
||||
|
||||
type_field_method
|
||||
type_field_method_literal
|
||||
: reference_type_descriptor
|
||||
( ARROW MEMBER_NAME
|
||||
( nonvoid_type_descriptor -> ^(I_ENCODED_FIELD reference_type_descriptor MEMBER_NAME nonvoid_type_descriptor)
|
||||
@ -574,3 +576,11 @@ type_field_method
|
||||
)
|
||||
| PRIMITIVE_TYPE
|
||||
| VOID_TYPE;
|
||||
|
||||
enum_literal
|
||||
: ENUM
|
||||
reference_type_descriptor
|
||||
ARROW
|
||||
MEMBER_NAME
|
||||
reference_type_descriptor
|
||||
-> ^(I_ENCODED_ENUM reference_type_descriptor MEMBER_NAME reference_type_descriptor);
|
||||
|
@ -241,7 +241,8 @@ literal returns[EncodedValue encodedValue]
|
||||
| array_literal { $encodedValue = new EncodedValue(dexFile, new ArrayEncodedValueSubField(dexFile, $array_literal.values)); }
|
||||
| subannotation { $encodedValue = new EncodedValue(dexFile, $subannotation.value); }
|
||||
| field_literal { $encodedValue = new EncodedValue(dexFile, $field_literal.value); }
|
||||
| method_literal { $encodedValue = new EncodedValue(dexFile, $method_literal.value); };
|
||||
| method_literal { $encodedValue = new EncodedValue(dexFile, $method_literal.value); }
|
||||
| enum_literal { $encodedValue = new EncodedValue(dexFile, $enum_literal.value); };
|
||||
|
||||
|
||||
//everything but string
|
||||
@ -1148,3 +1149,9 @@ method_literal returns[EncodedIndexedItemReference<MethodIdItem> value]
|
||||
{
|
||||
$value = new EncodedIndexedItemReference<MethodIdItem>(dexFile, $fully_qualified_method.methodIdItem);
|
||||
};
|
||||
|
||||
enum_literal returns[EncodedIndexedItemReference<FieldIdItem> value]
|
||||
: ^(I_ENCODED_ENUM fully_qualified_field)
|
||||
{
|
||||
$value = new EncodedIndexedItemReference<FieldIdItem>(dexFile, $fully_qualified_field.fieldIdItem, true);
|
||||
};
|
||||
|
@ -46,14 +46,21 @@ public class EncodedIndexedItemReference<T extends IndexedItem<T>>
|
||||
this.section = section;
|
||||
}
|
||||
|
||||
//TODO: implement support for enum values
|
||||
public EncodedIndexedItemReference(DexFile dexFile, T item) {
|
||||
this(dexFile, item, false);
|
||||
}
|
||||
|
||||
public EncodedIndexedItemReference(DexFile dexFile, T item, boolean isEnum) {
|
||||
if (item.getClass() == StringIdItem.class) {
|
||||
valueType = ValueType.VALUE_STRING;
|
||||
} else if (item.getClass() == TypeIdItem.class) {
|
||||
valueType = ValueType.VALUE_TYPE;
|
||||
} else if (item.getClass() == FieldIdItem.class) {
|
||||
valueType = ValueType.VALUE_FIELD;
|
||||
if (isEnum) {
|
||||
valueType = ValueType.VALUE_ENUM;
|
||||
} else {
|
||||
valueType = ValueType.VALUE_FIELD;
|
||||
}
|
||||
} else if (item.getClass() == MethodIdItem.class) {
|
||||
valueType = ValueType.VALUE_METHOD;
|
||||
}
|
||||
|
@ -42,6 +42,9 @@
|
||||
;.method public abstract fieldValue()Ljava/lang/reflect/Field;
|
||||
;.end method
|
||||
|
||||
.method public abstract enumValue()LEnum;
|
||||
.end method
|
||||
|
||||
.annotation system Ldalvik/annotation/AnnotationDefault;
|
||||
value = .subannotation LAnnotationWithValues;
|
||||
booleanValue = false
|
||||
@ -58,6 +61,7 @@
|
||||
.end subannotation
|
||||
typeValue = L10;
|
||||
methodValue = L10;->11()V
|
||||
enumValue = .enum LEnum;->12:LEnum;
|
||||
.end subannotation
|
||||
.end annotation
|
||||
|
||||
|
52
src/test/resources/examples/AnnotationValues/Enum.smali
Normal file
52
src/test/resources/examples/AnnotationValues/Enum.smali
Normal file
@ -0,0 +1,52 @@
|
||||
.class public final enum LEnum;
|
||||
.super Ljava/lang/Enum;
|
||||
|
||||
.field private static final synthetic $VALUES:[LEnum;
|
||||
|
||||
.field public static final enum 12:LEnum;
|
||||
|
||||
.method static constructor <clinit>()V
|
||||
.registers 4
|
||||
|
||||
const/4 v3, 1
|
||||
const/4 v2, 0
|
||||
new-instance v0, LEnum;
|
||||
const-string v1, "12"
|
||||
invoke-direct {v0, v1, v2}, LEnum;-><init>(Ljava/lang/String;I)V
|
||||
sput-object v0, LEnum;->12:LEnum;
|
||||
|
||||
const/4 v0, 1
|
||||
new-array v0, v0, [LEnum;
|
||||
sget-object v1, LEnum;->12:LEnum;
|
||||
aput-object v1, v0, v2
|
||||
|
||||
sput-object v0, LEnum;->$VALUES:[LEnum;
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method private constructor <init>(Ljava/lang/String;I)V
|
||||
.registers 3
|
||||
|
||||
invoke-direct {v0, v1, v2}, Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public static valueOf(Ljava/lang/String;)LEnum;
|
||||
.registers 2
|
||||
|
||||
const-class v0, LEnum;
|
||||
invoke-static {v0, v1}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
|
||||
move-result-object v1
|
||||
check-cast v1, LEnum;
|
||||
return-object v1
|
||||
.end method
|
||||
|
||||
.method public static values()[LEnum;
|
||||
.registers 1
|
||||
|
||||
sget-object v0, LEnum;->$VALUES:[LEnum;
|
||||
invoke-virtual {v0}, [LEnum;->clone()Ljava/lang/Object;
|
||||
move-result-object v0
|
||||
check-cast v0, [LEnum;
|
||||
return-object v0
|
||||
.end method
|
@ -2,9 +2,9 @@
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
;expected output:
|
||||
;@AnnotationWithValues(booleanValue=false, byteValue=1, charValue=2, doubleValue=7.0, floatValue=6.0, intValue=4, longValue=5, methodValue=public static void 10.11(), shortValue=3, stringValue=8, subAnnotationValue=@SubAnnotation(stringValue=9), typeValue=class 10)
|
||||
;@AnnotationWithValues(booleanValue=false, byteValue=1, charValue=2, doubleValue=7.0, enumValue=12, floatValue=6.0, intValue=4, longValue=5, methodValue=public static void 10.11(), shortValue=3, stringValue=8, subAnnotationValue=@SubAnnotation(stringValue=9), typeValue=class 10)
|
||||
|
||||
|
||||
|
||||
.method public static main([Ljava/lang/String;)V
|
||||
.registers 3
|
||||
|
||||
|
57
src/test/resources/examples/Enums/Enum.smali
Normal file
57
src/test/resources/examples/Enums/Enum.smali
Normal file
@ -0,0 +1,57 @@
|
||||
.class public final enum LEnum;
|
||||
.super Ljava/lang/Enum;
|
||||
|
||||
.field private static final synthetic $VALUES:[LEnum;
|
||||
|
||||
.field public static final enum VALUE1:LEnum;
|
||||
.field public static final enum VALUE2:LEnum;
|
||||
|
||||
.method static constructor <clinit>()V
|
||||
.registers 4
|
||||
|
||||
const/4 v3, 1
|
||||
const/4 v2, 0
|
||||
new-instance v0, LEnum;
|
||||
const-string v1, "VALUE1"
|
||||
invoke-direct {v0, v1, v2}, LEnum;-><init>(Ljava/lang/String;I)V
|
||||
sput-object v0, LEnum;->VALUE1:LEnum;
|
||||
new-instance v0, LEnum;
|
||||
const-string v1, "VALUE2"
|
||||
invoke-direct {v0, v1, v3}, LEnum;-><init>(Ljava/lang/String;I)V
|
||||
sput-object v0, LEnum;->VALUE2:LEnum;
|
||||
const/4 v0, 2
|
||||
new-array v0, v0, [LEnum;
|
||||
sget-object v1, LEnum;->VALUE1:LEnum;
|
||||
aput-object v1, v0, v2
|
||||
sget-object v1, LEnum;->VALUE2:LEnum;
|
||||
aput-object v1, v0, v3
|
||||
sput-object v0, LEnum;->$VALUES:[LEnum;
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method private constructor <init>(Ljava/lang/String;I)V
|
||||
.registers 3
|
||||
|
||||
invoke-direct {v0, v1, v2}, Ljava/lang/Enum;-><init>(Ljava/lang/String;I)V
|
||||
return-void
|
||||
.end method
|
||||
|
||||
.method public static valueof(Ljava/lang/String;)LEnum;
|
||||
.registers 2
|
||||
|
||||
const-class v0, LEnum;
|
||||
invoke-static {v0, v1}, Ljava/lang/Enum;->valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
|
||||
move-result-object v1
|
||||
check-cast v1, LEnum;
|
||||
return-object v1
|
||||
.end method
|
||||
|
||||
.method public static values()[LEnum;
|
||||
.registers 1
|
||||
|
||||
sget-object v0, LEnum;->$VALUES:[LEnum;
|
||||
invoke-virtual {v0}, [LEnum;->clone()Ljava/lang/Object;
|
||||
move-result-object v0
|
||||
check-cast v0, [LEnum;
|
||||
return-object v0
|
||||
.end method
|
15
src/test/resources/examples/Enums/Main.smali
Normal file
15
src/test/resources/examples/Enums/Main.smali
Normal file
@ -0,0 +1,15 @@
|
||||
.class public LMain;
|
||||
.super Ljava/lang/Object;
|
||||
|
||||
|
||||
|
||||
.method public static main([Ljava/lang/String;)V
|
||||
.registers 2
|
||||
|
||||
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
|
||||
sget-object v1, LEnum;->VALUE1:LEnum;
|
||||
|
||||
invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V
|
||||
|
||||
return-void
|
||||
.end method
|
Loading…
x
Reference in New Issue
Block a user