Skip to content

Commit

Permalink
Update staging.Compiler.make documentation
Browse files Browse the repository at this point in the history
This addresses part of scala#19211, scala#19170, and scala#19176
  • Loading branch information
nicolasstucki committed Jan 12, 2024
1 parent fa448fb commit 693a80a
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 10 deletions.
6 changes: 5 additions & 1 deletion docs/_spec/TODOreference/metaprogramming/staging.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ to get a source-like representation of the expression.
import scala.quoted.*

// make available the necessary compiler for runtime code generation
given staging.Compiler = staging.Compiler.make(getClass.getClassLoader)
given staging.Compiler =
// We need an instance of a class that is defined in the current application (not the standard library)
// `this` can be used instead of an instance of `Dummy` if the Compiler is instantiated within one of the application classes.
object Dummy
staging.Compiler.make(Dummy.getClass.getClassLoader)

val f: Array[Int] => Int = staging.run {
val stagedSum: Expr[Array[Int] => Int] =
Expand Down
28 changes: 20 additions & 8 deletions staging/src/scala/quoted/staging/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,27 @@ object Compiler:

/** Create a new instance of the compiler using the the classloader of the application.
*
* Usage:
* ```
* import scala.quoted.staging._
* given Compiler = Compiler.make(getClass.getClassLoader)
* ```
* Usage:
* ```
* import scala.quoted.staging._
* given Compiler =
* object Dummy
* Compiler.make(Dummy.getClass.getClassLoader)
* ```
*
* @param appClassloader classloader of the application that generated the quotes
* @param settings compiler settings
* @return A new instance of the compiler
* Note that we use an instance of `Dummy` to get the classloader that loaded the application.
* Any other instance of a class defined in the application would also work.
* Using a class defined in the standard library should be avoided as it might be loaded by a different classloader.
*
* If the given compiler is defined in one of your classes (e.i. not as a top-level definition), then
* the compiler can be instantiated with:
* ```
* given Compiler = Compiler.make(this.getClass.getClassLoader)
* ```
*
* @param appClassloader classloader of the application that generated the quotes
* @param settings compiler settings
* @return A new instance of the compiler
*/
def make(appClassloader: ClassLoader)(implicit settings: Settings): Compiler =
new Compiler:
Expand Down
2 changes: 1 addition & 1 deletion tests/run-staging/i11162.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import scala.quoted.*

object Test {

given staging.Compiler = staging.Compiler.make(getClass.getClassLoader)
given staging.Compiler = staging.Compiler.make(this.getClass.getClassLoader)

def main(args: Array[String]): Unit =
staging.run {
Expand Down
14 changes: 14 additions & 0 deletions tests/run-staging/i19170.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import scala.quoted.*

given staging.Compiler =
object Dummy
staging.Compiler.make(Dummy.getClass.getClassLoader)

class A(i: Int)

def f(i: Expr[Int])(using Quotes): Expr[A] = { '{ new A($i) } }

@main def Test = {
val g: Int => A = staging.run { '{ (i: Int) => ${ f('{i}) } } }
println(g(3))
}
10 changes: 10 additions & 0 deletions tests/run-staging/i19176.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import scala.quoted.*

given staging.Compiler =
object Dummy
staging.Compiler.make(Dummy.getClass.getClassLoader)

class A
val f: (A, Int) => Int = staging.run { '{ (q: A, x: Int) => x } }

@main def Test = f(new A, 3)

0 comments on commit 693a80a

Please sign in to comment.