desugar

object desugar
class Object
trait Matchable
class Any

Type members

Classlikes

A type tree that computes its type from an existing parameter.

A type tree that computes its type from an existing parameter.

What static check should be applied to a Match?

What static check should be applied to a Match?

class TermRefTree(implicit @constructorOnly src: SourceFile) extends DerivedTypeTree
class TypeRefTree(implicit @constructorOnly src: SourceFile) extends DerivedTypeTree

Types

The type of tests that check whether a MemberDef is OK for some flag. The test succeeds if the partial function is defined and returns true.

The type of tests that check whether a MemberDef is OK for some flag. The test succeeds if the partial function is defined and returns true.

Value members

Concrete methods

def addDefaultGetters(meth: DefDef)(using Context): Tree
def apply(tree: Tree)(using Context): Tree

Main desugaring method

Main desugaring method

def binop(left: Tree, op: Ident, right: Tree)(using Context): Apply

Translate infix operation expression

Translate infix operation expression

l op r ==> l.op(r) if op is left-associative ==> r.op(l) if op is right-associative

def block(tree: Block)(using Context): Block

{ stats; } ==> { stats; () }

{ stats; } ==> { stats; () }

def checkModifiers(tree: Tree)(using Context): Tree

Check that modifiers are legal for the definition tree. Right now, we only check for opaque. TODO: Move other modifier checks here.

Check that modifiers are legal for the definition tree. Right now, we only check for opaque. TODO: Move other modifier checks here.

def classDef(cdef: TypeDef)(using Context): Tree

The expansion of a class definition. See inline comments for what is involved

The expansion of a class definition. See inline comments for what is involved

def defTree(tree: Tree)(using Context): Tree

A value definition copied from vdef with a tpt typetree derived from it

A value definition copied from vdef with a tpt typetree derived from it

A type definition copied from tdef with a rhs typetree derived from it

A type definition copied from tdef with a rhs typetree derived from it

A derived type definition watching sym

A derived type definition watching sym

def extMethods(ext: ExtMethods)(using Context): Tree

Transform extension construct to list of extension methods

Transform extension construct to list of extension methods

Invent a name for an anonympus given of type or template impl.

Invent a name for an anonympus given of type or template impl.

Is name the name of a method that is added unconditionally to case classes?

Is name the name of a method that is added unconditionally to case classes?

Is name the name of a method that can be invalidated as a compiler-generated case class method if it clashes with a user-defined method?

Is name the name of a method that can be invalidated as a compiler-generated case class method if it clashes with a user-defined method?

def isSetterNeeded(valDef: ValDef)(using Context): Boolean

Setter generation is needed for:

Setter generation is needed for:

  • non-private class members
  • all trait members
  • all package object members
def makeAnnotated(fullName: String, tree: Tree)(using Context): Annotated

Add annotation to tree: tree @fullName

Add annotation to tree: tree @fullName

The annotation is usually represented as a TypeTree referring to the class with the given name fullName. However, if the annotation matches a file name that is still to be entered, the annotation is represented as a cascade of Selects following fullName. This is necessary so that we avoid reading an annotation from the classpath that is also compiled from source.

def makeCaseLambda(cases: List[CaseDef], checkMode: MatchCheck, nparams: Int)(using Context): Function

If nparams == 1, expand partial function

If nparams == 1, expand partial function

 { cases }

==> x$1 => (x$1 @unchecked?) match { cases }

If nparams != 1, expand instead to

 (x$1, ..., x$n) => (x$0, ..., x${n-1} @unchecked?) match { cases }
def makeClosure(params: List[ValDef], body: Tree, tpt: Tree, isContextual: Boolean, span: Span)(using Context): Block

Make closure corresponding to function. params => body ==> def $anonfun(params) = body Closure($anonfun)

Make closure corresponding to function. params => body ==> def $anonfun(params) = body Closure($anonfun)

def makeContextualFunction(formals: List[Tree], body: Tree, isErased: Boolean)(using Context): Function
def makeImplicitParameters(tpts: List[Tree], implicitFlag: FlagSet, forPrimaryConstructor: Boolean)(using Context): List[ValDef]
def makePatDef(original: Tree, mods: Modifiers, pat: Tree, rhs: Tree)(using Context): Tree

If pat is a variable pattern,

If pat is a variable pattern,

val/var/lazy val p = e

Otherwise, in case there is exactly one variable x_1 in pattern val/var/lazy val p = e ==> val/var/lazy val x_1 = (e: @unchecked) match (case p => (x_1))

in case there are zero or more than one variables in pattern val/var/lazy p = e ==> private[this] synthetic [lazy] val t$ = (e: @unchecked) match (case p => (x_1, ..., x_N)) val/var/def x_1 = t$._1 ... val/var/def x_N = t$._N If the original pattern variable carries a type annotation, so does the corresponding ValDef or DefDef.

def makeSelector(sel: Tree, checkMode: MatchCheck)(using Context): Tree

The selector of a match, which depends of the given checkMode.

The selector of a match, which depends of the given checkMode.

Value Params
sel

the original selector

Returns

if checkMode is - None : sel @unchecked - Exhaustive : sel - IrrefutablePatDef, IrrefutableGenFrom: sel with attachment CheckIrrefutable -> checkMode

def makeTryCase(handlerFun: Tree)(using Context): CaseDef

Turn a fucntion value handlerFun into a catch case for a try. If handlerFun is a partial function, translate to

