Skip to content

Commit

Permalink
Merge branch '1.0.x' into merge-1.0.x-into-1.x
Browse files Browse the repository at this point in the history
* 1.0.x: (28 commits)
  Split compiler bridge tests to another subproject
  Implement compiler bridge for 2.13.0-M2
  Add yourkit acknoledgement in the README
  "sbt '++ 2.13.0-M2!' compile" does not work with sbt 1.0.0
  Add header to cached hashing spec
  Add headers to missing files
  Fix scala#332: Add sbt-header back to the build
  Update sbt-scalafmt to 1.12
  Make classpath hashing more lightweight
  Fix scala#442: Name hash of value class should include underlying type
  source-dependencies/value-class-underlying: fix test
  Ignore null in generic lambda tparams
  Improve and make scripted parallel
  Fix scala#436: Remove annoying log4j scripted exception
  Fix scala#127: Use `unexpanded` name instead of `name`
  Add pending test case for issue/127
  source-dependencies / patMat-scope workaround
  Fixes undercompilation on inheritance on same source
  Add real reproduction case for sbt/zinc#417
  Add trait-trait-212 for Scala 2.12.3
  ...

 Conflicts:
	internal/zinc-apiinfo/src/main/scala/sbt/internal/inc/ClassToAPI.scala
	project/build.properties
	zinc/src/main/scala/sbt/internal/inc/MixedAnalyzingCompiler.scala

The ClassToAPI conflict is due to:
* sbt/zinc#393 (a 1.x PR), conflicting with
* sbt/zinc#446 (a 1.0.x PR).

The build.properties conflict is due to different PRs bumping
sbt.version from 1.0.0 to 1.0.2 to 1.0.3. (scala#413, scala#418, scala#453).

The MixedAnalyzingCompiler conflict is due to:
* sbt/zinc#427 (a 1.x PR), conflicting with
* sbt/zinc#452 (a 1.0.x PR).

Rewritten from sbt/zinc@e245d95
  • Loading branch information
dwijnand committed Nov 23, 2017
2 parents ccb8e34 + b359908 commit 4ff3d7b
Show file tree
Hide file tree
Showing 24 changed files with 302 additions and 1,474 deletions.
22 changes: 0 additions & 22 deletions src/main/java/xsbti/InteractiveConsoleFactory.java

This file was deleted.

13 changes: 0 additions & 13 deletions src/main/java/xsbti/InteractiveConsoleInterface.java

This file was deleted.

15 changes: 0 additions & 15 deletions src/main/java/xsbti/InteractiveConsoleResponse.java

This file was deleted.

14 changes: 0 additions & 14 deletions src/main/java/xsbti/InteractiveConsoleResult.java

This file was deleted.

6 changes: 6 additions & 0 deletions src/main/mima-filters/1.0.0.backwards.excludes
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# xsbti Java interfaces must be defined in the compiler interface, not the bridge.
# Bridge implementations are compiled per Zinc, so these are safe to change.
ProblemFilters.exclude[MissingClassProblem]("xsbti.InteractiveConsoleFactory")
ProblemFilters.exclude[MissingClassProblem]("xsbti.InteractiveConsoleResult")
ProblemFilters.exclude[MissingClassProblem]("xsbti.InteractiveConsoleInterface")
ProblemFilters.exclude[MissingClassProblem]("xsbti.InteractiveConsoleResponse")
8 changes: 6 additions & 2 deletions src/main/scala/xsbt/ClassName.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,19 @@ trait ClassName extends Compat {
*
* If `s` represents a package object `pkg3`, then the returned name will be `pkg1.pkg2.pkg3.package`.
* If `s` represents a class `Foo` nested in package object `pkg3` then the returned name is `pkg1.pkg2.pk3.Foo`.
*
* Note that some objects with special access rights are encoded in names
* (like qualified privates `private[qualifier]`). In order to get the right
* original names, we need to use `unexpandedName`.
*/
protected def classNameAsSeenIn(in: Symbol, s: Symbol): String =
enteringPhase(currentRun.picklerPhase.next) {
if (in.isRoot || in.isRootPackage || in == NoSymbol || in.isEffectiveRoot)
s.simpleName.toString
else if (in.isPackageObjectOrClass)
in.owner.fullName + "." + s.name
in.owner.fullName + "." + s.unexpandedName
else
in.fullName + "." + s.name
in.fullName + "." + s.unexpandedName
}

private def pickledName(s: Symbol): Name =
Expand Down
21 changes: 13 additions & 8 deletions src/main/scala/xsbt/Dependency.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,21 @@ final class Dependency(val global: CallbackGlobal) extends LocateClassFile with
}

// Define processor reusing `processDependency` definition
val memberRef = processDependency(DependencyByMemberRef) _
val inheritance = processDependency(DependencyByInheritance) _
val localInheritance = processDependency(LocalDependencyByInheritance) _
val memberRef = processDependency(DependencyByMemberRef, false) _
val inheritance = processDependency(DependencyByInheritance, true) _
val localInheritance = processDependency(LocalDependencyByInheritance, true) _

@deprecated("Use processDependency that takes allowLocal.", "1.1.0")
def processDependency(context: DependencyContext)(dep: ClassDependency): Unit =
processDependency(context, true)(dep)

/*
* Handles dependency on given symbol by trying to figure out if represents a term
* that is coming from either source code (not necessarily compiled in this compilation
* run) or from class file and calls respective callback method.
*/
def processDependency(context: DependencyContext)(dep: ClassDependency): Unit = {
def processDependency(context: DependencyContext, allowLocal: Boolean)(
dep: ClassDependency): Unit = {
val fromClassName = classNameAsString(dep.from)

def binaryDependency(file: File, binaryClassName: String) =
Expand Down Expand Up @@ -134,11 +139,12 @@ final class Dependency(val global: CallbackGlobal) extends LocateClassFile with
case None =>
debuglog(Feedback.noOriginFileForExternalSymbol(dep.to))
}
} else if (onSource.file != sourceFile) {
// Dependency is internal -- but from other file / compilation unit
} else if (onSource.file != sourceFile || allowLocal) {
// We cannot ignore dependencies coming from the same source file because
// the dependency info needs to propagate. See source-dependencies/trait-trait-211.
val onClassName = classNameAsString(dep.to)
callback.classDependency(onClassName, fromClassName, context)
} else () // Comes from the same file, ignore
}
}
}

