User Tools

Site Tools


Tiny v2

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.


tiny	2	0	official	intermediary	named
	someProperty	someValue
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>.

Miscellaneous Notes

  • The encoding for the entire file is UTF-8. Escape sequences are limited to the types, locations and conditions mentioned above.
  • Indenting uses tab characters exclusively, one tab character equals one level. The amount of leading tab characters is at most 1 more than in the preceding line.
  • Sections or properties with unknown types/keys should be skipped without generating an error.
  • The amount of extra namespaces defined in the header and the amount of names in every 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,.
  • Sections representing the same element must not be repeated, e.g. there can be only one top-level section for a specific class or one class-level section for a specific member.
  • If any variable mapping doesn't specify a LVT index, e.g. due to a missing LocalVariableTable attribute in one of the methods, the property missing-lvt-indices has to be added to.
  • Mappings without any (useful) names should be omitted.
  • Sections without any (useful) mappings or sub-sections should be omitted.
  • Comments should be without their enclosing syntax elements, indentation or decoration. For example, the comment
        * A comment
        * on two lines.

    (note the indentation) should be recorded as

    A comment<eol>on two lines.

Standard Properties

  • escaped-names: deserialize values with unescaping
  • missing-lvt-indices: expect local variable mappings without a lvt-index value
documentation/tiny2.txt · Last modified: 2023/09/16 21:23 by nebelnidas