mirror of
https://github.com/revanced/smali.git
synced 2025-05-01 15:14:32 +02:00
Added support for annotations
git-svn-id: https://smali.googlecode.com/svn/trunk@48 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
0d16dfbfcc
commit
6cbfb8b875
@ -215,7 +215,10 @@ FIELD_PHRASE
|
||||
WS
|
||||
FIELD_TYPE_DESCRIPTOR_EMITCHILD
|
||||
WS?
|
||||
('=' WS? LITERAL_EMITCHILD)?;
|
||||
(EQUAL_EMIT WS? LITERAL_EMITCHILD)?;
|
||||
|
||||
END_FIELD_PHRASE
|
||||
: END_FIELD_DIRECTIVE_EMIT;
|
||||
|
||||
METHOD_PHRASE
|
||||
: METHOD_DIRECTIVE_EMIT
|
||||
@ -239,7 +242,7 @@ INSTRUCTION_FORMAT11n_PHRASE
|
||||
: INSTRUCTION_FORMAT11n_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
INTEGRAL_LITERAL_EMITCHILD;
|
||||
|
||||
INSTRUCTION_FORMAT11x_PHRASE
|
||||
@ -251,7 +254,7 @@ INSTRUCTION_FORMAT12x_PHRASE
|
||||
: INSTRUCTION_FORMAT12x_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
REGISTER_EMIT;
|
||||
|
||||
INSTRUCTION_FORMAT20t_PHRASE
|
||||
@ -263,7 +266,7 @@ INSTRUCTION_FORMAT21c_FIELD_PHRASE
|
||||
: INSTRUCTION_FORMAT21c_FIELD_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
FULLY_QUALIFIED_MEMBER_NAME_EMITCHILDREN
|
||||
WS
|
||||
FIELD_TYPE_DESCRIPTOR_EMITCHILD;
|
||||
@ -272,53 +275,53 @@ INSTRUCTION_FORMAT21c_STRING_PHRASE
|
||||
: INSTRUCTION_FORMAT21c_STRING_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
STRING_LITERAL_EMIT;
|
||||
|
||||
INSTRUCTION_FORMAT21c_TYPE_PHRASE
|
||||
: INSTRUCTION_FORMAT21c_TYPE_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
CLASS_OR_ARRAY_TYPE_DESCRIPTOR_EMITCHILD;
|
||||
|
||||
INSTRUCTION_FORMAT21h_PHRASE
|
||||
: INSTRUCTION_FORMAT21h_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
INTEGRAL_LITERAL_EMITCHILD;
|
||||
|
||||
INSTRUCTION_FORMAT21s_PHRASE
|
||||
: INSTRUCTION_FORMAT21s_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
INTEGRAL_LITERAL_EMITCHILD;
|
||||
|
||||
INSTRUCTION_FORMAT21t_PHRASE
|
||||
: INSTRUCTION_FORMAT21t_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
(LABEL_EMIT | OFFSET_EMIT);
|
||||
|
||||
INSTRUCTION_FORMAT22b_PHRASE
|
||||
: INSTRUCTION_FORMAT22b_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
INTEGRAL_LITERAL_EMITCHILD;
|
||||
|
||||
INSTRUCTION_FORMAT22c_FIELD_PHRASE
|
||||
: INSTRUCTION_FORMAT22c_FIELD_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
FULLY_QUALIFIED_MEMBER_NAME_EMITCHILDREN
|
||||
WS
|
||||
FIELD_TYPE_DESCRIPTOR_EMITCHILD;
|
||||
@ -327,43 +330,43 @@ INSTRUCTION_FORMAT22c_TYPE_PHRASE
|
||||
: INSTRUCTION_FORMAT22c_TYPE_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
FIELD_TYPE_DESCRIPTOR_EMITCHILD;
|
||||
|
||||
INSTRUCTION_FORMAT22s_PHRASE
|
||||
: INSTRUCTION_FORMAT22s_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
INTEGRAL_LITERAL_EMITCHILD;
|
||||
|
||||
INSTRUCTION_FORMAT22t_PHRASE
|
||||
: INSTRUCTION_FORMAT22t_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
(LABEL_EMIT | OFFSET_EMIT);
|
||||
|
||||
INSTRUCTION_FORMAT22x_PHRASE
|
||||
: INSTRUCTION_FORMAT22x_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
REGISTER_EMIT;
|
||||
|
||||
INSTRUCTION_FORMAT23x_PHRASE
|
||||
: INSTRUCTION_FORMAT23x_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
REGISTER_EMIT;
|
||||
|
||||
INSTRUCTION_FORMAT30t_PHRASE
|
||||
@ -375,35 +378,35 @@ INSTRUCTION_FORMAT31c_PHRASE
|
||||
: INSTRUCTION_FORMAT31c_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
STRING_LITERAL_EMIT;
|
||||
|
||||
INSTRUCTION_FORMAT31i_PHRASE
|
||||
: INSTRUCTION_FORMAT31i_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
(FIXED_32BIT_LITERAL_EMITCHILD);
|
||||
|
||||
INSTRUCTION_FORMAT31t_PHRASE
|
||||
: INSTRUCTION_FORMAT31t_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
(LABEL_EMIT | OFFSET_EMIT);
|
||||
|
||||
INSTRUCTION_FORMAT32x_PHRASE
|
||||
: INSTRUCTION_FORMAT32x_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
REGISTER_EMIT;
|
||||
|
||||
INSTRUCTION_FORMAT35c_METHOD_PHRASE
|
||||
: INSTRUCTION_FORMAT35c_METHOD_EMIT
|
||||
WS
|
||||
REGISTER_LIST_EMITCHILDREN
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
FULLY_QUALIFIED_MEMBER_NAME_EMITCHILDREN
|
||||
METHOD_PROTOTYPE_EMITCHILDREN;
|
||||
|
||||
@ -411,7 +414,7 @@ INSTRUCTION_FORMAT3rc_METHOD_PHRASE
|
||||
: INSTRUCTION_FORMAT3rc_METHOD_EMIT
|
||||
WS
|
||||
REGISTER_RANGE_EMITCHILDREN
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
FULLY_QUALIFIED_MEMBER_NAME_EMITCHILDREN
|
||||
METHOD_PROTOTYPE_EMITCHILDREN;
|
||||
|
||||
@ -419,7 +422,7 @@ INSTRUCTION_FORMAT51l_PHRASE
|
||||
: INSTRUCTION_FORMAT51l_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
(FIXED_LITERAL_EMITCHILD);
|
||||
|
||||
ARRAY_DATA_PHRASE
|
||||
@ -473,16 +476,19 @@ PARAMETER_PHRASE
|
||||
: PARAMETER_DIRECTIVE_EMIT
|
||||
(WS STRING_LITERAL_EMIT?)?;
|
||||
|
||||
END_PARAMETER_PHRASE
|
||||
: END_PARAMETER_DIRECTIVE_EMIT;
|
||||
|
||||
LOCAL_PHRASE
|
||||
: LOCAL_DIRECTIVE_EMIT
|
||||
WS
|
||||
REGISTER_EMIT
|
||||
WS? ',' WS?
|
||||
WS? COMMA_EMIT WS?
|
||||
SIMPLE_NAME_EMIT
|
||||
WS
|
||||
FIELD_TYPE_DESCRIPTOR_EMITCHILD
|
||||
WS?
|
||||
( ',' WS? STRING_LITERAL_EMIT)?;
|
||||
( COMMA_EMIT WS? STRING_LITERAL_EMIT)?;
|
||||
|
||||
END_LOCAL_PHRASE
|
||||
: END_LOCAL_DIRECTIVE_EMIT
|
||||
@ -500,6 +506,16 @@ PROLOGUE_PHRASE
|
||||
EPILOGUE_PHRASE
|
||||
: EPILOGUE_DIRECTIVE_EMIT;
|
||||
|
||||
ANNOTATION_PHRASE
|
||||
: ANNOTATION_START_EMIT
|
||||
WS
|
||||
ANNOTATION_VISIBILITY_EMIT
|
||||
WS
|
||||
CLASS_DESCRIPTOR_EMIT
|
||||
WS
|
||||
(ANNOTATION_ELEMENT_EMITCHILDREN WS)*
|
||||
ANNOTATION_END_EMIT;
|
||||
|
||||
//TODO: add support for both relative and absolute offsets?
|
||||
fragment OFFSET_EMIT
|
||||
: OFFSET {emit($OFFSET, OFFSET);};
|
||||
@ -536,6 +552,11 @@ fragment FIELD_DIRECTIVE_EMIT
|
||||
fragment FIELD_DIRECTIVE
|
||||
: '.field';
|
||||
|
||||
fragment END_FIELD_DIRECTIVE_EMIT
|
||||
: END_FIELD_DIRECTIVE {emit($END_FIELD_DIRECTIVE, END_FIELD_DIRECTIVE);};
|
||||
fragment END_FIELD_DIRECTIVE
|
||||
: '.end field';
|
||||
|
||||
fragment METHOD_DIRECTIVE_EMIT
|
||||
: METHOD_DIRECTIVE {emit($METHOD_DIRECTIVE, METHOD_DIRECTIVE);};
|
||||
fragment METHOD_DIRECTIVE
|
||||
@ -596,6 +617,11 @@ fragment PARAMETER_DIRECTIVE_EMIT
|
||||
fragment PARAMETER_DIRECTIVE
|
||||
: '.parameter';
|
||||
|
||||
fragment END_PARAMETER_DIRECTIVE_EMIT
|
||||
: END_PARAMETER_DIRECTIVE {emit($END_PARAMETER_DIRECTIVE, END_PARAMETER_DIRECTIVE);};
|
||||
fragment END_PARAMETER_DIRECTIVE
|
||||
: '.end parameter';
|
||||
|
||||
fragment LOCAL_DIRECTIVE_EMIT
|
||||
: LOCAL_DIRECTIVE {emit($LOCAL_DIRECTIVE, LOCAL_DIRECTIVE);};
|
||||
fragment LOCAL_DIRECTIVE
|
||||
@ -629,7 +655,7 @@ fragment REGISTER
|
||||
fragment REGISTER_LIST_EMITCHILDREN
|
||||
: OPEN_BRACKET_EMIT
|
||||
( WS?
|
||||
REGISTER_EMIT (WS? ',' WS? REGISTER_EMIT)*
|
||||
REGISTER_EMIT (WS? COMMA_EMIT WS? REGISTER_EMIT)*
|
||||
WS?
|
||||
| WS?)
|
||||
CLOSE_BRACKET_EMIT;
|
||||
@ -821,7 +847,69 @@ fragment LITERAL_EMITCHILD
|
||||
| FLOAT_LITERAL_EMIT
|
||||
| DOUBLE_LITERAL_EMIT
|
||||
| CHAR_LITERAL_EMIT
|
||||
| BOOL_LITERAL_EMIT;
|
||||
| BOOL_LITERAL_EMIT
|
||||
| TYPE_DESCRIPTOR_EMITCHILD
|
||||
| ARRAY_LITERAL_EMITCHILDREN
|
||||
| SUBANNOTATION_EMITCHILDREN;
|
||||
|
||||
fragment SUBANNOTATION_EMITCHILDREN
|
||||
: SUBANNOTATION_START_EMIT
|
||||
WS
|
||||
CLASS_DESCRIPTOR_EMIT
|
||||
WS
|
||||
(ANNOTATION_ELEMENT_EMITCHILDREN WS)*
|
||||
SUBANNOTATION_END_EMIT
|
||||
;
|
||||
|
||||
fragment SUBANNOTATION_START_EMIT
|
||||
: SUBANNOTATION_START {emit($SUBANNOTATION_START, SUBANNOTATION_START);};
|
||||
fragment SUBANNOTATION_START
|
||||
: '.subannotation';
|
||||
|
||||
fragment SUBANNOTATION_END_EMIT
|
||||
: SUBANNOTATION_END {emit($SUBANNOTATION_END, SUBANNOTATION_END);};
|
||||
fragment SUBANNOTATION_END
|
||||
: '.end subannotation';
|
||||
|
||||
fragment ANNOTATION_START_EMIT
|
||||
: ANNOTATION_START {emit($ANNOTATION_START, ANNOTATION_START);};
|
||||
fragment ANNOTATION_START
|
||||
: '.annotation';
|
||||
|
||||
fragment ANNOTATION_END_EMIT
|
||||
: ANNOTATION_END {emit($ANNOTATION_END, ANNOTATION_END);};
|
||||
fragment ANNOTATION_END
|
||||
: '.end annotation';
|
||||
|
||||
fragment ANNOTATION_VISIBILITY_EMIT
|
||||
: ANNOTATION_VISIBILITY {emit($ANNOTATION_VISIBILITY, ANNOTATION_VISIBILITY);};
|
||||
fragment ANNOTATION_VISIBILITY
|
||||
: 'build'
|
||||
| 'runtime'
|
||||
| 'system';
|
||||
|
||||
fragment ANNOTATION_ELEMENT_EMITCHILDREN
|
||||
: MEMBER_NAME_EMIT
|
||||
WS?
|
||||
EQUAL_EMIT
|
||||
WS?
|
||||
LITERAL_EMITCHILD;
|
||||
|
||||
fragment ARRAY_LITERAL_EMITCHILDREN
|
||||
: ARRAY_START_EMIT
|
||||
WS?
|
||||
(LITERAL_EMITCHILD WS? (COMMA_EMIT WS? LITERAL_EMITCHILD WS?)*)?
|
||||
ARRAY_END_EMIT;
|
||||
|
||||
fragment ARRAY_START_EMIT
|
||||
: ARRAY_START {emit($ARRAY_START, ARRAY_START);};
|
||||
fragment ARRAY_START
|
||||
: '{';
|
||||
|
||||
fragment ARRAY_END_EMIT
|
||||
: ARRAY_END {emit($ARRAY_END, ARRAY_END);};
|
||||
fragment ARRAY_END
|
||||
: '}';
|
||||
|
||||
|
||||
fragment STRING_LITERAL_EMIT
|
||||
@ -1316,3 +1404,13 @@ LINE_COMMENT
|
||||
: (';' ~('\n'|'\r')* ('\r\n' | '\r' | '\n')
|
||||
| ';' ~('\n'|'\r')*)
|
||||
{$channel = HIDDEN;};
|
||||
|
||||
fragment EQUAL_EMIT
|
||||
: EQUAL {emit($EQUAL, EQUAL, Token.HIDDEN_CHANNEL);};
|
||||
fragment EQUAL
|
||||
: '=';
|
||||
|
||||
fragment COMMA_EMIT
|
||||
: COMMA {emit($COMMA, COMMA, Token.HIDDEN_CHANNEL);};
|
||||
fragment COMMA
|
||||
: ',';
|
||||
|
@ -52,6 +52,11 @@ tokens {
|
||||
I_REGISTERS;
|
||||
I_LABELS;
|
||||
I_LABEL;
|
||||
I_ANNOTATIONS;
|
||||
I_ANNOTATION;
|
||||
I_ANNOTATION_ELEMENT;
|
||||
I_SUBANNOTATION;
|
||||
I_ENCODED_ARRAY;
|
||||
I_ARRAY_ELEMENT_SIZE;
|
||||
I_ARRAY_ELEMENTS;
|
||||
I_PACKED_SWITCH_START_KEY;
|
||||
@ -146,25 +151,28 @@ import org.JesusFreke.dexlib.code.Format.*;
|
||||
|
||||
|
||||
smali_file
|
||||
:
|
||||
scope
|
||||
{
|
||||
boolean hasClassSpec = false;
|
||||
boolean hasSuperSpec = false;
|
||||
boolean hasSourceSpec = false;
|
||||
boolean hasClassSpec;
|
||||
boolean hasSuperSpec;
|
||||
boolean hasSourceSpec;
|
||||
}
|
||||
( {!hasClassSpec}?=> class_spec {hasClassSpec = true;}
|
||||
| {!hasSuperSpec}?=> super_spec {hasSuperSpec = true;}
|
||||
@init { $smali_file::hasClassSpec = $smali_file::hasSuperSpec = $smali_file::hasSourceSpec = false; }
|
||||
:
|
||||
( {!$smali_file::hasClassSpec}?=> class_spec {$smali_file::hasClassSpec = true;}
|
||||
| {!$smali_file::hasSuperSpec}?=> super_spec {$smali_file::hasSuperSpec = true;}
|
||||
| implements_spec
|
||||
| {!hasSourceSpec}?=> source_spec {hasSourceSpec = true;}
|
||||
| {!$smali_file::hasSourceSpec}?=> source_spec {$smali_file::hasSourceSpec = true;}
|
||||
| method
|
||||
| field)*
|
||||
| field
|
||||
| annotation)*
|
||||
{
|
||||
if (!hasClassSpec) {
|
||||
if (!$smali_file::hasClassSpec) {
|
||||
//TODO: throw correct exception type
|
||||
throw new RuntimeException("The file must contain a .class directive");
|
||||
}
|
||||
|
||||
if (!hasSuperSpec) {
|
||||
if (!$smali_file::hasSuperSpec) {
|
||||
//TODO: throw correct exception type
|
||||
throw new RuntimeException("The file must contain a .super directive");
|
||||
}
|
||||
@ -174,7 +182,7 @@ smali_file
|
||||
super_spec
|
||||
implements_spec*
|
||||
source_spec
|
||||
^(I_METHODS method*) ^(I_FIELDS field*));
|
||||
^(I_METHODS method*) ^(I_FIELDS field*) ^(I_ANNOTATIONS annotation*));
|
||||
|
||||
class_spec
|
||||
: CLASS_DIRECTIVE access_list CLASS_DESCRIPTOR -> CLASS_DESCRIPTOR access_list;
|
||||
@ -192,8 +200,11 @@ access_list
|
||||
: ACCESS_SPEC+ -> ^(I_ACCESS_LIST[$start,"I_ACCESS_LIST"] ACCESS_SPEC+);
|
||||
|
||||
|
||||
field : FIELD_DIRECTIVE access_list MEMBER_NAME field_type_descriptor literal?
|
||||
-> ^(I_FIELD[$start, "I_FIELD"] MEMBER_NAME access_list ^(I_FIELD_TYPE field_type_descriptor) ^(I_FIELD_INITIAL_VALUE literal)?);
|
||||
field : FIELD_DIRECTIVE access_list MEMBER_NAME field_type_descriptor literal?
|
||||
( (annotation+ END_FIELD_DIRECTIVE)=> annotation+ END_FIELD_DIRECTIVE
|
||||
| END_FIELD_DIRECTIVE?
|
||||
)
|
||||
-> ^(I_FIELD[$start, "I_FIELD"] MEMBER_NAME access_list ^(I_FIELD_TYPE field_type_descriptor) ^(I_FIELD_INITIAL_VALUE literal)? ^(I_ANNOTATIONS annotation*));
|
||||
|
||||
method
|
||||
scope {int currentAddress;}
|
||||
@ -215,19 +226,21 @@ fully_qualified_field
|
||||
: CLASS_NAME MEMBER_NAME field_type_descriptor;
|
||||
|
||||
statements_and_directives
|
||||
scope {boolean hasRegistersDirective;}
|
||||
: {
|
||||
$method::currentAddress = 0;
|
||||
boolean hasRegistersDirective = false;
|
||||
$statements_and_directives::hasRegistersDirective = false;
|
||||
}
|
||||
( instruction {$method::currentAddress += $instruction.size/2;}
|
||||
| {!hasRegistersDirective}?=> registers_directive {hasRegistersDirective = true;}
|
||||
| {!$statements_and_directives::hasRegistersDirective}?=> registers_directive {$statements_and_directives::hasRegistersDirective = true;}
|
||||
| label
|
||||
| catch_directive
|
||||
| parameter_directive
|
||||
| ordered_debug_directive
|
||||
| annotation
|
||||
)*
|
||||
{
|
||||
if (!hasRegistersDirective) {
|
||||
if (!$statements_and_directives::hasRegistersDirective) {
|
||||
//TODO: throw correct exception type here
|
||||
throw new RuntimeException("This method has no register directive");
|
||||
}
|
||||
@ -237,7 +250,8 @@ statements_and_directives
|
||||
^(I_STATEMENTS instruction*)
|
||||
^(I_CATCHES catch_directive*)
|
||||
^(I_PARAMETERS parameter_directive*)
|
||||
^(I_ORDERED_DEBUG_DIRECTIVES ordered_debug_directive*);
|
||||
^(I_ORDERED_DEBUG_DIRECTIVES ordered_debug_directive*)
|
||||
^(I_ANNOTATIONS annotation*);
|
||||
|
||||
registers_directive
|
||||
: REGISTERS_DIRECTIVE integral_literal
|
||||
@ -250,9 +264,17 @@ catch_directive
|
||||
|
||||
|
||||
parameter_directive
|
||||
: PARAMETER_DIRECTIVE ( STRING_LITERAL -> ^(I_PARAMETER STRING_LITERAL?)
|
||||
| -> ^(I_PARAMETER I_PARAMETER_NOT_SPECIFIED)
|
||||
);
|
||||
: PARAMETER_DIRECTIVE
|
||||
( STRING_LITERAL
|
||||
( (annotation+ END_PARAMETER_DIRECTIVE)=> annotation+ END_PARAMETER_DIRECTIVE
|
||||
| END_PARAMETER_DIRECTIVE?
|
||||
)
|
||||
-> ^(I_PARAMETER STRING_LITERAL ^(I_ANNOTATIONS annotation*))
|
||||
| ( (annotation+ END_PARAMETER_DIRECTIVE)=> annotation+ END_PARAMETER_DIRECTIVE
|
||||
| END_PARAMETER_DIRECTIVE?
|
||||
)
|
||||
-> ^(I_PARAMETER I_PARAMETER_NOT_SPECIFIED ^(I_ANNOTATIONS annotation*))
|
||||
);
|
||||
|
||||
ordered_debug_directive
|
||||
: line_directive
|
||||
@ -295,7 +317,7 @@ label
|
||||
: LABEL -> ^(I_LABEL LABEL I_ADDRESS[$start, Integer.toString($method::currentAddress)]);
|
||||
|
||||
instruction returns [int size]
|
||||
@init {boolean needsNop = false;}
|
||||
@init {boolean needsNop = false; int targetCount = 0;}
|
||||
: //e.g. goto endloop:
|
||||
//e.g. goto +3
|
||||
INSTRUCTION_FORMAT10t (LABEL | OFFSET) {$size = Format10t.Format.getByteCount();}
|
||||
@ -400,7 +422,7 @@ instruction returns [int size]
|
||||
|
|
||||
PACKED_SWITCH_DIRECTIVE
|
||||
{
|
||||
int targetCount = 0;
|
||||
targetCount = 0;
|
||||
if (($method::currentAddress \% 2) != 0) {
|
||||
needsNop = true;
|
||||
$size = 2;
|
||||
@ -434,7 +456,7 @@ instruction returns [int size]
|
||||
|
|
||||
SPARSE_SWITCH_DIRECTIVE
|
||||
{
|
||||
int targetCount = 0;
|
||||
targetCount = 0;
|
||||
if (($method::currentAddress \% 2) != 0) {
|
||||
needsNop = true;
|
||||
$size = 2;
|
||||
@ -516,10 +538,33 @@ fixed_literal returns[int size]
|
||||
| CHAR_LITERAL {$size = 2;}
|
||||
| BOOL_LITERAL {$size = 1;};
|
||||
|
||||
literal : INTEGER_LITERAL
|
||||
literal
|
||||
: INTEGER_LITERAL
|
||||
| LONG_LITERAL
|
||||
| SHORT_LITERAL_EMIT
|
||||
| BYTE_LITERAL_EMIT
|
||||
| FLOAT_LITERAL
|
||||
| DOUBLE_LITERAL
|
||||
| CHAR_LITERAL
|
||||
| STRING_LITERAL
|
||||
| BOOL_LITERAL;
|
||||
| BOOL_LITERAL
|
||||
| type_descriptor
|
||||
| array_literal
|
||||
| subannotation;
|
||||
|
||||
array_literal
|
||||
: ARRAY_START literal* ARRAY_END
|
||||
-> ^(I_ENCODED_ARRAY[$start, "I_ENCODED_ARRAY"] literal*);
|
||||
|
||||
annotation
|
||||
: ANNOTATION_START ANNOTATION_VISIBILITY CLASS_DESCRIPTOR
|
||||
annotation_element* ANNOTATION_END
|
||||
-> ^(I_ANNOTATION[$start, "I_ANNOTATION"] ANNOTATION_VISIBILITY ^(I_SUBANNOTATION[$start, "I_SUBANNOTATION"] CLASS_DESCRIPTOR annotation_element*));
|
||||
|
||||
annotation_element
|
||||
: MEMBER_NAME literal
|
||||
-> ^(I_ANNOTATION_ELEMENT[$start, "I_ANNOTATION_ELEMENT"] MEMBER_NAME literal);
|
||||
|
||||
subannotation
|
||||
: SUBANNOTATION_START CLASS_DESCRIPTOR annotation_element* SUBANNOTATION_END
|
||||
-> ^(I_SUBANNOTATION[$start, "I_SUBANNOTATION"] CLASS_DESCRIPTOR annotation_element*);
|
||||
|
@ -87,13 +87,33 @@ import org.JesusFreke.dexlib.code.Format.*;
|
||||
|
||||
|
||||
|
||||
smali_file returns[ClassDefItem classDefItem]
|
||||
: ^(I_CLASS_DEF header methods fields);
|
||||
smali_file
|
||||
: ^(I_CLASS_DEF header methods fields annotations)
|
||||
{
|
||||
AnnotationDirectoryItem annotationDirectoryItem = null;
|
||||
|
||||
if ( $methods.methodAnnotationSets != null ||
|
||||
$methods.parameterAnnotationSets != null ||
|
||||
$fields.fieldAnnotationSets != null ||
|
||||
$annotations.annotationSetItem != null) {
|
||||
annotationDirectoryItem = new AnnotationDirectoryItem(
|
||||
dexFile,
|
||||
$annotations.annotationSetItem,
|
||||
$fields.fieldAnnotationSets,
|
||||
$methods.methodAnnotationSets,
|
||||
$methods.parameterAnnotationSets);
|
||||
}
|
||||
|
||||
classDefItem.setAnnotations(annotationDirectoryItem);
|
||||
};
|
||||
|
||||
header : class_spec super_spec implements_list source_spec
|
||||
|
||||
header returns[TypeIdItem classType, int accessFlags, TypeIdItem superType, TypeListItem implementsList, StringIdItem sourceSpec]
|
||||
: class_spec super_spec implements_list source_spec
|
||||
{
|
||||
classDataItem = new ClassDataItem(dexFile, 0);
|
||||
classDefItem = new ClassDefItem(dexFile, $class_spec.type, $class_spec.accessFlags, $super_spec.type, $implements_list.implementsList, $source_spec.source, classDataItem);
|
||||
classDefItem = new ClassDefItem(dexFile, $class_spec.type, $class_spec.accessFlags,
|
||||
$super_spec.type, $implements_list.implementsList, $source_spec.source, classDataItem);
|
||||
};
|
||||
|
||||
class_spec returns[TypeIdItem type, int accessFlags]
|
||||
@ -143,20 +163,41 @@ access_list returns [int value]
|
||||
}
|
||||
)+);
|
||||
|
||||
fields : ^(I_FIELDS
|
||||
fields returns[List<AnnotationDirectoryItem.FieldAnnotation> fieldAnnotationSets]
|
||||
: ^(I_FIELDS
|
||||
(field
|
||||
{
|
||||
classDefItem.addField($field.encodedField, $field.encodedValue);
|
||||
if ($field.fieldAnnotationSet != null) {
|
||||
if ($fieldAnnotationSets == null) {
|
||||
$fieldAnnotationSets = new ArrayList<AnnotationDirectoryItem.FieldAnnotation>();
|
||||
}
|
||||
fieldAnnotationSets.add($field.fieldAnnotationSet);
|
||||
}
|
||||
})*);
|
||||
|
||||
methods : ^(I_METHODS
|
||||
methods returns[List<AnnotationDirectoryItem.MethodAnnotation> methodAnnotationSets,
|
||||
List<AnnotationDirectoryItem.ParameterAnnotation> parameterAnnotationSets]
|
||||
: ^(I_METHODS
|
||||
(method
|
||||
{
|
||||
classDataItem.addMethod($method.encodedMethod);
|
||||
if ($method.methodAnnotationSet != null) {
|
||||
if ($methodAnnotationSets == null) {
|
||||
$methodAnnotationSets = new ArrayList<AnnotationDirectoryItem.MethodAnnotation>();
|
||||
}
|
||||
$methodAnnotationSets.add($method.methodAnnotationSet);
|
||||
}
|
||||
if ($method.parameterAnnotationSets != null) {
|
||||
if ($parameterAnnotationSets == null) {
|
||||
$parameterAnnotationSets = new ArrayList<AnnotationDirectoryItem.ParameterAnnotation>();
|
||||
}
|
||||
$parameterAnnotationSets.add($method.parameterAnnotationSets);
|
||||
}
|
||||
})*);
|
||||
|
||||
field returns[ClassDataItem.EncodedField encodedField, EncodedValue encodedValue]
|
||||
:^(I_FIELD MEMBER_NAME access_list ^(I_FIELD_TYPE field_type_descriptor) field_initial_value)
|
||||
field returns[ClassDataItem.EncodedField encodedField, EncodedValue encodedValue, AnnotationDirectoryItem.FieldAnnotation fieldAnnotationSet]
|
||||
:^(I_FIELD MEMBER_NAME access_list ^(I_FIELD_TYPE field_type_descriptor) field_initial_value annotations?)
|
||||
{
|
||||
TypeIdItem classType = classDefItem.getClassType();
|
||||
StringIdItem memberName = new StringIdItem(dexFile, $MEMBER_NAME.text);
|
||||
@ -175,23 +216,31 @@ field returns[ClassDataItem.EncodedField encodedField, EncodedValue encodedValue
|
||||
} else {
|
||||
$encodedValue = null;
|
||||
}
|
||||
|
||||
if ($annotations.annotationSetItem != null) {
|
||||
$fieldAnnotationSet = new AnnotationDirectoryItem.FieldAnnotation(dexFile, fieldIdItem, $annotations.annotationSetItem);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//TODO: what about type or array encoded values?
|
||||
field_initial_value returns[EncodedValue encodedValue]
|
||||
: ^(I_FIELD_INITIAL_VALUE
|
||||
( integer_literal { $encodedValue = new EncodedValue(dexFile, new IntEncodedValueSubField($integer_literal.value)); }
|
||||
| long_literal { $encodedValue = new EncodedValue(dexFile, new LongEncodedValueSubField($long_literal.value)); }
|
||||
| short_literal { $encodedValue = new EncodedValue(dexFile, new ShortEncodedValueSubField($short_literal.value)); }
|
||||
| byte_literal { $encodedValue = new EncodedValue(dexFile, new ByteEncodedValueSubField($byte_literal.value)); }
|
||||
| float_literal { $encodedValue = new EncodedValue(dexFile, new FloatEncodedValueSubField($float_literal.value)); }
|
||||
| double_literal { $encodedValue = new EncodedValue(dexFile, new DoubleEncodedValueSubField($double_literal.value)); }
|
||||
| char_literal { $encodedValue = new EncodedValue(dexFile, new CharEncodedValueSubField($char_literal.value)); }
|
||||
| string_literal { $encodedValue = new EncodedValue(dexFile, new EncodedIndexedItemReference(dexFile, new StringIdItem(dexFile, $string_literal.value))); }
|
||||
| bool_literal { $encodedValue = new EncodedValue(dexFile, new BoolEncodedValueSubField($bool_literal.value)); }
|
||||
))
|
||||
| ;
|
||||
: ^(I_FIELD_INITIAL_VALUE literal) {$encodedValue = $literal.encodedValue;}
|
||||
| ;
|
||||
|
||||
literal returns[EncodedValue encodedValue]
|
||||
: integer_literal { $encodedValue = new EncodedValue(dexFile, new IntEncodedValueSubField($integer_literal.value)); }
|
||||
| long_literal { $encodedValue = new EncodedValue(dexFile, new LongEncodedValueSubField($long_literal.value)); }
|
||||
| short_literal { $encodedValue = new EncodedValue(dexFile, new ShortEncodedValueSubField($short_literal.value)); }
|
||||
| byte_literal { $encodedValue = new EncodedValue(dexFile, new ByteEncodedValueSubField($byte_literal.value)); }
|
||||
| float_literal { $encodedValue = new EncodedValue(dexFile, new FloatEncodedValueSubField($float_literal.value)); }
|
||||
| double_literal { $encodedValue = new EncodedValue(dexFile, new DoubleEncodedValueSubField($double_literal.value)); }
|
||||
| char_literal { $encodedValue = new EncodedValue(dexFile, new CharEncodedValueSubField($char_literal.value)); }
|
||||
| string_literal { $encodedValue = new EncodedValue(dexFile, new EncodedIndexedItemReference(dexFile, new StringIdItem(dexFile, $string_literal.value))); }
|
||||
| bool_literal { $encodedValue = new EncodedValue(dexFile, new BoolEncodedValueSubField($bool_literal.value)); }
|
||||
| type_descriptor { $encodedValue = new EncodedValue(dexFile, new EncodedIndexedItemReference(dexFile, $type_descriptor.type)); }
|
||||
| array_literal { $encodedValue = new EncodedValue(dexFile, new ArrayEncodedValueSubField(dexFile, $array_literal.values)); }
|
||||
| subannotation { $encodedValue = new EncodedValue(dexFile, $subannotation.value); };
|
||||
|
||||
|
||||
//everything but string
|
||||
fixed_size_literal returns[byte[\] value]
|
||||
@ -280,7 +329,9 @@ sparse_switch_targets[int baseOffset, int targetCount] returns[int[\] targets]
|
||||
})*
|
||||
);
|
||||
|
||||
method returns[ClassDataItem.EncodedMethod encodedMethod]
|
||||
method returns[ ClassDataItem.EncodedMethod encodedMethod,
|
||||
AnnotationDirectoryItem.MethodAnnotation methodAnnotationSet,
|
||||
AnnotationDirectoryItem.ParameterAnnotation parameterAnnotationSets]
|
||||
scope
|
||||
{
|
||||
HashMap<String, Integer> labels;
|
||||
@ -303,6 +354,7 @@ method returns[ClassDataItem.EncodedMethod encodedMethod]
|
||||
catches
|
||||
parameters
|
||||
ordered_debug_directives
|
||||
annotations
|
||||
)
|
||||
{
|
||||
MethodIdItem methodIdItem = $method_name_and_prototype.methodIdItem;
|
||||
@ -345,6 +397,14 @@ method returns[ClassDataItem.EncodedMethod encodedMethod]
|
||||
handlers);
|
||||
|
||||
$encodedMethod = new ClassDataItem.EncodedMethod(dexFile, methodIdItem, access, codeItem);
|
||||
|
||||
if ($annotations.annotationSetItem != null) {
|
||||
$methodAnnotationSet = new AnnotationDirectoryItem.MethodAnnotation(dexFile, methodIdItem, $annotations.annotationSetItem);
|
||||
}
|
||||
|
||||
if ($parameters.parameterAnnotations != null) {
|
||||
$parameterAnnotationSets = new AnnotationDirectoryItem.ParameterAnnotation(dexFile, methodIdItem, $parameters.parameterAnnotations);
|
||||
}
|
||||
};
|
||||
|
||||
method_prototype returns[ProtoIdItem protoIdItem]
|
||||
@ -436,14 +496,39 @@ address returns[int address]
|
||||
$address = Integer.parseInt($I_ADDRESS.text);
|
||||
};
|
||||
|
||||
parameters
|
||||
: ^(I_PARAMETERS parameter*);
|
||||
parameters returns[AnnotationSetRefList parameterAnnotations]
|
||||
@init
|
||||
{
|
||||
int parameterCount = 0;
|
||||
List<AnnotationSetItem> annotationSetItems = new ArrayList<AnnotationSetItem>();
|
||||
}
|
||||
: ^(I_PARAMETERS (parameter
|
||||
{
|
||||
if ($parameter.parameterAnnotationSet != null) {
|
||||
while (annotationSetItems.size() < parameterCount) {
|
||||
annotationSetItems.add(new AnnotationSetItem(dexFile, -1));
|
||||
}
|
||||
annotationSetItems.add($parameter.parameterAnnotationSet);
|
||||
}
|
||||
|
||||
parameterCount++;
|
||||
})*
|
||||
)
|
||||
{
|
||||
if (annotationSetItems.size() > 0) {
|
||||
while (annotationSetItems.size() < parameterCount) {
|
||||
annotationSetItems.add(new AnnotationSetItem(dexFile, -1));
|
||||
}
|
||||
$parameterAnnotations = new AnnotationSetRefList(dexFile, annotationSetItems);
|
||||
}
|
||||
};
|
||||
|
||||
parameter
|
||||
: ^(I_PARAMETER (
|
||||
string_literal {$method::debugInfo.addParameterName($string_literal.value);}
|
||||
parameter returns[AnnotationSetItem parameterAnnotationSet]
|
||||
: ^(I_PARAMETER ( string_literal {$method::debugInfo.addParameterName($string_literal.value);}
|
||||
| I_PARAMETER_NOT_SPECIFIED {$method::debugInfo.addParameterName(null);}
|
||||
));
|
||||
)
|
||||
annotations {$parameterAnnotationSet = $annotations.annotationSetItem;}
|
||||
);
|
||||
|
||||
ordered_debug_directives
|
||||
: ^(I_ORDERED_DEBUG_DIRECTIVES ( line
|
||||
@ -998,3 +1083,41 @@ string_literal returns[String value]
|
||||
|
||||
bool_literal returns[boolean value]
|
||||
: BOOL_LITERAL { $value = Boolean.parseBoolean($BOOL_LITERAL.text); };
|
||||
|
||||
array_literal returns[ArrayList<EncodedValue> values]
|
||||
: {$values = new ArrayList<EncodedValue>();}
|
||||
^(I_ENCODED_ARRAY (literal {$values.add($literal.encodedValue);})*);
|
||||
|
||||
|
||||
annotations returns[AnnotationSetItem annotationSetItem]
|
||||
: {ArrayList<AnnotationItem> annotationList = new ArrayList<AnnotationItem>();}
|
||||
^(I_ANNOTATIONS (annotation {annotationList.add($annotation.annotationItem);} )*)
|
||||
{
|
||||
if (annotationList.size() > 0) {
|
||||
$annotationSetItem = new AnnotationSetItem(dexFile, annotationList);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
annotation returns[AnnotationItem annotationItem]
|
||||
: ^(I_ANNOTATION ANNOTATION_VISIBILITY subannotation)
|
||||
{
|
||||
AnnotationVisibility visibility = AnnotationVisibility.fromName($ANNOTATION_VISIBILITY.text);
|
||||
$annotationItem = new AnnotationItem(dexFile, visibility, $subannotation.value);
|
||||
};
|
||||
|
||||
annotation_element returns[AnnotationElement element]
|
||||
: ^(I_ANNOTATION_ELEMENT MEMBER_NAME literal)
|
||||
{
|
||||
$element = new AnnotationElement(dexFile, new StringIdItem(dexFile, $MEMBER_NAME.text), $literal.encodedValue);
|
||||
};
|
||||
|
||||
subannotation returns[AnnotationEncodedValueSubField value]
|
||||
: {ArrayList<AnnotationElement> elements = new ArrayList<AnnotationElement>();}
|
||||
^( I_SUBANNOTATION
|
||||
class_type_descriptor
|
||||
(annotation_element {elements.add($annotation_element.element);} )* )
|
||||
{
|
||||
$value = new AnnotationEncodedValueSubField(dexFile, $class_type_descriptor.type, elements);
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,8 @@ package org.JesusFreke.dexlib;
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
//TODO: fix field names in dex-format.html and submit
|
||||
public class AnnotationDirectoryItem extends OffsettedItem<AnnotationDirectoryItem> {
|
||||
@ -74,6 +76,39 @@ public class AnnotationDirectoryItem extends OffsettedItem<AnnotationDirectoryIt
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AnnotationDirectoryItem(final DexFile dexFile,
|
||||
AnnotationSetItem classAnnotations,
|
||||
List<FieldAnnotation> fieldAnnotations,
|
||||
List<MethodAnnotation> methodAnnotations,
|
||||
List<ParameterAnnotation> parameterAnnotations) {
|
||||
this(dexFile, -1);
|
||||
|
||||
this.classAnnotations.setReference(classAnnotations);
|
||||
|
||||
if (fieldAnnotations != null) {
|
||||
this.fieldAnnotationList.addAll(fieldAnnotations);
|
||||
}
|
||||
|
||||
if (methodAnnotations != null) {
|
||||
this.methodAnnotationList.addAll(methodAnnotations);
|
||||
}
|
||||
|
||||
if (parameterAnnotations != null) {
|
||||
this.parameterAnnotationList.addAll(parameterAnnotations);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int place(int index, int offset)
|
||||
{
|
||||
Collections.sort(fieldAnnotationList);
|
||||
Collections.sort(methodAnnotationList);
|
||||
Collections.sort(parameterAnnotationList);
|
||||
return super.place(index, offset);
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
@ -86,48 +121,91 @@ public class AnnotationDirectoryItem extends OffsettedItem<AnnotationDirectoryIt
|
||||
return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM;
|
||||
}
|
||||
|
||||
public class FieldAnnotation extends CompositeField<FieldAnnotation> {
|
||||
public static class FieldAnnotation extends CompositeField<FieldAnnotation>
|
||||
implements Comparable<FieldAnnotation> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final IndexedItemReference<FieldIdItem> field;
|
||||
private final OffsettedItemReference<AnnotationSetItem> annotationSet;
|
||||
|
||||
public FieldAnnotation(DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
new IndexedItemReference<FieldIdItem>(dexFile.FieldIdsSection, new IntegerField()),
|
||||
new OffsettedItemReference<AnnotationSetItem>(dexFile.AnnotationSetsSection, new IntegerField())
|
||||
field = new IndexedItemReference<FieldIdItem>(dexFile.FieldIdsSection, new IntegerField()),
|
||||
annotationSet = new OffsettedItemReference<AnnotationSetItem>(dexFile.AnnotationSetsSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public FieldAnnotation(DexFile dexFile, FieldIdItem field, AnnotationSetItem annotationSet) {
|
||||
this(dexFile);
|
||||
this.field.setReference(field);
|
||||
this.annotationSet.setReference(annotationSet);
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public int compareTo(FieldAnnotation o) {
|
||||
return ((Integer)field.getReference().getIndex()).compareTo(o.field.getReference().getIndex());
|
||||
}
|
||||
}
|
||||
|
||||
public class MethodAnnotation extends CompositeField<MethodAnnotation> {
|
||||
public static class MethodAnnotation extends CompositeField<MethodAnnotation>
|
||||
implements Comparable<MethodAnnotation> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final IndexedItemReference<MethodIdItem> method;
|
||||
private final OffsettedItemReference<AnnotationSetItem> annotationSet;
|
||||
|
||||
public MethodAnnotation(DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
new IndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection, new IntegerField()),
|
||||
new OffsettedItemReference<AnnotationSetItem>(dexFile.AnnotationSetsSection, new IntegerField())
|
||||
method = new IndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection, new IntegerField()),
|
||||
annotationSet = new OffsettedItemReference<AnnotationSetItem>(dexFile.AnnotationSetsSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public MethodAnnotation(DexFile dexFile, MethodIdItem method, AnnotationSetItem annotationSet) {
|
||||
this(dexFile);
|
||||
this.method.setReference(method);
|
||||
this.annotationSet.setReference(annotationSet);
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public int compareTo(MethodAnnotation o) {
|
||||
return ((Integer)method.getReference().getIndex()).compareTo(o.method.getReference().getIndex());
|
||||
}
|
||||
}
|
||||
|
||||
public class ParameterAnnotation extends CompositeField<ParameterAnnotation> {
|
||||
public static class ParameterAnnotation extends CompositeField<ParameterAnnotation>
|
||||
implements Comparable<ParameterAnnotation> {
|
||||
private final Field[] fields;
|
||||
|
||||
private final IndexedItemReference<MethodIdItem> method;
|
||||
private final OffsettedItemReference<AnnotationSetRefList> parameterAnnotations;
|
||||
|
||||
public ParameterAnnotation(DexFile dexFile) {
|
||||
fields = new Field[] {
|
||||
new IndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection, new IntegerField()),
|
||||
new OffsettedItemReference<AnnotationSetItem>(dexFile.AnnotationSetsSection, new IntegerField())
|
||||
method = new IndexedItemReference<MethodIdItem>(dexFile.MethodIdsSection, new IntegerField()),
|
||||
parameterAnnotations = new OffsettedItemReference<AnnotationSetRefList>(
|
||||
dexFile.AnnotationSetRefListsSection, new IntegerField())
|
||||
};
|
||||
}
|
||||
|
||||
public ParameterAnnotation(DexFile dexFile, MethodIdItem method, AnnotationSetRefList parameterAnnotations) {
|
||||
this(dexFile);
|
||||
this.method.setReference(method);
|
||||
this.parameterAnnotations.setReference(parameterAnnotations);
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public int compareTo(ParameterAnnotation o) {
|
||||
return ((Integer)method.getReference().getIndex()).compareTo(o.method.getReference().getIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,16 @@ public class AnnotationItem extends OffsettedItem<AnnotationItem> {
|
||||
};
|
||||
}
|
||||
|
||||
public AnnotationItem(DexFile dexFile, AnnotationVisibility visibility,
|
||||
AnnotationEncodedValueSubField annotation) {
|
||||
super(-1);
|
||||
|
||||
fields = new Field[] {
|
||||
this.visibility = new ByteField(visibility.value),
|
||||
this.annotation = annotation
|
||||
};
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 1;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ package org.JesusFreke.dexlib;
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AnnotationSetItem extends OffsettedItem<AnnotationSetItem> {
|
||||
private final Field[] fields;
|
||||
@ -48,12 +49,22 @@ public class AnnotationSetItem extends OffsettedItem<AnnotationSetItem> {
|
||||
annotationCount = new ListSizeField(annotationReferences, new IntegerField()),
|
||||
annotations = new FieldListField<OffsettedItemReference<AnnotationItem>>(annotationReferences) {
|
||||
protected OffsettedItemReference<AnnotationItem> make() {
|
||||
return new OffsettedItemReference<AnnotationItem>(dexFile.AnnotationsSection, new IntegerField());
|
||||
return new OffsettedItemReference<AnnotationItem>(dexFile.AnnotationsSection,
|
||||
new IntegerField());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public AnnotationSetItem(final DexFile dexFile, List<AnnotationItem> annotations) {
|
||||
this(dexFile, -1);
|
||||
|
||||
for (AnnotationItem annotationItem: annotations) {
|
||||
this.annotationReferences.add(new OffsettedItemReference<AnnotationItem>(dexFile,
|
||||
annotationItem, new IntegerField()));
|
||||
}
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ package org.JesusFreke.dexlib;
|
||||
import org.JesusFreke.dexlib.ItemType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AnnotationSetRefList extends OffsettedItem<AnnotationSetRefList> {
|
||||
private final Field[] fields;
|
||||
@ -54,6 +55,14 @@ public class AnnotationSetRefList extends OffsettedItem<AnnotationSetRefList> {
|
||||
};
|
||||
}
|
||||
|
||||
public AnnotationSetRefList(final DexFile dexFile, List<AnnotationSetItem> annotationSets) {
|
||||
this(dexFile, -1);
|
||||
|
||||
for (AnnotationSetItem annotation: annotationSets) {
|
||||
this.annotationSetReferences.add(new OffsettedItemReference<AnnotationSetItem>(dexFile, annotation, new IntegerField()));
|
||||
}
|
||||
}
|
||||
|
||||
protected int getAlignment() {
|
||||
return 4;
|
||||
}
|
||||
|
@ -69,7 +69,13 @@ public class ClassDefItem extends IndexedItem<ClassDefItem> {
|
||||
};
|
||||
}
|
||||
|
||||
public ClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags, TypeIdItem superType, TypeListItem implementsList, StringIdItem source, ClassDataItem classDataItem) {
|
||||
public ClassDefItem(DexFile dexFile,
|
||||
TypeIdItem classType,
|
||||
int accessFlags,
|
||||
TypeIdItem superType,
|
||||
TypeListItem implementsList,
|
||||
StringIdItem source,
|
||||
ClassDataItem classDataItem) {
|
||||
super(-1);
|
||||
|
||||
this.dexFile = dexFile;
|
||||
@ -132,10 +138,9 @@ public class ClassDefItem extends IndexedItem<ClassDefItem> {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void addMethod(ClassDataItem.EncodedMethod encodedMethod) {
|
||||
}
|
||||
|
||||
public void addField(ClassDataItem.EncodedField encodedField, EncodedValue initialValue) {
|
||||
//fields are added in ClassDefItem instead of ClassDataItem because we need to grab
|
||||
//the static initializers for StaticFieldInitialValues
|
||||
if (!encodedField.isStatic() && initialValue != null) {
|
||||
throw new RuntimeException("Initial values are only allowed for static fields.");
|
||||
}
|
||||
@ -163,6 +168,10 @@ public class ClassDefItem extends IndexedItem<ClassDefItem> {
|
||||
}
|
||||
}
|
||||
|
||||
public void setAnnotations(AnnotationDirectoryItem annotations) {
|
||||
this.classAnnotations.setReference(annotations);
|
||||
}
|
||||
|
||||
public static int placeClassDefItems(IndexedSection<ClassDefItem> section, int offset) {
|
||||
ClassDefPlacer cdp = new ClassDefPlacer(section);
|
||||
return cdp.placeSection(offset);
|
||||
|
@ -42,6 +42,13 @@ public class AnnotationElement extends CompositeField<AnnotationElement> {
|
||||
encodedValue = new EncodedValue(dexFile)
|
||||
};
|
||||
}
|
||||
|
||||
public AnnotationElement(final DexFile dexFile, StringIdItem elementName, EncodedValue encodedValue) {
|
||||
fields = new Field[] {
|
||||
this.elementName = new IndexedItemReference<StringIdItem>(dexFile, elementName, new Leb128Field()),
|
||||
this.encodedValue = encodedValue
|
||||
};
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
|
@ -31,6 +31,7 @@ package org.JesusFreke.dexlib.EncodedValue;
|
||||
import org.JesusFreke.dexlib.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AnnotationEncodedValueSubField extends CompositeField<AnnotationEncodedValueSubField>
|
||||
implements EncodedValueSubField<AnnotationEncodedValueSubField> {
|
||||
@ -54,6 +55,13 @@ public class AnnotationEncodedValueSubField extends CompositeField<AnnotationEnc
|
||||
};
|
||||
}
|
||||
|
||||
public AnnotationEncodedValueSubField(final DexFile dexFile, TypeIdItem annotationType,
|
||||
List<AnnotationElement> annotationElements) {
|
||||
this(dexFile);
|
||||
this.annotationType.setReference(annotationType);
|
||||
this.annotationElementList.addAll(annotationElements);
|
||||
}
|
||||
|
||||
protected Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
@ -72,7 +72,9 @@ public class DebugInfoBuilder
|
||||
}
|
||||
|
||||
public void addParameterName(String parameterName) {
|
||||
hasData = true;
|
||||
if (parameterName != null) {
|
||||
hasData = true;
|
||||
}
|
||||
|
||||
parameterNames.add(parameterName);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user