Expand Down Expand Up @@ -228,7 +234,6 @@ final class Dependency(val global: CallbackGlobal) extends LocateClassFile with
val depClass = enclOrModuleClass(dep)
val dependency = ClassDependency(fromClass, depClass)
if (!cache.contains(dependency) &&
fromClass.associatedFile != depClass.associatedFile &&
!depClass.isRefinementClass) {
process(dependency)
cache.add(dependency)
Expand Down
11 changes: 10 additions & 1 deletion src/main/scala/xsbt/ExtractAPI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,16 @@ class ExtractAPI[GlobalType <: Global](
* TODO: can we include hashes for parent classes instead? This seems a bit messy.
*/
private def mkStructureWithInherited(info: Type, s: Symbol): xsbti.api.Structure = {
val ancestorTypes = linearizedAncestorTypes(info)
val ancestorTypes0 = linearizedAncestorTypes(info)
val ancestorTypes =
if (s.isDerivedValueClass) {
val underlying = s.derivedValueClassUnbox.tpe.finalResultType
// The underlying type of a value class should be part of the name hash
// of the value class (see the test `value-class-underlying`), this is accomplished
// by adding the underlying type to the list of parent types.
underlying :: ancestorTypes0
} else
ancestorTypes0
val decls = info.decls.toList
val declsNoModuleCtor = if (s.isModuleClass) removeConstructors(decls) else decls
val declSet = decls.toSet
Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/xsbt/InteractiveConsoleHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

package xsbt

import scala.tools.nsc.interpreter.IR
import Compat._
import xsbti.InteractiveConsoleResult

object InteractiveConsoleHelper {
implicit def toConsoleResult(ir: IR.Result): InteractiveConsoleResult =
implicit def toConsoleResult(ir: Results.Result): InteractiveConsoleResult =
ir match {
case IR.Success => InteractiveConsoleResult.Success
case IR.Incomplete => InteractiveConsoleResult.Incomplete
case IR.Error => InteractiveConsoleResult.Error
case Results.Success => InteractiveConsoleResult.Success
case Results.Incomplete => InteractiveConsoleResult.Incomplete
case Results.Error => InteractiveConsoleResult.Error
}
}
8 changes: 5 additions & 3 deletions src/main/scala/xsbt/InteractiveConsoleInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import scala.tools.nsc.{ GenericRunnerCommand, Settings }

import xsbti.Logger

import Compat._
import InteractiveConsoleHelper._

class InteractiveConsoleInterface(
Expand All @@ -38,9 +39,10 @@ class InteractiveConsoleInterface(
val outWriter: StringWriter = new StringWriter
val poutWriter: PrintWriter = new PrintWriter(outWriter)

val interpreter: IMain = new IMain(compilerSettings, new PrintWriter(outWriter)) {
def lastReq: Request = prevRequestList.last
}
val interpreter: IMain =
new IMain(compilerSettings, replReporter(compilerSettings, new PrintWriter(outWriter))) {
def lastReq: Request = prevRequestList.last
}

def interpret(line: String, synthetic: Boolean): InteractiveConsoleResponse = {
clearBuffer()
Expand Down
7 changes: 7 additions & 0 deletions src/main/scala_2.10/xsbt/Compat.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package xsbt

import java.io.PrintWriter
import xsbti.compile.Output
import scala.reflect.{ internal => sri }
import scala.reflect.internal.{ util => sriu }
Expand Down Expand Up @@ -150,6 +151,12 @@ trait ZincGlobalCompat {
}

object Compat {
// IR is renamed to Results
val Results = scala.tools.nsc.interpreter.IR

// IMain in 2.13 accepts ReplReporter
def replReporter(settings: Settings, writer: PrintWriter) = writer

implicit final class TreeOps(val tree: sri.Trees#Tree) extends AnyVal {
// Introduced in 2.11
@inline final def hasSymbolField: Boolean = tree.hasSymbol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
package xsbt

import xsbti.Logger
import scala.tools.nsc.interpreter.{ ILoop, IMain, InteractiveReader }
import scala.tools.nsc.interpreter.{ ILoop, IMain, InteractiveReader, NamedParam }
import scala.tools.nsc.reporters.Reporter
import scala.tools.nsc.{ GenericRunnerCommand, Settings }

Expand Down Expand Up @@ -54,7 +54,7 @@ class ConsoleInterface {
super.createInterpreter()

for ((id, value) <- bindNames zip bindValues)
intp.beQuietDuring(intp.bind(id, value.asInstanceOf[AnyRef].getClass.getName, value))
intp.quietBind(NamedParam.clazz(id, value))

if (!initialCommands.isEmpty)
intp.interpret(initialCommands)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@

package xsbt

import java.io.PrintWriter
import xsbti.compile.Output

import scala.tools.nsc.Settings

abstract class Compat
object Compat
object Compat {
// IR is renamed to Results
val Results = scala.tools.nsc.interpreter.IR

// IMain in 2.13 accepts ReplReporter
def replReporter(settings: Settings, writer: PrintWriter) = writer
}

/** Defines compatibility utils for [[ZincCompiler]]. */
trait ZincGlobalCompat {
Expand Down
105 changes: 105 additions & 0 deletions src/main/scala_2.11-12/xsbt/ConsoleInterface.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Zinc - The incremental compiler for Scala.
* Copyright 2011 - 2017, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* This software is released under the terms written in LICENSE.
*/

package xsbt

import xsbti.Logger
import scala.tools.nsc.interpreter.{ ILoop, IMain, InteractiveReader, NamedParam }
import scala.tools.nsc.reporters.Reporter
import scala.tools.nsc.{ GenericRunnerCommand, Settings }

class ConsoleInterface {
def commandArguments(
args: Array[String],
bootClasspathString: String,
classpathString: String,
log: Logger
): Array[String] =
MakeSettings.sync(args, bootClasspathString, classpathString, log).recreateArgs.toArray[String]

def run(
args: Array[String],
bootClasspathString: String,
classpathString: String,
initialCommands: String,
cleanupCommands: String,
loader: ClassLoader,
bindNames: Array[String],
bindValues: Array[Any],
log: Logger
): Unit = {
lazy val interpreterSettings = MakeSettings.sync(args.toList, log)
val compilerSettings = MakeSettings.sync(args, bootClasspathString, classpathString, log)

log.info(Message("Starting scala interpreter..."))
log.info(Message(""))

val loop = new ILoop {
override def createInterpreter() = {
if (loader ne null) {
in = InteractiveReader.apply()
intp = new IMain(settings) {
override protected def parentClassLoader =
if (loader eq null) super.parentClassLoader else loader

override protected def newCompiler(settings: Settings, reporter: Reporter) =
super.newCompiler(compilerSettings, reporter)
}
intp.setContextClassLoader()
} else
super.createInterpreter()

for ((id, value) <- bindNames zip bindValues)
intp.quietBind(NamedParam.clazz(id, value))

if (!initialCommands.isEmpty)
intp.interpret(initialCommands)

()
}

override def closeInterpreter(): Unit = {
if (!cleanupCommands.isEmpty)
intp.interpret(cleanupCommands)
super.closeInterpreter()
}
}

loop.process(if (loader eq null) compilerSettings else interpreterSettings)

()
}
}

object MakeSettings {
def apply(args: List[String], log: Logger): Settings = {
val command = new GenericRunnerCommand(args, message => log.error(Message(message)))
if (command.ok)
command.settings
else
throw new InterfaceCompileFailed(Array(), Array(), command.usageMsg)
}

def sync(
args: Array[String],
bootClasspathString: String,
classpathString: String,
log: Logger
): Settings = {
val compilerSettings = sync(args.toList, log)
if (!bootClasspathString.isEmpty)
compilerSettings.bootclasspath.value = bootClasspathString
compilerSettings.classpath.value = classpathString
compilerSettings
}

def sync(options: List[String], log: Logger): Settings = {
val settings = apply(options, log)
settings.Yreplsync.value = true
settings
}
}
Loading

0 comments on commit 4ff3d7b

Please sign in to comment.