Skip to content

Commit

Permalink
Support for Scala 2.13.0 (#972)
Browse files Browse the repository at this point in the history
* .

* .

* .

* wip

* update travis

* tweak appveyor

* mill 041

* wrap-lines

* Fix already added deps file generation

Must have been broken by bumping the coursier version in the build via
mill.

* 2.13.0-M5 -> 2.13.0 in .travis.yml

* bump scalatags version

* fix-tests

* fix

* fix

* tweak

* readme

* workaround for scala/bug#11564

* 1.6.8

.
  • Loading branch information
lihaoyi authored Jun 14, 2019
1 parent c28002d commit c684363
Show file tree
Hide file tree
Showing 35 changed files with 276 additions and 222 deletions.
16 changes: 3 additions & 13 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ install:
matrix:
include:

- stage: build
env: CI_SCRIPT="mill -i unitTest"
jdk: oraclejdk8
scala: 2.11.12

- stage: build
env: CI_SCRIPT="mill -i unitTest"
jdk: openjdk11
Expand All @@ -26,12 +21,7 @@ matrix:
- stage: build
env: CI_SCRIPT="mill -i unitTest"
jdk: oraclejdk8
scala: 2.13.0-M5

- stage: build
env: CI_SCRIPT="mill -i integrationTest"
jdk: oraclejdk8
scala: 2.11.12
scala: 2.13.0

- stage: build
env: CI_SCRIPT="mill -i integrationTest"
Expand All @@ -46,7 +36,7 @@ matrix:
- stage: build
env: CI_SCRIPT="mill -i integrationTest"
jdk: oraclejdk8
scala: 2.13.0-M5
scala: 2.13.0


# Everything worked, *then* kick off a release
Expand Down Expand Up @@ -82,7 +72,7 @@ script:
- export PATH=~/bin/amm:~/bin/mill:$PATH
- mkdir -p ~/bin
# We use 2.11 since we need to run tests on Java 7
- if [ ! -f ~/bin/mill-0.3.3 ]; then sudo sh -c '(echo "#!/usr/bin/env sh" && curl -L https://github.com/lihaoyi/mill/releases/download/0.3.3/0.3.3) > ~/bin/mill-0.3.3 && chmod +x ~/bin/mill-0.3.3 && ( cd ~/bin && rm -f mill && ln -s mill-0.3.3 mill)'; fi
- if [ ! -f ~/bin/mill-0.4.1 ]; then sudo sh -c '(echo "#!/usr/bin/env sh" && curl -L https://github.com/lihaoyi/mill/releases/download/0.4.1/0.4.1) > ~/bin/mill-0.4.1 && chmod +x ~/bin/mill-0.4.1 && ( cd ~/bin && rm -f mill && ln -s mill-0.4.1 mill)'; fi
- JAVAOPTS="-Xmx2048m" $CI_SCRIPT

notifications:
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package ammonite.interp

import ammonite.runtime.Classpath

import scala.reflect.io.{AbstractFile, FileZipArchive, VirtualDirectory}
import scala.tools.nsc
import scala.tools.nsc.classpath._
import scala.tools.nsc.{CustomZipAndJarFileLookupFactory, 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.{CustomZipAndJarFileLookupFactory, Global, Settings}

object GlobalInitCompat{

Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
package ammonite.interp


import scala.tools.nsc.Global
import scala.tools.nsc.interactive.{ Global => InteractiveGlobal }
import scala.tools.nsc.interactive.{Global => InteractiveGlobal}
import scala.tools.nsc.plugins.Plugin
import scala.tools.nsc.typechecker.Analyzer

object CompilerCompatibility extends ExtraCompilerCompatibility {
def newUnitParser(compiler: Global, line: String, fileName: String) = {
compiler.newUnitParser(line, fileName)
}
def analyzer(g: Global, cl: ClassLoader): Analyzer { val global: g.type } =
def analyzer(g: Global, cl: ClassLoader): Analyzer { val global: g.type } = {
new { val global: g.type = g } with Analyzer {
override def findMacroClassLoader() = cl
override def defaultMacroClassloader = global.findMacroClassLoader
}
}

type InteractiveAnalyzer = scala.tools.nsc.interactive.InteractiveAnalyzer

def interactiveAnalyzer(g: InteractiveGlobal, cl: ClassLoader)
: InteractiveAnalyzer { val global: g.type } =
def interactiveAnalyzer(g: InteractiveGlobal,
cl: ClassLoader): InteractiveAnalyzer { val global: g.type } = {
new { val global: g.type = g } with InteractiveAnalyzer {
override def findMacroClassLoader() = cl
}
}

def trees(g: Global)(parser: g.syntaxAnalyzer.UnitParser): Seq[Global#Tree] =
def trees(g: Global)(parser: g.syntaxAnalyzer.UnitParser): Seq[Global#Tree] = {
parser.parseStatsOrPackages()
}

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

}
}
112 changes: 112 additions & 0 deletions amm/interp/src/main/scala-2.13/ammonite/interp/GlobalInitCompat.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package ammonite.interp

import ammonite.runtime.Classpath
import scala.reflect.io.{AbstractFile, FileZipArchive, VirtualDirectory}
import scala.tools.nsc
import scala.tools.nsc.classpath._
import scala.tools.nsc.{CustomZipAndJarFileLookupFactory, Global, Settings}
import scala.tools.nsc.interactive.{Global => InteractiveGlobal}
import scala.tools.nsc.plugins.Plugin
import scala.tools.nsc.reporters.AbstractReporter

object GlobalInitCompat{

def initInteractiveGlobal(settings: Settings,
reporter: AbstractReporter,
jcp: AggregateClassPath,
evalClassloader: ClassLoader): InteractiveGlobal = {
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 platform: ThisPlatform = new GlobalPlatform {
override val global = g
override val settings = g.settings
override val classPath = jcp
}

override lazy val analyzer = CompilerCompatibility.interactiveAnalyzer(g, evalClassloader)
}
}

def initGlobal(settings: Settings,
reporter: AbstractReporter,
jcp: AggregateClassPath,
evalClassloader: ClassLoader,
createPlugins: Global => List[Plugin]): Global = {

new nsc.Global(settings, reporter) { g =>
override lazy val plugins = createPlugins(g)

// Actually jcp, avoiding a path-dependent type issue in 2.10 here
override def classPath = jcp
override def findMacroClassLoader() = evalClassloader
override lazy val platform: ThisPlatform = new GlobalPlatform {
override val global = g
override val settings = g.settings
override val 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 initGlobalClasspath(dirDeps: Seq[java.io.File],
jarDeps: Seq[java.net.URL],
dynamicClasspath: VirtualDirectory,
settings: Settings) = {

val jarCP =
jarDeps.filter(x => x.getPath.endsWith(".jar") || Classpath.canBeOpenedAsJar(x))
.map { x =>
if (x.getProtocol == "file") {
val arc = new FileZipArchive(java.nio.file.Paths.get(x.toURI).toFile)
ZipAndJarClassPathFactory.create(arc, settings, new scala.tools.nsc.CloseableRegistry())
} else {
val arc = new internal.CustomURLZipArchive(x)
CustomZipAndJarFileLookupFactory.create(arc, settings)
}
}
.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))


jcp
}
}
5 changes: 5 additions & 0 deletions amm/interp/src/main/scala/ammonite/interp/Interpreter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ class Interpreter(val printer: Printer,
source: CodeSource,
wrapperPath: Seq[Name]): Res[ImportHookInfo] = synchronized{

// Fake an update to the classpath to force re-creation of the compiler
// Workaround for https://github.com/scala/bug/issues/11564#issuecomment-501834821,
// which I caused in 2.13.0 and should be fixed in 2.13.1
if (scala.util.Properties.versionNumberString == "2.13.0") headFrame.addClasspath(Nil)

for (hookImports <- Res.map(importTrees)(resolveSingleImportHook(source, _, wrapperPath)))
yield ImportHookInfo(
Imports(hookImports.flatten.flatMap(_.value)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ object CustomZipAndJarFileLookupFactory {
def zipFile: File = null

override def asURLs: Seq[URL] = Seq(zipUrl)

override def asClassPathStrings: Seq[String] = Seq(zipUrl.toURI.toASCIIString) // ???

private val archive = new CustomURLZipArchive(zipUrl)
Expand All @@ -51,6 +52,7 @@ object CustomZipAndJarFileLookupFactory {
} yield createFileEntry(entry)

def hasPackage(pkg: String) = findDirEntry(pkg).isDefined

override private[nsc] def list(inPackage: String): ClassPathEntries = {
val foundDirEntry = findDirEntry(inPackage)

Expand All @@ -76,6 +78,7 @@ object CustomZipAndJarFileLookupFactory {
val (pkg, simpleClassName) = PackageNameUtils.separatePkgAndClassNames(className)
file(pkg, simpleClassName + ".class").map(_.file)
}

// This method is performance sensitive as it is used by SBT's ExtractDependencies phase.
override def findClass(className: String): Option[ClassRepresentation] = {
val (pkg, simpleClassName) = PackageNameUtils.separatePkgAndClassNames(className)
Expand All @@ -87,6 +90,7 @@ object CustomZipAndJarFileLookupFactory {

protected def createFileEntry(file: CustomURLZipArchive#Entry): ClassFileEntryImpl =
ClassFileEntryImpl(file)

protected def isRequiredFileType(file: AbstractFile): Boolean =
!file.isDirectory && file.hasExtension("class")
}
Expand Down
2 changes: 1 addition & 1 deletion amm/repl/src/main/scala/ammonite/repl/FullReplAPI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ object FullReplAPI {
)
val output = mutable.Buffer.empty[fansi.Str]

prefix.foreach(output +=)
prefix.foreach(output += _)

val rhs = custom match {
case None =>
Expand Down
1 change: 1 addition & 0 deletions amm/repl/src/main/scala/ammonite/repl/Highlighter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ object Highlighter {
case "Interp" => reset
case "Comment" => comment
case "ExprLiteral" => literal
case "PatLiteral" => literal
case "TypeId" => `type`
case BackTicked(body)
if parse(body, scalaparse.syntax.Identifiers.AlphabetKeywords(_)).isSuccess => keyword
Expand Down
2 changes: 1 addition & 1 deletion amm/repl/src/main/scala/ammonite/repl/PPrints.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ object PPrints{
)
val snippets = for (p <- t) yield {
fansi.Str.join(
renderer.rec(relPathRepr(os.RelPath(p relativeTo t.base toString)), 0, 0)
renderer.rec(relPathRepr(os.RelPath(p.relativeTo(t.base).toString)), 0, 0)
.iter
.toStream:_*
)
Expand Down
Loading

0 comments on commit c684363

Please sign in to comment.