Skip to content

Commit

Permalink
Merge pull request #175 from szeiger/scala-2.12
Browse files Browse the repository at this point in the history
Scala 2.12 support
  • Loading branch information
2m authored Jun 13, 2017
2 parents 6ed4655 + af7ba7d commit 412dd4a
Show file tree
Hide file tree
Showing 15 changed files with 141 additions and 70 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ env:
- TEST_COMMAND="-Dmima.testScalaVersion=2.11.8 testFunctional"
- TEST_COMMAND="-Dmima.testScalaVersion=2.12.1 testFunctional"
- TEST_COMMAND="it:test"
- TEST_COMMAND="-Dmima.buildScalaVersion=2.12.2 testFunctional"
- TEST_COMMAND="-Dmima.buildScalaVersion=2.12.2 it:test"
# "test" and "scripted" require the plugin, which cannot yet be compiled on 2.12

script:
- sbt $TEST_COMMAND
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,3 @@ class PathResolver(settings: Settings) extends scala.tools.util.PathResolver(set
}

object DefaultJavaContext extends ClassPath.JavaContext


Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.typesafe.tools.mima

import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.util.{ClassPath, DirectoryClassPath, JavaClassPath}

package object core {
type ProblemFilter = (Problem) => Boolean
type CompilerClassPath = scala.tools.nsc.util.ClassPath[AbstractFile]

def resolveClassPath(): CompilerClassPath =
new PathResolver(Config.settings).mimaResult

def definitionsPackageInfo(defs: Definitions): ConcretePackageInfo =
new ConcretePackageInfo(null,
new JavaClassPath(
if (defs.lib.isDefined) Vector(defs.lib.get, defs.classPath)
else Vector(defs.classPath), DefaultJavaContext),
"",
defs)

def asClassPathString(cp: CompilerClassPath): String = cp.asClasspathString

def classFilesFrom(cp: CompilerClassPath, pkg: String): IndexedSeq[AbstractFile] =
cp.classes flatMap (_.binary)

def packagesFrom(cp: CompilerClassPath, owner: ConcretePackageInfo): Seq[(String, PackageInfo)] =
(cp.packages map (cp => cp.name -> new ConcretePackageInfo(owner, cp, owner.pkg + "." + cp.name, owner.defs)))

def definitionsTargetPackages(pkg: PackageInfo, cp: CompilerClassPath, defs: Definitions): Seq[(String, PackageInfo)] =
cp.packages.map(p => p.name -> new ConcretePackageInfo(pkg, p, p.name, defs))

def baseClassPath(cpString: String): CompilerClassPath =
new JavaClassPath(ClassPath.DefaultJavaContext.classesInPath(cpString).toIndexedSeq, ClassPath.DefaultJavaContext)

def reporterClassPath(classpath: String): CompilerClassPath =
new JavaClassPath(DefaultJavaContext.classesInPath(classpath).toIndexedSeq, DefaultJavaContext)

def dirClassPath(dir: AbstractFile): CompilerClassPath =
new DirectoryClassPath(dir, DefaultJavaContext)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.typesafe.tools.mima

import scala.tools.nsc.util.ClassPath
import scala.tools.nsc.classpath.{AggregateClassPath, ClassPathFactory}
import scala.tools.nsc.io.AbstractFile
import scala.tools.util.PathResolver
import scala.tools.nsc.mima.ClassPathAccessors

package object core {
type ProblemFilter = (Problem) => Boolean
type CompilerClassPath = ClassPath

def resolveClassPath(): CompilerClassPath =
AggregateClassPath.createAggregate(new PathResolver(Config.settings).containers: _*)

def definitionsPackageInfo(defs: Definitions): ConcretePackageInfo = {
val elems = defs.lib.toList :+ defs.classPath
new ConcretePackageInfo(
null,
AggregateClassPath.createAggregate(elems: _*),
ClassPath.RootPackage,
defs)
}

def asClassPathString(cp: CompilerClassPath): String = cp.asClassPathString

def classFilesFrom(cp: CompilerClassPath, pkg: String): IndexedSeq[AbstractFile] =
cp.classesIn(pkg).flatMap(_.binary).toIndexedSeq

def packagesFrom(cp: CompilerClassPath, owner: ConcretePackageInfo): Seq[(String, PackageInfo)] =
(cp.packagesIn(owner.pkg) map (p => p.name -> new ConcretePackageInfo(owner, cp, owner.pkg + p.name, owner.defs)))

def definitionsTargetPackages(pkg: PackageInfo, cp: CompilerClassPath, defs: Definitions): Seq[(String, PackageInfo)] =
cp.packagesIn(ClassPath.RootPackage).map(p => p.name -> new ConcretePackageInfo(pkg, cp, p.name, defs))

def baseClassPath(cpString: String): CompilerClassPath =
AggregateClassPath.createAggregate(new ClassPathFactory(Config.settings).classesInPath(cpString): _*)

def reporterClassPath(classpath: String): CompilerClassPath = AggregateClassPath.createAggregate(
new ClassPathFactory(Config.settings).classesInPath(classpath): _*)

def dirClassPath(dir: AbstractFile): CompilerClassPath =
ClassPathFactory.newClassPath(dir, Config.settings)
}
13 changes: 13 additions & 0 deletions core/src/main/scala-2.12/scala/tools/nsc/mima/package.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package scala.tools.nsc

import scala.tools.nsc.util.ClassPath

/**
* Some extension methods to allow accessing private[nsc] members of ClassPath.
*/
package object mima {
implicit class ClassPathAccessors(val cp: ClassPath) extends AnyVal {
def classesIn(pkg: String) = cp.classes(pkg)
def packagesIn(pkg: String) = cp.packages(pkg)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ object ClassInfo {
lazy val ObjectClass = Config.baseDefinitions.ObjectClass
}

import com.typesafe.tools.mima.core.util.log.{ConsoleLogging, Logging}

/** A placeholder class info for a class that is not found on the classpath or in a given
* package.
*/
Expand Down
17 changes: 4 additions & 13 deletions core/src/main/scala/com/typesafe/tools/mima/core/Config.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package com.typesafe.tools.mima.core

import scala.tools.nsc.io.{ Path, Directory }
import scala.tools.nsc.util.JavaClassPath
import scala.util.Properties
import java.io.File
import scala.tools.nsc.io.{Directory, Path}

object Config {

private var settings: Settings = _
private var _classpath: JavaClassPath = _
var settings: Settings = _
var baseClassPath: CompilerClassPath = _

def inPlace = settings.mimaOutDir.isDefault

Expand All @@ -19,14 +16,8 @@ object Config {

def error(msg: String) = System.err.println(msg)

def baseClassPath: JavaClassPath = _classpath

lazy val baseDefinitions = new Definitions(None, baseClassPath)

def baseClassPath_=(cp: JavaClassPath) {
_classpath = cp
}

def fatal(msg: String): Nothing = {
error(msg)
System.exit(-1)
Expand Down Expand Up @@ -56,7 +47,7 @@ object Config {
def setup(cmd: String, args: Array[String], validate: List[String] => Boolean, specificOptions: String*): List[String] = {
settings = new Settings(specificOptions: _*)
val (_, resargs) = settings.processArguments(args.toList, true)
baseClassPath = new PathResolver(settings).mimaResult
baseClassPath = resolveClassPath()
if (settings.help.value) {
println(usageMsg(cmd))
System.exit(0)
Expand Down
16 changes: 5 additions & 11 deletions core/src/main/scala/com/typesafe/tools/mima/core/Definitions.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.typesafe.tools.mima.core

import scala.tools.nsc.util.{ClassPath, JavaClassPath, DirectoryClassPath}


/** This class holds together a root package and a classpath. It
* also offers definitions of commonly used classes, including
Expand All @@ -10,14 +8,10 @@ import scala.tools.nsc.util.{ClassPath, JavaClassPath, DirectoryClassPath}
* Each version of the input jar file has an instance of Definitions, used
* to resolve type names during classfile parsing.
*/
class Definitions(val lib: Option[DirectoryClassPath], val classPath: JavaClassPath) {
class Definitions(val lib: Option[CompilerClassPath], val classPath: CompilerClassPath) {
import com.typesafe.tools.mima.core.util.log.ConsoleLogging._

lazy val root =
new ConcretePackageInfo(null,
new JavaClassPath(
if (lib.isDefined) Vector(lib.get, classPath)
else Vector(classPath), DefaultJavaContext), this)
lazy val root = definitionsPackageInfo(this)

/** Return all packages in the target library. */
lazy val targetPackage: PackageInfo = {
Expand All @@ -26,8 +20,8 @@ class Definitions(val lib: Option[DirectoryClassPath], val classPath: JavaClassP
/** Needed to fetch classes located in the root (empty package) */
override lazy val classes = Definitions.this.root.classes
}
pkg.packages ++= lib.get.packages map (cp => cp.name -> new ConcretePackageInfo(pkg, cp, this))

val cp = lib.get
pkg.packages ++= definitionsTargetPackages(pkg, cp, this)
debugLog("added packages to <root>: %s".format(pkg.packages.keys.mkString(", ")))
pkg
}
Expand Down Expand Up @@ -100,6 +94,6 @@ class Definitions(val lib: Option[DirectoryClassPath], val classPath: JavaClassP
}

override def toString = {
"definitions:\n\tlib: %s\n%s".format(lib, classPath.asClasspathString)
"definitions:\n\tlib: %s\n%s".format(lib, asClassPathString(classPath))
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.typesafe.tools.mima.core

import scala.collection.mutable
import scala.annotation.tailrec
import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.util.ClassPath
import collection.mutable

object PackageInfo {
val classExtension = ".class"
Expand All @@ -20,7 +19,7 @@ object PackageInfo {
}
}

import PackageInfo._
import com.typesafe.tools.mima.core.PackageInfo._

class SyntheticPackageInfo(owner: PackageInfo, val name: String) extends PackageInfo(owner) {
def definitions: Definitions = sys.error("Called definitions on synthetic package")
Expand All @@ -32,13 +31,13 @@ object NoPackageInfo extends SyntheticPackageInfo(null, "<no package>")

/** A concrete package. cp should be a directory classpath.
*/
class ConcretePackageInfo(owner: PackageInfo, cp: ClassPath[AbstractFile], val defs: Definitions) extends PackageInfo(owner) {
class ConcretePackageInfo(owner: PackageInfo, cp: CompilerClassPath, val pkg: String, val defs: Definitions) extends PackageInfo(owner) {
def definitions = defs
def name = cp.name
private def classFiles: IndexedSeq[AbstractFile] = cp.classes flatMap (_.binary)
def name = pkg.split('.').last
private def classFiles: IndexedSeq[AbstractFile] = classFilesFrom(cp, pkg)

lazy val packages: mutable.Map[String, PackageInfo] =
mutable.Map() ++= (cp.packages map (cp => cp.name -> new ConcretePackageInfo(this, cp, defs)))
mutable.Map() ++= packagesFrom(cp, this)

lazy val classes: mutable.Map[String, ClassInfo] =
mutable.Map() ++= (classFiles map (f => className(f.name) -> new ConcreteClassInfo(this, f)))
Expand All @@ -65,7 +64,7 @@ abstract class PackageInfo(val owner: PackageInfo) {
def classes: mutable.Map[String, ClassInfo]

lazy val accessibleClasses: Set[ClassInfo] = {
/** Fixed point iteration for finding all accessible classes. */
/* Fixed point iteration for finding all accessible classes. */
@tailrec
def accessibleClassesUnder(prefix: Set[ClassInfo], found: Set[ClassInfo]): Set[ClassInfo] = {
val vclasses = (classes.valuesIterator.filter(isAccessible(_, prefix))).toSet
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ object BuildSettings {

val commonSettings = Defaults.coreDefaultSettings ++ Seq (
organization := buildOrganization,
scalaVersion := "2.10.6",
scalaVersion := sys.props.getOrElse("mima.buildScalaVersion", "2.10.6"),
git.gitTagToVersionNumber := { tag: String =>
if(tag matches "[0.9]+\\..*") Some(tag)
else None
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.typesafe.tools.mima.lib

import com.typesafe.tools.mima.core.Config
import com.typesafe.tools.mima.core.{asClassPathString, baseClassPath}
import java.io.{BufferedInputStream, File, FileInputStream}

import com.typesafe.config.ConfigFactory
import com.typesafe.tools.mima.cli.ProblemFiltersConfig
import com.typesafe.tools.mima.core.{Config, PathResolver, Settings}
import com.typesafe.tools.mima.core.Config

import scala.io.Source
import scala.tools.nsc.util._
Expand All @@ -16,9 +18,9 @@ class CollectProblemsTest {
def runTest(testClasspath: Array[String])(testName: String, oldJarPath: String, newJarPath: String, oraclePath: String, filterPath: String) {
// load test setup
Config.setup("scala com.typesafe.tools.mima.MiMaLibUI <old-dir> <new-dir>", Array(oldJarPath, newJarPath))
val cp = testClasspath ++ ClassPath.split(Config.baseClassPath.asClasspathString)
val cp = testClasspath ++ ClassPath.split(asClassPathString(Config.baseClassPath))
val cpString = ClassPath.join(cp: _*)
Config.baseClassPath = new JavaClassPath(ClassPath.DefaultJavaContext.classesInPath(cpString).toIndexedSeq, ClassPath.DefaultJavaContext)
Config.baseClassPath = baseClassPath(cpString)

val mima = new MiMaLib(Config.baseClassPath)

Expand Down
14 changes: 6 additions & 8 deletions reporter/src/main/scala/com/typesafe/tools/mima/cli/Main.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.typesafe.tools.mima
package cli

import lib.MiMaLib
import scala.tools.cmd._
import scala.tools.nsc.util.{JavaClassPath,ClassPath}
import ClassPath.DefaultJavaContext
import core.{Config, ProblemFilter}
import java.io.File

import com.typesafe.tools.mima.core.{Config, ProblemFilter}
import com.typesafe.tools.mima.lib.MiMaLib

import scala.tools.cmd._

/** A program to run the MIMA tools from the command line.
*/
trait MimaSpec extends Spec with Meta.StdOpts with Interpolation {
Expand Down Expand Up @@ -54,9 +54,7 @@ class Main(args: List[String]) extends {

def isDefined: Boolean = !(curr.isEmpty || prev.isEmpty)

def makeClasspath = new JavaClassPath(
// TODO expand path?
DefaultJavaContext.classesInPath(classpath).toIndexedSeq, DefaultJavaContext)
def makeClasspath = com.typesafe.tools.mima.core.reporterClassPath(classpath) // TODO expand path?

def makeMima = {
// TODO: get mima to use paul's CMD library *or*
Expand Down
19 changes: 8 additions & 11 deletions reporter/src/main/scala/com/typesafe/tools/mima/lib/MiMaLib.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@ package com.typesafe.tools.mima.lib

import com.typesafe.tools.mima.core.Config._
import com.typesafe.tools.mima.core._
import com.typesafe.tools.mima._
import analyze.Analyzer
import core.util.IndentedOutput._
import scala.tools.nsc.io.{ File, AbstractFile }
import scala.tools.nsc.util.{ DirectoryClassPath, JavaClassPath}
import collection.mutable.ListBuffer
import com.typesafe.tools.mima.core.util.IndentedOutput._
import com.typesafe.tools.mima.core.util.log.{ConsoleLogging, Logging}
import com.typesafe.tools.mima.lib.analyze.Analyzer

import scala.collection.mutable.ListBuffer
import scala.tools.nsc.io.{AbstractFile, File}

import com.typesafe.tools.mima.core.util.log.{Logging, ConsoleLogging}

class MiMaLib(classpath: JavaClassPath, val log: Logging = ConsoleLogging) {
class MiMaLib(classpath: CompilerClassPath, val log: Logging = ConsoleLogging) {
/*
options:
-classpath foo
Expand All @@ -26,7 +23,7 @@ class MiMaLib(classpath: JavaClassPath, val log: Logging = ConsoleLogging) {
val f = new File(new java.io.File(name))
val dir = AbstractFile.getDirectory(f)
if (dir == null) None
else Some(new DirectoryClassPath(dir, DefaultJavaContext))
else Some(dirClassPath(dir))
}

private def root(name: String): Definitions = classPath(name) match {
Expand Down Expand Up @@ -79,7 +76,7 @@ class MiMaLib(classpath: JavaClassPath, val log: Logging = ConsoleLogging) {
val newRoot = root(newDir)
log.debugLog("[old version in: " + oldRoot + "]")
log.debugLog("[new version in: " + newRoot + "]")
log.debugLog("classpath: " + Config.baseClassPath.asClasspathString)
log.debugLog("classpath: " + asClassPathString(Config.baseClassPath))
traversePackages(oldRoot.targetPackage, newRoot.targetPackage)
problems.toList
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.typesafe.tools.mima
package plugin

import sbt._
import sbt.Keys.TaskStreams
import com.typesafe.tools.mima.core.Config
import com.typesafe.tools.mima.core.util.log.Logging
import scala.tools.nsc.util.JavaClassPath
import scala.tools.nsc.util.DirectoryClassPath
import sbt.Keys.TaskStreams
import sbt._

import scala.util.Try
import core.DefaultJavaContext

/** Wrapper on SBT logging for MiMa */
class SbtLogger(s: TaskStreams) extends Logging {
Expand All @@ -24,7 +23,7 @@ object SbtMima {
// TODO: Fix MiMa so we don't have to hack this bit in.
core.Config.setup("sbt-mima-plugin", Array.empty)
val cpstring = cp map (_.data.getAbsolutePath()) mkString System.getProperty("path.separator")
val classpath = new JavaClassPath(DefaultJavaContext.classesInPath(cpstring).toIndexedSeq, DefaultJavaContext)
val classpath = com.typesafe.tools.mima.core.reporterClassPath(cpstring)
new lib.MiMaLib(classpath, new SbtLogger(s))
}

Expand Down

0 comments on commit 412dd4a

Please sign in to comment.