Turn a fucntion value handlerFun into a catch case for a try. If handlerFun is a partial function, translate to

case ex => val ev$1 = handlerFun if ev$1.isDefinedAt(ex) then ev$1.apply(ex) else throw ex

Otherwise translate to

case ex => handlerFun.apply(ex)

def makeTupledFunction(params: List[ValDef], body: Tree, isGenericTuple: Boolean)(using Context): Tree

Map n-ary function (x1: T1, ..., xn: Tn) => body where n != 1 to unary function as follows:

Map n-ary function (x1: T1, ..., xn: Tn) => body where n != 1 to unary function as follows:

(x$1: (T1, ..., Tn)) => { def x1: T1 = x$1._1 ... def xn: Tn = x$1._n body }

or if isGenericTuple

(x$1: (T1, ... Tn) => { def x1: T1 = x$1.apply(0) ... def xn: Tn = x$1.apply(n-1) body }

If some of the Ti's are absent, omit the : (T1, ..., Tn) type ascription in the selector.

def mapParamss(paramss: List[ParamClause])(mapTypeParam: TypeDef => TypeDef)(mapTermParam: ValDef => ValDef)(using Context): List[ParamClause]
def moduleDef(mdef: ModuleDef)(using Context): Tree

Expand

Expand

object name extends parents { self => body }

to:

val name: name$ = New(name$) final class name$ extends parents { self: name.type => body }

def normalizeName(mdef: MemberDef, impl: Tree)(using Context): Name

The normalized name of mdef. This means

The normalized name of mdef. This means

  1. Check that the name does not redefine a Scala core class. If it does redefine, issue an error and return a mangled name instead of the original one.
  2. If the name is missing (this can be the case for instance definitions), invent one instead.

Group all definitions that can't be at the toplevel in an object named <source>$package where <source> is the name of the source file. Definitions that can't be at the toplevel are:

Group all definitions that can't be at the toplevel in an object named <source>$package where <source> is the name of the source file. Definitions that can't be at the toplevel are:

  • all pattern, value and method definitions
  • non-class type definitions
  • implicit classes and objects
  • "companion objects" of wrapped type definitions (i.e. objects having the same name as a wrapped type)

Expand

Expand

package object name { body }

to:

package name { object package { body } }

Assuming src contains top-level definition, returns the name that should be using for the package object that will wrap them.

Assuming src contains top-level definition, returns the name that should be using for the package object that will wrap them.

def patDef(pdef: PatDef)(using Context): Tree

val p1, ..., pN: T = E ==> makePatDefp1: T1 = E; ...; makePatDefpN: TN = E

val p1, ..., pN: T = E ==> makePatDefp1: T1 = E; ...; makePatDefpN: TN = E

case e1, ..., eN

==> expandSimpleEnumCase([case e1]); ...; expandSimpleEnumCase([case eN])

def patternVar(tree: Tree)(using Context): Bind

Expand variable identifier x to x @ _

Expand variable identifier x to x @ _

def quotedPattern(tree: Tree, expectedTpt: Tree)(using Context): Tree

Add an explicit ascription to the expectedTpt to every tail splice.

Add an explicit ascription to the expectedTpt to every tail splice.

  • '{ x } -> '{ x }
  • '{ $x } -> '{ $x: T }
  • '{ if (...) $x else $y } -> '{ if (...) ($x: T) else ($y: T) }

Note that the splice $t: T will be typed as ${t: Expr[T]}

Transforms

Transforms

type t >: Low <: Hi to

def refinedTypeToClass(parent: Tree, refinements: List[Tree])(using Context): TypeDef

Create a class definition with the same info as the refined type given by parent and refinements.

Create a class definition with the same info as the refined type given by parent and refinements.

parent { refinements }

==> trait extends core { this: self => refinements }

Here, core is the (possibly parameterized) class part of parent. If parent is the same as core, self is empty. Otherwise self is parent.

Example: Given

class C
type T1 = C { type T <: A }

the refined type

T1 { type T <: B }

is expanded to

trait <refinement> extends C { this: T1 => type T <: A }

The result of this method is used for validity checking, is thrown away afterwards.

Value Params
parent

The type of parent

def smallTuple(tree: Tuple)(using Context): Tree

Translate tuple expressions of arity <= 22

Translate tuple expressions of arity <= 22

() ==> () (t) ==> t (t1, ..., tN) ==> TupleN(t1, ..., tN)

def valDef(vdef0: ValDef)(using Context): Tree

var x: Int = expr ==> def x: Int = expr def x_=($1: <TypeTree()>): Unit = ()

var x: Int = expr ==> def x: Int = expr def x_=($1: <TypeTree()>): Unit = ()

Generate setter where needed

Concrete fields

An attachment for match expressions generated from a PatDef or GenFrom. Value of key == one of IrrefutablePatDef, IrrefutableGenFrom

An attachment for match expressions generated from a PatDef or GenFrom. Value of key == one of IrrefutablePatDef, IrrefutableGenFrom

An attachment for companion modules of classes that have a derives clause. The position value indicates the start position of the template of the deriving class.

An attachment for companion modules of classes that have a derives clause. The position value indicates the start position of the template of the deriving class.

A multi-line infix operation with the infix operator starting a new line. Used for explaining potential errors.

A multi-line infix operation with the infix operator starting a new line. Used for explaining potential errors.