Pattern match some if/else's

This commit is contained in:
Dale Wijnand 2016-07-07 01:39:05 +01:00
parent 4c75d778b9
commit 12c2734052
11 changed files with 167 additions and 135 deletions

View File

@ -11,52 +11,56 @@ import sbt.internal.util.appmacro.{ Convert, Converted }
object InputInitConvert extends Convert {
def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] =
if (nme == InputWrapper.WrapInitName)
Converted.Success(in)
else if (nme == InputWrapper.WrapInitTaskName)
Converted.Failure(in.pos, "Internal sbt error: initialize+task wrapper not split")
else
Converted.NotApplicable
nme match {
case InputWrapper.WrapInitName => Converted.Success(in)
case InputWrapper.WrapInitTaskName => Converted.Failure(in.pos, initTaskErrorMessage)
case _ => Converted.NotApplicable
}
private def initTaskErrorMessage = "Internal sbt error: initialize+task wrapper not split"
}
/** Converts an input `Tree` of type `Parser[T]` or `State => Parser[T]` into a `Tree` of type `State => Parser[T]`.*/
object ParserConvert extends Convert {
def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] =
{
if (nme == ParserInput.WrapName)
Converted.Success(in)
else if (nme == ParserInput.WrapInitName)
Converted.Failure(in.pos, "Internal sbt error: initialize+parser wrapper not split")
else
Converted.NotApplicable
nme match {
case ParserInput.WrapName => Converted.Success(in)
case ParserInput.WrapInitName => Converted.Failure(in.pos, initParserErrorMessage)
case _ => Converted.NotApplicable
}
private def initParserErrorMessage = "Internal sbt error: initialize+parser wrapper not split"
}
/** Convert instance for plain `Task`s not within the settings system. */
object TaskConvert extends Convert {
def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] =
if (nme == InputWrapper.WrapTaskName)
Converted.Success(in)
else
Converted.NotApplicable
if (nme == InputWrapper.WrapTaskName) Converted.Success(in) else Converted.NotApplicable
}
/** Converts an input `Tree` of type `Initialize[T]`, `Initialize[Task[T]]`, or `Task[T]` into a `Tree` of type `Initialize[Task[T]]`.*/
object FullConvert extends Convert {
import InputWrapper._
def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] =
if (nme == WrapInitTaskName || nme == WrapPreviousName)
Converted.Success(in)
else if (nme == WrapInitName) {
val i = c.Expr[Initialize[T]](in)
val t = c.universe.reify(Def.toITask(i.splice)).tree
Converted.Success(t)
} else if (nme == WrapTaskName) {
val i = c.Expr[Task[T]](in)
val t = c.universe.reify(Def.valueStrict[Task[T]](i.splice)).tree
Converted.Success(t)
} else
Converted.NotApplicable
nme match {
case WrapInitTaskName => Converted.Success(in)
case WrapPreviousName => Converted.Success(in)
case WrapInitName => wrapInit[T](c)(in)
case WrapTaskName => wrapTask[T](c)(in)
case _ => Converted.NotApplicable
}
private def wrapInit[T](c: Context)(tree: c.Tree): Converted[c.type] = {
val i = c.Expr[Initialize[T]](tree)
val t = c.universe.reify(Def.toITask(i.splice)).tree
Converted.Success(t)
}
private def wrapTask[T](c: Context)(tree: c.Tree): Converted[c.type] = {
val i = c.Expr[Task[T]](tree)
val t = c.universe.reify(Def.valueStrict[Task[T]](i.splice)).tree
Converted.Success(t)
}
}
/**
@ -65,12 +69,15 @@ object FullConvert extends Convert {
*/
object InitParserConvert extends Convert {
def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] =
if (nme == ParserInput.WrapName) {
val e = c.Expr[State => Parser[T]](in)
val t = c.universe.reify { Def.valueStrict[State => Parser[T]](e.splice) }
Converted.Success(t.tree)
} else if (nme == ParserInput.WrapInitName)
Converted.Success(in)
else
Converted.NotApplicable
nme match {
case ParserInput.WrapName => wrap[T](c)(in)
case ParserInput.WrapInitName => Converted.Success(in)
case _ => Converted.NotApplicable
}
private def wrap[T](c: Context)(tree: c.Tree): Converted[c.type] = {
val e = c.Expr[State => Parser[T]](tree)
val t = c.universe.reify { Def.valueStrict[State => Parser[T]](e.splice) }
Converted.Success(t.tree)
}
}

