Skip to content

Commit 2cc8671

Browse files
Make classpathFromClassloader non quadratic, add tests
The tests ensure that we've fixed #7897. Co-Authored-By: Guillaume Martres <[email protected]>
1 parent cd8f1b8 commit 2cc8671

File tree

7 files changed

+42
-17
lines changed

7 files changed

+42
-17
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
scalaVersion := sys.props("plugin.scalaVersion")
2+
3+
libraryDependencies += "ch.epfl.lamp" %% "dotty-staging" % scalaVersion.value
4+
5+
fork := false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
scalaVersion := sys.props("plugin.scalaVersion")
2+
3+
libraryDependencies += "ch.epfl.lamp" %% "dotty-staging" % scalaVersion.value
4+
5+
fork := true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sbt.version=1.3.6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % sys.props("plugin.version"))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import scala.quoted._, staging._
2+
3+
given Toolbox = Toolbox.make(getClass.getClassLoader)
4+
5+
val f: Array[Int] => Int = run {
6+
val stagedSum: Expr[Array[Int] => Int] = '{ (arr: Array[Int]) => 6 }
7+
println(stagedSum.show)
8+
stagedSum
9+
}
10+
11+
object Main {
12+
def main(args: Array[String]): Unit =
13+
f.apply(Array(1, 2, 3)) // Returns 6
14+
}
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
> run
2+
$ copy-file build-no-fork.sbt build.sbt
3+
> run

staging/src/scala/quoted/staging/QuoteDriver.scala

+13-17
Original file line numberDiff line numberDiff line change
@@ -73,23 +73,19 @@ private class QuoteDriver(appClassloader: ClassLoader) extends Driver {
7373
* the wrong thing.
7474
*/
7575
private def classpathFromClassloader(cl: ClassLoader): String = {
76-
@tailrec
77-
def loop(cl: ClassLoader, suffixClasspath: String): String =
78-
cl match {
79-
case cl: URLClassLoader =>
80-
val updatedClasspath = cl.getURLs
81-
.map(url => Paths.get(url.toURI).toAbsolutePath.toString)
82-
.mkString(
83-
"",
84-
File.pathSeparator,
85-
if (suffixClasspath.isEmpty) "" else File.pathSeparator + suffixClasspath
86-
)
87-
loop(cl.getParent, updatedClasspath)
88-
case _ =>
89-
suffixClasspath
90-
}
91-
92-
loop(cl, "")
76+
val classpathBuff = List.newBuilder[String]
77+
def collectClassLoaderPaths(cl: ClassLoader): Unit = cl match {
78+
case cl: URLClassLoader =>
79+
collectClassLoaderPaths(cl.getParent)
80+
// Parent classloaders are searched before their child, so the part of
81+
// the classpath coming from the child is added at the _end_ of the
82+
// classpath.
83+
classpathBuff ++=
84+
cl.getURLs.iterator.map(url => Paths.get(url.toURI).toAbsolutePath.toString)
85+
case _ =>
86+
}
87+
collectClassLoaderPaths(cl)
88+
classpathBuff.result().mkString(java.io.File.pathSeparator)
9389
}
9490
}
9591

0 commit comments

Comments
 (0)