mirror of https://github.com/sbt/sbt.git
Merge branch '0.13' into wip13/fix-2551
This commit is contained in:
commit
8a78de1ff3
|
|
@ -0,0 +1,61 @@
|
|||
package sbt
|
||||
package inc
|
||||
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import javax.xml.bind.DatatypeConverter
|
||||
|
||||
private[sbt] trait Base64 {
|
||||
def encode(bytes: Array[Byte]): String
|
||||
|
||||
def decode(string: String): Array[Byte]
|
||||
}
|
||||
|
||||
private[sbt] object Base64 {
|
||||
lazy val factory: () => Base64 = {
|
||||
try {
|
||||
new Java678Encoder().encode(Array[Byte]())
|
||||
() => new Java678Encoder()
|
||||
} catch {
|
||||
case _: LinkageError =>
|
||||
() => new Java89Encoder
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private[sbt] class Java678Encoder extends Base64 {
|
||||
def encode(bytes: Array[Byte]): String = DatatypeConverter.printBase64Binary(bytes)
|
||||
|
||||
def decode(string: String): Array[Byte] = DatatypeConverter.parseBase64Binary(string)
|
||||
}
|
||||
|
||||
private[sbt] object Java89Encoder {
|
||||
|
||||
import scala.runtime.ScalaRunTime.ensureAccessible
|
||||
|
||||
private val Base64_class = Class.forName("java.util.Base64")
|
||||
private val Base64_getEncoder = ensureAccessible(Base64_class.getMethod("getEncoder"))
|
||||
private val Base64_getDecoder = ensureAccessible(Base64_class.getMethod("getEncoder"))
|
||||
private val Base64_Encoder_class = Class.forName("java.util.Base64$Encoder")
|
||||
private val Base64_Decoder_class = Class.forName("java.util.Base64$Decoder")
|
||||
private val Base64_Encoder_encodeToString = ensureAccessible(Base64_Encoder_class.getMethod("encodeToString", classOf[Array[Byte]]))
|
||||
private val Base64_Decoder_decode = ensureAccessible(Base64_Decoder_class.getMethod("decode", classOf[String]))
|
||||
}
|
||||
|
||||
private[sbt] class Java89Encoder extends Base64 {
|
||||
|
||||
import Java89Encoder._
|
||||
|
||||
def encode(bytes: Array[Byte]): String = try {
|
||||
val encoder = Base64_getEncoder.invoke(null)
|
||||
Base64_Encoder_encodeToString.invoke(encoder, bytes).asInstanceOf[String]
|
||||
} catch {
|
||||
case ex: InvocationTargetException => throw ex.getCause
|
||||
}
|
||||
|
||||
def decode(string: String): Array[Byte] = try {
|
||||
val decoder = Base64_getDecoder.invoke(null)
|
||||
Base64_Decoder_decode.invoke(decoder, string).asInstanceOf[Array[Byte]]
|
||||
} catch {
|
||||
case ex: InvocationTargetException => throw ex.getCause
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,6 @@ import java.io._
|
|||
import sbt.{ CompileSetup, Relation }
|
||||
import xsbti.api.{ Compilation, Source }
|
||||
import xsbti.compile.{ MultipleOutput, SingleOutput }
|
||||
import javax.xml.bind.DatatypeConverter
|
||||
|
||||
// Very simple timer for timing repeated code sections.
|
||||
// TODO: Temporary. Remove once we've milked all available performance gains.
|
||||
|
|
@ -328,11 +327,11 @@ object TextAnalysisFormat {
|
|||
val out = new sbinary.JavaOutput(baos)
|
||||
FormatTimer.aggregate("sbinary write") { try { fmt.writes(out, o) } finally { baos.close() } }
|
||||
val bytes = FormatTimer.aggregate("byte copy") { baos.toByteArray }
|
||||
FormatTimer.aggregate("bytes -> base64") { DatatypeConverter.printBase64Binary(bytes) }
|
||||
FormatTimer.aggregate("bytes -> base64") { Base64.factory().encode(bytes) }
|
||||
}
|
||||
|
||||
def stringToObj[T](s: String)(implicit fmt: sbinary.Format[T]) = {
|
||||
val bytes = FormatTimer.aggregate("base64 -> bytes") { DatatypeConverter.parseBase64Binary(s) }
|
||||
val bytes = FormatTimer.aggregate("base64 -> bytes") { Base64.factory().decode(s) }
|
||||
val in = new sbinary.JavaInput(new ByteArrayInputStream(bytes))
|
||||
FormatTimer.aggregate("sbinary read") { fmt.reads(in) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ final class CompilerArguments(scalaInstance: xsbti.compile.ScalaInstance, cp: xs
|
|||
def bootClasspathFor(classpath: Seq[File]) = bootClasspath(hasLibrary(classpath))
|
||||
|
||||
import Path._
|
||||
def extClasspath: Seq[File] = (IO.parseClasspath(System.getProperty("java.ext.dirs")) * "*.jar").get
|
||||
def extClasspath: Seq[File] = (IO.parseClasspath(System.getProperty("java.ext.dirs", "")) * "*.jar").get
|
||||
}
|
||||
object CompilerArguments {
|
||||
val BootClasspathOption = "-bootclasspath"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
package sbt
|
||||
|
||||
import java.io.File
|
||||
import Def.Classpath
|
||||
import Def.{ Classpath, Initialize }
|
||||
import scala.annotation.implicitNotFound
|
||||
import reflect.internal.annotations.compileTimeOnly
|
||||
|
||||
object Append {
|
||||
@implicitNotFound(msg = "No implicit for Append.Value[${A}, ${B}] found,\n so ${B} cannot be appended to ${A}")
|
||||
|
|
@ -23,6 +24,14 @@ object Append {
|
|||
def appendValues(a: Seq[T], b: Seq[V]): Seq[T] = a ++ (b map { x => (x: T) })
|
||||
def appendValue(a: Seq[T], b: V): Seq[T] = a :+ (b: T)
|
||||
}
|
||||
@compileTimeOnly("This can be used in += only.")
|
||||
implicit def appendTaskValueSeq[T, V <: T]: Value[Seq[Task[T]], Initialize[Task[V]]] = new Value[Seq[Task[T]], Initialize[Task[V]]] {
|
||||
def appendValue(a: Seq[Task[T]], b: Initialize[Task[V]]): Seq[Task[T]] = ???
|
||||
}
|
||||
@compileTimeOnly("This can be used in += only.")
|
||||
implicit def appendTaskKeySeq[T, V <: T]: Value[Seq[Task[T]], TaskKey[V]] = new Value[Seq[Task[T]], TaskKey[V]] {
|
||||
def appendValue(a: Seq[Task[T]], b: TaskKey[V]): Seq[Task[T]] = ???
|
||||
}
|
||||
implicit def appendList[T, V <: T]: Sequence[List[T], List[V], V] = new Sequence[List[T], List[V], V] {
|
||||
def appendValues(a: List[T], b: List[V]): List[T] = a ::: b
|
||||
def appendValue(a: List[T], b: V): List[T] = a :+ b
|
||||
|
|
|
|||
|
|
@ -168,9 +168,24 @@ object TaskMacro {
|
|||
/** Implementation of += macro for settings. */
|
||||
def settingAppend1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(v: c.Expr[U])(a: c.Expr[Append.Value[T, U]]): c.Expr[Setting[T]] =
|
||||
{
|
||||
val init = SettingMacro.settingMacroImpl[U](c)(v)
|
||||
val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName)
|
||||
c.Expr[Setting[T]](append)
|
||||
import c.universe._
|
||||
val util = ContextUtil[c.type](c)
|
||||
val ttpe = c.weakTypeOf[T]
|
||||
val typeArgs = util.typeArgs(ttpe)
|
||||
v.tree.tpe match {
|
||||
// To allow Initialize[Task[A]] in the position of += RHS, we're going to call "taskValue" automatically.
|
||||
case tpe if typeArgs.nonEmpty && (tpe weak_<:< c.weakTypeOf[Initialize[_]]) =>
|
||||
c.macroApplication match {
|
||||
case Apply(Apply(TypeApply(Select(preT, nmeT), targs), _), _) =>
|
||||
val tree = Apply(TypeApply(Select(preT, newTermName("+=").encodedName), TypeTree(typeArgs.head) :: Nil), Select(v.tree, newTermName("taskValue").encodedName) :: Nil)
|
||||
c.Expr[Setting[T]](tree)
|
||||
case x => ContextUtil.unexpectedTree(x)
|
||||
}
|
||||
case _ =>
|
||||
val init = SettingMacro.settingMacroImpl[U](c)(v)
|
||||
val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName)
|
||||
c.Expr[Setting[T]](append)
|
||||
}
|
||||
}
|
||||
/** Implementation of ++= macro for tasks. */
|
||||
def taskAppendNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(vs: c.Expr[U])(a: c.Expr[Append.Values[T, U]]): c.Expr[Setting[Task[T]]] =
|
||||
|
|
@ -186,7 +201,6 @@ object TaskMacro {
|
|||
val append = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName)
|
||||
c.Expr[Setting[T]](append)
|
||||
}
|
||||
|
||||
/** Implementation of -= macro for tasks. */
|
||||
def taskRemove1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(v: c.Expr[U])(r: c.Expr[Remove.Value[T, U]]): c.Expr[Setting[Task[T]]] =
|
||||
{
|
||||
|
|
@ -221,7 +235,7 @@ object TaskMacro {
|
|||
import c.universe.{ Apply, ApplyTag, newTermName, Select, SelectTag, TypeApply, TypeApplyTag }
|
||||
c.macroApplication match {
|
||||
case Apply(Apply(TypeApply(Select(preT, nmeT), targs), _), a) =>
|
||||
Apply(Apply(TypeApply(Select(preT, newTermName(newName).encodedName), targs), init :: sourcePosition(c).tree :: Nil), a)
|
||||
Apply(Apply(TypeApply(Select(preT, newTermName(newName).encodedName), targs), init :: sourcePosition(c).tree :: Nil), append :: Nil)
|
||||
case x => ContextUtil.unexpectedTree(x)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ object Defaults extends BuildCommon {
|
|||
unmanagedResources := collectFiles(unmanagedResourceDirectories, includeFilter in unmanagedResources, excludeFilter in unmanagedResources).value,
|
||||
watchSources in ConfigGlobal ++= unmanagedResources.value,
|
||||
resourceGenerators :== Nil,
|
||||
resourceGenerators += ((discoveredSbtPlugins, resourceManaged) map PluginDiscovery.writeDescriptors).taskValue,
|
||||
resourceGenerators += Def.task { PluginDiscovery.writeDescriptors(discoveredSbtPlugins.value, resourceManaged.value) },
|
||||
managedResources := generate(resourceGenerators).value,
|
||||
resources := Classpaths.concat(managedResources, unmanagedResources).value
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
### Bug fixes
|
||||
|
||||
- Fixes regressions in sbt 0.13.11 - 0.13.13 that processed build-level keys incorrectly. [#2851][2851]/[#2460][2460] by [@eed3si9n]
|
||||
- Fixes regressions in sbt 0.13.11 - 0.13.13 that processed build-level keys incorrectly. [#2851][2851]/[#2460][2460] by [@eed3si9n][]
|
||||
|
||||
[#2851]: https://github.com/sbt/sbt/issues/2851
|
||||
[#2460]: https://github.com/sbt/sbt/issues/2460
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
### Bug fixes
|
||||
|
||||
- Fix .triggeredBy/.storeAs/etc not working when using `:=` and `.value` macros. [#1444][1444]/[#2908][2908] by [@dwijnand][]
|
||||
|
||||
[1444]: https://github.com/sbt/sbt/issues/1444
|
||||
[2908]: https://github.com/sbt/sbt/pull/2908
|
||||
[@dwijnand]: https://github.com/dwijnand
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
### Improvements
|
||||
|
||||
- XML generated by JUnitXmlTestsListener now correctly flags ignored, skipped and pending tests. [#PULL][PULL]/[#2198][2198] by [@ashleymercer][@ashleymercer]
|
||||
- XML generated by JUnitXmlTestsListener now correctly flags ignored, skipped and pending tests. [#2198][2198]/[#2854][2854] by [@ashleymercer][@ashleymercer]
|
||||
|
||||
[PULL]: https://github.com/sbt/sbt/pull/PULL
|
||||
[2198]: https://github.com/sbt/sbt/issues/2198
|
||||
[2854]: https://github.com/sbt/sbt/pull/2854
|
||||
[@ashleymercer]: https://github.com/ashleymercer
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
### Improvements
|
||||
|
||||
- Added preliminary compatibility with JDK 9. [#2951][2951]/ by [@retronym][]
|
||||
|
||||
[2951]: https://github.com/sbt/sbt/pull/2951
|
||||
[@retronym]: https://github.com/retronym
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
lazy val buildInfo = taskKey[Seq[File]]("The task that generates the build info.")
|
||||
|
||||
lazy val root = (project in file("."))
|
||||
.settings(
|
||||
scalaVersion := "2.11.8",
|
||||
buildInfo := {
|
||||
val x = sourceManaged.value / "BuildInfo.scala"
|
||||
IO.write(x, """object BuildInfo""")
|
||||
x :: Nil
|
||||
},
|
||||
sourceGenerators in Compile += buildInfo,
|
||||
sourceGenerators in Compile += Def.task { Nil }
|
||||
)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
> compile
|
||||
$ exists target/scala-2.11/src_managed/BuildInfo.scala
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
val test123 = project in file(".") enablePlugins TestP settings(
|
||||
resourceGenerators in Compile += (Def.task {
|
||||
resourceGenerators in Compile += Def.task {
|
||||
streams.value.log info "resource generated in settings"
|
||||
Nil
|
||||
}).taskValue
|
||||
}
|
||||
)
|
||||
|
||||
TaskKey[Unit]("check") := {
|
||||
|
|
|
|||
|
|
@ -126,6 +126,9 @@ final class ContextUtil[C <: Context](val ctx: C) {
|
|||
def freshMethodParameter(tpe: Type): ValDef =
|
||||
ValDef(parameterModifiers, freshTermName("p"), TypeTree(tpe), EmptyTree)
|
||||
|
||||
def typeArgs(tpe: Type): List[Type] =
|
||||
tpe.asInstanceOf[global.Type].typeArgs map { _.asInstanceOf[Type] }
|
||||
|
||||
/** Constructs a ValDef with local modifiers and a unique name. */
|
||||
def localValDef(tpt: Tree, rhs: Tree): ValDef =
|
||||
ValDef(localModifiers, freshTermName("q"), tpt, rhs)
|
||||
|
|
|
|||
Loading…
Reference in New Issue