Skip to content

Add extra regression test for #12221 #12266

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

Merged
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
120 changes: 120 additions & 0 deletions tests/pos-macros/i12221/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import scala.quoted.*
import scala.reflect.*

object Macros {

inline def show[A,B](inline expr: A => B): Unit =
${printExpr('expr)}

def printExpr[A,B](expr: Expr[A=>B])(using Quotes) = '{
println(${showExpr3(expr)})
}

def showExpr3[A,B](expr: Expr[A=>B])(using Quotes): Expr[String] =
import quotes.reflect.*

val sb = new StringBuilder

// Makes us only print the body of thr function
def printDefFun(tree: Tree): Unit ={
val acc = new TreeAccumulator[Unit]{
def foldTree(s: Unit, tree: Tree)(owner: Symbol): Unit =
tree match
case deff : DefDef =>
treePrint(deff.rhs.get, 0)
sb.append("++++++++++++++++\n")
sb.append(deff.rhs.get.show(using Printer.TreeStructure)).append('\n')
case _ =>
foldOverTree(s, tree)(owner)
}
acc.foldTree(List(), tree)(tree.symbol)
}

def treePrint(tree: Tree, level: Int): Unit = {
val pre = " " * level
tree match {
case body : Term => {
body match {
// Normal typed
case typed: Typed =>
sb.append(pre + typed.getClass()).append('\n')
sb.append(pre + s"Typed with ${typed.tpt}:\n")
treePrint(typed.expr , level + 1)
case Block(statements, expr) =>
sb.append(pre + "Block:{").append('\n')
statements.map(stat => stat match{
case term: Term => treePrint(term, level + 1)
case deff: Definition =>
sb.append(pre + "Definition statement\n")
treePrint(deff, level + 1)
case _ =>
sb.append(pre + "Non-term statement\n")
sb.append(stat.show(using Printer.TreeStructure)).append('\n')
})
treePrint(expr, level + 1)
sb.append(pre + "}\n")

case Match(scrutinee, cases) =>
sb.append(pre + "Match:\n")
treePrint(scrutinee, level + 1)
sb.append(pre + "with\n")
cases.map(treePrint(_, level +1))

case Ident(name) =>
sb.append(pre + s"Identifier(${name})\n")

case Apply(fun, args) =>
sb.append(pre + "Apply\n")
treePrint(fun, level + 1)
if !args.isEmpty then
sb.append(pre + "with arguments\n")
args.zipWithIndex.map(
(arg, index) =>
treePrint(arg, level +1)
if args.size > 1 && index < args.size -1 then
// Used to seperate list of parameters
sb.append(pre + ",\n")
)
case _ =>
sb.append("Term\n")
sb.append(tree.getClass()).append('\n')
sb.append(tree.show(using Printer.TreeStructure)).append('\n')
}
}

case CaseDef(pattern, guard, rhs) =>
sb.append(pre + "caseDef:\n" )
treePrint(pattern, level + 1)
treePrint(rhs, level + 1)

//Adding this unappy makes the typed get swallowed
/*
case Unapply(fun, implicits, pattern) =>
sb.append(pre + "Unapply with function").append('\n')
treePrint(fun , level + 1)
sb.append(pre + "with patterns").append('\n')
pattern.map(treePrint(_ , level + 1))
*/
case b: Bind => sb.append(pre + "Bind with stuff").append('\n')

case typed : Typed =>
//sb.append(pre + typed.getClass()).append('\n')
sb.append(pre + tree.getClass()).append('\n')
sb.append(pre + s"Typed2 with ${typed.tpt}:").append('\n')
treePrint(typed.expr , level + 1)

case Unapply(_,_,_) => sb.append(pre + "Unapply with stuff").append('\n')
case _ =>
tree match
case t: Term => sb.append("Term").append('\n')
case _ => ()
sb.append(tree.getClass()).append('\n')
sb.append(tree.show(using Printer.TreeStructure)).append('\n')
}
}

val tree: Term = expr.asTerm
printDefFun(tree)
sb.append("Finished").append('\n')
Expr(sb.result())
}
20 changes: 20 additions & 0 deletions tests/pos-macros/i12221/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@main
def hello: Unit = {
abstract class A
case class Foo(a: Int) extends A

//Will print the body of the given function, then its print (using Printer.TreeStructure)
Macros.show((x: A)=>{
x match {
case Foo(a) => a
}:Int
})
/*
val x = Foo(3)
Macros.show(
x match {
case Foo(1) => 3
}
)*/

}