Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ToMorphirValue of Concept.Record. Option to disable typer. #328

Merged
merged 1 commit into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions morphir/runtime/src/org/finos/morphir/runtime/Utils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,9 @@ object Utils {
case other => other // leaf nodes
}

def typeCheckArg(arg: UType, param: UType, found: Map[Name, UType]): Either[TypeError, Map[Name, UType]] =
def typeCheckArg(arg: UType, param: UType, found: Map[Name, UType])(
implicit options: RTExecutionContext.Options
): Either[TypeError, Map[Name, UType]] =
(arg, param) match {
case (argType, Type.Variable(_, name)) =>
if (found.contains(name) && found(name) != argType) {
Expand Down Expand Up @@ -243,7 +245,17 @@ object Utils {
case (acc, (argTpe, paramTpe)) =>
acc.flatMap(found => typeCheckArg(argTpe, paramTpe, found))
}
case (otherArg, otherParam) => Left(NotImplementedType(s"Cannot match $otherArg with $otherParam"))
case (otherArg, otherParam) =>
options.enableTyper match {
case EnableTyper.Enabled =>
Left(NotImplementedType(s"Cannot match $otherArg with $otherParam"))
case EnableTyper.Warn =>
println(s"[WARNING] Cannot match $otherArg with $otherParam")
Right(found)
case EnableTyper.Disabled =>
Right(found)
}

}
def specificationToType[TA](spec: V.Specification[TA]): Type[TA] =
curryTypeFunction(spec.output, spec.inputs)
Expand All @@ -253,7 +265,7 @@ object Utils {
args: List[UType],
dists: Distributions,
knownBindings: Map[Name, UType]
): RTAction[Any, TypeError, UType] = {
)(implicit options: RTExecutionContext.Options): RTAction[Any, TypeError, UType] = {
val dealiaser = new Dealiased(dists)
(curried, args) match {
case (Type.Function(attributes, parameterType, returnType), head :: tail) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import org.finos.morphir.datamodel.*
import scala.util.{Failure, Success, Try}
import org.finos.morphir.runtime.{EvaluationError, MorphirRuntimeError}
import org.finos.morphir.runtime.environment.MorphirEnv
import zio.prelude.fx.ZPure

private[runtime] case class QuickMorphirRuntime(dists: Distributions, store: Store[scala.Unit, UType])
extends TypedMorphirRuntime {
Expand Down Expand Up @@ -46,13 +47,18 @@ private[runtime] case class QuickMorphirRuntime(dists: Distributions, store: Sto
entryPoint: Value[scala.Unit, UType],
params: Value[scala.Unit, UType]*
): RTAction[Any, TypeError, Value[scala.Unit, UType]] =
entryPoint match {
case Value.Reference.Typed(tpe, entryName) =>
for {
tpe <- unCurryTypeFunction(tpe, params.toList.map(_.attributes), dists, Map())
} yield V.apply(tpe, entryPoint, params.head, params.tail: _*)
case other => RTAction.fail(UnsupportedType(s"Entry point must be a Reference, instead found $other"))
}
for {
ctx <- ZPure.get[RTExecutionContext]
out <- {
entryPoint match {
case Value.Reference.Typed(tpe, entryName) =>
for {
tpe <- unCurryTypeFunction(tpe, params.toList.map(_.attributes), dists, Map())(ctx.options)
} yield V.apply(tpe, entryPoint, params.head, params.tail: _*)
case other => RTAction.fail(UnsupportedType(s"Entry point must be a Reference, instead found $other"))
}
}
} yield out

}

Expand Down
18 changes: 16 additions & 2 deletions morphir/src/org/finos/morphir/runtime/RTExecutionContext.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
package org.finos.morphir.runtime

final case class RTExecutionContext()
sealed trait EnableTyper
object EnableTyper {
case object Enabled extends EnableTyper
case object Disabled extends EnableTyper
case object Warn extends EnableTyper
}

final case class RTExecutionContext(options: RTExecutionContext.Options)
object RTExecutionContext {
val default: RTExecutionContext = RTExecutionContext()
val default: RTExecutionContext = RTExecutionContext(RTExecutionContext.Options.default)

case class Options(
enableTyper: EnableTyper
)
object Options {
val default: Options = Options(EnableTyper.Enabled)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ object ToMorphirType {
}
// TODO: When we provide MorphirType map this to a spec or definition
toUTypeConverter(T.record(types: _*))
case Concept.Record(_, fields) =>
val types: scala.List[(String, UType)] = fields.map {
case (k: Label, v: Concept) => (k.value, conceptToTypeIR(v).morphirType)
}
// TODO: When we provide MorphirType map this to a spec or definition
toUTypeConverter(T.record(types: _*))

// Treat a record as an aliased reference on the type level, on the value level it has fields
// Record('Pack.Mod.Person', [name, age]) on the type-level is just Reference(Pack.Mod.Person)
// on the value level it's the equivalent of a record behind a type alias e.g. `person:Person; person = {name:"", age:""}`
case Concept.Record(name, fields) =>
toUTypeConverter(T.reference(name))

case Concept.Tuple(values) =>
val types: scala.List[UType] = values.map(conceptToTypeIR(_).morphirType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ object TypeConversionSpec extends MorphirBaseSpec {
val recordName = pn.morphirIR % "Record1"
val conceptRecord = Concept.Record(recordName, List(Label("1") -> Concept.String, Label("2") -> Concept.Char))
val morphirType = ToMorphirType.summon[Concept].withAttributesOf(conceptRecord).morphirType
assertTrue(morphirType == T.record(Chunk("1" -> sdk.String.stringType, "2" -> sdk.Char.charType): _*))
assertTrue(morphirType == T.reference(recordName))
}
),
suite("Concept.Map")(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ object ValueConversionSpec extends MorphirBaseSpec {
Data.Record(recordName, List(Label("1") -> Data.String("Testing Record"), Label("2") -> Data.False))
val actual = toValue(inputValue)
val result = V.record(
T.record(Chunk("1" -> sdk.String.stringType, "2" -> sdk.Basics.boolType): _*),
T.reference(recordName),
"1" -> V.string(sdk.String.stringType, "Testing Record"),
"2" -> Lit.False
)
Expand Down