-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add console to bridge #1314
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
Add console to bridge #1314
Changes from all commits
01463f7
1f1b357
fbf44eb
a00a972
df84901
22b40bf
8fe3e37
9b15ac1
42030aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* sbt -- Simple Build Tool | ||
* Copyright 2008, 2009 Mark Harrah | ||
*/ | ||
package xsbt | ||
|
||
import xsbti.Logger | ||
import scala.tools.nsc.{ GenericRunnerCommand, Interpreter, InterpreterLoop, ObjectRunner, Settings } | ||
import scala.tools.nsc.interpreter.InteractiveReader | ||
import scala.tools.nsc.reporters.Reporter | ||
import scala.tools.nsc.util.ClassPath | ||
|
||
import dotty.tools.dotc.core.Contexts.Context | ||
import dotty.tools.dotc.repl.REPL | ||
import dotty.tools.dotc.repl.REPL.Config | ||
|
||
class ConsoleInterface { | ||
def commandArguments( | ||
args: Array[String], | ||
bootClasspathString: String, | ||
classpathString: String, | ||
log: Logger | ||
): Array[String] = args | ||
|
||
def run(args: Array[String], | ||
bootClasspathString: String, | ||
classpathString: String, | ||
initialCommands: String, | ||
cleanupCommands: String, | ||
loader: ClassLoader, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, it isn't necessary to pass the loader (here atm) - but if a modified loader is passed somehow, it makes sense that it be propagated to the REPL. Will add that in the morning :) thanks! |
||
bindNames: Array[String], | ||
bindValues: Array[Any], | ||
log: Logger | ||
): Unit = { | ||
val completeArgs = | ||
args :+ | ||
"-bootclasspath" :+ bootClasspathString :+ | ||
"-classpath" :+ classpathString | ||
|
||
println("Starting dotty interpreter...") | ||
val repl = ConsoleInterface.customRepl( | ||
initialCommands :: Nil, | ||
cleanupCommands :: Nil, | ||
bindNames zip bindValues, | ||
loader | ||
) | ||
repl.process(completeArgs) | ||
} | ||
} | ||
|
||
object ConsoleInterface { | ||
def customConfig( | ||
initCmds: List[String], | ||
cleanupCmds: List[String], | ||
boundVals: Array[(String, Any)], | ||
loader: ClassLoader | ||
) = new Config { | ||
override val initialCommands: List[String] = initCmds | ||
override val cleanupCommands: List[String] = cleanupCmds | ||
override val boundValues: Array[(String, Any)] = boundVals | ||
override val classLoader: Option[ClassLoader] = Option(loader) | ||
} | ||
|
||
def customRepl(cfg: Config): REPL = new REPL { | ||
override lazy val config = cfg | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why lazy? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Must be lazy to override lazy val ;) |
||
} | ||
|
||
def customRepl( | ||
initCmds: List[String], | ||
cleanupCmds: List[String], | ||
boundVals: Array[(String, Any)], | ||
loader: ClassLoader | ||
): REPL = customRepl(customConfig(initCmds, cleanupCmds, boundVals, loader)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,7 +25,8 @@ object DottyBuild extends Build { | |
override def settings: Seq[Setting[_]] = { | ||
super.settings ++ Seq( | ||
scalaVersion in Global := "2.11.5", | ||
version in Global := "0.1-SNAPSHOT", | ||
version in Global := | ||
"0.1-" + VersionUtil.commitDate + "-" + VersionUtil.gitHash + "-SNAPSHOT", | ||
organization in Global := "ch.epfl.lamp", | ||
organizationName in Global := "LAMP/EPFL", | ||
organizationHomepage in Global := Some(url("http://lamp.epfl.ch")), | ||
|
@@ -50,7 +51,8 @@ object DottyBuild extends Build { | |
autoScalaLibrary := false, | ||
//Remove javac invalid options in Compile doc | ||
javacOptions in (Compile, doc) --= Seq("-Xlint:unchecked", "-Xlint:deprecation") | ||
) | ||
). | ||
settings(publishing) | ||
|
||
lazy val dotty = project.in(file(".")). | ||
dependsOn(`dotty-interfaces`). | ||
|
@@ -207,11 +209,15 @@ object DottyBuild extends Build { | |
"org.scala-sbt" % "api" % sbtVersion.value % "test", | ||
"org.specs2" %% "specs2" % "2.3.11" % "test" | ||
), | ||
version := "0.1.1-SNAPSHOT", | ||
// The sources should be published with crossPaths := false, the binaries | ||
// are unused so it doesn't matter. | ||
version := | ||
"0.1.1-" + VersionUtil.commitDate + "-" + VersionUtil.gitHash + "-SNAPSHOT", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if it is a good idea to publish hundreds of distinct snapshots on maven. Users would need to depend on a specific git-hash and update it by hand. I'd prefer to publish one snapshot and have version information reported by REPL. Something similar to https://github.com/hmrc/sbt-git-stamp may be in handy for implementing this. |
||
// The sources should be published with crossPaths := false since they | ||
// need to be compiled by the project using the bridge. | ||
crossPaths := false, | ||
|
||
// Don't publish any binaries for the bridge because of the above | ||
publishArtifact in (Compile, packageBin) := false, | ||
|
||
fork in Test := true, | ||
parallelExecution in Test := false | ||
). | ||
|
@@ -244,7 +250,8 @@ object DottyInjectedPlugin extends AutoPlugin { | |
""") | ||
} | ||
*/ | ||
) | ||
). | ||
settings(publishing) | ||
|
||
|
||
/** A sandbox to play with the Scala.js back-end of dotty. | ||
|
@@ -329,9 +336,9 @@ object DottyInjectedPlugin extends AutoPlugin { | |
) | ||
|
||
lazy val publishing = Seq( | ||
publishMavenStyle := true, | ||
publishMavenStyle := true, | ||
publishArtifact := true, | ||
isSnapshot := version.value.contains("SNAPSHOT"), | ||
publishTo := { | ||
val nexus = "https://oss.sonatype.org/" | ||
if (isSnapshot.value) | ||
|
@@ -341,11 +348,47 @@ object DottyInjectedPlugin extends AutoPlugin { | |
}, | ||
publishArtifact in Test := false, | ||
homepage := Some(url("https://github.com/lampepfl/dotty")), | ||
licenses += ("BSD New", | ||
url("https://github.com/lampepfl/dotty/blob/master/LICENSE.md")), | ||
scmInfo := Some( | ||
ScmInfo( | ||
url("https://github.com/lampepfl/dotty"), | ||
"scm:git:git@github.com:lampepfl/dotty.git" | ||
) | ||
), | ||
pomExtra := ( | ||
<developers> | ||
<developer> | ||
<id>odersky</id> | ||
<name>Martin Odersky</name> | ||
<email>martin.odersky@epfl.ch</email> | ||
<url>https://github.com/odersky</url> | ||
</developer> | ||
<developer> | ||
<id>DarkDimius</id> | ||
<name>Dmitry Petrashko</name> | ||
<email>me@d-d.me</email> | ||
<url>https://d-d.me</url> | ||
</developer> | ||
<developer> | ||
<id>smarter</id> | ||
<name>Guillaume Martres</name> | ||
<email>smarter@ubuntu.com</email> | ||
<url>http://guillaume.martres.me</url> | ||
</developer> | ||
<developer> | ||
<id>felixmulder</id> | ||
<name>Felix Mulder</name> | ||
<email>felix.mulder@gmail.com</email> | ||
<url>http://felixmulder.com</url> | ||
</developer> | ||
<developer> | ||
<id>liufengyun</id> | ||
<name>Liu Fengyun</name> | ||
<email>liufengyun@chaos-lab.com</email> | ||
<url>http://chaos-lab.com</url> | ||
</developer> | ||
</developers> | ||
) | ||
) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import scala.sys.process.Process | ||
|
||
object VersionUtil { | ||
def executeScript(scriptName: String) = { | ||
val cmd = | ||
if (System.getProperty("os.name").toLowerCase.contains("windows")) | ||
s"cmd.exe /c scripts\\build\\$scriptName.bat -p" | ||
else s"scripts/build/$scriptName" | ||
Process(cmd).lines.head.trim | ||
} | ||
|
||
/** Seven letters of the SHA hash is considered enough to uniquely identify a | ||
* commit, albeit extremely large projects - such as the Linux kernel - need | ||
* more letters to stay unique | ||
*/ | ||
def gitHash = executeScript("get-scala-commit-sha").substring(0, 7) | ||
def commitDate = executeScript("get-scala-commit-date") | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# Usage: get-scala-commit-date [dir] | ||
# Figures out current commit date of a git clone. | ||
# If no dir is given, current working dir is used. | ||
# | ||
# Example build version string: | ||
# 20120312 | ||
# | ||
|
||
[[ $# -eq 0 ]] || cd "$1" | ||
|
||
lastcommitdate=$(git log --format="%ci" HEAD | head -n 1 | cut -d ' ' -f 1) | ||
|
||
# 20120324 | ||
echo "${lastcommitdate//-/}" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
@echo off | ||
for %%X in (bash.exe) do (set FOUND=%%~$PATH:X) | ||
if defined FOUND ( | ||
bash "%~dp0\get-scala-commit-date" 2>NUL | ||
) else ( | ||
rem echo this script does not work with cmd.exe. please, install bash | ||
echo unknown | ||
exit 1 | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# Usage: get-scala-commit-sha [dir] | ||
# Figures out current commit sha of a git clone. | ||
# If no dir is given, current working dir is used. | ||
# | ||
# Example build version string: | ||
# 6f1c486d0ba | ||
# | ||
|
||
[[ $# -eq 0 ]] || cd "$1" | ||
|
||
# printf %016s is not portable for 0-padding, has to be a digit. | ||
# so we're stuck disassembling it. | ||
hash=$(git log -1 --format="%H" HEAD) | ||
hash=${hash#g} | ||
hash=${hash:0:10} | ||
echo "$hash" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
@echo off | ||
for %%X in (bash.exe) do (set FOUND=%%~$PATH:X) | ||
if defined FOUND ( | ||
bash "%~dp0\get-scala-commit-sha" 2>NUL | ||
) else ( | ||
rem echo this script does not work with cmd.exe. please, install bash | ||
echo unknown | ||
exit 1 | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,7 +60,11 @@ import printing.SyntaxHighlighting | |
* @param ictx The context to use for initialization of the interpreter, | ||
* needed to access the current classpath. | ||
*/ | ||
class CompilingInterpreter(out: PrintWriter, ictx: Context) extends Compiler with Interpreter { | ||
class CompilingInterpreter( | ||
out: PrintWriter, | ||
ictx: Context, | ||
parentClassLoader: Option[ClassLoader] | ||
) extends Compiler with Interpreter { | ||
import ast.untpd._ | ||
import CompilingInterpreter._ | ||
|
||
|
@@ -136,8 +140,6 @@ class CompilingInterpreter(out: PrintWriter, ictx: Context) extends Compiler wit | |
/** the compiler's classpath, as URL's */ | ||
val compilerClasspath: List[URL] = ictx.platform.classPath(ictx).asURLs | ||
|
||
protected def parentClassLoader: ClassLoader = classOf[Interpreter].getClassLoader | ||
|
||
/* A single class loader is used for all commands interpreted by this Interpreter. | ||
It would also be possible to create a new class loader for each command | ||
to interpret. The advantages of the current approach are: | ||
|
@@ -153,8 +155,10 @@ class CompilingInterpreter(out: PrintWriter, ictx: Context) extends Compiler wit | |
*/ | ||
/** class loader used to load compiled code */ | ||
val classLoader: ClassLoader = { | ||
val parent = new URLClassLoader(compilerClasspath.toArray, parentClassLoader) | ||
new AbstractFileClassLoader(virtualDirectory, parent) | ||
lazy val parent = new URLClassLoader(compilerClasspath.toArray, | ||
classOf[Interpreter].getClassLoader) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question - I think this was originally written by @odersky |
||
|
||
new AbstractFileClassLoader(virtualDirectory, parentClassLoader.getOrElse(parent)) | ||
} | ||
|
||
// Set the current Java "context" class loader to this interpreter's class loader | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you figure out what this method is for? Could you add a comment explaining why it makes sense to return just
args
here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the scalac version it looks like it's just setting up the state of the compiler during this method call. Not sure if that makes sense for dotty...