Merge pull request #44 from dwijnand/cleanups

Fix compilation warnings, migrate to blackbox.Context
This commit is contained in:
eugene yokota 2016-06-20 08:38:42 +02:00 committed by GitHub
commit 7b766e90a8
7 changed files with 47 additions and 67 deletions

View File

@ -3,7 +3,6 @@ package appmacro
import scala.reflect._ import scala.reflect._
import macros._ import macros._
import scala.tools.nsc.Global
import ContextUtil.{ DynamicDependencyError, DynamicReferenceError } import ContextUtil.{ DynamicDependencyError, DynamicReferenceError }
object ContextUtil { object ContextUtil {
@ -14,7 +13,7 @@ object ContextUtil {
* Constructs an object with utility methods for operating in the provided macro context `c`. * Constructs an object with utility methods for operating in the provided macro context `c`.
* Callers should explicitly specify the type parameter as `c.type` in order to preserve the path dependent types. * Callers should explicitly specify the type parameter as `c.type` in order to preserve the path dependent types.
*/ */
def apply[C <: Context with Singleton](c: C): ContextUtil[C] = new ContextUtil(c) def apply[C <: blackbox.Context with Singleton](c: C): ContextUtil[C] = new ContextUtil(c)
/** /**
* Helper for implementing a no-argument macro that is introduced via an implicit. * Helper for implementing a no-argument macro that is introduced via an implicit.
@ -23,7 +22,7 @@ object ContextUtil {
* Given `myImplicitConversion(someValue).extensionMethod`, where `extensionMethod` is a macro that uses this * Given `myImplicitConversion(someValue).extensionMethod`, where `extensionMethod` is a macro that uses this
* method, the result of this method is `f(<Tree of someValue>)`. * method, the result of this method is `f(<Tree of someValue>)`.
*/ */
def selectMacroImpl[T: c.WeakTypeTag](c: Context)(f: (c.Expr[Any], c.Position) => c.Expr[T]): c.Expr[T] = def selectMacroImpl[T: c.WeakTypeTag](c: blackbox.Context)(f: (c.Expr[Any], c.Position) => c.Expr[T]): c.Expr[T] =
{ {
import c.universe._ import c.universe._
c.macroApplication match { c.macroApplication match {
@ -32,20 +31,18 @@ object ContextUtil {
} }
} }
def unexpectedTree[C <: Context](tree: C#Tree): Nothing = sys.error("Unexpected macro application tree (" + tree.getClass + "): " + tree) def unexpectedTree[C <: blackbox.Context](tree: C#Tree): Nothing = sys.error("Unexpected macro application tree (" + tree.getClass + "): " + tree)
} }
// TODO 2.11 Remove this after dropping 2.10.x support.
private object HasCompat { val compat = this }; import HasCompat._
/** /**
* Utility methods for macros. Several methods assume that the context's universe is a full compiler (`scala.tools.nsc.Global`). * Utility methods for macros. Several methods assume that the context's universe is a full compiler
* (`scala.tools.nsc.Global`).
* This is not thread safe due to the underlying Context and related data structures not being thread safe. * This is not thread safe due to the underlying Context and related data structures not being thread safe.
* Use `ContextUtil[c.type](c)` to construct. * Use `ContextUtil[c.type](c)` to construct.
*/ */
final class ContextUtil[C <: Context](val ctx: C) { final class ContextUtil[C <: blackbox.Context](val ctx: C) {
import ctx.universe.{ Apply => ApplyTree, _ } import ctx.universe.{ Apply => ApplyTree, _ }
import compat._ import internal.decorators._
val powerContext = ctx.asInstanceOf[reflect.macros.runtime.Context] val powerContext = ctx.asInstanceOf[reflect.macros.runtime.Context]
val global: powerContext.universe.type = powerContext.universe val global: powerContext.universe.type = powerContext.universe
@ -53,7 +50,7 @@ final class ContextUtil[C <: Context](val ctx: C) {
val initialOwner: Symbol = callsiteTyper.context.owner.asInstanceOf[ctx.universe.Symbol] val initialOwner: Symbol = callsiteTyper.context.owner.asInstanceOf[ctx.universe.Symbol]
lazy val alistType = ctx.typeOf[AList[KList]] lazy val alistType = ctx.typeOf[AList[KList]]
lazy val alist: Symbol = alistType.typeSymbol.companionSymbol lazy val alist: Symbol = alistType.typeSymbol.companion
lazy val alistTC: Type = alistType.typeConstructor lazy val alistTC: Type = alistType.typeConstructor
/** Modifiers for a local val.*/ /** Modifiers for a local val.*/
@ -63,9 +60,9 @@ final class ContextUtil[C <: Context](val ctx: C) {
/** /**
* Constructs a unique term name with the given prefix within this Context. * Constructs a unique term name with the given prefix within this Context.
* (The current implementation uses Context.fresh, which increments * (The current implementation uses Context.freshName, which increments
*/ */
def freshTermName(prefix: String) = newTermName(ctx.fresh("$" + prefix)) def freshTermName(prefix: String) = TermName(ctx.freshName("$" + prefix))
/** /**
* Constructs a new, synthetic, local ValDef Type `tpe`, a unique name, * Constructs a new, synthetic, local ValDef Type `tpe`, a unique name,
@ -76,7 +73,7 @@ final class ContextUtil[C <: Context](val ctx: C) {
val SYNTHETIC = (1 << 21).toLong.asInstanceOf[FlagSet] val SYNTHETIC = (1 << 21).toLong.asInstanceOf[FlagSet]
val sym = owner.newTermSymbol(freshTermName("q"), pos, SYNTHETIC) val sym = owner.newTermSymbol(freshTermName("q"), pos, SYNTHETIC)
setInfo(sym, tpe) setInfo(sym, tpe)
val vd = ValDef(sym, EmptyTree) val vd = internal.valDef(sym, EmptyTree)
vd.setPos(pos) vd.setPos(pos)
vd vd
} }
@ -94,7 +91,7 @@ final class ContextUtil[C <: Context](val ctx: C) {
val process = new Traverser { val process = new Traverser {
override def traverse(t: Tree) = t match { override def traverse(t: Tree) = t match {
case _: Ident => () case _: Ident => ()
case ApplyTree(TypeApply(Select(_, nme), tpe :: Nil), qual :: Nil) if isWrapper(nme.decoded, tpe.tpe, qual) => () case ApplyTree(TypeApply(Select(_, nme), tpe :: Nil), qual :: Nil) if isWrapper(nme.decodedName.toString, tpe.tpe, qual) => ()
case tree => case tree =>
if (tree.symbol ne null) defs += tree.symbol; if (tree.symbol ne null) defs += tree.symbol;
super.traverse(tree) super.traverse(tree)
@ -117,7 +114,7 @@ final class ContextUtil[C <: Context](val ctx: C) {
*/ */
def checkReferences(defs: collection.Set[Symbol], isWrapper: (String, Type, Tree) => Boolean): Tree => Unit = { def checkReferences(defs: collection.Set[Symbol], isWrapper: (String, Type, Tree) => Boolean): Tree => Unit = {
case s @ ApplyTree(TypeApply(Select(_, nme), tpe :: Nil), qual :: Nil) => case s @ ApplyTree(TypeApply(Select(_, nme), tpe :: Nil), qual :: Nil) =>
if (isWrapper(nme.decoded, tpe.tpe, qual)) ctx.error(s.pos, DynamicDependencyError) if (isWrapper(nme.decodedName.toString, tpe.tpe, qual)) ctx.error(s.pos, DynamicDependencyError)
case id @ Ident(name) if illegalReference(defs, id.symbol) => ctx.error(id.pos, DynamicReferenceError + ": " + name) case id @ Ident(name) if illegalReference(defs, id.symbol) => ctx.error(id.pos, DynamicReferenceError + ": " + name)
case _ => () case _ => ()
} }
@ -134,11 +131,11 @@ final class ContextUtil[C <: Context](val ctx: C) {
def mkTuple(args: List[Tree]): Tree = def mkTuple(args: List[Tree]): Tree =
global.gen.mkTuple(args.asInstanceOf[List[global.Tree]]).asInstanceOf[ctx.universe.Tree] global.gen.mkTuple(args.asInstanceOf[List[global.Tree]]).asInstanceOf[ctx.universe.Tree]
def setSymbol[Tree](t: Tree, sym: Symbol): Unit = { def setSymbol[_Tree](t: _Tree, sym: Symbol): Unit = {
t.asInstanceOf[global.Tree].setSymbol(sym.asInstanceOf[global.Symbol]) t.asInstanceOf[global.Tree].setSymbol(sym.asInstanceOf[global.Symbol])
() ()
} }
def setInfo[Tree](sym: Symbol, tpe: Type): Unit = { def setInfo(sym: Symbol, tpe: Type): Unit = {
sym.asInstanceOf[global.Symbol].setInfo(tpe.asInstanceOf[global.Type]) sym.asInstanceOf[global.Symbol].setInfo(tpe.asInstanceOf[global.Type])
() ()
} }
@ -151,7 +148,7 @@ final class ContextUtil[C <: Context](val ctx: C) {
lazy val idTC: Type = lazy val idTC: Type =
{ {
val tvar = newTypeVariable(NoSymbol) val tvar = newTypeVariable(NoSymbol)
polyType(tvar :: Nil, refVar(tvar)) internal.polyType(tvar :: Nil, refVar(tvar))
} }
/** A Type that references the given type variable. */ /** A Type that references the given type variable. */
def refVar(variable: TypeSymbol): Type = variable.toTypeConstructor def refVar(variable: TypeSymbol): Type = variable.toTypeConstructor
@ -159,12 +156,12 @@ final class ContextUtil[C <: Context](val ctx: C) {
def newTCVariable(owner: Symbol): TypeSymbol = def newTCVariable(owner: Symbol): TypeSymbol =
{ {
val tc = newTypeVariable(owner) val tc = newTypeVariable(owner)
val arg = newTypeVariable(tc, "x") val arg = newTypeVariable(tc, "x");
tc.setTypeSignature(PolyType(arg :: Nil, emptyTypeBounds)) tc.setInfo(internal.polyType(arg :: Nil, emptyTypeBounds))
tc tc
} }
/** >: Nothing <: Any */ /** >: Nothing <: Any */
def emptyTypeBounds: TypeBounds = TypeBounds(definitions.NothingClass.toType, definitions.AnyClass.toType) def emptyTypeBounds: TypeBounds = internal.typeBounds(definitions.NothingClass.toType, definitions.AnyClass.toType)
/** Creates a new anonymous function symbol with Position `pos`. */ /** Creates a new anonymous function symbol with Position `pos`. */
def functionSymbol(pos: Position): Symbol = def functionSymbol(pos: Position): Symbol =
@ -210,7 +207,7 @@ final class ContextUtil[C <: Context](val ctx: C) {
case x => sys.error("Instance must be static (was " + x + ").") case x => sys.error("Instance must be static (was " + x + ").")
} }
def select(t: Tree, name: String): Tree = Select(t, newTermName(name)) def select(t: Tree, name: String): Tree = Select(t, TermName(name))
/** Returns the symbol for the non-private method named `name` for the class/module `obj`. */ /** Returns the symbol for the non-private method named `name` for the class/module `obj`. */
def method(obj: Symbol, name: String): Symbol = { def method(obj: Symbol, name: String): Symbol = {
@ -247,7 +244,7 @@ final class ContextUtil[C <: Context](val ctx: C) {
override def transform(tree: Tree): Tree = override def transform(tree: Tree): Tree =
tree match { tree match {
case ApplyTree(TypeApply(Select(_, nme), targ :: Nil), qual :: Nil) => case ApplyTree(TypeApply(Select(_, nme), targ :: Nil), qual :: Nil) =>
subWrapper(nme.decoded, targ.tpe, qual, tree) match { subWrapper(nme.decodedName.toString, targ.tpe, qual, tree) match {
case Converted.Success(t, finalTx) => case Converted.Success(t, finalTx) =>
changeOwner(qual, currentOwner, initialOwner) // Fixes https://github.com/sbt/sbt/issues/1150 changeOwner(qual, currentOwner, initialOwner) // Fixes https://github.com/sbt/sbt/issues/1150
finalTx(t) finalTx(t)

View File

@ -6,32 +6,32 @@ import macros._
import Types.idFun import Types.idFun
abstract class Convert { abstract class Convert {
def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type]
def asPredicate(c: Context): (String, c.Type, c.Tree) => Boolean = def asPredicate(c: blackbox.Context): (String, c.Type, c.Tree) => Boolean =
(n, tpe, tree) => { (n, tpe, tree) => {
val tag = c.WeakTypeTag(tpe) val tag = c.WeakTypeTag(tpe)
apply(c)(n, tree)(tag).isSuccess apply(c)(n, tree)(tag).isSuccess
} }
} }
sealed trait Converted[C <: Context with Singleton] { sealed trait Converted[C <: blackbox.Context with Singleton] {
def isSuccess: Boolean def isSuccess: Boolean
def transform(f: C#Tree => C#Tree): Converted[C] def transform(f: C#Tree => C#Tree): Converted[C]
} }
object Converted { object Converted {
def NotApplicable[C <: Context with Singleton] = new NotApplicable[C] def NotApplicable[C <: blackbox.Context with Singleton] = new NotApplicable[C]
final case class Failure[C <: Context with Singleton](position: C#Position, message: String) extends Converted[C] { final case class Failure[C <: blackbox.Context with Singleton](position: C#Position, message: String) extends Converted[C] {
def isSuccess = false def isSuccess = false
def transform(f: C#Tree => C#Tree): Converted[C] = new Failure(position, message) def transform(f: C#Tree => C#Tree): Converted[C] = new Failure(position, message)
} }
final class NotApplicable[C <: Context with Singleton] extends Converted[C] { final class NotApplicable[C <: blackbox.Context with Singleton] extends Converted[C] {
def isSuccess = false def isSuccess = false
def transform(f: C#Tree => C#Tree): Converted[C] = this def transform(f: C#Tree => C#Tree): Converted[C] = this
} }
final case class Success[C <: Context with Singleton](tree: C#Tree, finalTransform: C#Tree => C#Tree) extends Converted[C] { final case class Success[C <: blackbox.Context with Singleton](tree: C#Tree, finalTransform: C#Tree => C#Tree) extends Converted[C] {
def isSuccess = true def isSuccess = true
def transform(f: C#Tree => C#Tree): Converted[C] = Success(f(tree), finalTransform) def transform(f: C#Tree => C#Tree): Converted[C] = Success(f(tree), finalTransform)
} }
object Success { object Success {
def apply[C <: Context with Singleton](tree: C#Tree): Success[C] = Success(tree, idFun) def apply[C <: blackbox.Context with Singleton](tree: C#Tree): Success[C] = Success(tree, idFun)
} }
} }

View File

@ -23,7 +23,6 @@ trait MonadInstance extends Instance {
import scala.reflect._ import scala.reflect._
import macros._ import macros._
import reflect.internal.annotations.compileTimeOnly
object Instance { object Instance {
final val ApplyName = "app" final val ApplyName = "app"
@ -33,10 +32,10 @@ object Instance {
final val InstanceTCName = "M" final val InstanceTCName = "M"
final class Input[U <: Universe with Singleton](val tpe: U#Type, val expr: U#Tree, val local: U#ValDef) final class Input[U <: Universe with Singleton](val tpe: U#Type, val expr: U#Tree, val local: U#ValDef)
trait Transform[C <: Context with Singleton, N[_]] { trait Transform[C <: blackbox.Context with Singleton, N[_]] {
def apply(in: C#Tree): C#Tree def apply(in: C#Tree): C#Tree
} }
def idTransform[C <: Context with Singleton]: Transform[C, Id] = new Transform[C, Id] { def idTransform[C <: blackbox.Context with Singleton]: Transform[C, Id] = new Transform[C, Id] {
def apply(in: C#Tree): C#Tree = in def apply(in: C#Tree): C#Tree = in
} }
@ -76,7 +75,7 @@ object Instance {
* If this is for multi-input flatMap (app followed by flatMap), * If this is for multi-input flatMap (app followed by flatMap),
* this should be the argument wrapped in Right. * this should be the argument wrapped in Right.
*/ */
def contImpl[T, N[_]](c: Context, i: Instance with Singleton, convert: Convert, builder: TupleBuilder)(t: Either[c.Expr[T], c.Expr[i.M[T]]], inner: Transform[c.type, N])( def contImpl[T, N[_]](c: blackbox.Context, i: Instance with Singleton, convert: Convert, builder: TupleBuilder)(t: Either[c.Expr[T], c.Expr[i.M[T]]], inner: Transform[c.type, N])(
implicit implicit
tt: c.WeakTypeTag[T], nt: c.WeakTypeTag[N[T]], it: c.TypeTag[i.type] tt: c.WeakTypeTag[T], nt: c.WeakTypeTag[N[T]], it: c.TypeTag[i.type]
): c.Expr[i.M[N[T]]] = ): c.Expr[i.M[N[T]]] =
@ -85,11 +84,11 @@ object Instance {
val util = ContextUtil[c.type](c) val util = ContextUtil[c.type](c)
val mTC: Type = util.extractTC(i, InstanceTCName) val mTC: Type = util.extractTC(i, InstanceTCName)
val mttpe: Type = appliedType(mTC, nt.tpe :: Nil).normalize val mttpe: Type = appliedType(mTC, nt.tpe :: Nil).dealias
// the tree for the macro argument // the tree for the macro argument
val (tree, treeType) = t match { val (tree, treeType) = t match {
case Left(l) => (l.tree, nt.tpe.normalize) case Left(l) => (l.tree, nt.tpe.dealias)
case Right(r) => (r.tree, mttpe) case Right(r) => (r.tree, mttpe)
} }
// the Symbol for the anonymous function passed to the appropriate Instance.map/flatMap/pure method // the Symbol for the anonymous function passed to the appropriate Instance.map/flatMap/pure method

View File

@ -1,27 +1,21 @@
package sbt.internal.util package sbt.internal.util
package appmacro package appmacro
import Types.Id
import scala.tools.nsc.Global
import scala.reflect._ import scala.reflect._
import macros._ import macros._
/** A `TupleBuilder` that uses a KList as the tuple representation.*/ /** A `TupleBuilder` that uses a KList as the tuple representation.*/
object KListBuilder extends TupleBuilder { object KListBuilder extends TupleBuilder {
// TODO 2.11 Remove this after dropping 2.10.x support. def make(c: blackbox.Context)(mt: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type] = new BuilderResult[c.type] {
private object HasCompat { val compat = this }; import HasCompat._
def make(c: Context)(mt: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type] = new BuilderResult[c.type] {
val ctx: c.type = c val ctx: c.type = c
val util = ContextUtil[c.type](c) val util = ContextUtil[c.type](c)
import c.universe.{ Apply => ApplyTree, _ } import c.universe.{ Apply => ApplyTree, _ }
import compat._
import util._ import util._
val knilType = c.typeOf[KNil] val knilType = c.typeOf[KNil]
val knil = Ident(knilType.typeSymbol.companionSymbol) val knil = Ident(knilType.typeSymbol.companion)
val kconsTpe = c.typeOf[KCons[Int, KNil, List]] val kconsTpe = c.typeOf[KCons[Int, KNil, List]]
val kcons = kconsTpe.typeSymbol.companionSymbol val kcons = kconsTpe.typeSymbol.companion
val mTC: Type = mt.asInstanceOf[c.universe.Type] val mTC: Type = mt.asInstanceOf[c.universe.Type]
val kconsTC: Type = kconsTpe.typeConstructor val kconsTC: Type = kconsTpe.typeConstructor
@ -62,8 +56,7 @@ object KListBuilder extends TupleBuilder {
*/ */
val klistType: Type = (inputs :\ knilType)((in, klist) => kconsType(in.tpe, klist)) val klistType: Type = (inputs :\ knilType)((in, klist) => kconsType(in.tpe, klist))
val representationC = PolyType(tcVariable :: Nil, klistType) val representationC = internal.polyType(tcVariable :: Nil, klistType)
val resultType = appliedType(representationC, idTC :: Nil)
val input = klist val input = klist
val alistInstance: ctx.universe.Tree = TypeApply(select(Ident(alist), "klist"), TypeTree(representationC) :: Nil) val alistInstance: ctx.universe.Tree = TypeApply(select(Ident(alist), "klist"), TypeTree(representationC) :: Nil)
def extract(param: ValDef) = bindKList(param, Nil, inputs.map(_.local)) def extract(param: ValDef) = bindKList(param, Nil, inputs.map(_.local))

View File

@ -9,7 +9,7 @@ import macros._
* and `KList` for larger numbers of inputs. This builder cannot handle fewer than 2 inputs. * and `KList` for larger numbers of inputs. This builder cannot handle fewer than 2 inputs.
*/ */
object MixedBuilder extends TupleBuilder { object MixedBuilder extends TupleBuilder {
def make(c: Context)(mt: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type] = def make(c: blackbox.Context)(mt: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type] =
{ {
val delegate = if (inputs.size > TupleNBuilder.MaxInputs) KListBuilder else TupleNBuilder val delegate = if (inputs.size > TupleNBuilder.MaxInputs) KListBuilder else TupleNBuilder
delegate.make(c)(mt, inputs) delegate.make(c)(mt, inputs)

View File

@ -1,8 +1,6 @@
package sbt.internal.util package sbt.internal.util
package appmacro package appmacro
import Types.Id
import scala.tools.nsc.Global
import scala.reflect._ import scala.reflect._
import macros._ import macros._
@ -29,10 +27,10 @@ trait TupleBuilder {
type Inputs[U <: Universe with Singleton] = List[Instance.Input[U]] type Inputs[U <: Universe with Singleton] = List[Instance.Input[U]]
/** Constructs a one-time use Builder for Context `c` and type constructor `tcType`. */ /** Constructs a one-time use Builder for Context `c` and type constructor `tcType`. */
def make(c: Context)(tcType: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type] def make(c: blackbox.Context)(tcType: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type]
} }
trait BuilderResult[C <: Context with Singleton] { trait BuilderResult[C <: blackbox.Context with Singleton] {
val ctx: C val ctx: C
import ctx.universe._ import ctx.universe._

View File

@ -1,7 +1,6 @@
package sbt.internal.util package sbt.internal.util
package appmacro package appmacro
import Types.Id
import scala.tools.nsc.Global import scala.tools.nsc.Global
import scala.reflect._ import scala.reflect._
import macros._ import macros._
@ -15,26 +14,20 @@ object TupleNBuilder extends TupleBuilder {
final val MaxInputs = 11 final val MaxInputs = 11
final val TupleMethodName = "tuple" final val TupleMethodName = "tuple"
// TODO 2.11 Remove this after dropping 2.10.x support. def make(c: blackbox.Context)(mt: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type] = new BuilderResult[c.type] {
private object HasCompat { val compat = this }; import HasCompat._
def make(c: Context)(mt: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type] = new BuilderResult[c.type] {
val util = ContextUtil[c.type](c) val util = ContextUtil[c.type](c)
import c.universe.{ Apply => ApplyTree, _ } import c.universe._
import compat._
import util._ import util._
val global: Global = c.universe.asInstanceOf[Global] val global: Global = c.universe.asInstanceOf[Global]
val mTC: Type = mt.asInstanceOf[c.universe.Type]
val ctx: c.type = c val ctx: c.type = c
val representationC: PolyType = { val representationC: PolyType = {
val tcVariable: Symbol = newTCVariable(util.initialOwner) val tcVariable: Symbol = newTCVariable(util.initialOwner)
val tupleTypeArgs = inputs.map(in => typeRef(NoPrefix, tcVariable, in.tpe :: Nil).asInstanceOf[global.Type]) val tupleTypeArgs = inputs.map(in => internal.typeRef(NoPrefix, tcVariable, in.tpe :: Nil).asInstanceOf[global.Type])
val tuple = global.definitions.tupleType(tupleTypeArgs) val tuple = global.definitions.tupleType(tupleTypeArgs)
PolyType(tcVariable :: Nil, tuple.asInstanceOf[Type]) internal.polyType(tcVariable :: Nil, tuple.asInstanceOf[Type])
} }
val resultType = appliedType(representationC, idTC :: Nil)
val input: Tree = mkTuple(inputs.map(_.expr)) val input: Tree = mkTuple(inputs.map(_.expr))
val alistInstance: Tree = { val alistInstance: Tree = {