Skip to content

Commit

Permalink
Lots of changed to make things cross-build with Scala 2.12
Browse files Browse the repository at this point in the history
wip conversion for 2.12 compatibility; not done yet

REPL compiles and runs, tests still red

patch VirtualDirectoryClassPath to override borked methods to fix compilation problems, and skip tests relying on libraries missing for 2.12

break out global-instantiation logic into scalaversion-dependant code, since the way we inject the classpath into the global changed in 2.12

fix more tests, enable travis build for 2.12

cleanup

fix

fix readme build

add scala 2.12 to build.sc

fix build.sc executable generation

try to force assembly generation before building readme

tweak doc publishing script again...
  • Loading branch information
lihaoyi committed Nov 20, 2016
1 parent 1de96ff commit 057440b
Show file tree
Hide file tree
Showing 28 changed files with 370 additions and 160 deletions.
7 changes: 7 additions & 0 deletions .travis.yml
Expand Up @@ -17,6 +17,13 @@ matrix:
# `integration/test`; for some reason, running them on the same box is
# flaky and `integration/test` ends up hanging, even if they are run in
# separate, sequential processes.
- env: CI_SCRIPT="ci/build.sc test published/test"
jdk: oraclejdk8
scala: 2.12.0
- env: CI_SCRIPT="ci/build.sc test integration/test"
jdk: oraclejdk8
scala: 2.12.0

- env: CI_SCRIPT="ci/build.sc test published/test"
jdk: oraclejdk8
scala: 2.11.8
Expand Down
Expand Up @@ -24,4 +24,5 @@ object CompilerCompatibility {
plugin.processOptions(options, error)
true
}

}
@@ -0,0 +1,124 @@
package ammonite.runtime

import ammonite.util.ImportData

import scala.reflect.internal.util.Position
import scala.reflect.io
import scala.reflect.io.{AbstractFile, FileZipArchive, VirtualDirectory}
import scala.tools.nsc.{Global, Settings}
import scala.tools.nsc.interactive.{Global => InteractiveGlobal}
import scala.tools.nsc.plugins.Plugin
import scala.tools.nsc.reporters.AbstractReporter
import scala.tools.nsc.typechecker.Analyzer
import scala.tools.nsc.util.ClassPath.JavaContext
import scala.tools.nsc.util._
import scala.reflect.io._
import scala.tools.nsc
import scala.tools.nsc.backend.JavaPlatform
object GlobalInitCompat {
def initInteractiveGlobal(settings: Settings,
reporter: AbstractReporter,
jcp: JavaClassPath,
evalClassloader: ClassLoader) = {
new nsc.interactive.Global(settings, reporter) { g =>
// Actually jcp, avoiding a path-dependent type issue in 2.10 here
override def classPath = platform.classPath

override lazy val platform: ThisPlatform = new JavaPlatform {
val global: g.type = g

override def classPath = jcp
}
override lazy val analyzer = CompilerCompatibility.interactiveAnalyzer(g, evalClassloader)
}
}
def initGlobal(settings: Settings,
reporter: AbstractReporter,
plugins0: Vector[(String, Class[_])],
jcp: JavaClassPath,
evalClassloader: ClassLoader,
importsLen: => Int,
updateLastImports: Seq[ImportData] => Unit): nsc.Global = {
new nsc.Global(settings, reporter) { g =>
override lazy val plugins = List(new AmmonitePlugin(g, updateLastImports, importsLen)) ++ {
for {
(name, cls) <- plugins0
plugin = Plugin.instantiate(cls, g)
initOk =
try CompilerCompatibility.pluginInit(plugin, Nil, g.globalError)
catch { case ex: Exception =>
Console.err.println(s"Warning: disabling plugin $name, initialization failed: $ex")
false
}
if initOk
} yield plugin
}

// Actually jcp, avoiding a path-dependent type issue in 2.10 here
override def classPath = platform.classPath
val x = new JavaPlatform{
val global: g.type = g
override def classPath = jcp
}
override lazy val platform: ThisPlatform = x

override lazy val analyzer = CompilerCompatibility.analyzer(g, evalClassloader)
}
}
/**
* Code to initialize random bits and pieces that are needed
* for the Scala compiler to function, common between the
* normal and presentation compiler
*/
def initGlobalBits(classpath: Seq[java.io.File],
dynamicClasspath: VirtualDirectory,
errorLogger: => String => Unit,
warningLogger: => String => Unit,
infoLogger: => String => Unit,
settings: Settings) = {
val vd = new io.VirtualDirectory("(memory)", None)
val settingsX = settings
val jCtx = new JavaContext()
val (dirDeps, jarDeps) = classpath.partition(_.isDirectory)

val jarCP =
jarDeps.filter(x => x.getName.endsWith(".jar") || Classpath.canBeOpenedAsJar(x))
.map(x => new DirectoryClassPath(new FileZipArchive(x), jCtx))
.toVector

val dirCP =
dirDeps.map(x => new DirectoryClassPath(new PlainDirectory(new Directory(x)), jCtx))

val dynamicCP = Seq(new DirectoryClassPath(dynamicClasspath, jCtx))
val jcp = new JavaClassPath(jarCP ++ dirCP ++ dynamicCP, jCtx)

if (Classpath.traceClasspathIssues) {
settings.Ylogcp.value = true
println("jardeps")
jarDeps.foreach(p => println(s"${p.getName.takeRight(4)} $p"))
println("finished")
}

settings.outputDirs.setSingleOutput(vd)

settings.nowarnings.value = true
val reporter = new AbstractReporter {
def displayPrompt(): Unit = ???

def display(pos: Position, msg: String, severity: Severity) = {
severity match{
case ERROR =>
Classpath.traceClasspathProblem(s"ERROR: $msg")
errorLogger(Position.formatMessage(pos, msg, false))
case WARNING =>
warningLogger(Position.formatMessage(pos, msg, false))
case INFO =>
infoLogger(Position.formatMessage(pos, msg, false))
}
}

val settings = settingsX
}
(reporter, vd, jcp)
}
}
@@ -1,5 +1,6 @@
package ammonite.runtime


