Tiny v2 consists of a list of hierarchical sections. Every line starts a new section, whether it continues an existing section is determined by the indentation level. A section's parent is always the closest preceding section indented once less than itself. Accordingly, a section ends just before the next line with the same or a lesser indentation level.
The child-to-parent relationships form the paths to uniquely identify any element globally. For example, all field and method sections that are children of a class section represent members of the represented class.
Sections need to be unique within their level. For example a specific class may only be recorded once, a comment can't be redefined or the same parameter listed twice.
Example:
tiny 2 0 official intermediary named someProperty someValue anotherProperty c a class_123 pkg/SomeClass f [I a field_789 someField m (III)V a method_456 someMethod p 1 param_0 x p 2 param_1 y p 3 param_2 z c Just a method for demonstrating the format. c b class_234 pkg/xy/AnotherClass m (Ljava/lang/String;)I a method_567 anotherMethod
<file> ::= <header> | <header> <content> <header> ::= 'tiny' <tab> <major-version> <tab> <minor-version> <tab> <namespace-a> <tab> <namespace-b> <extra-namespaces> <eol> <properties> <major-version> ::= <non-negative-int> <minor-version> ::= <non-negative-int> <namespace-a> ::= <namespace> <namespace-b> ::= <namespace> <extra-namespaces> ::= '' | <tab> <namespace> <extra-namespaces> <namespace> ::= <safe-string> <properties> ::= '' | <tab> <property> <eol> <properties> <property> ::= <property-key> | <property-key> <tab> <property-value> <property-key> ::= <safe-string> <property-value> ::= <escaped-string> <content> ::= '' | <class-section> <content> <class-section> ::= 'c' <tab> <class-name-a> <tab> <class-name-b> <extra-ns-class-names> <eol> <class-sub-sections> <class-name-a> ::= <class-name> <class-name-b> ::= <optional-class-name> <optional-class-name> ::= '' | <class-name> <extra-ns-cls-names> ::= '' | <tab> <optional-class-name> <extra-ns-class-names> <class-name> ::= <conf-safe-string> <class-sub-sections> ::= '' | <class-comment-section> <class-sub-sections> | <field-section> <class-sub-sections> | <method-section> <class-sub-sections> <field-section> ::= <tab> 'f' <tab> <field-desc-a> <tab> <field-name-a> <tab> <field-name-b> <extra-ns-field-names> <eol> <field-sub-sections> <field-name-a> ::= <field-name> <field-name-b> ::= <optional-field-name> <optional-field-name> ::= '' | <field-name> <extra-ns-field-names> ::= '' | <tab> <optional-field-name> <extra-ns-field-names> <field-name> ::= <conf-safe-string> <field-desc-a> ::= <field-desc> <field-desc> ::= <conf-safe-string> <field-sub-sections> ::= '' | <member-comment-section> <field-sub-sections> <method-section> ::= <tab> 'm' <tab> <method-desc-a> <tab> <method-name-a> <tab> <method-name-b> <extra-ns-method-names> <eol> <method-sub-sections> <method-name-a> ::= <method-name> <method-name-b> ::= <optional-method-name> <optional-method-name> ::= '' | <method-name> <extra-ns-method-names> ::= '' | <tab> <optional-method-name> <extra-ns-method-names> <method-name> ::= <conf-safe-string> <method-desc-a> ::= <method-desc> <method-desc> ::= <conf-safe-string> <method-sub-sections> ::= '' | <member-comment-section> <method-sub-sections> | <method-parameter-section> <method-sub-sections> | <method-variable-section> <method-sub-sections> <method-parameter-section> ::= <tab> <tab> 'p' <tab> <lv-index> <tab> <var-name-a> <tab> <var-name-b> <extra-ns-var-names> <eol> <method-parameter-sub-sections> <var-name-a> ::= <optional-var-name> <var-name-b> ::= <optional-var-name> <optional-var-name> ::= '' | <var-name> <extra-ns-var-names> ::= '' | <tab> <optional-var-name> <extra-ns-var-names> <var-name> ::= <conf-safe-string> <lv-index> ::= <non-negative-int> <method-parameter-sub-sections> ::= '' | <var-comment-section> <method-parameter-sub-sections> <method-variable-section> ::= <tab> <tab> 'v' <tab> <lv-index> <tab> <lv-start-offset> <tab> <optional-lvt-index> <tab> <var-name-a> <tab> <var-name-b> <extra-ns-var-names> <eol> <method-variable-sub-sections> <lv-start-offset> ::= <non-negative-int> <optional-lvt-index> ::= '-1' | <lvt-index> <lvt-index> ::= <non-negative-int> <method-variable-sub-sections> ::= '' | <var-comment-section> <method-variable-sub-sections> <comment> ::= <escaped-string> <class-comment-section> ::= <tab> 'c' <tab> <comment> <eol> <member-comment-section> ::= <tab> <tab> 'c' <tab> <comment> <eol> <var-comment-section> ::= <tab> <tab> <tab> 'c' <tab> <comment> <eol>
<tab>
is \t
.<eol>
is \n
or \r\n
.<safe-string>
is a non-empty string that must not contain:\
,\n
,\r
,\t
or\0
.<conf-safe-string>
is the same as <safe-string>
if <properties>
doesn't contain a <property>
escaped-names
, otherwise it's a non-empty string further described by <escaped-string>
.<escaped-string>
is a string that must not contain an <eol>
, escapes \
to \\
and the other forbidden values to their string literal equivalents, as seen in the list above.<non-negative-int>
is any integer from 0 to 2147483647 (2^31-1) inclusive, represented as per java.lang.Integer.toString()
.<class-name>
, once optionally unescaped, is the binary name of a class as specified in JVMS SE 8 §4.2.1. Nested class identifiers are typically separated with $
(e.g. some/package/class$nested$subnested
). Outer names must not be omitted for any namespace.<field-name>
/<method-name>
/<var-name>
, once optionally unescaped, is the unqualified name of a field/method/variable as specified in JVMS SE 8 §4.2.2.<field-desc>
, once optionally unescaped, is a field descriptor as specified in JVMS SE 8 §4.3.2.<method-desc>
, once optionally unescaped, is a method descriptor as specified in JVMS SE 8 §4.3.3.<lv-index>
refers to the local variable array index of the frames having the variable, see “index” in JVMS SE 8 §4.7.13.<lv-start-offset>
is at most the start of the range in which the variable has a value, but doesn't overlap with another variable with the same <lv-index>
, see “start_pc” in JVMS SE 8 §4.7.13. The start offset/range for Tiny v2 is measured in instructions with a valid opcode, not bytes.<lvt-index>
is the index into the LocalVariableTable attribute's local_variable_table array
, see “local_variable_table” in JVMS SE 8 §4.7.13, not to be confused with “index” referred by <lv-index>
.extra-ns-*-names
definition have to match. They are associated by their relative position, like the mandatory name spaces a
and b
that are associated by the suffix, e.g. namespace-a
covers class-name-a
, field-name-a
, field-desc-a
, method-name-a
, method-desc-a
and var-desc-a
,.LocalVariableTable
attribute in one of the methods, the property missing-lvt-indices
has to be added to./** * A comment * on two lines. */
(note the indentation) should be recorded as
A comment<eol>on two lines.
escaped-names
: deserialize values with unescapingmissing-lvt-indices
: expect local variable mappings without a lvt-index value