View File

@ -90,19 +90,14 @@ object InputWrapper {
def valueMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[T] =
ContextUtil.selectMacroImpl[T](c) { (ts, pos) =>
val tpe = ts.tree.tpe
if (tpe <:< c.weakTypeOf[Initialize[Task[T]]])
InputWrapper.wrapInitTask[T](c)(ts, pos)
else if (tpe <:< c.weakTypeOf[Initialize[T]])
InputWrapper.wrapInit[T](c)(ts, pos)
else if (tpe <:< c.weakTypeOf[Task[T]])
InputWrapper.wrapTask[T](c)(ts, pos)
else if (tpe <:< c.weakTypeOf[InputTask[T]])
InputWrapper.wrapInputTask[T](c)(ts, pos)
else if (tpe <:< c.weakTypeOf[Initialize[InputTask[T]]])
InputWrapper.wrapInitInputTask[T](c)(ts, pos)
else
c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.widen}")
ts.tree.tpe match {
case tpe if tpe <:< c.weakTypeOf[Initialize[Task[T]]] => InputWrapper.wrapInitTask[T](c)(ts, pos)
case tpe if tpe <:< c.weakTypeOf[Initialize[T]] => InputWrapper.wrapInit[T](c)(ts, pos)
case tpe if tpe <:< c.weakTypeOf[Task[T]] => InputWrapper.wrapTask[T](c)(ts, pos)
case tpe if tpe <:< c.weakTypeOf[InputTask[T]] => InputWrapper.wrapInputTask[T](c)(ts, pos)
case tpe if tpe <:< c.weakTypeOf[Initialize[InputTask[T]]] => InputWrapper.wrapInitInputTask[T](c)(ts, pos)
case tpe => unexpectedType(c)(pos, tpe)
}
}
def taskValueMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[Task[T]] =
ContextUtil.selectMacroImpl[Task[T]](c) { (ts, pos) =>
@ -110,7 +105,7 @@ object InputWrapper {
if (tpe <:< c.weakTypeOf[Initialize[Task[T]]])
InputWrapper.wrapInit[Task[T]](c)(ts, pos)
else
c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.widen}")
unexpectedType(c)(pos, tpe)
}
/** Translates <task: TaskKey[T]>.previous(format) to Previous.runtime(<task>)(format).value*/
def previousMacroImpl[T: c.WeakTypeTag](c: Context)(format: c.Expr[sbinary.Format[T]]): c.Expr[Option[T]] =
@ -123,10 +118,13 @@ object InputWrapper {
val newTree = c.universe.reify { Previous.runtime[T](tsTyped.splice)(format.splice) }
wrapPrevious[T](c)(newTree, a.pos)
} else
c.abort(a.pos, s"Internal sbt error. Unexpected type ${t.tpe.widen}")
unexpectedType(c)(a.pos, t.tpe)
case x => ContextUtil.unexpectedTree(x)
}
}
private def unexpectedType(c: Context)(pos: c.Position, tpe: c.Type) =
c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.widen}")
}
sealed abstract class MacroTaskValue[T] {
@ -177,35 +175,46 @@ object ParserInput {
def parsedInputMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[Task[T]] =
ContextUtil.selectMacroImpl[Task[T]](c) { (p, pos) =>
import c.universe.reify
val tpe = p.tree.tpe
if (tpe <:< c.weakTypeOf[InputTask[T]]) {
val e = c.Expr[InputTask[T]](p.tree)
wrap[Task[T]](c)(inputParser(c)(e), pos)
} else if (tpe <:< c.weakTypeOf[Initialize[InputTask[T]]]) {
val e = c.Expr[Initialize[InputTask[T]]](p.tree)
wrapInit[Task[T]](c)(reify { Def.toIParser(e.splice) }, pos)
} else
c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.dealias} in parsedInputMacroImpl.")
p.tree.tpe match {
case tpe if tpe <:< c.weakTypeOf[InputTask[T]] => wrapInputTask[T](c)(p.tree, pos)
case tpe if tpe <:< c.weakTypeOf[Initialize[InputTask[T]]] => wrapInitInputTask[T](c)(p.tree, pos)
case tpe => unexpectedType(c)(pos, tpe, "parsedInputMacroImpl")
}
}
private def wrapInputTask[T: c.WeakTypeTag](c: Context)(tree: c.Tree, pos: c.Position) = {
val e = c.Expr[InputTask[T]](tree)
wrap[Task[T]](c)(inputParser(c)(e), pos)
}
private def wrapInitInputTask[T: c.WeakTypeTag](c: Context)(tree: c.Tree, pos: c.Position) = {
val e = c.Expr[Initialize[InputTask[T]]](tree)
wrapInit[Task[T]](c)(c.universe.reify {Def.toIParser(e.splice)}, pos)
}
/** Implements `Parser[T].parsed` by wrapping the Parser with the ParserInput wrapper.*/
def parsedMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[T] =
ContextUtil.selectMacroImpl[T](c) { (p, pos) =>
import c.universe.reify
val tpe = p.tree.tpe
if (tpe <:< c.weakTypeOf[Parser[T]]) {
val e = c.Expr[Parser[T]](p.tree)
wrap[T](c)(reify { Def.toSParser(e.splice) }, pos)
} else if (tpe <:< c.weakTypeOf[State => Parser[T]])
wrap[T](c)(p, pos)
else if (tpe <:< c.weakTypeOf[Initialize[Parser[T]]]) {
val e = c.Expr[Initialize[Parser[T]]](p.tree)
val es = reify { Def.toISParser(e.splice) }
wrapInit[T](c)(es, pos)
} else if (tpe <:< c.weakTypeOf[Initialize[State => Parser[T]]])
wrapInit[T](c)(p, pos)
else
c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.dealias} in parsedMacroImpl")
p.tree.tpe match {
case tpe if tpe <:< c.weakTypeOf[Parser[T]] => wrapParser[T](c)(p.tree, pos)
case tpe if tpe <:< c.weakTypeOf[State => Parser[T]] => wrap[T](c)(p, pos)
case tpe if tpe <:< c.weakTypeOf[Initialize[Parser[T]]] => wrapInitParser[T](c)(p.tree, pos)
case tpe if tpe <:< c.weakTypeOf[Initialize[State => Parser[T]]] => wrapInit[T](c)(p, pos)
case tpe => unexpectedType(c)(pos, tpe, "parsedMacroImpl")
}
}
private def wrapParser[T: c.WeakTypeTag](c: Context)(tree: c.Tree, pos: c.Position) = {
val e = c.Expr[Parser[T]](tree)
wrap[T](c)(c.universe.reify {Def.toSParser(e.splice)}, pos)
}
private def wrapInitParser[T: c.WeakTypeTag](c: Context)(tree: c.Tree, pos: c.Position) = {
val e = c.Expr[Initialize[Parser[T]]](tree)
val es = c.universe.reify {Def.toISParser(e.splice)}
wrapInit[T](c)(es, pos)
}
private def unexpectedType(c: Context)(pos: c.Position, tpe: c.Type, label: String) =
c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.dealias} in $label.")
}