import scala.tools.nsc.Global
import scala.tools.nsc.interactive.{ Global => InteractiveGlobal }
import scala.tools.nsc.plugins.Plugin
Expand All @@ -24,4 +25,5 @@ object CompilerCompatibility {

def pluginInit(plugin: Plugin, options: List[String], error: String => Unit): Boolean =
plugin.init(options, error)

}
@@ -1,8 +1,17 @@
package ammonite.runtime

import scala.tools.nsc.Global
import scala.tools.nsc.interactive.{ Global => InteractiveGlobal }
import ammonite.util.ImportData

import scala.reflect.internal.util.Position
import scala.reflect.io
import scala.reflect.io.{AbstractFile, FileZipArchive, VirtualDirectory}
import scala.tools.nsc
import scala.tools.nsc.backend.JavaPlatform
import scala.tools.nsc.classpath._
import scala.tools.nsc.{Global, Settings}
import scala.tools.nsc.interactive.{Global => InteractiveGlobal}
import scala.tools.nsc.plugins.Plugin
import scala.tools.nsc.reporters.AbstractReporter
import scala.tools.nsc.typechecker.Analyzer

object CompilerCompatibility {
Expand All @@ -24,4 +33,128 @@ object CompilerCompatibility {

def pluginInit(plugin: Plugin, options: List[String], error: String => Unit): Boolean =
plugin.init(options, error)

}
object GlobalInitCompat{
def initInteractiveGlobal(settings: Settings,
reporter: AbstractReporter,
jcp: AggregateClassPath,
evalClassloader: ClassLoader) = {
new nsc.interactive.Global(settings, reporter) { g =>
// Actually jcp, avoiding a path-dependent type issue in 2.10 here
override def classPath = jcp

override lazy val analyzer = CompilerCompatibility.interactiveAnalyzer(g, evalClassloader)
}
}
def initGlobal(settings: Settings,
reporter: AbstractReporter,
plugins0: Vector[(String, Class[_])],
jcp: AggregateClassPath,
evalClassloader: ClassLoader,
importsLen: => Int,
updateLastImports: Seq[ImportData] => Unit) = {
new nsc.Global(settings, reporter) { g =>
override lazy val plugins = List(new AmmonitePlugin(g, updateLastImports, importsLen)) ++ {
for {
(name, cls) <- plugins0
plugin = Plugin.instantiate(cls, g)
initOk =
try CompilerCompatibility.pluginInit(plugin, Nil, g.globalError)
catch { case ex: Exception =>
Console.err.println(s"Warning: disabling plugin $name, initialization failed: $ex")
false
}
if initOk
} yield plugin
}

// Actually jcp, avoiding a path-dependent type issue in 2.10 here
override def classPath = jcp

override lazy val analyzer = CompilerCompatibility.analyzer(g, evalClassloader)
}
}
/**
* Code to initialize random bits and pieces that are needed
* for the Scala compiler to function, common between the
* normal and presentation compiler
*/
def initGlobalBits(classpath: Seq[java.io.File],
dynamicClasspath: VirtualDirectory,
errorLogger: => String => Unit,
warningLogger: => String => Unit,
infoLogger: => String => Unit,
settings: Settings) = {
val vd = new io.VirtualDirectory("(memory)", None)
val settingsX = settings

val (dirDeps, jarDeps) = classpath.partition(_.isDirectory)

val jarCP =
jarDeps.filter(x => x.getName.endsWith(".jar") || Classpath.canBeOpenedAsJar(x))
.map(x => ZipAndJarClassPathFactory.create(new FileZipArchive(x), settingsX))
.toVector

val dirCP = dirDeps.map(x => new DirectoryClassPath(x))
val dynamicCP = new VirtualDirectoryClassPath(dynamicClasspath){

override def getSubDir(packageDirName: String): Option[AbstractFile] = {
val pathParts = packageDirName.split('/')
var file: AbstractFile = dir
for (dirPart <- pathParts) {
file = file.lookupName(dirPart, directory = true)
if (file == null) return None
}
Some(file)

}
override def findClassFile(className: String): Option[AbstractFile] = {
val relativePath = FileUtils.dirPath(className)
val pathParts = relativePath.split('/')
var file: AbstractFile = dir
for (dirPart <- pathParts.init) {
file = file.lookupName(dirPart, directory = true)
if (file == null) return None
}

file.lookupName(pathParts.last + ".class", directory = false) match {
case null => None
case file => Some(file)
}
}

}

val jcp = new AggregateClassPath(jarCP ++ dirCP ++ Seq(dynamicCP))

if (Classpath.traceClasspathIssues) {
settings.Ylogcp.value = true
println("jardeps")
jarDeps.foreach(p => println(s"${p.getName.takeRight(4)} $p"))
println("finished")
}

settings.outputDirs.setSingleOutput(vd)

settings.nowarnings.value = true
val reporter = new AbstractReporter {
def displayPrompt(): Unit = ???

def display(pos: Position, msg: String, severity: Severity) = {
severity match{
case ERROR =>
Classpath.traceClasspathProblem(s"ERROR: $msg")
errorLogger(Position.formatMessage(pos, msg, false))
case WARNING =>
warningLogger(Position.formatMessage(pos, msg, false))
case INFO =>
infoLogger(Position.formatMessage(pos, msg, false))
}
}

val settings = settingsX
}
(reporter, vd, jcp)
}
}

0 comments on commit 057440b

Please sign in to comment.