Skip to content

Commit

Permalink
finish //todos and copy to cascades
Browse files Browse the repository at this point in the history
  • Loading branch information
THWiseman committed Apr 10, 2024
1 parent 58fb27d commit 9ffff90
Show file tree
Hide file tree
Showing 4 changed files with 245 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object BiscayneTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomMapType(WomAnyType, WomAnyType)) flatMap {
validateParamType(a.param, linkedValues, WomMapType(WomAnyType, WomAnyType), typeAliases) flatMap {
case WomMapType(keyType, _) => WomArrayType(keyType).validNel
case other => s"Cannot invoke 'keys' on type '${other.stableName}'. Expected a map".invalidNel
}
Expand All @@ -32,7 +32,7 @@ object BiscayneTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType))) flatMap {
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType)), typeAliases) flatMap {
case WomArrayType(WomPairType(x: WomPrimitiveType, y)) => WomMapType(x, y).validNel
case other @ WomArrayType(WomPairType(x, _)) =>
s"Cannot invoke 'as_map' on type ${other.stableName}. Map keys must be primitive but got '${x.stableName}'".invalidNel
Expand All @@ -47,7 +47,7 @@ object BiscayneTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomMapType(WomAnyType, WomAnyType)) flatMap {
validateParamType(a.param, linkedValues, WomMapType(WomAnyType, WomAnyType), typeAliases) flatMap {
case WomMapType(x, y) => WomArrayType(WomPairType(x, y)).validNel
case other => s"Cannot invoke 'as_pairs' on type '${other.stableName}'. Expected a map".invalidNel
}
Expand All @@ -60,7 +60,7 @@ object BiscayneTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType))) flatMap {
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType)), typeAliases) flatMap {
case WomArrayType(WomPairType(x: WomPrimitiveType, y)) => WomMapType(x, WomArrayType(y)).validNel
case other @ WomArrayType(WomPairType(x, _)) =>
s"Cannot invoke 'collect_by_key' on type ${other.stableName}. Map keys must be primitive but got '${x.stableName}'".invalidNel
Expand Down Expand Up @@ -114,7 +114,7 @@ object BiscayneTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.arg2, linkedValues, WomArrayType(WomAnyType)) flatMap {
validateParamType(a.arg2, linkedValues, WomArrayType(WomAnyType), typeAliases) flatMap {

Check warning on line 117 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/types/BiscayneTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/types/BiscayneTypeEvaluators.scala#L117

Added line #L117 was not covered by tests
case WomArrayType(WomArrayType(_)) =>
s"Cannot invoke 'sep' on type 'Array[Array[_]]'. Expected an Array[String].".invalidNel
case WomArrayType(_) => WomStringType.validNel
Expand All @@ -131,9 +131,9 @@ object BiscayneTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
(validateParamType(a.input, linkedValues, WomSingleFileType),
validateParamType(a.pattern, linkedValues, WomSingleFileType),
validateParamType(a.replace, linkedValues, WomSingleFileType)
(validateParamType(a.input, linkedValues, WomSingleFileType, typeAliases),
validateParamType(a.pattern, linkedValues, WomSingleFileType, typeAliases),
validateParamType(a.replace, linkedValues, WomSingleFileType, typeAliases)
) mapN { (_, _, _) => WomStringType }
}

Expand All @@ -144,8 +144,8 @@ object BiscayneTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
(validateParamType(a.suffix, linkedValues, WomStringType),
validateParamType(a.array, linkedValues, WomArrayType(WomStringType))
(validateParamType(a.suffix, linkedValues, WomStringType, typeAliases),
validateParamType(a.array, linkedValues, WomArrayType(WomStringType), typeAliases)
) mapN { (_, _) => WomArrayType(WomStringType) }
}

Expand All @@ -156,7 +156,7 @@ object BiscayneTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomArrayType(WomAnyType)) flatMap {
validateParamType(a.param, linkedValues, WomArrayType(WomAnyType), typeAliases) flatMap {
case WomArrayType(WomNothingType) => WomArrayType(WomNothingType).validNel
case WomArrayType(_: WomPrimitiveType) => WomArrayType(WomStringType).validNel
case other @ WomArrayType(_) =>
Expand All @@ -173,7 +173,7 @@ object BiscayneTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomArrayType(WomAnyType)) flatMap {
validateParamType(a.param, linkedValues, WomArrayType(WomAnyType), typeAliases) flatMap {
case WomArrayType(WomNothingType) => WomArrayType(WomNothingType).validNel
case WomArrayType(_: WomPrimitiveType) => WomArrayType(WomStringType).validNel
case other @ WomArrayType(_) =>
Expand All @@ -190,7 +190,7 @@ object BiscayneTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType))) flatMap {
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType)), typeAliases) flatMap {
case WomArrayType(WomNothingType) => WomPairType(WomArrayType(WomAnyType), WomArrayType(WomAnyType)).validNel
case WomArrayType(WomPairType(x, y)) => WomPairType(WomArrayType(x), WomArrayType(y)).validNel
case other => s"Cannot invoke 'unzip' on type '${other.stableName}'. Expected an array of pairs".invalidNel
Expand Down Expand Up @@ -240,6 +240,8 @@ object BiscayneTypeEvaluators {
structDefinition: WomCompositeType,
linkedValues: Map[UnlinkedConsumedValueHook, GeneratedValueHandle],
typeAliases: Map[String, WomType]
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomCompositeType] = {
val checkedMembers: Map[String, ErrorOr[WomType]] = a.elements.map { case (memberKey, memberExpressionElement) =>
val evaluatedType =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package wdl.transforms.biscayne.linking.expression.types

import cats.data.Validated.{Invalid, Valid}
import cats.implicits.{catsSyntaxTuple2Semigroupal, catsSyntaxTuple3Semigroupal}
import cats.syntax.validated._
import common.validation.ErrorOr._
Expand All @@ -18,7 +19,7 @@ object cascadesTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomMapType(WomAnyType, WomAnyType)) flatMap {
validateParamType(a.param, linkedValues, WomMapType(WomAnyType, WomAnyType), typeAliases) flatMap {

Check warning on line 22 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L22

Added line #L22 was not covered by tests
case WomMapType(keyType, _) => WomArrayType(keyType).validNel
case other => s"Cannot invoke 'keys' on type '${other.stableName}'. Expected a map".invalidNel
}
Expand All @@ -31,7 +32,7 @@ object cascadesTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType))) flatMap {
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType)), typeAliases) flatMap {

Check warning on line 35 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L35

Added line #L35 was not covered by tests
case WomArrayType(WomPairType(x: WomPrimitiveType, y)) => WomMapType(x, y).validNel
case other @ WomArrayType(WomPairType(x, _)) =>
s"Cannot invoke 'as_map' on type ${other.stableName}. Map keys must be primitive but got '${x.stableName}'".invalidNel
Expand All @@ -46,7 +47,7 @@ object cascadesTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomMapType(WomAnyType, WomAnyType)) flatMap {
validateParamType(a.param, linkedValues, WomMapType(WomAnyType, WomAnyType), typeAliases) flatMap {

Check warning on line 50 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L50

Added line #L50 was not covered by tests
case WomMapType(x, y) => WomArrayType(WomPairType(x, y)).validNel
case other => s"Cannot invoke 'as_pairs' on type '${other.stableName}'. Expected a map".invalidNel
}
Expand All @@ -59,7 +60,7 @@ object cascadesTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType))) flatMap {
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType)), typeAliases) flatMap {

Check warning on line 63 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L63

Added line #L63 was not covered by tests
case WomArrayType(WomPairType(x: WomPrimitiveType, y)) => WomMapType(x, WomArrayType(y)).validNel
case other @ WomArrayType(WomPairType(x, _)) =>
s"Cannot invoke 'collect_by_key' on type ${other.stableName}. Map keys must be primitive but got '${x.stableName}'".invalidNel
Expand Down Expand Up @@ -113,7 +114,7 @@ object cascadesTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.arg2, linkedValues, WomArrayType(WomAnyType)) flatMap {
validateParamType(a.arg2, linkedValues, WomArrayType(WomAnyType), typeAliases) flatMap {

Check warning on line 117 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L117

Added line #L117 was not covered by tests
case WomArrayType(WomArrayType(_)) =>
s"Cannot invoke 'sep' on type 'Array[Array[_]]'. Expected an Array[String].".invalidNel
case WomArrayType(_) => WomStringType.validNel
Expand All @@ -130,9 +131,9 @@ object cascadesTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
(validateParamType(a.input, linkedValues, WomSingleFileType),
validateParamType(a.pattern, linkedValues, WomSingleFileType),
validateParamType(a.replace, linkedValues, WomSingleFileType)
(validateParamType(a.input, linkedValues, WomSingleFileType, typeAliases),
validateParamType(a.pattern, linkedValues, WomSingleFileType, typeAliases),
validateParamType(a.replace, linkedValues, WomSingleFileType, typeAliases)
) mapN { (_, _, _) => WomStringType }
}

Expand All @@ -143,8 +144,8 @@ object cascadesTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
(validateParamType(a.suffix, linkedValues, WomStringType),
validateParamType(a.array, linkedValues, WomArrayType(WomStringType))
(validateParamType(a.suffix, linkedValues, WomStringType, typeAliases),
validateParamType(a.array, linkedValues, WomArrayType(WomStringType), typeAliases)

Check warning on line 148 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L147-L148

Added lines #L147 - L148 were not covered by tests
) mapN { (_, _) => WomArrayType(WomStringType) }
}

Expand All @@ -155,7 +156,7 @@ object cascadesTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomArrayType(WomAnyType)) flatMap {
validateParamType(a.param, linkedValues, WomArrayType(WomAnyType), typeAliases) flatMap {

Check warning on line 159 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L159

Added line #L159 was not covered by tests
case WomArrayType(WomNothingType) => WomArrayType(WomNothingType).validNel
case WomArrayType(_: WomPrimitiveType) => WomArrayType(WomStringType).validNel
case other @ WomArrayType(_) =>
Expand All @@ -172,7 +173,7 @@ object cascadesTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomArrayType(WomAnyType)) flatMap {
validateParamType(a.param, linkedValues, WomArrayType(WomAnyType), typeAliases) flatMap {

Check warning on line 176 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L176

Added line #L176 was not covered by tests
case WomArrayType(WomNothingType) => WomArrayType(WomNothingType).validNel
case WomArrayType(_: WomPrimitiveType) => WomArrayType(WomStringType).validNel
case other @ WomArrayType(_) =>
Expand All @@ -189,25 +190,131 @@ object cascadesTypeEvaluators {
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType))) flatMap {
validateParamType(a.param, linkedValues, WomArrayType(WomPairType(WomAnyType, WomAnyType)), typeAliases) flatMap {

Check warning on line 193 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L193

Added line #L193 was not covered by tests
case WomArrayType(WomNothingType) => WomPairType(WomArrayType(WomAnyType), WomArrayType(WomAnyType)).validNel
case WomArrayType(WomPairType(x, y)) => WomPairType(WomArrayType(x), WomArrayType(y)).validNel
case other => s"Cannot invoke 'unzip' on type '${other.stableName}'. Expected an array of pairs".invalidNel
}
}

implicit val structLiteralTypeEvaluator: TypeEvaluator[StructLiteral] = new TypeEvaluator[StructLiteral] {

/**
* Is the evaluated type allowed to be assigned to the expectedType?
*/
def areTypesAssignable(evaluatedType: WomType, expectedType: WomType): Boolean =
// NB: This check is a little looser than we'd like it to be.
// For example, String is coercible to Int (Int i = "1" is OK)
// It's not until we actually evaluate the value of the string that we can know if that coercion succeeded or not. (Int i = "orange" will fail)
// We don't know whether the user has provided "1" or "orange" at this stage.
// This is OK as-is because the value evaluators do the coercing and throw meaningful errors if the coercion fails.
expectedType.isCoerceableFrom(evaluatedType)

Check warning on line 211 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L211

Added line #L211 was not covered by tests

/**
* Helper method to check if something (maybe) found in the struct literal against something (maybe) found in the struct definition.
* @return The WomType of the evaluated member. Error if either is not present, or if the types aren't compatible.
*/
def checkIfMemberIsValid(typeName: String,
memberName: String,
evaluatedType: Option[WomType],
expectedType: Option[WomType]
): ErrorOr[WomType] =
evaluatedType match {
case Some(evaluated) =>
expectedType match {

Check warning on line 224 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L224

Added line #L224 was not covered by tests
case Some(expected) =>
if (areTypesAssignable(evaluated, expected)) evaluated.validNel

Check warning on line 226 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L226

Added line #L226 was not covered by tests
else
s"$typeName.$memberName expected to be ${expected.friendlyName}. Found ${evaluated.friendlyName}.".invalidNel
case None => s"Type $typeName does not have a member called $memberName.".invalidNel

Check warning on line 229 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L228-L229

Added lines #L228 - L229 were not covered by tests
}
case None => s"Error evaluating the type of ${typeName}.${memberName}.".invalidNel

Check warning on line 231 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L231

Added line #L231 was not covered by tests
}

/**
* For each member in the literal, check that it exists in the struct definition and is the expected type.
* @return The WomCompositeType of the struct literal, as determined from evaluating each member.
* This might not *exactly* match the struct definition due to permitted type coercions.
*/
def checkMembersAgainstDefinition(a: StructLiteral,
structDefinition: WomCompositeType,
linkedValues: Map[UnlinkedConsumedValueHook, GeneratedValueHandle],
typeAliases: Map[String, WomType]
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomCompositeType] = {
val checkedMembers: Map[String, ErrorOr[WomType]] = a.elements.map { case (memberKey, memberExpressionElement) =>

Check warning on line 246 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L246

Added line #L246 was not covered by tests
val evaluatedType =
expressionTypeEvaluator.evaluateType(memberExpressionElement, linkedValues, typeAliases).toOption
val expectedType = structDefinition.typeMap.get(memberKey)
(memberKey, checkIfMemberIsValid(a.structTypeName, memberKey, evaluatedType, expectedType))

Check warning on line 250 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L248-L250

Added lines #L248 - L250 were not covered by tests
}

val (errors, validatedTypes) = checkedMembers.partition { case (_, errorOr) =>

Check warning on line 253 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L253

Added line #L253 was not covered by tests
errorOr match {
case Invalid(_) => true
case Valid(_) => false
}
}

if (errors.nonEmpty) {
errors.collect { case (_, Invalid(e)) => e.toList.mkString(", ") }.toList.mkString("[ ", ", ", " ]").invalidNel
} else {
val types = validatedTypes.collect { case (key, Valid(v)) => (key, v) }
WomCompositeType(types, Some(a.structTypeName)).validNel

Check warning on line 264 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L260-L264

Added lines #L260 - L264 were not covered by tests
}
}

/**
* For each member in the struct definition, if that member isn't optional, confirm that it is also in the struct literal.
*/
def checkForMissingMembers(foundMembers: Map[String, WomType],
structDefinition: WomCompositeType
): ErrorOr[Unit] = {
val errors: Iterable[String] = structDefinition.typeMap flatMap { case (memberName, memberType) =>

Check warning on line 274 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L274

Added line #L274 was not covered by tests
memberType match {
case WomOptionalType(_) => None

Check warning on line 276 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L276

Added line #L276 was not covered by tests
case _ =>
if (!foundMembers.contains(memberName)) Some(s"Expected member ${memberName} not found. ")
else None

Check warning on line 279 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L278-L279

Added lines #L278 - L279 were not covered by tests
}
}
if (errors.nonEmpty) errors.mkString.invalidNel else ().validNel

Check warning on line 282 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L282

Added line #L282 was not covered by tests
}

/**
* Returns the type of a struct literal, assuming it is compatible with an existing struct definition.
* It is required that:
* - a struct definition exist for the literal (looked up the via name of the struct type). This is defined elsewhere in the WDL and is not part of the literal.
* - the struct definition be a WomCompositeType (it's programmer error if it's not)
* - each member provided in the literal is also in the definition, and is coercible to the defined type.
* - all non-optional members of the definition are present in the literal.
* @param a The literal to evaluate
* @param linkedValues Used by the expression type evaluator.
* @param typeAliases A map containing available struct definitions
* @param expressionTypeEvaluator An object capable of evaluating the types of ExpressionElements. Used to evaluate the type of each member provided in the literal.
* @return The type of the struct definition (as found in typeAliases) if all goes well. A list of errors otherwise.
*/
override def evaluateType(a: StructLiteral,
linkedValues: Map[UnlinkedConsumedValueHook, GeneratedValueHandle],
typeAliases: Map[String, WomType]
)(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
// This works fine, but is not yet a strong enough type check for the WDL 1.1 spec
// (i.e. users are able to instantiate struct literals with k/v pairs that aren't actually in the struct definition, without an error being thrown.)
// We want to add extra validation here, and return a WomCompositeType that matches the struct definition of everything is OK.
// Note that users are allowed to omit optional k/v pairs in their literal.
// This requires some extra work to be done in a subsequent PR.
WomObjectType.validNel
typeAliases.get(a.structTypeName) match {

Check warning on line 304 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L304

Added line #L304 was not covered by tests
case Some(definition) =>
definition match {

Check warning on line 306 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L306

Added line #L306 was not covered by tests
case compositeType: WomCompositeType =>
checkMembersAgainstDefinition(a, compositeType, linkedValues, typeAliases).flatMap { foundMembers =>
checkForMissingMembers(foundMembers.typeMap, compositeType) match {
case Invalid(error) => error.invalid
case _ => compositeType.validNel

Check warning on line 311 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L308-L311

Added lines #L308 - L311 were not covered by tests
}
}
case _ =>
s"Programmer error: Expected the struct definition of ${a.structTypeName} to be a WomCompositeType".invalidNel

Check warning on line 315 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L315

Added line #L315 was not covered by tests
}
case None => s"Could not find Struct Definition for type ${a.structTypeName}".invalidNel

Check warning on line 317 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L317

Added line #L317 was not covered by tests
}
}
}
Loading

0 comments on commit 9ffff90

Please sign in to comment.