- 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:
JesusFreke@JesusFreke.com 2009-06-03 07:05:59 +00:00
parent 361fa2548e
commit d54c635f84
9 changed files with 175 additions and 8 deletions

View File

@ -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

View File

@ -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);

View File

@ -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);
};

View File

@ -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;
}

View File

@ -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

View 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

View File

@ -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

View 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

View 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