View File

@ -20,16 +20,24 @@ import reflect.macros._
object InitializeConvert extends Convert {
def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] =
if (nme == InputWrapper.WrapInitName) {
nme match {
case InputWrapper.WrapInitName => convert[T](c)(in)
case InputWrapper.WrapTaskName | InputWrapper.WrapInitTaskName => failTask[c.type](c)(in.pos)
case InputWrapper.WrapPreviousName => failPrevious[c.type](c)(in.pos)
case _ => Converted.NotApplicable
}
private def convert[T](c: Context)(in: c.Tree): Converted[c.type] =
{
val i = c.Expr[Initialize[T]](in)
val t = c.universe.reify(i.splice).tree
Converted.Success(t)
} else if (nme == InputWrapper.WrapTaskName || nme == InputWrapper.WrapInitTaskName)
Converted.Failure(in.pos, "A setting cannot depend on a task")
else if (nme == InputWrapper.WrapPreviousName)
Converted.Failure(in.pos, "A setting cannot depend on a task's previous value.")
else
Converted.NotApplicable
}
private def failTask[C <: Context with Singleton](c: C)(pos: c.Position): Converted[c.type] =
Converted.Failure(pos, "A setting cannot depend on a task")
private def failPrevious[C <: Context with Singleton](c: C)(pos: c.Position): Converted[c.type] =
Converted.Failure(pos, "A setting cannot depend on a task's previous value.")
}
object SettingMacro {

View File

@ -10,6 +10,7 @@ import sbt.internal.util.complete.{ DefaultParsers, Parser }
import sbt.internal.util.{ AList, LinePosition, NoPosition, SourcePosition }
import language.experimental.macros
import scala.annotation.tailrec
import scala.reflect._
import reflect.macros._
import reflect.internal.annotations.compileTimeOnly
@ -236,15 +237,14 @@ object TaskMacro {
}
private[this] def settingSource(c: Context, path: String, name: String): String =
{
val ec = c.enclosingClass.symbol
def inEmptyPackage(s: c.Symbol): Boolean =
s != c.universe.NoSymbol && (s.owner == c.mirror.EmptyPackage || s.owner == c.mirror.EmptyPackageClass || inEmptyPackage(s.owner))
if (!ec.isStatic)
name
else if (inEmptyPackage(ec))
path
else
s"(${ec.fullName}) $name"
@tailrec def inEmptyPackage(s: c.Symbol): Boolean = s != c.universe.NoSymbol && (
s.owner == c.mirror.EmptyPackage || s.owner == c.mirror.EmptyPackageClass || inEmptyPackage(s.owner)
)
c.enclosingClass.symbol match {
case ec if !ec.isStatic => name
case ec if inEmptyPackage(ec) => path
case ec => s"(${ec.fullName}) $name"
}
}
private[this] def constant[T: c.TypeTag](c: Context, t: T): c.Expr[T] = {

View File

@ -621,12 +621,10 @@ object Defaults extends BuildCommon {
val includeFilters = includeArgs map GlobFilter.apply
val excludeFilters = excludeArgs.map(_.substring(1)).map(GlobFilter.apply)
if (includeFilters.isEmpty && excludeArgs.isEmpty) {
Seq(const(true))
} else if (includeFilters.isEmpty) {
Seq({ (s: String) => !matches(excludeFilters, s) })
} else {
includeFilters.map { f => (s: String) => (f.accept(s) && !matches(excludeFilters, s)) }
(includeFilters, excludeArgs) match {
case (Nil, Nil) => Seq(const(true))
case (Nil, _) => Seq((s: String) => !matches(excludeFilters, s))
case _ => includeFilters.map(f => (s: String) => (f.accept(s) && !matches(excludeFilters, s)))
}
}
def detectTests: Initialize[Task[Seq[TestDefinition]]] = (loadedTestFrameworks, compile, streams) map { (frameworkMap, analysis, s) =>
@ -1786,8 +1784,11 @@ object Classpaths {
a => (Seq[B]() /: maps) { _ ++ _(a) } distinct;
def parseList(s: String, allConfs: Seq[String]): Seq[String] = (trim(s split ",") flatMap replaceWildcard(allConfs)).distinct
def replaceWildcard(allConfs: Seq[String])(conf: String): Seq[String] =
if (conf == "") Nil else if (conf == "*") allConfs else conf :: Nil
def replaceWildcard(allConfs: Seq[String])(conf: String): Seq[String] = conf match {
case "" => Nil
case "*" => allConfs
case _ => conf :: Nil
}
private def trim(a: Array[String]): List[String] = a.toList.map(_.trim)
def missingConfiguration(in: String, conf: String) =

View File

@ -461,20 +461,16 @@ object BuiltinCommands {
{
val result = (SimpleReader.readLine("Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? ") getOrElse Quit).toLowerCase(Locale.ENGLISH)
def matches(s: String) = !result.isEmpty && (s startsWith result)
def retry = loadProjectCommand(LoadProject, loadArg) :: s.clearGlobalLog
def ignoreMsg = if (Project.isProjectLoaded(s)) "using previously loaded project" else "no project loaded"
if (result.isEmpty || matches("retry"))
loadProjectCommand(LoadProject, loadArg) :: s.clearGlobalLog
else if (matches(Quit))
s.exit(ok = false)
else if (matches("ignore")) {
val hadPrevious = Project.isProjectLoaded(s)
s.log.warn("Ignoring load failure: " + (if (hadPrevious) "using previously loaded project." else "no project loaded."))
s
} else if (matches("last"))
LastCommand :: loadProjectCommand(LoadFailed, loadArg) :: s
else {
println("Invalid response.")
doLoadFailed(s, loadArg)
result match {
case "" => retry
case _ if matches("retry") => retry
case _ if matches(Quit) => s.exit(ok = false)
case _ if matches("ignore") => s.log.warn(s"Ignoring load failure: $ignoreMsg.") ; s
case _ if matches("last") => LastCommand :: loadProjectCommand(LoadFailed, loadArg) :: s
case _ => println("Invalid response."); doLoadFailed(s, loadArg)
}
}

View File

@ -11,8 +11,13 @@ final case class ScopedKeyData[A](scoped: ScopedKey[A], value: Any) {
def description: String = fold(fmtMf("Task: %s"), fmtMf("Input task: %s"),
"Setting: %s = %s" format (key.manifest.toString, value.toString))
def fold[T](targ: OptManifest[_] => T, itarg: OptManifest[_] => T, s: => T): T =
if (key.manifest.runtimeClass == classOf[Task[_]]) targ(key.manifest.typeArguments.head)
else if (key.manifest.runtimeClass == classOf[InputTask[_]]) itarg(key.manifest.typeArguments.head)
else s
key.manifest.runtimeClass match {
case TaskClass => targ(key.manifest.typeArguments.head)
case InputTaskClass => itarg(key.manifest.typeArguments.head)
case _ => s
}
def fmtMf(s: String): OptManifest[_] => String = s format _
private val TaskClass = classOf[Task[_]]
private val InputTaskClass = classOf[InputTask[_]]
}

View File

@ -47,12 +47,11 @@ object IvyConsole {
final case class Dependencies(managed: Seq[ModuleID], resolvers: Seq[Resolver], unmanaged: Seq[File])
def parseDependencies(args: Seq[String], log: Logger): Dependencies = (Dependencies(Nil, Nil, Nil) /: args)(parseArgument(log))
def parseArgument(log: Logger)(acc: Dependencies, arg: String): Dependencies =
if (arg contains " at ")
acc.copy(resolvers = parseResolver(arg) +: acc.resolvers)
else if (arg endsWith ".jar")
acc.copy(unmanaged = new File(arg) +: acc.unmanaged)
else
acc.copy(managed = parseManaged(arg, log) ++ acc.managed)
arg match {
case _ if arg contains " at " => acc.copy(resolvers = parseResolver(arg) +: acc.resolvers)
case _ if arg endsWith ".jar" => acc.copy(unmanaged = new File(arg) +: acc.unmanaged)
case _ => acc.copy(managed = parseManaged(arg, log) ++ acc.managed)
}
private[this] def parseResolver(arg: String): MavenRepository =
{

View File

@ -286,10 +286,13 @@ private[sbt] object SettingCompletions {
def keyType[S](key: AttributeKey[_])(onSetting: Manifest[_] => S, onTask: Manifest[_] => S, onInput: Manifest[_] => S)(implicit tm: Manifest[Task[_]], im: Manifest[InputTask[_]]): S =
{
def argTpe = key.manifest.typeArguments.head
val e = key.manifest.runtimeClass
if (e == tm.runtimeClass) onTask(argTpe)
else if (e == im.runtimeClass) onInput(argTpe)
else onSetting(key.manifest)
val TaskClass = tm.runtimeClass
val InputTaskClass = im.runtimeClass
key.manifest.runtimeClass match {
case TaskClass => onTask(argTpe)
case InputTaskClass => onInput(argTpe)
case _ => onSetting(key.manifest)
}
}
/** For a Task[T], InputTask[T], or Setting[T], this returns the manifest for T. */

View File

@ -77,10 +77,11 @@ object TestBuild {
global += skey
else {
val keys = tasks map makeKey
if (keys.size == 1)
single ++= keys
else if (keys.size > 1)
multi ++= keys
keys.size match {
case 0 =>
case 1 => single ++= keys
case _ => multi ++= keys
}
}
}
(taskAxes, global.toSet, single.toSet, multi.toSet)

View File

@ -76,10 +76,13 @@ object TestEvent {
private[sbt] def overallResult(events: Seq[TEvent]): TestResult.Value =
(TestResult.Passed /: events) { (sum, event) =>
val status = event.status
if (sum == TestResult.Error || status == TStatus.Error) TestResult.Error
else if (sum == TestResult.Failed || status == TStatus.Failure) TestResult.Failed
else TestResult.Passed
(sum, event.status) match {
case (TestResult.Error, _) => TestResult.Error
case (_, TStatus.Error) => TestResult.Error
case (TestResult.Failed, _) => TestResult.Failed
case (_, TStatus.Failure) => TestResult.Failed
case _ => TestResult.Passed
}
}
}