trait Macros extends MacroRuntimes with Traces with Helpers
Code to deal with macros, namely with: * Compilation of macro definitions * Expansion of macro applications
Say we have in a class C:
def foo[T](xs: List[T]): T = macro fooBar
Then fooBar needs to point to a static method of the following form:
def fooBar[T: c.WeakTypeTag] // type tag annotation is optional (c: scala.reflect.macros.blackbox.Context) (xs: c.Expr[List[T]]) : c.Expr[T] = { ... }
Then, if foo is called in qual.foo[Int](elems), where qual: D, the macro application is expanded to a reflective invocation of fooBar with parameters:
(simpleMacroContext{ type PrefixType = D; val prefix = qual }) (Expr(elems)) (TypeTag(Int))
- Self Type
- Analyzer
- Source
- Macros.scala
- Alphabetic
- By Inheritance
- Macros
- Helpers
- Traces
- MacroRuntimes
- JavaReflectionRuntimes
- AnyRef
- Any
- by any2stringadd
- by StringFormat
- by Ensuring
- by ArrowAssoc
- Hide All
- Show All
- Public
- All
Type Members
-
trait
JavaReflectionResolvers
extends AnyRef
- Definition Classes
- JavaReflectionRuntimes
-
class
MacroRuntimeResolver
extends tools.nsc.typechecker.Analyzer.JavaReflectionResolvers
- Definition Classes
- MacroRuntimes
-
class
DefMacroExpander
extends Analyzer.MacroExpander
Expands a term macro used in apply role as
M(2)(3)
inval x = M(2)(3)
. - case class Delayed (delayed: Global.Tree) extends Analyzer.MacroStatus with Product with Serializable
- case class Failure (failure: Global.Tree) extends Analyzer.MacroStatus with Product with Serializable
- case class Fallback (fallback: Global.Tree) extends Analyzer.MacroStatus with Product with Serializable
-
case class
MacroArgs
(c: Analyzer.MacroContext, others: List[Any]) extends Product with Serializable
Calculate the arguments to pass to a macro implementation when expanding the provided tree.
-
abstract
class
MacroExpander
extends AnyRef
Performs macro expansion:
Performs macro expansion:
Expandable trees
A term of one of the following shapes:
Ident(<term macro>) Select(<any qualifier>, <term macro>) TypeApply(<any of the above>, <targs>) Apply(...Apply(<any of the above>, <args1>)...<argsN>)
Macro expansion
First of all
macroExpandXXX
: 1) If necessary desugars theexpandee
to fit into the default expansion scheme that is understood bymacroExpandWithRuntime
/macroExpandWithoutRuntime
Then
macroExpandWithRuntime
: 2) Checks whether the expansion needs to be delayed 3) Loads macro implementation usingmacroMirror
4) Synthesizes invocation arguments for the macro implementation 5) Checks that the result is a tree or an expr bound to this universeFinally
macroExpandXXX
: 6) Validates the expansion against the white list of supported tree shapes 7) Typechecks the result as required by the circumstances of the macro applicationIf -Ymacro-debug-lite is enabled, you will get basic notifications about macro expansion along with macro expansions logged in the form that can be copy/pasted verbatim into REPL.
If -Ymacro-debug-verbose is enabled, you will get detailed log of how exactly this function performs class loading and method resolution in order to load the macro implementation. The log will also include other non-trivial steps of macro expansion.
- returns
the expansion result if the expansion has been successful, the fallback tree if the expansion has been unsuccessful, but there is a fallback, the expandee unchanged if the expansion has been delayed, the expandee fully expanded if the expansion has been delayed before and has been expanded now, the expandee with an error marker set if the expansion has been cancelled due malformed arguments or implementation the expandee with an error marker set if there has been an error
-
case class
MacroImplBinding
(isBundle: Boolean, isBlackbox: Boolean, className: String, methName: String, signature: List[List[Fingerprint]], targs: List[Global.Tree]) extends Product with Serializable
Represents all the information that a macro definition needs to know about its implementation.
Represents all the information that a macro definition needs to know about its implementation. Includes a path to load the implementation via Java reflection, and various accounting information necessary when composing an argument list for the reflective invocation.
-
type
MacroRuntime = (Analyzer.MacroArgs) ⇒ Any
Abstracts away resolution of macro runtimes.
Abstracts away resolution of macro runtimes.
- Definition Classes
- MacroRuntimes
- sealed abstract class MacroStatus extends AnyRef
- case class Skipped (skipped: Global.Tree) extends Analyzer.MacroStatus with Product with Serializable
- case class Success (expanded: Global.Tree) extends Analyzer.MacroStatus with Product with Serializable
Value Members
-
final
def
!=(arg0: Any): Boolean
Test two objects for inequality.
Test two objects for inequality.
- returns
true
if !(this == that), false otherwise.
- Definition Classes
- AnyRef → Any
-
final
def
##(): Int
Equivalent to
x.hashCode
except for boxed numeric types andnull
.Equivalent to
x.hashCode
except for boxed numeric types andnull
. For numerics, it returns a hash value which is consistent with value equality: if two value type instances compare as true, then ## will produce the same hash value for each of them. Fornull
returns a hashcode wherenull.hashCode
throws aNullPointerException
.- returns
a hash value consistent with ==
- Definition Classes
- AnyRef → Any
- def +(other: String): String
- def ->[B](y: B): (Macros, B)
-
final
def
==(arg0: Any): Boolean
The expression
x == that
is equivalent toif (x eq null) that eq null else x.equals(that)
.The expression
x == that
is equivalent toif (x eq null) that eq null else x.equals(that)
.- returns
true
if the receiver object is equivalent to the argument;false
otherwise.
- Definition Classes
- AnyRef → Any
- def Delay(expanded: Global.Tree): Analyzer.Delayed
- def Skip(expanded: Global.Tree): Analyzer.Skipped
-
var
_openMacros: collection.immutable.List[Context { val universe: Macros.this.global.type }]
Keeps track of macros in-flight.
Keeps track of macros in-flight. See more informations in comments to
openMacros
inscala.reflect.macros.whitebox.Context
. -
final
def
asInstanceOf[T0]: T0
Cast the receiver object to be of type
T0
.Cast the receiver object to be of type
T0
.Note that the success of a cast at runtime is modulo Scala's erasure semantics. Therefore the expression
1.asInstanceOf[String]
will throw aClassCastException
at runtime, while the expressionList(1).asInstanceOf[List[String]]
will not. In the latter example, because the type argument is erased as part of compilation it is not possible to check whether the contents of the list are of the requested type.- returns
the receiver object.
- Definition Classes
- Any
- Exceptions thrown
ClassCastException
if the receiver object is not an instance of the erasure of typeT0
.
- def bindMacroImpl(macroDef: Global.Symbol, macroImplRef: Global.Tree): Unit
-
def
clone(): AnyRef
Create a copy of the receiver object.
Create a copy of the receiver object.
The default implementation of the
clone
method is platform dependent.- returns
a copy of the receiver object.
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
- Note
not specified by SLS as a member of AnyRef
- def computeMacroDefTypeFromMacroImplRef(macroDdef: Global.DefDef, macroImplRef: Global.Tree): Global.Type
-
def
decreaseMetalevel(tp: Global.Type): Global.Type
Decreases metalevel of the type, i.e.
Decreases metalevel of the type, i.e. transforms: * c.Expr[T] to T * Nothing to Nothing * Anything else to NoType
- Definition Classes
- Helpers
- See also
Metalevels.scala for more information and examples about metalevels
-
def
defaultMacroClassloader: ClassLoader
- Definition Classes
- MacroRuntimes
- def enclosingMacroPosition: Position
- def ensuring(cond: (Macros) ⇒ Boolean, msg: ⇒ Any): Macros
- def ensuring(cond: (Macros) ⇒ Boolean): Macros
- def ensuring(cond: Boolean, msg: ⇒ Any): Macros
- def ensuring(cond: Boolean): Macros
-
final
def
eq(arg0: AnyRef): Boolean
Tests whether the argument (
that
) is a reference to the receiver object (this
).Tests whether the argument (
that
) is a reference to the receiver object (this
).The
eq
method implements an equivalence relation on non-null instances ofAnyRef
, and has three additional properties:- It is consistent: for any non-null instances
x
andy
of typeAnyRef
, multiple invocations ofx.eq(y)
consistently returnstrue
or consistently returnsfalse
. - For any non-null instance
x
of typeAnyRef
,x.eq(null)
andnull.eq(x)
returnsfalse
. null.eq(null)
returnstrue
.
When overriding the
equals
orhashCode
methods, it is important to ensure that their behavior is consistent with reference equality. Therefore, if two objects are references to each other (o1 eq o2
), they should be equal to each other (o1 == o2
) and they should hash to the same value (o1.hashCode == o2.hashCode
).- returns
true
if the argument is a reference to the receiver object;false
otherwise.
- Definition Classes
- AnyRef
- It is consistent: for any non-null instances
-
def
equals(arg0: Any): Boolean
The equality method for reference types.
- lazy val fastTrack: FastTrack[Macros.this.type]
-
def
finalize(): Unit
Called by the garbage collector on the receiver object when there are no more references to the object.
Called by the garbage collector on the receiver object when there are no more references to the object.
The details of when and if the
finalize
method is invoked, as well as the interaction betweenfinalize
and non-local returns and exceptions, are all platform dependent.- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( classOf[java.lang.Throwable] )
- Note
not specified by SLS as a member of AnyRef
-
def
findMacroClassLoader(): ClassLoader
Obtains a
ClassLoader
instance used for macro expansion.Obtains a
ClassLoader
instance used for macro expansion.By default a new
ScalaClassLoader
is created using the classpath from global and the classloader of self as parent.Mirrors with runtime definitions (e.g. Repl) need to adjust this method.
- Attributes
- protected
- def formatted(fmtstr: String): String
-
final
def
getClass(): Class[_]
Returns the runtime class representation of the object.
Returns the runtime class representation of the object.
- returns
a class object corresponding to the runtime type of the receiver.
- Definition Classes
- AnyRef → Any
- def globalSettings: Settings
-
var
hasPendingMacroExpansions: Boolean
Without any restrictions on macro expansion, macro applications will expand at will, and when type inference is involved, expansions will end up using yet uninferred type params.
Without any restrictions on macro expansion, macro applications will expand at will, and when type inference is involved, expansions will end up using yet uninferred type params.
For some macros this might be ok (thanks to TreeTypeSubstituter that replaces the occurrences of undetparams with their inferred values), but in general case this won't work. E.g. for reification simple substitution is not enough - we actually need to re-reify inferred types.
Luckily, there exists a very simple way to fix the problem: delay macro expansion until everything is inferred. Here are the exact rules. Macro application gets delayed if any of its subtrees contain: 1) type vars (tpe.isInstanceOf[TypeVar]) // [Eugene] this check is disabled right now, because TypeVars seem to be created from undetparams anyways 2) undetparams (sym.isTypeParameter && !sym.isSkolem)
-
def
hashCode(): Int
The hashCode method for reference types.
-
def
increaseMetalevel(pre: Global.Type, tp: Global.Type): Global.Type
Increases metalevel of the type, i.e.
Increases metalevel of the type, i.e. transforms: * T to c.Expr[T]
- Definition Classes
- Helpers
- See also
Metalevels.scala for more information and examples about metalevels
- def isBlackbox(macroDef: Global.Symbol): Boolean
- def isBlackbox(expandee: Global.Tree): Boolean
-
final
def
isInstanceOf[T0]: Boolean
Test whether the dynamic type of the receiver object is
T0
.Test whether the dynamic type of the receiver object is
T0
.Note that the result of the test is modulo Scala's erasure semantics. Therefore the expression
1.isInstanceOf[String]
will returnfalse
, while the expressionList(1).isInstanceOf[List[String]]
will returntrue
. In the latter example, because the type argument is erased as part of compilation it is not possible to check whether the contents of the list are of the specified type.- returns
true
if the receiver object is an instance of erasure of typeT0
;false
otherwise.
- Definition Classes
- Any
- def loadMacroImplBinding(macroDef: Global.Symbol): Option[Analyzer.MacroImplBinding]
- def macroArgs(typer: Analyzer.Typer, expandee: Global.Tree): Analyzer.MacroArgs
- def macroContext(typer: Analyzer.Typer, prefixTree: Global.Tree, expandeeTree: Global.Tree): Analyzer.MacroContext
-
val
macroDebugLite: Boolean
- Definition Classes
- Traces
-
val
macroDebugVerbose: Boolean
- Definition Classes
- Traces
-
def
macroEngine: String
Macro def -> macro impl bindings are serialized into a
macroImpl
annotation with synthetic content that carries the payload described inMacroImplBinding
.Macro def -> macro impl bindings are serialized into a
macroImpl
annotation with synthetic content that carries the payload described inMacroImplBinding
.For example, for a pair of macro definition and macro implementation: def impl(c: scala.reflect.macros.blackbox.Context): c.Expr[Unit] = ??? def foo: Unit = macro impl
We will have the following annotation added on the macro definition
foo
: -
def
macroExpand(typer: Analyzer.Typer, expandee: Global.Tree, mode: Mode, pt: Global.Type): Global.Tree
Expands a term macro used in apply role as
M(2)(3)
inval x = M(2)(3)
.Expands a term macro used in apply role as
M(2)(3)
inval x = M(2)(3)
.- See also
DefMacroExpander
-
def
macroExpandAll(typer: Analyzer.Typer, expandee: Global.Tree): Global.Tree
Performs macro expansion on all subtrees of a given tree.
Performs macro expansion on all subtrees of a given tree. Innermost macros are expanded first, outermost macros are expanded last. See the documentation for
macroExpand
for more information. -
def
macroExpandWithRuntime(typer: Analyzer.Typer, expandee: Global.Tree, runtime: Analyzer.MacroRuntime): Analyzer.MacroStatus
Expands a macro when a runtime (i.e.
Expands a macro when a runtime (i.e. the macro implementation) can be successfully loaded Meant for internal use within the macro infrastructure, don't use it elsewhere.
-
def
macroExpandWithoutRuntime(typer: Analyzer.Typer, expandee: Global.Tree): Analyzer.MacroStatus
Expands a macro when a runtime (i.e.
Expands a macro when a runtime (i.e. the macro implementation) cannot be loaded Meant for internal use within the macro infrastructure, don't use it elsewhere.
-
final
def
macroLogLite(msg: ⇒ Any): Unit
- Definition Classes
- Traces
- Annotations
- @inline()
-
final
def
macroLogVerbose(msg: ⇒ Any): Unit
- Definition Classes
- Traces
- Annotations
- @inline()
-
def
macroRuntime(expandee: Global.Tree): Analyzer.MacroRuntime
Produces a function that can be used to invoke macro implementation for a given macro definition: 1) Looks up macro implementation symbol in this universe.
Produces a function that can be used to invoke macro implementation for a given macro definition: 1) Looks up macro implementation symbol in this universe. 2) Loads its enclosing class from the macro classloader. 3) Loads the companion of that enclosing class from the macro classloader. 4) Resolves macro implementation within the loaded companion.
- returns
Requested runtime if macro implementation can be loaded successfully from either of the mirrors,
null
otherwise.
- Definition Classes
- MacroRuntimes
-
final
def
ne(arg0: AnyRef): Boolean
Equivalent to
!(this eq that)
.Equivalent to
!(this eq that)
.- returns
true
if the argument is not a reference to the receiver object;false
otherwise.
- Definition Classes
- AnyRef
-
final
def
notify(): Unit
Wakes up a single thread that is waiting on the receiver object's monitor.
Wakes up a single thread that is waiting on the receiver object's monitor.
- Definition Classes
- AnyRef
- Note
not specified by SLS as a member of AnyRef
-
final
def
notifyAll(): Unit
Wakes up all threads that are waiting on the receiver object's monitor.
Wakes up all threads that are waiting on the receiver object's monitor.
- Definition Classes
- AnyRef
- Note
not specified by SLS as a member of AnyRef
- def notifyUndetparamsAdded(newUndets: List[Global.Symbol]): Unit
- def notifyUndetparamsInferred(undetNoMore: List[Global.Symbol], inferreds: List[Global.Type]): Unit
- def openMacros: collection.immutable.List[Context { val universe: Macros.this.global.type }]
- def popMacroContext(): Unit
- def pushMacroContext(c: Analyzer.MacroContext): Unit
-
def
standardIsBlackbox(macroDef: Global.Symbol): Boolean
Default implementation of
isBlackbox
.Default implementation of
isBlackbox
. Can be overridden by analyzer plugins (see AnalyzerPlugins.pluginsIsBlackbox for more details) -
def
standardMacroArgs(typer: Analyzer.Typer, expandee: Global.Tree): Analyzer.MacroArgs
Default implementation of
macroArgs
.Default implementation of
macroArgs
. Can be overridden by analyzer plugins (see AnalyzerPlugins.pluginsMacroArgs for more details) -
def
standardMacroExpand(typer: Analyzer.Typer, expandee: Global.Tree, mode: Mode, pt: Global.Type): Global.Tree
Default implementation of
macroExpand
.Default implementation of
macroExpand
. Can be overridden by analyzer plugins (see AnalyzerPlugins.pluginsMacroExpand for more details) -
def
standardMacroRuntime(expandee: Global.Tree): Analyzer.MacroRuntime
- Definition Classes
- MacroRuntimes
-
def
standardTypedMacroBody(typer: Analyzer.Typer, macroDdef: Global.DefDef): Global.Tree
Default implementation of
typedMacroBody
.Default implementation of
typedMacroBody
. Can be overridden by analyzer plugins (see AnalyzerPlugins.pluginsTypedMacroBody for more details) -
final
def
synchronized[T0](arg0: ⇒ T0): T0
- Definition Classes
- AnyRef
-
def
toString(): String
Creates a String representation of this object.
Creates a String representation of this object. The default representation is platform dependent. On the java platform it is the concatenation of the class name, "@", and the object's hashcode in hexadecimal.
- returns
a String representation of the object.
- Definition Classes
- AnyRef → Any
-
def
transformTypeTagEvidenceParams(macroImplRef: Global.Tree, transform: (Global.Symbol, Global.Symbol) ⇒ Global.Symbol): List[List[Global.Symbol]]
Transforms parameters lists of a macro impl.
Transforms parameters lists of a macro impl. The
transform
function is invoked only for WeakTypeTag evidence parameters.The transformer takes two arguments: a value parameter from the parameter list and a type parameter that is witnesses by the value parameter.
If the transformer returns a NoSymbol, the value parameter is not included from the result. If the transformer returns something else, this something else is included in the result instead of the value parameter.
Despite of being highly esoteric, this function significantly simplifies signature analysis. For example, it can be used to strip macroImpl.paramss from the evidences (necessary when checking def <-> impl correspondence) or to streamline creation of the list of macro arguments.
- Definition Classes
- Helpers
-
def
typedMacroBody(typer: Analyzer.Typer, macroDdef: Global.DefDef): Global.Tree
Verifies that the body of a macro def typechecks to a reference to a static public non-overloaded method or a top-level macro bundle, and that that method is signature-wise compatible with the given macro definition.
Verifies that the body of a macro def typechecks to a reference to a static public non-overloaded method or a top-level macro bundle, and that that method is signature-wise compatible with the given macro definition.
- returns
Macro impl reference for the given macro definition if everything is okay. EmptyTree if an error occurs.
-
def
untypeMetalevel(tp: Global.Type): Global.Type
Transforms c.Expr[T] types into c.Tree and leaves the rest unchanged.
Transforms c.Expr[T] types into c.Tree and leaves the rest unchanged.
- Definition Classes
- Helpers
-
final
def
wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
- def →[B](y: B): (Macros, B)
- object MacroImplBinding extends Serializable
The Scala compiler API.
The following resources are useful for Scala plugin/compiler development: