Skip to content
This repository has been archived by the owner on Jan 25, 2018. It is now read-only.

Commit

Permalink
Merge 7a9095c into 3d4a2a0
Browse files Browse the repository at this point in the history
  • Loading branch information
cjllanwarne committed Jan 18, 2017
2 parents 3d4a2a0 + 7a9095c commit 8a5c1ba
Show file tree
Hide file tree
Showing 14 changed files with 84 additions and 71 deletions.
35 changes: 19 additions & 16 deletions src/main/scala/wdl4s/Call.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import wdl4s.AstTools.EnhancedAstNode
import wdl4s.exception.{ValidationException, VariableLookupException, VariableNotFoundException}
import wdl4s.expression.WdlFunctions
import wdl4s.parser.WdlParser.{Ast, SyntaxError, Terminal}
import wdl4s.types.WdlOptionalType
import wdl4s.values.WdlValue
import wdl4s.types.{WdlAnyType, WdlOptionalType}
import wdl4s.values.{WdlOptionalValue, WdlValue}

import scala.language.postfixOps
import scala.util.{Failure, Success, Try}
Expand Down Expand Up @@ -97,30 +97,33 @@ sealed abstract class Call(val alias: Option[String],
def evaluateTaskInputs(inputs: WorkflowCoercedInputs,
wdlFunctions: WdlFunctions[WdlValue],
outputResolver: OutputResolver = NoOutputResolver,
shards: Map[Scatter, Int] = Map.empty[Scatter, Int]): EvaluatedTaskInputs = {
shards: Map[Scatter, Int] = Map.empty[Scatter, Int]): Try[EvaluatedTaskInputs] = {
val declarationAttempts = callable.declarations map { declaration =>
val lookup = lookupFunction(inputs, wdlFunctions, outputResolver, shards, relativeTo = declaration)
val evaluatedDeclaration = Try(lookup(declaration.unqualifiedName))
val coercedDeclaration = evaluatedDeclaration flatMap { declaration.wdlType.coerceRawValue(_) }


val coercedDeclaration: Try[WdlValue] = evaluatedDeclaration match {
case Success(ed) => declaration.wdlType.coerceRawValue(ed)
case Failure(_: VariableNotFoundException) if declaration.wdlType.isInstanceOf[WdlOptionalType] =>
val innerType = declaration.wdlType.asInstanceOf[WdlOptionalType].memberType
Success(WdlOptionalValue(innerType, None))
case Failure(f) => Failure(f)
}

declaration -> coercedDeclaration
}

val (success, errors) = declarationAttempts partition {
case (_, Success(_)) => true
case (d, Failure(_: VariableNotFoundException)) if d.wdlType.isInstanceOf[WdlOptionalType] => true
case _ => false
}

if (errors.nonEmpty) {
val throwables = errors.toList map { _._2.failed.get }
throw ValidationException(
s"Input evaluation for Call $fullyQualifiedName failed.", throwables
)
Failure(ValidationException(s"Input evaluation for Call $fullyQualifiedName failed.", throwables))
} else {
Success(success map { case (d, v) => d -> v.get } toMap)
}

val successfulDeclarations = success map { case (d, v) => v.toOption map { d -> _ } }
successfulDeclarations.flatten.toMap
}

/**
Expand Down Expand Up @@ -148,12 +151,12 @@ sealed abstract class Call(val alias: Option[String],

val declarationLookup = for {
declaration <- declarationsWithMatchingName
inputsLookup <- Try(inputs.getOrElse(declaration.fullyQualifiedName, throw VariableNotFoundException(s"No input for ${declaration.fullyQualifiedName}")))
inputsLookup <- Try(inputs.getOrElse(declaration.fullyQualifiedName, throw VariableNotFoundException(declaration)))
} yield inputsLookup

val declarationExprLookup = for {
declaration <- declarationsWithMatchingName
declarationExpr <- Try(declaration.expression.getOrElse(throw VariableNotFoundException(s"No expression defined for declaration ${declaration.fullyQualifiedName}")))
declarationExpr <- Try(declaration.expression.getOrElse(throw VariableNotFoundException(declaration)))
evaluatedExpr <- declarationExpr.evaluate(lookupFunction(inputs, wdlFunctions, outputResolver, shards, relativeTo), wdlFunctions)
} yield evaluatedExpr

Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/wdl4s/command/ParameterCommandPart.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ case class ParameterCommandPart(attributes: Map[String, String], expression: Wdl
case v: VariableNotFoundException => declarations.find(_.unqualifiedName == v.variable) match {
/* Allow an expression to fail evaluation if one of the variables that it requires is optional (the type has ? after it, e.g. String?) */
case Some(d) if d.wdlType.isInstanceOf[WdlOptionalType] => defaultString(d.wdlType.asInstanceOf[WdlOptionalType].memberType)
case Some(d) => throw new UnsupportedOperationException(s"Parameter ${v.variable} is required, but no value is specified")
case None => throw new UnsupportedOperationException(s"Could not find declaration for ${v.variable}")
case Some(d) => throw new UnsupportedOperationException(s"Parameter ${v.variable} is required, but no value is specified", f)
case None => throw new UnsupportedOperationException(s"Could not find declaration for ${v.variable}", f)
}
case e => throw new UnsupportedOperationException(s"Could not evaluate expression: ${expression.toWdlString}", e)
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/wdl4s/examples/ex7.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ object ex7 {

ns.taskCalls.find( _.unqualifiedName == "a") foreach { call =>
val wdlFunctions: CustomFunctions = new CustomFunctions
val evaluatedInputs = call.evaluateTaskInputs(inputs, wdlFunctions)
val evaluatedInputs = call.evaluateTaskInputs(inputs, wdlFunctions).get
println(call.task.instantiateCommand(evaluatedInputs, wdlFunctions).get)
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/main/scala/wdl4s/exception/LookupException.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package wdl4s.exception

import lenthall.exception.ThrowableAggregation
import wdl4s.GraphNode
import wdl4s.{Declaration, GraphNode}
import wdl4s.types.WdlType

sealed trait LookupException { this: Exception => }

/**
* When a variable does not reference any known scope in the namespace.
*/
final case class VariableNotFoundException(variable: String) extends Exception(s"Variable '$variable' not found") with LookupException
final case class VariableNotFoundException(variable: String) extends Exception(s"Variable $variable not found") with LookupException

object VariableNotFoundException {
def apply(declaration: Declaration): VariableNotFoundException = VariableNotFoundException.apply(declaration.fullyQualifiedName, declaration.wdlType)
def apply(variable: String, variableType: WdlType): VariableNotFoundException= VariableNotFoundException(variable + variableType.toWdlString)
}

/**
* When an unexpected exception occurred while attempting to resolve a variable.
Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/wdl4s/values/WdlBoolean.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,31 @@ class WdlBoolean private(val value: Boolean) extends WdlPrimitive {

override def equals(rhs: WdlValue): Try[WdlBoolean] = rhs match {
case r:WdlBoolean => Success(WdlBoolean(value == r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, equals)
case r: WdlOptionalValue => evaluateIfDefined("==", r, equals)
case _ => invalid(s"$value || $rhs")
}

override def lessThan(rhs: WdlValue): Try[WdlBoolean] = rhs match {
case r:WdlBoolean => Success(WdlBoolean(value < r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, lessThan)
case r: WdlOptionalValue => evaluateIfDefined("<", r, lessThan)
case _ => invalid(s"$value < $rhs")
}

override def greaterThan(rhs: WdlValue): Try[WdlBoolean] = rhs match {
case r:WdlBoolean => Success(WdlBoolean(value > r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, greaterThan)
case r: WdlOptionalValue => evaluateIfDefined(">", r, greaterThan)
case _ => invalid(s"$value > $rhs")
}

override def or(rhs: WdlValue): Try[WdlBoolean] = rhs match {
case r:WdlBoolean => Success(WdlBoolean(value || r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, or)
case r: WdlOptionalValue => evaluateIfDefined("||", r, or)
case _ => invalid(s"$value || $rhs")
}

override def and(rhs: WdlValue): Try[WdlBoolean] = rhs match {
case r:WdlBoolean => Success(WdlBoolean(value && r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, and)
case r: WdlOptionalValue => evaluateIfDefined("&&", r, and)
case _ => invalid(s"$value && $rhs")
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/wdl4s/values/WdlFile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ sealed trait WdlFile extends WdlPrimitive {

override def add(rhs: WdlValue): Try[WdlValue] = rhs match {
case r: WdlString => Success(WdlFile(value + r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, add)
case r: WdlOptionalValue => evaluateIfDefined("+", r, add)
case _ => invalid(s"$value + $rhs")
}

override def equals(rhs: WdlValue): Try[WdlBoolean] = rhs match {
case r: WdlFile => Success(WdlBoolean(value.equals(r.value) && isGlob.equals(r.isGlob)))
case r: WdlString => Success(WdlBoolean(value.toString.equals(r.value.toString) && !isGlob))
case r: WdlOptionalValue => evaluateIfDefined(r, equals)
case r: WdlOptionalValue => evaluateIfDefined("==", r, equals)
case _ => invalid(s"$value == $rhs")
}

Expand Down
16 changes: 8 additions & 8 deletions src/main/scala/wdl4s/values/WdlFloat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,23 @@ case class WdlFloat(value: Double) extends WdlPrimitive {
case r:WdlFloat => Success(WdlFloat(value + r.value))
case r:WdlInteger => Success(WdlFloat(value + r.value))
case r:WdlString => Success(WdlString(value + r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, add)
case r: WdlOptionalValue => evaluateIfDefined("+", r, add)
case _ => invalid(s"$this + $rhs")
}
}
override def subtract(rhs: WdlValue): Try[WdlValue] = {
rhs match {
case r:WdlFloat => Success(WdlFloat(value - r.value))
case r:WdlInteger => Success(WdlFloat(value - r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, subtract)
case r: WdlOptionalValue => evaluateIfDefined("-", r, subtract)
case _ => invalid(s"$this - $rhs")
}
}
override def multiply(rhs: WdlValue): Try[WdlValue] = {
rhs match {
case r:WdlFloat => Success(WdlFloat(value * r.value))
case r:WdlInteger => Success(WdlFloat(value * r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, multiply)
case r: WdlOptionalValue => evaluateIfDefined("*", r, multiply)
case _ => invalid(s"$this * $rhs")
}
}
Expand All @@ -38,7 +38,7 @@ case class WdlFloat(value: Double) extends WdlPrimitive {
case r:WdlFloat => Success(WdlFloat(value / r.value))
case r:WdlInteger if r.value == 0 => Failure(new WdlExpressionException("Divide by zero"))
case r:WdlInteger => Success(WdlFloat(value / r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, divide)
case r: WdlOptionalValue => evaluateIfDefined("/", r, divide)
case _ => invalid(s"$this / $rhs")
}
}
Expand All @@ -48,31 +48,31 @@ case class WdlFloat(value: Double) extends WdlPrimitive {
case r:WdlFloat => Success(WdlFloat(value % r.value))
case r:WdlInteger if r.value == 0 => Failure(new WdlExpressionException("Divide by zero"))
case r:WdlInteger => Success(WdlFloat(value % r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, mod)
case r: WdlOptionalValue => evaluateIfDefined("%", r, mod)
case _ => invalid(s"$this % $rhs")
}
}
override def equals(rhs: WdlValue): Try[WdlBoolean] = {
rhs match {
case r:WdlFloat => Success(WdlBoolean(value == r.value))
case r:WdlInteger => Success(WdlBoolean(value == r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, equals)
case r: WdlOptionalValue => evaluateIfDefined("==", r, equals)
case _ => invalid(s"$this == $rhs")
}
}
override def lessThan(rhs: WdlValue): Try[WdlBoolean] = {
rhs match {
case r:WdlFloat => Success(WdlBoolean(value < r.value))
case r:WdlInteger => Success(WdlBoolean(value < r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, lessThan)
case r: WdlOptionalValue => evaluateIfDefined("<", r, lessThan)
case _ => invalid(s"$this < $rhs")
}
}
override def greaterThan(rhs: WdlValue): Try[WdlBoolean] = {
rhs match {
case r:WdlFloat => Success(WdlBoolean(value > r.value))
case r:WdlInteger => Success(WdlBoolean(value > r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, greaterThan)
case r: WdlOptionalValue => evaluateIfDefined(">", r, greaterThan)
case _ => invalid(s"$this > $rhs")
}
}
Expand Down
16 changes: 8 additions & 8 deletions src/main/scala/wdl4s/values/WdlInteger.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ case class WdlInteger(value: Integer) extends WdlPrimitive {
case r:WdlInteger => Success(WdlInteger(value + r.value))
case r:WdlString => Success(WdlString(value + r.value))
case r:WdlFloat => Success(WdlFloat(value + r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, add)
case r: WdlOptionalValue => evaluateIfDefined("+", r, add)
case _ => invalid(s"$value + $rhs")
}

override def subtract(rhs: WdlValue): Try[WdlValue] = rhs match {
case r:WdlInteger => Success(WdlInteger(value - r.value))
case r:WdlFloat => Success(WdlFloat(value - r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, subtract)
case r: WdlOptionalValue => evaluateIfDefined("-", r, subtract)
case _ => invalid(s"$value - $rhs")
}

override def multiply(rhs: WdlValue): Try[WdlValue] = rhs match {
case r:WdlInteger => Success(WdlInteger(value * r.value))
case r:WdlFloat => Success(WdlFloat(value * r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, multiply)
case r: WdlOptionalValue => evaluateIfDefined("*", r, multiply)
case _ => invalid(s"$value * $rhs")
}

Expand All @@ -35,7 +35,7 @@ case class WdlInteger(value: Integer) extends WdlPrimitive {
case r:WdlInteger => Success(WdlInteger(value / r.value))
case r:WdlFloat if r.value == 0.toDouble => Failure(new WdlExpressionException(s"Divide by zero error: $value / $rhs"))
case r:WdlFloat => Success(WdlFloat(value / r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, divide)
case r: WdlOptionalValue => evaluateIfDefined("/", r, divide)
case _ => invalid(s"$value / $rhs")
}

Expand All @@ -44,28 +44,28 @@ case class WdlInteger(value: Integer) extends WdlPrimitive {
case r:WdlInteger => Success(WdlInteger(value % r.value))
case r:WdlFloat if r.value == 0.toDouble => Failure(new WdlExpressionException(s"Divide by zero error: $value / $rhs"))
case r:WdlFloat => Success(WdlFloat(value % r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, mod)
case r: WdlOptionalValue => evaluateIfDefined("%", r, mod)
case _ => invalid(s"$value % $rhs")
}

override def equals(rhs: WdlValue): Try[WdlBoolean] = rhs match {
case r:WdlInteger => Success(WdlBoolean(value == r.value))
case r:WdlFloat => Success(WdlBoolean(value == r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, equals)
case r: WdlOptionalValue => evaluateIfDefined("==", r, equals)
case _ => invalid(s"$value == $rhs")
}

override def lessThan(rhs: WdlValue): Try[WdlBoolean] = rhs match {
case r:WdlInteger => Success(WdlBoolean(value < r.value))
case r:WdlFloat => Success(WdlBoolean(value < r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, lessThan)
case r: WdlOptionalValue => evaluateIfDefined("<", r, lessThan)
case _ => invalid(s"$value < $rhs")
}

override def greaterThan(rhs: WdlValue): Try[WdlBoolean] = rhs match {
case r:WdlInteger => Success(WdlBoolean(value > r.value))
case r:WdlFloat => Success(WdlBoolean(value > r.value))
case r: WdlOptionalValue => evaluateIfDefined(r, greaterThan)
case r: WdlOptionalValue => evaluateIfDefined(">", r, greaterThan)
case _ => invalid(s"$value > $rhs")
}

Expand Down
28 changes: 14 additions & 14 deletions src/main/scala/wdl4s/values/WdlOptionalValue.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,72 +10,72 @@ case class WdlOptionalValue(innerType: WdlType, value: Option[WdlValue]) extends

override def add(rhs: WdlValue): Try[WdlValue] = value match {
case Some(lhs) => lhs.add(rhs)
case None => emptyValue(this)
case None => emptyValueFailure("+")
}

override def subtract(rhs: WdlValue): Try[WdlValue] = value match {
case Some(lhs) => lhs.subtract(rhs)
case None => emptyValue(this)
case None => emptyValueFailure("-")
}

override def multiply(rhs: WdlValue): Try[WdlValue] = value match {
case Some(lhs) => lhs.multiply(rhs)
case None => emptyValue(this)
case None => emptyValueFailure("*")
}

override def divide(rhs: WdlValue): Try[WdlValue] = value match {
case Some(lhs) => lhs.divide(rhs)
case None => emptyValue(this)
case None => emptyValueFailure("/")
}

override def mod(rhs: WdlValue): Try[WdlValue] = value match {
case Some(lhs) => lhs.mod(rhs)
case None => emptyValue(this)
case None => emptyValueFailure("%")
}

override def notEquals(rhs: WdlValue): Try[WdlBoolean] = value match {
case Some(lhs) => lhs.notEquals(rhs)
case None => emptyValue(this)
case None => emptyValueFailure("!=")
}

override def or(rhs: WdlValue): Try[WdlBoolean] = value match {
case Some(lhs) => lhs.or(rhs)
case None => emptyValue(this)
case None => emptyValueFailure("||")
}

override def and(rhs: WdlValue): Try[WdlBoolean] = value match {
case Some(lhs) => lhs.and(rhs)
case None => emptyValue(this)
case None => emptyValueFailure("&&")
}

override def not: Try[WdlValue] = value match {
case Some(lhs) => lhs.not
case None => emptyValue(this)
case None => emptyValueFailure("!")
}

override def unaryPlus: Try[WdlValue] = value match {
case Some(lhs) => lhs.unaryPlus
case None => emptyValue(this)
case None => emptyValueFailure("+")
}

override def unaryMinus: Try[WdlValue] = value match {
case Some(lhs) => lhs.unaryMinus
case None => emptyValue(this)
case None => emptyValueFailure("-")
}

override def equals(rhs: WdlValue): Try[WdlBoolean] = value match {
case Some(lhs) => lhs.equals(rhs)
case None => emptyValue(this)
case None => emptyValueFailure("==")
}

override def lessThan(rhs: WdlValue): Try[WdlBoolean] = value match {
case Some(lhs) => lhs.lessThan(rhs)
case None => emptyValue(this)
case None => emptyValueFailure("<")
}

override def greaterThan(rhs: WdlValue): Try[WdlBoolean] = value match {
case Some(lhs) => lhs.greaterThan(rhs)
case None => emptyValue(this)
case None => emptyValueFailure(">")
}
}

Expand Down
Loading

0 comments on commit 8a5c1ba

Please sign in to comment.