Skip to content

Commit 8270aed

Browse files
authored
Merge pull request #6017 from dotty-staging/fix-#6007
Fix #6007: Get the classloader that loaded the application
2 parents cdb6250 + abd0c56 commit 8270aed

File tree

100 files changed

+198
-199
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+198
-199
lines changed

compiler/src/dotty/tools/dotc/consumetasty/ConsumeTasty.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ object ConsumeTasty {
1616
new TastyFromClass(tastyConsumer)
1717
}
1818

19-
val currentClasspath = QuoteDriver.currentClasspath
19+
val currentClasspath = QuoteDriver.currentClasspath(getClass.getClassLoader)
2020
import java.io.File.{ pathSeparator => sep }
2121
val args = "-from-tasty" :: "-Yretain-trees" :: "-classpath" :: s"$classpath$sep$currentClasspath" :: classes
2222
(new Consume).process(args.toArray)

compiler/src/dotty/tools/dotc/quoted/QuoteCompiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class QuoteCompiler extends Compiler {
3737
new ExprRun(this, ctx.addMode(Mode.ReadPositions))
3838
}
3939

40-
def outputClassName: TypeName = "Quoted".toTypeName
40+
def outputClassName: TypeName = "Generated$Code$From$Quoted".toTypeName
4141

4242
/** Frontend that receives a scala.quoted.Expr or scala.quoted.Type as input */
4343
class QuotedFrontend(putInClass: Boolean) extends Phase {

compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ import scala.quoted.{Expr, Type}
1111
import scala.quoted.Toolbox
1212
import java.net.URLClassLoader
1313

14-
class QuoteDriver extends Driver {
14+
/** Driver to compile quoted code
15+
*
16+
* @param appClassloader classloader of the application that generated the quotes
17+
*/
18+
class QuoteDriver(appClassloader: ClassLoader) extends Driver {
1519
import tpd._
1620

1721
private[this] val contextBase: ContextBase = new ContextBase
@@ -32,7 +36,9 @@ class QuoteDriver extends Driver {
3236
val driver = new QuoteCompiler
3337
driver.newRun(ctx).compileExpr(expr)
3438

35-
val classLoader = new AbstractFileClassLoader(outDir, this.getClass.getClassLoader)
39+
assert(!ctx.reporter.hasErrors)
40+
41+
val classLoader = new AbstractFileClassLoader(outDir, appClassloader)
3642

3743
val clazz = classLoader.loadClass(driver.outputClassName.toString)
3844
val method = clazz.getMethod("apply")
@@ -82,7 +88,7 @@ class QuoteDriver extends Driver {
8288

8389
override def initCtx: Context = {
8490
val ictx = contextBase.initialCtx
85-
ictx.settings.classpath.update(QuoteDriver.currentClasspath)(ictx)
91+
ictx.settings.classpath.update(QuoteDriver.currentClasspath(appClassloader))(ictx)
8692
ictx
8793
}
8894

@@ -94,9 +100,9 @@ class QuoteDriver extends Driver {
94100

95101
object QuoteDriver {
96102

97-
def currentClasspath: String = {
103+
def currentClasspath(cl: ClassLoader): String = {
98104
val classpath0 = System.getProperty("java.class.path")
99-
this.getClass.getClassLoader match {
105+
cl match {
100106
case cl: URLClassLoader =>
101107
// Loads the classes loaded by this class loader
102108
// When executing `run` or `test` in sbt the classpath is not in the property java.class.path

compiler/src/dotty/tools/dotc/quoted/ToolboxImpl.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@ import scala.quoted.Exprs.{LiftedExpr, TastyTreeExpr}
99
object ToolboxImpl {
1010
import tpd._
1111

12-
def make(settings: scala.quoted.Toolbox.Settings): scala.quoted.Toolbox = new scala.quoted.Toolbox {
12+
/** Create a new instance of the toolbox using the the classloader of the application.
13+
*
14+
* @param appClassloader classloader of the application that generated the quotes
15+
* @param settings toolbox settings
16+
* @return A new instance of the toolbox
17+
*/
18+
def make(settings: scala.quoted.Toolbox.Settings, appClassloader: ClassLoader): scala.quoted.Toolbox = new scala.quoted.Toolbox {
1319

14-
private[this] val driver: QuoteDriver = new QuoteDriver()
20+
private[this] val driver: QuoteDriver = new QuoteDriver(appClassloader)
1521

1622
def run[T](expr: Expr[T]): T = expr match {
1723
case expr: LiftedExpr[T] =>
@@ -26,4 +32,5 @@ object ToolboxImpl {
2632

2733
def show[T](tpe: Type[T]): String = synchronized(driver.show(tpe, settings))
2834
}
35+
2936
}

compiler/test-resources/repl/i6007

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
scala> implicit def toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
2+
def toolbox: quoted.Toolbox
3+
scala> val v = '{ (if true then Some(1) else None).map(v => v+1) }
4+
val v: quoted.Expr[Option[Int]] = Expr(<pickled tasty>)
5+
scala> v.show
6+
val res0: String = (if (true) scala.Some.apply[scala.Int](1) else scala.None).map[scala.Int](((v: scala.Int) => v.+(1)))
7+
scala> v.run
8+
val res1: Option[Int] = Some(2)

library/src/scala/quoted/Toolbox.scala

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package scala.quoted
22

33
import scala.annotation.implicitNotFound
44

5-
@implicitNotFound("Could not find implicit quoted.Toolbox.\n\nDefault toolbox can be instantiated with:\n `implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make`\n\nIf only needed once it can also be imported with:\n `import scala.quoted.Toolbox.Default._`")
5+
@implicitNotFound("Could not find implicit quoted.Toolbox.\n\nDefault toolbox can be instantiated with:\n `implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)`\n\n")
66
trait Toolbox {
77
def run[T](expr: Expr[T]): T
88
def show[T](expr: Expr[T]): String
@@ -11,17 +11,22 @@ trait Toolbox {
1111

1212
object Toolbox {
1313

14-
object Default {
15-
// TODO remove? It may be better to only have one way to instantiate the toolbox
16-
implicit def make(implicit settings: Settings): Toolbox = Toolbox.make
17-
}
18-
19-
def make(implicit settings: Settings): Toolbox = {
20-
val cl = getClass.getClassLoader
14+
/** Create a new instance of the toolbox using the the classloader of the application.
15+
*
16+
* Usuage:
17+
* ```
18+
* implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
19+
* ```
20+
*
21+
* @param appClassloader classloader of the application that generated the quotes
22+
* @param settings toolbox settings
23+
* @return A new instance of the toolbox
24+
*/
25+
def make(appClassloader: ClassLoader)(implicit settings: Settings): Toolbox = {
2126
try {
22-
val toolboxImplCls = cl.loadClass("dotty.tools.dotc.quoted.ToolboxImpl")
23-
val makeMeth = toolboxImplCls.getMethod("make", classOf[Settings])
24-
makeMeth.invoke(null, settings).asInstanceOf[Toolbox]
27+
val toolboxImplCls = appClassloader.loadClass("dotty.tools.dotc.quoted.ToolboxImpl")
28+
val makeMeth = toolboxImplCls.getMethod("make", classOf[Settings], classOf[ClassLoader])
29+
makeMeth.invoke(null, settings, appClassloader).asInstanceOf[Toolbox]
2530
}
2631
catch {
2732
case ex: ClassNotFoundException =>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
scalaVersion := sys.props("plugin.scalaVersion")
2+
3+
libraryDependencies ++= Seq(
4+
"ch.epfl.lamp" % "dotty_0.14" % scalaVersion.value,
5+
"ch.epfl.lamp" % "dotty_0.14" % scalaVersion.value % "test->runtime",
6+
"com.novocode" % "junit-interface" % "0.11" % "test"
7+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % sys.props("plugin.version"))
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package hello
2+
3+
// Import Expr and some extension methods
4+
import scala.quoted._
5+
6+
object Main {
7+
8+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
9+
10+
def main(args: Array[String]): Unit = {
11+
12+
val square = stagedPower(2)
13+
14+
assert(Math.pow(3, 2) == square(3))
15+
16+
square(3)
17+
square(4)
18+
19+
assert(Math.pow(4, 2) == square(4))
20+
21+
val cube = stagedPower(3)
22+
cube(2)
23+
24+
25+
assert(Math.pow(2, 3) == cube(2))
26+
27+
28+
29+
val toTheFourth = stagedPower(4)
30+
assert(Math.pow(3, 4) == toTheFourth(3))
31+
}
32+
33+
def stagedPower(n: Int): Double => Double = {
34+
// Code representing the labmda where the recursion is unrolled based on the value of n
35+
val code = '{ (x: Double) => ${powerCode(n, '{x})}}
36+
37+
code.show
38+
39+
// Evaluate the contents of the code and return it's value
40+
code.run
41+
}
42+
43+
def powerCode(n: Int, x: Expr[Double]): Expr[Double] =
44+
if (n == 0) '{1.0}
45+
else if (n == 1) x
46+
else if (n < 0) throw new Exception("Negative powers not implemented. Left as a small exercise. Dont be shy, try it out.")
47+
else if (n == 2) '{$x * $x}
48+
else if (n % 2 == 1) '{$x * ${powerCode(n - 1, x)}}
49+
else '{ val y = $x * $x; ${powerCode(n / 2, '{y})}}
50+
51+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
> run

tests/neg-with-compiler/i5941/macro_1.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ object Lens {
1313
}
1414

1515
def impl[S: Type, T: Type](getter: Expr[S => T])(implicit refl: Reflection): Expr[Lens[S, T]] = {
16+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(this.getClass.getClassLoader)
1617
import refl._
1718
import util._
18-
import quoted.Toolbox.Default._
19-
2019
// obj.copy(field = value)
2120
def setterBody(obj: Expr[S], value: Expr[T], field: String): Expr[S] =
2221
Select.overloaded(obj.unseal, "copy", Nil, NamedArg(field, value.unseal) :: Nil).seal.cast[S]

tests/neg-with-compiler/quote-run-in-macro-1/quoted_1.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import scala.quoted._
22
import scala.quoted.autolift._
33

4-
import scala.quoted.Toolbox.Default._
5-
64
object Macros {
5+
6+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
77
inline def foo(i: => Int): Int = ${ fooImpl('i) }
88
def fooImpl(i: Expr[Int]): Expr[Int] = {
99
val y: Int = i.run

tests/neg-with-compiler/quote-run-in-macro-2/quoted_1.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import scala.quoted._
22
import scala.quoted.autolift._
3-
import scala.quoted.Toolbox.Default._
43

54
object Macros {
5+
66
inline def foo(i: => Int): Int = ${ fooImpl('i) }
77
def fooImpl(i: Expr[Int]): Expr[Int] = {
8+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
89
val y: Int = i.run
910
y
1011
}

tests/neg/tasty-string-interpolator-position-a/Macro_1.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import scala.quoted._
22
import scala.tasty.Reflection
33
import scala.language.implicitConversions
44
import scala.quoted.Exprs.LiftedExpr
5-
import scala.quoted.Toolbox.Default._
65

76
object Macro {
87

tests/neg/tasty-string-interpolator-position-b/Macro_1.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import scala.quoted._
22
import scala.tasty.Reflection
33
import scala.language.implicitConversions
44
import scala.quoted.Exprs.LiftedExpr
5-
import scala.quoted.Toolbox.Default._
65

76
object Macro {
87

@@ -11,7 +10,7 @@ object Macro {
1110
}
1211

1312
object FIntepolator {
14-
13+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
1514
def apply(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Any]])(implicit reflect: Reflection): Expr[String] = {
1615
import reflect._
1716
error("there are no args", argsExpr.unseal.underlyingArgument.pos)

tests/pos-with-compiler/quote-0.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import scala.quoted._
22
import scala.quoted.autolift._
33

4-
import scala.quoted.Toolbox.Default._
5-
64
object Macros {
75

86

@@ -41,5 +39,6 @@ class Test {
4139
${ powerCode(3, '{math.sqrt(2.0)}) }
4240
}
4341

42+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
4443
program.run
4544
}

tests/pos-with-compiler/quote-assert/quoted_2.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import scala.quoted.Toolbox.Default._
1+
22
import scala.quoted._
33
import Macros._
44

@@ -15,5 +15,6 @@ object Test {
1515
${ assertImpl('{x != 0}) }
1616
}
1717

18+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
1819
program.run
1920
}

tests/run-with-compiler-custom-args/staged-streams_1.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,8 +677,7 @@ object Test {
677677
.fold('{0}, ((a: Expr[Int], b : Expr[Int]) => '{ $a + $b }))
678678

679679
def main(args: Array[String]): Unit = {
680-
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make
681-
680+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
682681
println(test1().run)
683682
println
684683
println(test2().run)

tests/run-with-compiler/i3823-b.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import scala.quoted.Toolbox.Default._
21
import scala.quoted._
32
object Test {
43
def main(args: Array[String]): Unit = {
54
def f[T](x: Expr[T])(implicit t: Type[T]) = '{
65
val z: $t = $x
76
}
7+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
88
println(f('{2})(Type.IntTag).show)
99
}
1010
}

tests/run-with-compiler/i3823-c.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import scala.quoted.Toolbox.Default._
21
import scala.quoted._
32
object Test {
43
def main(args: Array[String]): Unit = {
54
def f[T](x: Expr[T])(implicit t: Type[T]) = '{
65
val z = $x
76
}
7+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
88
println(f('{2})(Type.IntTag).show)
99
}
1010
}

tests/run-with-compiler/i3823.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import scala.quoted.Toolbox.Default._
21
import scala.quoted._
32
object Test {
43
def main(args: Array[String]): Unit = {
54
def f[T: Type](x: Expr[T])(t: Type[T]) = '{
65
val z: $t = $x
76
}
7+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
88
println(f('{2})('[Int]).show)
99
}
1010
}

tests/run-with-compiler/i3847-b.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import scala.quoted.Toolbox.Default._
21
import scala.quoted._
32
import scala.reflect.ClassTag
43

@@ -15,6 +14,7 @@ object Arrays {
1514

1615
object Test {
1716
def main(args: Array[String]): Unit = {
17+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
1818
import Arrays._
1919
implicit val ct: Expr[ClassTag[Int]] = '{ClassTag.Int}
2020
val arr: Expr[Array[List[Int]]] = Array[List[Int]](List(1, 2, 3)).toExpr

tests/run-with-compiler/i3847.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import scala.quoted.Toolbox.Default._
21
import scala.quoted._
32
import scala.reflect.ClassTag
43

@@ -15,6 +14,7 @@ object Arrays {
1514

1615
object Test {
1716
def main(args: Array[String]): Unit = {
17+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(this.getClass.getClassLoader)
1818
import Arrays._
1919
implicit val ct: Expr[ClassTag[Int]] = '{ClassTag.Int}
2020
val arr: Expr[Array[Int]] = Array[Int](1, 2, 3).toExpr

tests/run-with-compiler/i3876-b.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import scala.quoted.Toolbox.Default._
21
import scala.quoted._
32
object Test {
43
def main(args: Array[String]): Unit = {
5-
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make
4+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
65

76
val x: Expr[Int] = '{3}
87

tests/run-with-compiler/i3876-c.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import scala.quoted.Toolbox.Default._
21
import scala.quoted._
32
object Test {
43
def main(args: Array[String]): Unit = {
5-
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make
4+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
65

76
val x: Expr[Int] = '{3}
87

0 commit comments

Comments
 (0)