Skip to content

Fix classpath in QuoteDriver when executing from sbt #3871

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 1 commit into from
Jan 22, 2018
Merged
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
13 changes: 11 additions & 2 deletions compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package dotty.tools.dotc.quoted
import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.Driver
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.StdNames._
import dotty.tools.io.{AbstractFile, Directory, PlainDirectory, VirtualDirectory}
import dotty.tools.repl.AbstractFileClassLoader
import dotty.tools.dotc.printing.DecompilerPrinter

import scala.quoted.Expr

import java.net.URLClassLoader

class QuoteDriver extends Driver {
import tpd._

Expand Down Expand Up @@ -61,7 +62,15 @@ class QuoteDriver extends Driver {

override def initCtx: Context = {
val ictx = super.initCtx.fresh
val classpath = System.getProperty("java.class.path")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using ctx.settings.classpath instead, isn't that enough?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the classpath of the library in not in there. That is why I needed to add it explicitly. We also need the current classpath in case the quote refers to something in the application (such as class or static method).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example

class Foo
object Foo {
  def main(...) = {
    val q = '(new Foo)
    q.run // Foo need to be present in the classpath of the compiler that will compile q
  }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In scala.reflect macros, it assumes separation (ahead-of) compilation of macro definitions. The user-app must depend on the lib that contains Foo in order to use that macro, thus it's automatically on the path.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. But the app is guaranteed to have separate compilation as the macro is staged.

var classpath = System.getProperty("java.class.path")
this.getClass.getClassLoader match {
case cl: URLClassLoader =>
// Loads the classes loaded by this class loader
// When executing `run` or `test` in sbt the classpath is not in the property java.class.path
val newClasspath = cl.getURLs.map(_.getFile())
classpath = newClasspath.mkString("", ":", if (classpath == "") "" else ":" + classpath)
case _ =>
}
ictx.settings.classpath.update(classpath)(ictx)
ictx
}
Expand Down