We use BNF notation. Terminal symbols start with at least two
consecutive upper case letters. Each terminal is represented as a
single byte tag. Non-terminals are mixed case. Prefixes of the form
lower case letter*_ are for explanation of semantic content only, they
can be dropped without changing the grammar.
Micro-syntax:
LongInt = Digit* StopDigit // big endian 2's complement, value fits in a Long w/o overflow
Int = LongInt // big endian 2's complement, fits in an Int w/o overflow
Nat = LongInt // non-negative value, fits in an Int without overflow
Digit = 0 | ... | 127
StopDigit = 128 | ... | 255 // value = digit - 128
NameRef = Nat // ordinal number of name in name table, starting from 1.
Note: Unqualified names in the name table are strings. The context decides whether a name is
a type-name or a term-name. The same string can represent both.
Standard-Section: "ASTs" TopLevelStat*
TopLevelStat = PACKAGE Length Path TopLevelStat*
Stat
// Imports are for scala.meta, they are not used in the backend
TypeParam = TYPEPARAM Length NameRef Type Modifier*
Params = PARAMS Length Param*
Param = PARAM Length NameRef Type rhs_Term? Modifier* // rhs_Term is present in the case of an aliased class parameter
Template = TEMPLATE Length TypeParam* Param* Parent* Self? Stat* // Stat* always starts with the primary constructor.
Parent = Application
Type
Self = SELFDEF selfName_NameRef selfType_Type
Term = Path
Application
IDENT NameRef Type // used when ident’s type is not a TermRef
SELECT possiblySigned_NameRef qual_Term
NEW cls_Type
SUPER Length this_Term mixinTrait_Type?
TYPED Length expr_Term ascription_Type
NAMEDARG Length paramName_NameRef arg_Term
ASSIGN Length lhs_Term rhs_Term
BLOCK Length expr_Term Stat*
INLINED Length call_Term expr_Term Stat*
LAMBDA Length meth_Term target_Type
IF Length cond_Term then_Term else_Term
MATCH Length sel_Term CaseDef*
TRY Length expr_Term CaseDef* finalizer_Term?
RETURN Length meth_ASTRef expr_Term?
REPEATED Length elem_Type elem_Term*
BIND Length boundName_NameRef patType_Type pat_Term
ALTERNATIVE Length alt_Term*
UNAPPLY Length fun_Term ImplicitArg* pat_Type pat_Term*
EMPTYTREE
SHARED term_ASTRef
Application = APPLY Length fn_Term arg_Term*
Constant = UNITconst
FALSEconst
TRUEconst
BYTEconst Int
SHORTconst Int
CHARconst Nat
INTconst Int
LONGconst LongInt
FLOATconst Int
DOUBLEconst LongInt
STRINGconst NameRef
NULLconst
CLASSconst Type
ENUMconst Path
Type = Path
TYPEREFdirect sym_ASTRef
TYPEREFsymbol sym_ASTRef qual_Type
TYPEREFpkg fullyQualified_NameRef
TYPEREF possiblySigned_NameRef qual_Type
RECtype parent_Type
SUPERtype Length this_Type underlying_Type
REFINEDtype Length underlying_Type refinement_NameRef info_Type
APPLIEDtype Length tycon_Type arg_Type*
TYPEBOUNDS Length low_Type high_Type
TYPEALIAS Length alias_Type (COVARIANT | CONTRAVARIANT)?
ANNOTATED Length underlying_Type fullAnnotation_Term
ANDtype Length left_Type right_Type
ORtype Length left_Type right_Type
BIND Length boundName_NameRef bounds_Type
// for type-variables defined in a type pattern
BYNAMEtype underlying_Type
POLYtype Length result_Type NamesTypes // variance encoded in front of name: +/-/=
METHODtype Length result_Type NamesTypes // needed for refinements
PARAMtype Length binder_ASTref paramNum_Nat // needed for refinements
SHARED type_ASTRef
NamesTypes = NameType*
NameType = paramName_NameRef typeOrBounds_ASTRef
Modifier = PRIVATE
INTERNAL // package private
PROTECTED
PRIVATEqualified qualifier_Type // will be dropped
PROTECTEDqualified qualifier_Type // will be dropped
ABSTRACT
FINAL
SEALED
CASE
IMPLICIT
LAZY
OVERRIDE
INLINE // macro
STATIC // mapped to static Java member
OBJECT // an object or its class
TRAIT // a trait
LOCAL // private[this] or protected[this]
SYNTHETIC // generated by Scala compiler
ARTIFACT // to be tagged Java Synthetic
MUTABLE // a var
LABEL // method generated as a label
FIELDaccessor // getter or setter
CASEaccessor // getter for case class param
COVARIANT // type param marked “+”
CONTRAVARIANT // type param marked “-”
SCALA2X // Imported from Scala2.x
DEFAULTparameterized // Method with default params
INSUPERCALL // defined in the argument of a constructor supercall
STABLE // Method that is assumed to be stable
Annotation
Annotation = ANNOTATION Length tycon_Type fullAnnotation_Term
Note: Tree tags are grouped into 5 categories that determine what follows, and thus allow to compute the size of the tagged tree in a generic way.
Category 1 (tags 0-63) : tag
Category 2 (tags 64-95) : tag Nat
Category 3 (tags 96-111) : tag AST
Category 4 (tags 112-127): tag Nat AST
Category 5 (tags 128-255): tag Length <payload>
Standard Section: "Positions" Assoc*
Assoc = Header offset_Delta? offset_Delta?
Header = addr_Delta + // in one Nat: difference of address to last recorded node << 2 +
hasStartDiff + // one bit indicating whether there follows a start address delta << 1
hasEndDiff // one bit indicating whether there follows an end address delta
// Nodes which have the same positions as their parents are omitted.
// offset_Deltas give difference of start/end offset wrt to the
// same offset in the previously recorded node (or 0 for the first recorded node)
Delta = Int // Difference between consecutive offsets,
If non-negative, the number of leading references (represented as nats) of a length/trees entry.
If negative, minus the number of leading non-reference trees.
********************************************************** Notation:
We use BNF notation. Terminal symbols start with at least two consecutive upper case letters. Each terminal is represented as a single byte tag. Non-terminals are mixed case. Prefixes of the form lower case letter*_ are for explanation of semantic content only, they can be dropped without changing the grammar.
Micro-syntax:
LongInt = Digit* StopDigit // big endian 2's complement, value fits in a Long w/o overflow Int = LongInt // big endian 2's complement, fits in an Int w/o overflow Nat = LongInt // non-negative value, fits in an Int without overflow Digit = 0 | ... | 127 StopDigit = 128 | ... | 255 // value = digit - 128
Macro-format:
File = Header majorVersion_Nat minorVersion_Nat UUID nameTable_Length Name* Section* Header = 0x5CA1AB1F UUID = Byte*16 // random UUID
Section = NameRef Length Bytes Length = Nat // length of rest of entry in bytes
Name = UTF8 Length UTF8-CodePoint* QUALIFIED Length qualified_NameRef selector_NameRef SIGNED Length original_NameRef resultSig_NameRef paramSig_NameRef* EXPANDED Length original_NameRef OBJECTCLASS Length module_NameRef SUPERACCESSOR Length accessed_NameRef DEFAULTGETTER Length method_NameRef paramNumber_Nat SHADOWED Length original_NameRef MANGLED Length mangle_NameRef name_NameRef ...
NameRef = Nat // ordinal number of name in name table, starting from 1.
Note: Unqualified names in the name table are strings. The context decides whether a name is a type-name or a term-name. The same string can represent both.
Standard-Section: "ASTs" TopLevelStat*
TopLevelStat = PACKAGE Length Path TopLevelStat* Stat
Stat = Term VALDEF Length NameRef Type rhs_Term? Modifier* DEFDEF Length NameRef TypeParam* Params* return_Type rhs_Term? Modifier* TYPEDEF Length NameRef (Type | Template) Modifier* IMPORT Length qual_Term Selector* Selector = IMPORTED name_NameRef RENAMED to_NameRef
// Imports are for scala.meta, they are not used in the backend
TypeParam = TYPEPARAM Length NameRef Type Modifier* Params = PARAMS Length Param* Param = PARAM Length NameRef Type rhs_Term? Modifier* // rhs_Term is present in the case of an aliased class parameter Template = TEMPLATE Length TypeParam* Param* Parent* Self? Stat* // Stat* always starts with the primary constructor. Parent = Application Type Self = SELFDEF selfName_NameRef selfType_Type
Term = Path Application IDENT NameRef Type // used when ident’s type is not a TermRef SELECT possiblySigned_NameRef qual_Term NEW cls_Type SUPER Length this_Term mixinTrait_Type? TYPED Length expr_Term ascription_Type NAMEDARG Length paramName_NameRef arg_Term ASSIGN Length lhs_Term rhs_Term BLOCK Length expr_Term Stat* INLINED Length call_Term expr_Term Stat* LAMBDA Length meth_Term target_Type IF Length cond_Term then_Term else_Term MATCH Length sel_Term CaseDef* TRY Length expr_Term CaseDef* finalizer_Term? RETURN Length meth_ASTRef expr_Term? REPEATED Length elem_Type elem_Term* BIND Length boundName_NameRef patType_Type pat_Term ALTERNATIVE Length alt_Term* UNAPPLY Length fun_Term ImplicitArg* pat_Type pat_Term* EMPTYTREE SHARED term_ASTRef Application = APPLY Length fn_Term arg_Term*
TYPEAPPLY Length fn_Term arg_Type* CaseDef = CASEDEF Length pat_Term rhs_Tree guard_Tree? ImplicitArg = IMPLICITARG arg_Term ASTRef = Nat // byte position in AST payload
Path = Constant TERMREFdirect sym_ASTRef TERMREFsymbol sym_ASTRef qual_Type TERMREFpkg fullyQualified_NameRef TERMREF possiblySigned_NameRef qual_Type THIS clsRef_Type RECthis recType_ASTRef SHARED path_ASTRef
Constant = UNITconst FALSEconst TRUEconst BYTEconst Int SHORTconst Int CHARconst Nat INTconst Int LONGconst LongInt FLOATconst Int DOUBLEconst LongInt STRINGconst NameRef NULLconst CLASSconst Type ENUMconst Path
Type = Path TYPEREFdirect sym_ASTRef TYPEREFsymbol sym_ASTRef qual_Type TYPEREFpkg fullyQualified_NameRef TYPEREF possiblySigned_NameRef qual_Type RECtype parent_Type SUPERtype Length this_Type underlying_Type REFINEDtype Length underlying_Type refinement_NameRef info_Type APPLIEDtype Length tycon_Type arg_Type* TYPEBOUNDS Length low_Type high_Type TYPEALIAS Length alias_Type (COVARIANT | CONTRAVARIANT)? ANNOTATED Length underlying_Type fullAnnotation_Term ANDtype Length left_Type right_Type ORtype Length left_Type right_Type BIND Length boundName_NameRef bounds_Type // for type-variables defined in a type pattern BYNAMEtype underlying_Type POLYtype Length result_Type NamesTypes // variance encoded in front of name: +/-/= METHODtype Length result_Type NamesTypes // needed for refinements PARAMtype Length binder_ASTref paramNum_Nat // needed for refinements SHARED type_ASTRef NamesTypes = NameType* NameType = paramName_NameRef typeOrBounds_ASTRef
Modifier = PRIVATE INTERNAL // package private PROTECTED PRIVATEqualified qualifier_Type // will be dropped PROTECTEDqualified qualifier_Type // will be dropped ABSTRACT FINAL SEALED CASE IMPLICIT LAZY OVERRIDE INLINE // macro STATIC // mapped to static Java member OBJECT // an object or its class TRAIT // a trait LOCAL // private[this] or protected[this] SYNTHETIC // generated by Scala compiler ARTIFACT // to be tagged Java Synthetic MUTABLE // a var LABEL // method generated as a label FIELDaccessor // getter or setter CASEaccessor // getter for case class param COVARIANT // type param marked “+” CONTRAVARIANT // type param marked “-” SCALA2X // Imported from Scala2.x DEFAULTparameterized // Method with default params INSUPERCALL // defined in the argument of a constructor supercall STABLE // Method that is assumed to be stable Annotation Annotation = ANNOTATION Length tycon_Type fullAnnotation_Term
Note: Tree tags are grouped into 5 categories that determine what follows, and thus allow to compute the size of the tagged tree in a generic way.
Category 1 (tags 0-63) : tag Category 2 (tags 64-95) : tag Nat Category 3 (tags 96-111) : tag AST Category 4 (tags 112-127): tag Nat AST Category 5 (tags 128-255): tag Length <payload>
Standard Section: "Positions" Assoc*
Assoc = Header offset_Delta? offset_Delta? Header = addr_Delta + // in one Nat: difference of address to last recorded node << 2 + hasStartDiff + // one bit indicating whether there follows a start address delta << 1 hasEndDiff // one bit indicating whether there follows an end address delta // Nodes which have the same positions as their parents are omitted. // offset_Deltas give difference of start/end offset wrt to the // same offset in the previously recorded node (or 0 for the first recorded node) Delta = Int // Difference between consecutive offsets,
************************************************************************************