Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Wildcard in reflection #13363

Merged
merged 3 commits into from
Aug 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,20 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
end extension
end IdentMethods

type Wildcard = tpd.Ident

object WildcardTypeTest extends TypeTest[Tree, Wildcard]:
def unapply(x: Tree): Option[Wildcard & x.type] = x match
case x: (tpd.Ident & x.type) if x.name == nme.WILDCARD => Some(x)
case _ => None
end WildcardTypeTest

object Wildcard extends WildcardModule:
def apply(): Wildcard =
withDefaultPos(untpd.Ident(nme.WILDCARD).withType(dotc.core.Symbols.defn.AnyType))
def unapply(pattern: Wildcard): true = true
end Wildcard

type Select = tpd.Select

object SelectTypeTest extends TypeTest[Tree, Select]:
Expand Down
12 changes: 8 additions & 4 deletions compiler/src/scala/quoted/runtime/impl/printers/Extractors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,14 @@ object Extractors {
def result(): String = sb.result()

def visitTree(x: Tree): this.type = x match {
case Ident(name) =>
this += "Ident(\"" += name += "\")"
case Select(qualifier, name) =>
this += "Select(" += qualifier += ", \"" += name += "\")"
case tree: Ref =>
tree match
case Wildcard() =>
this += "Wildcard()"
case Ident(name) =>
this += "Ident(\"" += name += "\")"
case Select(qualifier, name) =>
this += "Select(" += qualifier += ", \"" += name += "\")"
case This(qual) =>
this += "This(" += qual += ")"
case Super(qual, mix) =>
Expand Down
10 changes: 5 additions & 5 deletions compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ object SourceCode {
}
this

case Ident("_") =>
case Wildcard() =>
this += "_"

case tree: Ident =>
Expand Down Expand Up @@ -896,13 +896,13 @@ object SourceCode {
}

private def printPattern(pattern: Tree): this.type = pattern match {
case Ident("_") =>
case Wildcard() =>
this += "_"

case Bind(name, Ident("_")) =>
case Bind(name, Wildcard()) =>
this += name

case Bind(name, Typed(Ident("_"), tpt)) =>
case Bind(name, Typed(Wildcard(), tpt)) =>
this += highlightValDef(name) += ": "
printTypeTree(tpt)

Expand All @@ -928,7 +928,7 @@ object SourceCode {
case Alternatives(trees) =>
inParens(printPatterns(trees, " | "))

case Typed(Ident("_"), tpt) =>
case Typed(Wildcard(), tpt) =>
this += "_: "
printTypeTree(tpt)

Expand Down
19 changes: 18 additions & 1 deletion library/src/scala/quoted/Quotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
* | | +- DefDef
* | | +- ValDef
* | |
* | +- Term --------+- Ref -+- Ident
* | +- Term --------+- Ref -+- Ident -+- Wildcard
* | | +- Select
* | |
* | +- Literal
Expand Down Expand Up @@ -784,6 +784,23 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
end extension
end IdentMethods

/** Pattern representing a `_` wildcard. */
type Wildcard <: Ident

/** `TypeTest` that allows testing at runtime in a pattern match if a `Tree` is a `Wildcard` */
given WildcardTypeTest: TypeTest[Tree, Wildcard]

/** Module object of `type Wildcard` */
val Wildcard: WildcardModule

/** Methods of the module object `val Wildcard` */
trait WildcardModule { this: Wildcard.type =>
/** Create a tree representing a `_` wildcard. */
def apply(): Wildcard
/** Match a tree representing a `_` wildcard. */
def unapply(wildcard: Wildcard): true
}

/** Tree representing a selection of definition with a given name on a given prefix */
type Select <: Ref

Expand Down
2 changes: 2 additions & 0 deletions project/MiMaFilters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import com.typesafe.tools.mima.core.ProblemFilters._
object MiMaFilters {
val Library: Seq[ProblemFilter] = Seq(
// New APIs that will be introduced in 3.1.0
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.Wildcard"),
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.WildcardTypeTest"),
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.getJPath"),
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.name"),
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.path"),
Expand Down
13 changes: 13 additions & 0 deletions tests/pos-macros/i12188b/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import scala.quoted.*

object MatchTest {
inline def test[T](inline obj: Any): Unit = ${testImpl('obj)}

def testImpl[T](objExpr: Expr[T])(using Quotes): Expr[Unit] = {
import quotes.reflect.*
// test that the extractors work
val Inlined(None, Nil, Block(Nil, Match(param @ Ident("a"), List(CaseDef(Literal(IntConstant(1)), None, Block(Nil, Literal(UnitConstant()))), CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant()))))))) = objExpr.asTerm
// test that the constructors work
Block(Nil, Match(param, List(CaseDef(Literal(IntConstant(1)), None, Block(Nil, Literal(UnitConstant()))), CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant())))))).asExprOf[Unit]
}
}
5 changes: 5 additions & 0 deletions tests/pos-macros/i12188b/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def test(a: Int) = MatchTest.test {
a match
case 1 =>
case _ =>
}
14 changes: 14 additions & 0 deletions tests/pos-macros/i12188c/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import scala.quoted.*

object MatchTest {
inline def test(a: Int): Unit = ${testImpl('a)}

def testImpl(a: Expr[Any])(using Quotes): Expr[Unit] = {
import quotes.reflect.*
val matchTree = Match(a.asTerm, List(
CaseDef(Literal(IntConstant(1)), None, Block(Nil, Literal(UnitConstant()))),
CaseDef(Alternatives(List(Literal(IntConstant(2)), Literal(IntConstant(3)), Literal(IntConstant(4)))), None, Block(Nil, Literal(UnitConstant()))),
CaseDef(Typed(Wildcard(), TypeIdent(defn.IntClass)), None, Block(Nil, Literal(UnitConstant())))))
matchTree.asExprOf[Unit]
}
}
1 change: 1 addition & 0 deletions tests/pos-macros/i12188c/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
def test(a: Int) = MatchTest.test(a)
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
DefDef("foo", Nil, TypeIdent("Int"), Some(Apply(Select(Literal(IntConstant(1)), "+"), List(Literal(IntConstant(2))))))
ValDef("bar", TypeIdent("Int"), Some(Apply(Select(Literal(IntConstant(2)), "+"), List(Literal(IntConstant(3))))))
Bind("x", Ident("_"))
Bind("x", Wildcard())
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
DefDef("foo", Nil, TypeIdent("Int"), Some(Apply(Select(Literal(IntConstant(1)), "+"), List(Literal(IntConstant(2))))))
ValDef("bar", TypeIdent("Int"), Some(Apply(Select(Literal(IntConstant(2)), "+"), List(Literal(IntConstant(3))))))
Bind("x", Ident("_"))
Bind("x", Wildcard())
23 changes: 23 additions & 0 deletions tests/run-macros/i12188/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import scala.quoted.*

object MatchTest {
inline def test[T](inline obj: T): String = ${testImpl('obj)}

def testImpl[T](objExpr: Expr[T])(using qctx: Quotes, t: Type[T]): Expr[String] = {
import qctx.reflect.*

val obj = objExpr.asTerm
val cases = obj.tpe.typeSymbol.children.map { child =>
val subtype = TypeIdent(child)
val bind = Symbol.newBind(Symbol.spliceOwner, "c", Flags.EmptyFlags, subtype.tpe)
CaseDef(Bind(bind, Typed(Ref(bind), subtype)), None, Literal(StringConstant(subtype.show)))
} ::: {
CaseDef(Wildcard(), None, Literal(StringConstant("default")))
} :: Nil
val bind = Symbol.newBind(Symbol.spliceOwner, "o", Flags.EmptyFlags, obj.tpe)
val result = Match(obj, cases)
val code = result.show(using Printer.TreeAnsiCode)
// println(code)
result.asExprOf[String]
}
}
8 changes: 8 additions & 0 deletions tests/run-macros/i12188/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sealed trait P
case class PC1(a: String) extends P
case class PC2(b: Int) extends P

@main def Test =
println(MatchTest.test(PC1("ab"): P))
println(MatchTest.test(PC2(10): P))
println(MatchTest.test(null: P))
20 changes: 10 additions & 10 deletions tests/run-macros/tasty-extractors-1.check
Original file line number Diff line number Diff line change
Expand Up @@ -40,37 +40,37 @@ OrType(ConstantType(IntConstant(1)), ConstantType(IntConstant(2)))
Inlined(None, Nil, Match(Literal(StringConstant("a")), List(CaseDef(Literal(StringConstant("a")), None, Block(Nil, Literal(UnitConstant()))))))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Match(Literal(StringConstant("b")), List(CaseDef(Bind("n", Ident("_")), None, Block(Nil, Literal(UnitConstant()))))))
Inlined(None, Nil, Match(Literal(StringConstant("b")), List(CaseDef(Bind("n", Wildcard()), None, Block(Nil, Literal(UnitConstant()))))))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Match(Literal(StringConstant("c")), List(CaseDef(Bind("n", Typed(Ident("_"), TypeIdent("String"))), None, Block(Nil, Literal(UnitConstant()))))))
Inlined(None, Nil, Match(Literal(StringConstant("c")), List(CaseDef(Bind("n", Typed(Wildcard(), TypeIdent("String"))), None, Block(Nil, Literal(UnitConstant()))))))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Match(Literal(StringConstant("e")), List(CaseDef(Ident("_"), None, Block(Nil, Literal(UnitConstant()))))))
Inlined(None, Nil, Match(Literal(StringConstant("e")), List(CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant()))))))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Match(Literal(StringConstant("f")), List(CaseDef(Typed(Ident("_"), TypeIdent("String")), None, Block(Nil, Literal(UnitConstant()))))))
Inlined(None, Nil, Match(Literal(StringConstant("f")), List(CaseDef(Typed(Wildcard(), TypeIdent("String")), None, Block(Nil, Literal(UnitConstant()))))))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Match(Typed(Literal(StringConstant("g")), TypeIdent("Any")), List(CaseDef(Alternatives(List(Typed(Ident("_"), TypeIdent("String")), Typed(Ident("_"), TypeIdent("Int")))), None, Block(Nil, Literal(UnitConstant()))))))
Inlined(None, Nil, Match(Typed(Literal(StringConstant("g")), TypeIdent("Any")), List(CaseDef(Alternatives(List(Typed(Wildcard(), TypeIdent("String")), Typed(Wildcard(), TypeIdent("Int")))), None, Block(Nil, Literal(UnitConstant()))))))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Match(Literal(StringConstant("h")), List(CaseDef(Ident("_"), Some(Literal(BooleanConstant(false))), Block(Nil, Literal(UnitConstant()))))))
Inlined(None, Nil, Match(Literal(StringConstant("h")), List(CaseDef(Wildcard(), Some(Literal(BooleanConstant(false))), Block(Nil, Literal(UnitConstant()))))))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Block(List(ValDef("a", Inferred(), Some(Literal(StringConstant("o"))))), Match(Literal(StringConstant("i")), List(CaseDef(Bind("a", Ident("_")), None, Block(Nil, Literal(UnitConstant())))))))
Inlined(None, Nil, Block(List(ValDef("a", Inferred(), Some(Literal(StringConstant("o"))))), Match(Literal(StringConstant("i")), List(CaseDef(Bind("a", Wildcard()), None, Block(Nil, Literal(UnitConstant())))))))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Match(Ident("Nil"), List(CaseDef(Unapply(TypeApply(Select(Ident("List"), "unapplySeq"), List(Inferred())), Nil, List(Bind("a", Ident("_")), Bind("b", Ident("_")), Bind("c", Ident("_")))), None, Block(Nil, Literal(UnitConstant()))))))
Inlined(None, Nil, Match(Ident("Nil"), List(CaseDef(Unapply(TypeApply(Select(Ident("List"), "unapplySeq"), List(Inferred())), Nil, List(Bind("a", Wildcard()), Bind("b", Wildcard()), Bind("c", Wildcard()))), None, Block(Nil, Literal(UnitConstant()))))))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Try(Literal(IntConstant(1)), List(CaseDef(Ident("_"), None, Block(Nil, Literal(UnitConstant())))), None))
Inlined(None, Nil, Try(Literal(IntConstant(1)), List(CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant())))), None))
OrType(ConstantType(IntConstant(1)), TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit"))

Inlined(None, Nil, Try(Literal(IntConstant(2)), Nil, Some(Literal(UnitConstant()))))
ConstantType(IntConstant(2))

Inlined(None, Nil, Try(Literal(IntConstant(3)), List(CaseDef(Ident("_"), None, Block(Nil, Literal(UnitConstant())))), Some(Literal(UnitConstant()))))
Inlined(None, Nil, Try(Literal(IntConstant(3)), List(CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant())))), Some(Literal(UnitConstant()))))
OrType(ConstantType(IntConstant(3)), TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit"))

Inlined(None, Nil, Literal(BooleanConstant(false)))
Expand Down
2 changes: 1 addition & 1 deletion tests/run-macros/tasty-extractors-2.check
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")
Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("<init>", List(TermParamClause(Nil)), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil)), None, List(DefDef("a", Nil, Inferred(), Some(Literal(IntConstant(0))))))), Literal(UnitConstant())))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("<init>", List(TermParamClause(Nil)), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil), TypeSelect(Select(Ident("_root_"), "scala"), "Product"), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), None, List(DefDef("hashCode", List(TermParamClause(Nil)), Inferred(), Some(Apply(Ident("_hashCode"), List(This(Some("Foo")))))), DefDef("equals", List(TermParamClause(List(ValDef("x$0", Inferred(), None)))), Inferred(), Some(Apply(Select(Apply(Select(This(Some("Foo")), "eq"), List(TypeApply(Select(Ident("x$0"), "$asInstanceOf$"), List(Inferred())))), "||"), List(Match(Ident("x$0"), List(CaseDef(Bind("x$0", Typed(Ident("_"), Inferred())), None, Apply(Select(Literal(BooleanConstant(true)), "&&"), List(Apply(Select(Ident("x$0"), "canEqual"), List(This(Some("Foo"))))))), CaseDef(Ident("_"), None, Literal(BooleanConstant(false))))))))), DefDef("toString", List(TermParamClause(Nil)), Inferred(), Some(Apply(Ident("_toString"), List(This(Some("Foo")))))), DefDef("canEqual", List(TermParamClause(List(ValDef("that", Inferred(), None)))), Inferred(), Some(TypeApply(Select(Ident("that"), "isInstanceOf"), List(Inferred())))), DefDef("productArity", Nil, Inferred(), Some(Literal(IntConstant(0)))), DefDef("productPrefix", Nil, Inferred(), Some(Literal(StringConstant("Foo")))), DefDef("productElement", List(TermParamClause(List(ValDef("n", Inferred(), None)))), Inferred(), Some(Match(Ident("n"), List(CaseDef(Ident("_"), None, Apply(Ident("throw"), List(Apply(Select(New(Inferred()), "<init>"), List(Apply(Select(Ident("n"), "toString"), Nil)))))))))), DefDef("productElementName", List(TermParamClause(List(ValDef("n", Inferred(), None)))), Inferred(), Some(Match(Ident("n"), List(CaseDef(Ident("_"), None, Apply(Ident("throw"), List(Apply(Select(New(Inferred()), "<init>"), List(Apply(Select(Ident("n"), "toString"), Nil)))))))))), DefDef("copy", List(TermParamClause(Nil)), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))))), ValDef("Foo", TypeIdent("Foo$"), Some(Apply(Select(New(TypeIdent("Foo$")), "<init>"), Nil))), ClassDef("Foo$", DefDef("<init>", List(TermParamClause(Nil)), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil), Inferred()), Some(ValDef("_", Singleton(Ident("Foo")), None)), List(DefDef("apply", List(TermParamClause(Nil)), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))), DefDef("unapply", List(TermParamClause(List(ValDef("x$1", Inferred(), None)))), Singleton(Literal(BooleanConstant(true))), Some(Literal(BooleanConstant(true)))), DefDef("toString", Nil, Inferred(), Some(Literal(StringConstant("Foo")))), TypeDef("MirroredMonoType", TypeBoundsTree(Inferred(), Inferred())), DefDef("fromProduct", List(TermParamClause(List(ValDef("x$0", Inferred(), None)))), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil)))))), Literal(UnitConstant())))
Inlined(None, Nil, Block(List(ClassDef("Foo", DefDef("<init>", List(TermParamClause(Nil)), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil), TypeSelect(Select(Ident("_root_"), "scala"), "Product"), TypeSelect(Select(Ident("_root_"), "scala"), "Serializable")), None, List(DefDef("hashCode", List(TermParamClause(Nil)), Inferred(), Some(Apply(Ident("_hashCode"), List(This(Some("Foo")))))), DefDef("equals", List(TermParamClause(List(ValDef("x$0", Inferred(), None)))), Inferred(), Some(Apply(Select(Apply(Select(This(Some("Foo")), "eq"), List(TypeApply(Select(Ident("x$0"), "$asInstanceOf$"), List(Inferred())))), "||"), List(Match(Ident("x$0"), List(CaseDef(Bind("x$0", Typed(Wildcard(), Inferred())), None, Apply(Select(Literal(BooleanConstant(true)), "&&"), List(Apply(Select(Ident("x$0"), "canEqual"), List(This(Some("Foo"))))))), CaseDef(Wildcard(), None, Literal(BooleanConstant(false))))))))), DefDef("toString", List(TermParamClause(Nil)), Inferred(), Some(Apply(Ident("_toString"), List(This(Some("Foo")))))), DefDef("canEqual", List(TermParamClause(List(ValDef("that", Inferred(), None)))), Inferred(), Some(TypeApply(Select(Ident("that"), "isInstanceOf"), List(Inferred())))), DefDef("productArity", Nil, Inferred(), Some(Literal(IntConstant(0)))), DefDef("productPrefix", Nil, Inferred(), Some(Literal(StringConstant("Foo")))), DefDef("productElement", List(TermParamClause(List(ValDef("n", Inferred(), None)))), Inferred(), Some(Match(Ident("n"), List(CaseDef(Wildcard(), None, Apply(Ident("throw"), List(Apply(Select(New(Inferred()), "<init>"), List(Apply(Select(Ident("n"), "toString"), Nil)))))))))), DefDef("productElementName", List(TermParamClause(List(ValDef("n", Inferred(), None)))), Inferred(), Some(Match(Ident("n"), List(CaseDef(Wildcard(), None, Apply(Ident("throw"), List(Apply(Select(New(Inferred()), "<init>"), List(Apply(Select(Ident("n"), "toString"), Nil)))))))))), DefDef("copy", List(TermParamClause(Nil)), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))))), ValDef("Foo", TypeIdent("Foo$"), Some(Apply(Select(New(TypeIdent("Foo$")), "<init>"), Nil))), ClassDef("Foo$", DefDef("<init>", List(TermParamClause(Nil)), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil), Inferred()), Some(ValDef("_", Singleton(Ident("Foo")), None)), List(DefDef("apply", List(TermParamClause(Nil)), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil))), DefDef("unapply", List(TermParamClause(List(ValDef("x$1", Inferred(), None)))), Singleton(Literal(BooleanConstant(true))), Some(Literal(BooleanConstant(true)))), DefDef("toString", Nil, Inferred(), Some(Literal(StringConstant("Foo")))), TypeDef("MirroredMonoType", TypeBoundsTree(Inferred(), Inferred())), DefDef("fromProduct", List(TermParamClause(List(ValDef("x$0", Inferred(), None)))), Inferred(), Some(Apply(Select(New(Inferred()), "<init>"), Nil)))))), Literal(UnitConstant())))
TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "Unit")

Inlined(None, Nil, Block(List(ClassDef("Foo1", DefDef("<init>", List(TermParamClause(List(ValDef("a", TypeIdent("Int"), None)))), Inferred(), None), List(Apply(Select(New(Inferred()), "<init>"), Nil)), None, List(ValDef("a", Inferred(), None)))), Literal(UnitConstant())))
Expand Down