From 15e6061b35bbb4f4643c371a3774c6771b798137 Mon Sep 17 00:00:00 2001 From: Edward Peters Date: Tue, 8 Aug 2023 08:59:55 -0700 Subject: [PATCH 01/10] Incremental --- .../src/org/finos/morphir/runtime/Utils.scala | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/morphir/runtime/src/org/finos/morphir/runtime/Utils.scala b/morphir/runtime/src/org/finos/morphir/runtime/Utils.scala index 91ac0ff8f..ad3d3c8ef 100644 --- a/morphir/runtime/src/org/finos/morphir/runtime/Utils.scala +++ b/morphir/runtime/src/org/finos/morphir/runtime/Utils.scala @@ -167,18 +167,18 @@ object Utils { params match { case Chunk() => inner case chunk => - curryTypeFunction(Type.Function(getattributes(inner), chunk.head._2, inner), chunk.tail) - } - - def getattributes[TA](tpe: Type[TA]): TA = - tpe match { - case Type.ExtensibleRecord(attributes, _, _) => attributes - case Type.Function(attributes, _, _) => attributes - case Type.Record(attributes, _) => attributes - case Type.Reference(attributes, _, _) => attributes // TODO: Ignored type arguments here might be an issue - case Type.Tuple(attributes, _) => attributes - case Type.Unit(attributes) => attributes - case Type.Variable(attributes, _) => attributes + curryTypeFunction(Type.Function(getAttributes(inner), chunk.head._2, inner), chunk.tail) } + def getAttributes[TA](tpe: Type[TA]): TA = + tpe.attributes +// tpe match { +// case Type.ExtensibleRecord(attributes, _, _) => attributes +// case Type.Function(attributes, _, _) => attributes +// case Type.Record(attributes, _) => attributes +// case Type.Reference(attributes, _, _) => attributes // TODO: Ignored type arguments here might be an issue +// case Type.Tuple(attributes, _) => attributes +// case Type.Unit(attributes) => attributes +// case Type.Variable(attributes, _) => attributes +// } } From 92368ac8b74dd26f23d7a391e9d700d1313dafee Mon Sep 17 00:00:00 2001 From: Edward Peters Date: Tue, 8 Aug 2023 18:06:14 -0700 Subject: [PATCH 02/10] Gather references implementation --- .../Morphir/Examples/App/TypeCheckerTests.elm | 12 ++ .../runtime/quick/GatherReferences.scala | 157 ++++++++++++++++++ .../morphir/runtime/TypeCheckerSpec.scala | 122 ++++++++++++++ .../quick/ExtensionInterfaceSpec.scala | 45 +++++ .../runtime/quick/GatherRefsSpec.scala | 91 ++++++++++ .../morphir/runtime/quick/TypeCheckSpec.scala | 74 +++++++++ 6 files changed, 501 insertions(+) create mode 100644 examples/morphir-elm-projects/evaluator-tests/src/Morphir/Examples/App/TypeCheckerTests.elm create mode 100644 morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala create mode 100644 morphir/runtime/test/jvm/src/org/finos/morphir/runtime/TypeCheckerSpec.scala create mode 100644 morphir/runtime/test/src/org/finos/morphir/runtime/quick/ExtensionInterfaceSpec.scala create mode 100644 morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala create mode 100644 morphir/runtime/test/src/org/finos/morphir/runtime/quick/TypeCheckSpec.scala diff --git a/examples/morphir-elm-projects/evaluator-tests/src/Morphir/Examples/App/TypeCheckerTests.elm b/examples/morphir-elm-projects/evaluator-tests/src/Morphir/Examples/App/TypeCheckerTests.elm new file mode 100644 index 000000000..341ccccda --- /dev/null +++ b/examples/morphir-elm-projects/evaluator-tests/src/Morphir/Examples/App/TypeCheckerTests.elm @@ -0,0 +1,12 @@ +module Morphir.Examples.App.TypeCheckerTests exposing (..) + + +withParam : (List a) -> a +withParam l = case l of + head :: _ -> head + _ -> withParam l + +withInt : (List Int) -> Int +withInt l = case l of + head :: _ -> head + _ -> withParam l \ No newline at end of file diff --git a/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala b/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala new file mode 100644 index 000000000..01b85430f --- /dev/null +++ b/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala @@ -0,0 +1,157 @@ +package org.finos.morphir.runtime.quick + +import org.finos.morphir.naming._ +import org.finos.morphir.ir.Value.{Pattern, Value as V} +import org.finos.morphir.ir.Type as T +import org.finos.morphir.ir.Type.Type +import org.finos.morphir.ir.Value.Pattern.* +import org.finos.morphir.ir.Value.Value +import org.finos.morphir.ir.Type.UType +import org.finos.morphir.ir.distribution.Distribution.Library +import org.finos.morphir.ir.distribution.Distribution +import zio.Chunk + +object GatherReferences { + type TypedValue = Value[Unit, UType] + //Gather references from distribution* + //Also from Store? (Yeah, redundancy is okay, and there are + //Helper: Recursively explore value + //Diff vs. Store + def fromStore(store : Store[Unit, UType]) : ReferenceSet = { + store.definitions.map{case (name, value) => value match { + case SDKValue.SDKValueDefinition(definition) => loop(definition.body).withDefinition(name) //TODO: Types! + case _ => ReferenceSet.empty.withDefinition(name) + }}.foldLeft(ReferenceSet.empty)((acc, next) => acc ++ next) ++ + store.ctors.keys.foldLeft(ReferenceSet.empty)((acc, next) => acc.withConstructor(next)) + } + + def fromEntrySet(entrySet : ReferenceSet, dists : Distribution*) : ReferenceSet = { + val mapped = dists.map(dist => (dist.asInstanceOf[Library].packageName, dist)).toMap + def f(known : Set[FQName], ref : FQName) : Set[FQName] = { + //if (depth > 100) throw new Exception(s"Still recursing on $next with known values ${known.toList.mkString("\n")}") + val (pkg, mod, loc) = (ref.pack, ref.getModulePath, ref.localName) + val qName = QName(mod, loc) + mapped.get(pkg) match { + case Some(dist) => + val definition = dist.asInstanceOf[Library].lookupValueDefinition(qName).get + val discovered = loop(definition.body).definitions + val newbs = discovered.diff(known) + println(s"Exploring $ref found $discovered") + newbs.foldLeft(known ++ discovered)((acc, newb) => acc ++ f(acc, newb)) + case None => known + ref + } + } + val found = entrySet.definitions.foldLeft(entrySet.definitions)((acc, newb) => acc ++ f(acc, newb)) + ReferenceSet(entrySet.definitions ++ found, Set(), Set()) + } + def fromDistributions(dists : Distribution*): ReferenceSet = { + dists.foldLeft(ReferenceSet.empty)((acc : ReferenceSet, dist : Distribution) => acc ++ (dist match{ + case l : Library => fromLibrary(l) + })) + } + def fromLibrary(lib : Library) : ReferenceSet = { + val packageName = lib.packageName + val valueReferences : List[ReferenceSet] = lib.packageDef.modules.toList.flatMap { case (moduleName, accessControlledModule) => + accessControlledModule.value.values.map { + case (localName, accessControlledValue) => + val fqn = FQName(packageName, moduleName, localName) + val definition = accessControlledValue.value.value + loop(definition.body).withDefinition(fqn) + } + } + val ctorReferences : List[ReferenceSet]= + lib.packageDef.modules.toList.flatMap { case (moduleName, accessControlledModule) => + accessControlledModule.value.types.flatMap { + case (localName, accessControlledType) => + val definition = accessControlledType.value.value + definition match { + case T.Definition.CustomType(_, accessControlledCtors) => + val ctors = accessControlledCtors.value.toMap + ctors.map { case (ctorName, ctorArgs) => + val name = FQName(packageName, moduleName, ctorName) + ReferenceSet.empty.withConstructor(name) + } + case T.Definition.TypeAlias(_, _) => List(ReferenceSet.empty) + } + } + } + valueReferences.foldLeft(ReferenceSet.empty)((acc, next) => acc ++ next) ++ + ctorReferences.foldLeft(ReferenceSet.empty)((acc, next) => acc ++ next) + } + + case class ReferenceSet( + definitions : Set[FQName], + constructors : Set[FQName], + types : Set[FQName] + ){ + def ++ (other : ReferenceSet) : ReferenceSet = { + ReferenceSet( + definitions ++ other.definitions, + constructors ++ other.constructors, + types ++ other.types + ) + } + def withConstructor(ctor : FQName) = { + ReferenceSet( + definitions, + constructors + ctor, + types + ) + } + + def withDefinition(definition: FQName) = { + ReferenceSet( + definitions + definition, + constructors, + types + ) + } + } + object ReferenceSet{ + val empty = ReferenceSet(Set(), Set(), Set()) + } + + def loop(ir: TypedValue): ReferenceSet = { + val empty = ReferenceSet.empty; + + def fold(stuff: Iterable[TypedValue]): ReferenceSet = stuff.foldLeft(empty) { case (acc, next) => acc ++ loop(next) } + + ir match { + case Value.Literal(_, lit) => empty + case Value.Apply(_, function, argument) => loop(function) ++ loop(argument) + case Value.Destructure(_, pattern, valueToDestruct, inValue) => + loop(valueToDestruct) ++ loop(inValue) ++ patternLoop(pattern) + case Value.Constructor(_, fqn) => empty.withConstructor(fqn) + case Value.Field(_, recordValue, _) => loop(recordValue) + case Value.FieldFunction(_, name) => empty + case Value.IfThenElse(_, condition, thenValue, elseValue) => + loop(condition) ++ loop(thenValue) ++ loop(elseValue) + case Value.Lambda(_, pattern, body) => patternLoop(pattern) ++ loop(body) + case Value.LetDefinition(_, _, definition, inValue) => + loop(definition.body) ++ loop(inValue) + case Value.LetRecursion(_, definitions, inValue) => fold(definitions.map(_._2.body)) ++ loop(inValue) + case Value.List(_, elements) => fold(elements) + case Value.PatternMatch(_, value, cases) => loop(value) ++ cases.foldLeft(empty) { case (acc, (pattern, value)) => acc ++ loop(value) ++ patternLoop(pattern) } + case Value.Record(_, fields) => fold(fields.map(_._2)) + case Value.Reference(_, name) => empty.withDefinition(name) + case Value.Tuple(_, elements) => fold(elements) + case Value.Unit(_) => empty + case Value.UpdateRecord(_, valueToUpdate, fields) => loop(valueToUpdate) ++ fold(fields.map(_._2)) + case Value.Variable(_, name) => empty + } + } + def patternLoop(pattern : Pattern[UType]) : ReferenceSet = { + val empty = ReferenceSet.empty; + def fold(stuff: Chunk[Pattern[UType]]): ReferenceSet = stuff.foldLeft(empty) { case (acc, next) => acc ++ patternLoop(next) } + pattern match { + case _: WildcardPattern[_] => empty + case AsPattern(_, innerPattern, name) =>patternLoop(innerPattern) + case _: UnitPattern[_] => empty + case LiteralPattern(_, _)=> empty + case _: EmptyListPattern[_] => empty + case HeadTailPattern(_, headPattern, tailPattern) => patternLoop(headPattern) ++ patternLoop(tailPattern) + case TuplePattern(_, patterns) => fold(patterns) + case ConstructorPattern(_, patternName, patterns) => empty.withConstructor(patternName) ++fold(patterns) + } + } +} diff --git a/morphir/runtime/test/jvm/src/org/finos/morphir/runtime/TypeCheckerSpec.scala b/morphir/runtime/test/jvm/src/org/finos/morphir/runtime/TypeCheckerSpec.scala new file mode 100644 index 000000000..172768d72 --- /dev/null +++ b/morphir/runtime/test/jvm/src/org/finos/morphir/runtime/TypeCheckerSpec.scala @@ -0,0 +1,122 @@ +package org.finos.morphir.runtime + +import org.finos.morphir.testing.MorphirBaseSpec +import zio.{Console, Task, ZIO, ZLayer} +import zio.test.{test, *} +import org.finos.morphir.runtime.MorphirRuntime +import org.finos.morphir.datamodel.{Data, Concept, Label, EnumLabel} +import org.finos.morphir.datamodel.namespacing.Namespace.ns +import org.finos.morphir.datamodel.namespacing.PackageName.root +import org.finos.morphir.datamodel.Util.* +import org.finos.morphir.ir.Type +import org.finos.morphir.naming.* +import org.finos.morphir.ir.conversion.* +import org.finos.morphir.datamodel.Util.* +import org.finos.morphir.datamodel.* +import org.finos.morphir.naming.* +import org.finos.morphir.runtime.environment.MorphirEnv +import zio.test.TestAspect.{ignore, tag} + +object TypeCheckerSpec extends MorphirBaseSpec { + type MorphirRuntimeTyped = MorphirRuntime[Unit, Type.UType] + + val morphirRuntimeLayer: ZLayer[Any, Throwable, MorphirRuntime[Unit, Type.UType]] = + ZLayer(for { + irFilePath <- ZIO.succeed(os.pwd / "examples" / "morphir-elm-projects" / "evaluator-tests" / "morphir-ir.json") + _ <- Console.printLine(s"Loading distribution from $irFilePath") + dist <- EvaluationLibrary.loadDistributionFromFileZIO(irFilePath.toString) + } yield MorphirRuntime.quick(dist)) + + def deriveData(input: Any): Data = + input match { + case u: Unit => Deriver.toData(u) + case i: Int => Deriver.toData(i) + case s: String => Deriver.toData(s) + case (l: Any, r: Any) => Data.Tuple(deriveData(l), deriveData(r)) + case l: List[_] => Data.List(deriveData(l.head), l.tail.map(deriveData(_)): _*) + case other => throw new Exception(s"Couldn't derive $other") + } + + def checkEvaluation( + moduleName: String, + functionName: String, + value: Any + )(expected: => Data): ZIO[MorphirRuntimeTyped, Throwable, TestResult] = + runTest(moduleName, functionName, value).map { actual => + assertTrue(actual == expected) + } + def testEval(label: String)(moduleName: String, functionName: String, value: Any)(expected: => Data) = + test(label) { + checkEvaluation(moduleName, functionName, value)(expected) + } + def runTest( + moduleName: String, + functionName: String, + value: Any + ): ZIO[MorphirRuntimeTyped, Throwable, Data] = + ZIO.serviceWithZIO[MorphirRuntimeTyped] { runtime => + val fullName = s"Morphir.Examples.App:$moduleName:$functionName" + val data = deriveData(value) + + runtime.evaluate(FQName.fromString(fullName), data) + .provideEnvironment(MorphirEnv.live) + .toZIOWith(RTExecutionContext.default) + } + + def typeArgUnionShape(c1: Concept, c2: Concept): Concept.Enum = Concept.Enum( + qn"Morphir/Examples/App:ExampleModule:TypeArgUnion", + List( + Concept.Enum.Case( + Label("b"), + List(Tuple2( + EnumLabel.Named("arg1"), + c2 + )) + ), + Concept.Enum.Case( + Label("aB"), + List( + ( + EnumLabel.Named("arg1"), + c1 + ), + ( + EnumLabel.Named("arg2"), + c2 + ) + ) + ), + Concept.Enum.Case( + Label("a"), + List(( + EnumLabel.Named("arg1"), + c1 + )) + ), + Concept.Enum.Case( + Label("dictBA"), + List(( + EnumLabel.Named("arg1"), + Concept.Map( + c2, + c1 + ) + )) + ), + Concept.Enum.Case( + Label("maybeA"), + List(( + EnumLabel.Named("arg1"), + Concept.Optional(c1) + )) + ) + ) + ) + + def spec = + suite("Evaluator Type Checker Tests")( + suite("List Tests")( + testEval("Finds element type of list")("typeCheckerTests", "withParam", List(4, 5, 7))(Data.Int(4)) + ) + ).provideLayerShared(morphirRuntimeLayer) +} diff --git a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/ExtensionInterfaceSpec.scala b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/ExtensionInterfaceSpec.scala new file mode 100644 index 000000000..cb03cf7fb --- /dev/null +++ b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/ExtensionInterfaceSpec.scala @@ -0,0 +1,45 @@ +//package org.finos.morphir.runtime.quick +// +//import org.finos.morphir.testing.MorphirBaseSpec +//import org.finos.morphir.ir.{FQName, Module, MorphirIRFile, Name, QName} +//import org.finos.morphir.ir.Type as T +//import org.finos.morphir.ir.Value as V +//import org.finos.morphir.ir.Documented +// +//import scala.collection.immutable.ListMap +//import zio.{test as _, *} +//import zio.prelude.fx.* +//import zio.test.{Result as TestResult, *} +//import zio.test.Assertion.{equalTo, fails} +//import zio.test.TestAspect.{ignore, tag} +//import org.finos.morphir.ir.sdk.Basics +//import ExtensionInterface.* +//import org.finos.morphir.runtime.quick.EvaluatorQuick.IntType +// +// +//object ExtensionInterfaceSpec extends MorphirBaseSpec{ +// +// +// +// def spec = suite("Basic Exploration")( +// test("Value lookup") { +// val something = Basics.moduleSpec.values(Name("floor")) +// val extracted : Any = extract(something) +// assertTrue(true) +// }, +// test("Lookup by FQName"){ +// val lookedUp = lookup(FQName.fromString("Morphir.SDK:Basics:round")) +// val extracted : Any = extract(lookedUp) +// assertTrue(true) +// }, +// test("Auto conversion 1"){ +// val nativeFunction : Any= makeNative(FQName.fromString("Morphir.SDK:Basics:round"), (x : Double) => x.toInt) +// assertTrue (true) +// }, +// test("Auto conversion 2") { +// val addName = FQName.fromString("Morphir.SDK:Basics:add") +// val gennedAdd : Any= ExtensionInterface.makeNative[Unit, T.UType](addName, (arg1: IntType, arg2: IntType) => arg1 + arg2) +// assertTrue(gennedAdd == "Woo!") +// } +// ) +//} diff --git a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala new file mode 100644 index 000000000..d86a7bca1 --- /dev/null +++ b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala @@ -0,0 +1,91 @@ +package org.finos.morphir.runtime.quick + +import org.finos.morphir.datamodel.* +import org.finos.morphir.datamodel.Util.* +import org.finos.morphir.ir.Type.UType +import org.finos.morphir.ir.conversion.* +import org.finos.morphir.ir.distribution.Distribution.Library +import org.finos.morphir.ir.printing.{DetailLevel, FieldNames, PrintIR} +import org.finos.morphir.ir.sdk.Basics +import org.finos.morphir.ir.{Documented, Module, MorphirIRFile, Type as T, Value as V} +import org.finos.morphir.naming.* +import org.finos.morphir.runtime.* +import org.finos.morphir.testing.MorphirBaseSpec +import zio.prelude.fx.* +import zio.test.Assertion.{equalTo, fails} +import zio.test.TestAspect.{ignore, tag} +import zio.test.{Result as TestResult, *} +import zio.{test as _, *} + +import scala.collection.immutable.ListMap + +object GatherRefsSpec extends MorphirBaseSpec { + val dist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") + val mattDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/matt-instrument/morphir-ir.json") + val maestroDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/maestro-sdk/morphir-ir.json") + val mappingDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/mapping-logic/morphir-ir.json") + val example : FQName = FQName.fromString("Morphir.SDK:Basics:and") + val existing = Native.native.keys +// +// class ListThing(name: String) { +// val ref = FQName.fromString(name) +// val (pkg, mod, loc) = (ref.getPackagePath, ref.getModulePath, ref.localName) +// val value = lib.lookupValueSpecification(PackageName(pkg), ModuleName(mod), loc).get +// val listArg = value.inputs(0)._2 +// } +// val withParam = new ListThing("Morphir.Examples.App:TypeCheckerTests:withParam") +// val withInt = new ListThing("Morphir.Examples.App:TypeCheckerTests:withInt") +// val listConcept = Concept.List(Concept.Integer) +// val toType = ToMorphirType.summon[Concept] +// val intListType = toType.withAttributesOf(listConcept).morphirType + + + def spec = suite("Exploration")( + suite("From Distribution")( + test("Everything") { + val stuff = GatherReferences.fromDistributions(dist) + val defs = stuff.definitions.map(_.toString).mkString("\n") + assertTrue(defs == "") + }, + test("SDK Defs") { + val stuff = GatherReferences.fromDistributions(dist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + }, + test("SDK Defs from Mapping"){ + val stuff = GatherReferences.fromDistributions(mattDist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + }, + test("SDK Defs from Everywhere") { + val stuff = GatherReferences.fromDistributions(mattDist, mappingDist, maestroDist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + }, + test("Missing Defs from Mapping") { + val stuff = GatherReferences.fromDistributions(mattDist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + }, + test("Missing SDK Defs from Everywhere") { + val stuff = GatherReferences.fromDistributions(mattDist, mappingDist, maestroDist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + }, + test("Only actually used"){ + val stuff = GatherReferences.fromDistributions(mattDist) + val moreStuff = GatherReferences.fromEntrySet(stuff, mattDist, mappingDist, maestroDist) + val defs = moreStuff.definitions//.filter(_.getPackagePath == example.getPackagePath)//.diff(existing.toSet) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + + } + ), + ) + +} diff --git a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/TypeCheckSpec.scala b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/TypeCheckSpec.scala new file mode 100644 index 000000000..cc95b98c7 --- /dev/null +++ b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/TypeCheckSpec.scala @@ -0,0 +1,74 @@ +package org.finos.morphir.runtime.quick + +import org.finos.morphir.naming.* +import org.finos.morphir.testing.MorphirBaseSpec +import org.finos.morphir.ir.{Module, MorphirIRFile} +import org.finos.morphir.ir.Type as T +import org.finos.morphir.ir.Value as V +import org.finos.morphir.ir.Documented +import org.finos.morphir.runtime.* +import scala.collection.immutable.ListMap +import zio.{test as _, *} +import zio.prelude.fx.* +import zio.test.{Result as TestResult, *} +import zio.test.Assertion.{equalTo, fails} +import zio.test.TestAspect.{ignore, tag} +import org.finos.morphir.ir.sdk.Basics +import org.finos.morphir.ir.distribution.Distribution.Library +import org.finos.morphir.ir.printing.PrintIR +import org.finos.morphir.ir.printing.DetailLevel +import org.finos.morphir.ir.printing.FieldNames +import org.finos.morphir.ir.conversion.* +import org.finos.morphir.datamodel.Util.* +import org.finos.morphir.datamodel.* +import org.finos.morphir.ir.sdk.Basics +import org.finos.morphir.ir.Type.UType + +object TypeCheckSpec extends MorphirBaseSpec { + val lib = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") + .asInstanceOf[Library] + + class ListThing(name: String) { + val ref = FQName.fromString(name) + val (pkg, mod, loc) = (ref.getPackagePath, ref.getModulePath, ref.localName) + val value = lib.lookupValueSpecification(PackageName(pkg), ModuleName(mod), loc).get + val listArg = value.inputs(0)._2 + } + val withParam = new ListThing("Morphir.Examples.App:TypeCheckerTests:withParam") + val withInt = new ListThing("Morphir.Examples.App:TypeCheckerTests:withInt") + val listConcept = Concept.List(Concept.Integer) + val toType = ToMorphirType.summon[Concept] + val intListType = toType.withAttributesOf(listConcept).morphirType + + def spec = suite("Exploration")( +// suite("Lookup")( +// test("withParam") { +// assertTrue(PrintIR(withParam.value).toString() == "Yes") +// }, +// test("withInt") { +// assertTrue(PrintIR(withInt.value).toString() == "Yes") +// } +// ), +// suite("listArg")( +// test("withParam") { +// assertTrue(PrintIR(withParam.listArg, DetailLevel.Medium).toString() == "listArg") +// }, +// test("withInt") { +// assertTrue(PrintIR(withInt.listArg, DetailLevel.Medium).toString() == "listArg") +// } +// ), + suite("Int List Type Checks")( + test("Concept") { + val mapped = Utils.typeCheckArg(intListType, withInt.listArg, Map()) + assertTrue(mapped == Right(Map[Name, UType]())) + } + ), + suite("Param List Type Checks")( + test("Concept") { + val mapped = Utils.typeCheckArg(intListType, withParam.listArg, Map()) + assertTrue(mapped == Right(Map(Name("a") -> Basics.intType))) + } + ) + ) + +} From 87466865a5775726fc491ee436cffbd77be9c295 Mon Sep 17 00:00:00 2001 From: Edward Peters Date: Tue, 22 Aug 2023 09:10:21 -0700 Subject: [PATCH 03/10] Removed unwanted files --- .../morphir/runtime/TypeCheckerSpec.scala | 122 ------------------ .../quick/ExtensionInterfaceSpec.scala | 45 ------- .../morphir/runtime/quick/TypeCheckSpec.scala | 74 ----------- 3 files changed, 241 deletions(-) delete mode 100644 morphir/runtime/test/jvm/src/org/finos/morphir/runtime/TypeCheckerSpec.scala delete mode 100644 morphir/runtime/test/src/org/finos/morphir/runtime/quick/ExtensionInterfaceSpec.scala delete mode 100644 morphir/runtime/test/src/org/finos/morphir/runtime/quick/TypeCheckSpec.scala diff --git a/morphir/runtime/test/jvm/src/org/finos/morphir/runtime/TypeCheckerSpec.scala b/morphir/runtime/test/jvm/src/org/finos/morphir/runtime/TypeCheckerSpec.scala deleted file mode 100644 index 172768d72..000000000 --- a/morphir/runtime/test/jvm/src/org/finos/morphir/runtime/TypeCheckerSpec.scala +++ /dev/null @@ -1,122 +0,0 @@ -package org.finos.morphir.runtime - -import org.finos.morphir.testing.MorphirBaseSpec -import zio.{Console, Task, ZIO, ZLayer} -import zio.test.{test, *} -import org.finos.morphir.runtime.MorphirRuntime -import org.finos.morphir.datamodel.{Data, Concept, Label, EnumLabel} -import org.finos.morphir.datamodel.namespacing.Namespace.ns -import org.finos.morphir.datamodel.namespacing.PackageName.root -import org.finos.morphir.datamodel.Util.* -import org.finos.morphir.ir.Type -import org.finos.morphir.naming.* -import org.finos.morphir.ir.conversion.* -import org.finos.morphir.datamodel.Util.* -import org.finos.morphir.datamodel.* -import org.finos.morphir.naming.* -import org.finos.morphir.runtime.environment.MorphirEnv -import zio.test.TestAspect.{ignore, tag} - -object TypeCheckerSpec extends MorphirBaseSpec { - type MorphirRuntimeTyped = MorphirRuntime[Unit, Type.UType] - - val morphirRuntimeLayer: ZLayer[Any, Throwable, MorphirRuntime[Unit, Type.UType]] = - ZLayer(for { - irFilePath <- ZIO.succeed(os.pwd / "examples" / "morphir-elm-projects" / "evaluator-tests" / "morphir-ir.json") - _ <- Console.printLine(s"Loading distribution from $irFilePath") - dist <- EvaluationLibrary.loadDistributionFromFileZIO(irFilePath.toString) - } yield MorphirRuntime.quick(dist)) - - def deriveData(input: Any): Data = - input match { - case u: Unit => Deriver.toData(u) - case i: Int => Deriver.toData(i) - case s: String => Deriver.toData(s) - case (l: Any, r: Any) => Data.Tuple(deriveData(l), deriveData(r)) - case l: List[_] => Data.List(deriveData(l.head), l.tail.map(deriveData(_)): _*) - case other => throw new Exception(s"Couldn't derive $other") - } - - def checkEvaluation( - moduleName: String, - functionName: String, - value: Any - )(expected: => Data): ZIO[MorphirRuntimeTyped, Throwable, TestResult] = - runTest(moduleName, functionName, value).map { actual => - assertTrue(actual == expected) - } - def testEval(label: String)(moduleName: String, functionName: String, value: Any)(expected: => Data) = - test(label) { - checkEvaluation(moduleName, functionName, value)(expected) - } - def runTest( - moduleName: String, - functionName: String, - value: Any - ): ZIO[MorphirRuntimeTyped, Throwable, Data] = - ZIO.serviceWithZIO[MorphirRuntimeTyped] { runtime => - val fullName = s"Morphir.Examples.App:$moduleName:$functionName" - val data = deriveData(value) - - runtime.evaluate(FQName.fromString(fullName), data) - .provideEnvironment(MorphirEnv.live) - .toZIOWith(RTExecutionContext.default) - } - - def typeArgUnionShape(c1: Concept, c2: Concept): Concept.Enum = Concept.Enum( - qn"Morphir/Examples/App:ExampleModule:TypeArgUnion", - List( - Concept.Enum.Case( - Label("b"), - List(Tuple2( - EnumLabel.Named("arg1"), - c2 - )) - ), - Concept.Enum.Case( - Label("aB"), - List( - ( - EnumLabel.Named("arg1"), - c1 - ), - ( - EnumLabel.Named("arg2"), - c2 - ) - ) - ), - Concept.Enum.Case( - Label("a"), - List(( - EnumLabel.Named("arg1"), - c1 - )) - ), - Concept.Enum.Case( - Label("dictBA"), - List(( - EnumLabel.Named("arg1"), - Concept.Map( - c2, - c1 - ) - )) - ), - Concept.Enum.Case( - Label("maybeA"), - List(( - EnumLabel.Named("arg1"), - Concept.Optional(c1) - )) - ) - ) - ) - - def spec = - suite("Evaluator Type Checker Tests")( - suite("List Tests")( - testEval("Finds element type of list")("typeCheckerTests", "withParam", List(4, 5, 7))(Data.Int(4)) - ) - ).provideLayerShared(morphirRuntimeLayer) -} diff --git a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/ExtensionInterfaceSpec.scala b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/ExtensionInterfaceSpec.scala deleted file mode 100644 index cb03cf7fb..000000000 --- a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/ExtensionInterfaceSpec.scala +++ /dev/null @@ -1,45 +0,0 @@ -//package org.finos.morphir.runtime.quick -// -//import org.finos.morphir.testing.MorphirBaseSpec -//import org.finos.morphir.ir.{FQName, Module, MorphirIRFile, Name, QName} -//import org.finos.morphir.ir.Type as T -//import org.finos.morphir.ir.Value as V -//import org.finos.morphir.ir.Documented -// -//import scala.collection.immutable.ListMap -//import zio.{test as _, *} -//import zio.prelude.fx.* -//import zio.test.{Result as TestResult, *} -//import zio.test.Assertion.{equalTo, fails} -//import zio.test.TestAspect.{ignore, tag} -//import org.finos.morphir.ir.sdk.Basics -//import ExtensionInterface.* -//import org.finos.morphir.runtime.quick.EvaluatorQuick.IntType -// -// -//object ExtensionInterfaceSpec extends MorphirBaseSpec{ -// -// -// -// def spec = suite("Basic Exploration")( -// test("Value lookup") { -// val something = Basics.moduleSpec.values(Name("floor")) -// val extracted : Any = extract(something) -// assertTrue(true) -// }, -// test("Lookup by FQName"){ -// val lookedUp = lookup(FQName.fromString("Morphir.SDK:Basics:round")) -// val extracted : Any = extract(lookedUp) -// assertTrue(true) -// }, -// test("Auto conversion 1"){ -// val nativeFunction : Any= makeNative(FQName.fromString("Morphir.SDK:Basics:round"), (x : Double) => x.toInt) -// assertTrue (true) -// }, -// test("Auto conversion 2") { -// val addName = FQName.fromString("Morphir.SDK:Basics:add") -// val gennedAdd : Any= ExtensionInterface.makeNative[Unit, T.UType](addName, (arg1: IntType, arg2: IntType) => arg1 + arg2) -// assertTrue(gennedAdd == "Woo!") -// } -// ) -//} diff --git a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/TypeCheckSpec.scala b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/TypeCheckSpec.scala deleted file mode 100644 index cc95b98c7..000000000 --- a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/TypeCheckSpec.scala +++ /dev/null @@ -1,74 +0,0 @@ -package org.finos.morphir.runtime.quick - -import org.finos.morphir.naming.* -import org.finos.morphir.testing.MorphirBaseSpec -import org.finos.morphir.ir.{Module, MorphirIRFile} -import org.finos.morphir.ir.Type as T -import org.finos.morphir.ir.Value as V -import org.finos.morphir.ir.Documented -import org.finos.morphir.runtime.* -import scala.collection.immutable.ListMap -import zio.{test as _, *} -import zio.prelude.fx.* -import zio.test.{Result as TestResult, *} -import zio.test.Assertion.{equalTo, fails} -import zio.test.TestAspect.{ignore, tag} -import org.finos.morphir.ir.sdk.Basics -import org.finos.morphir.ir.distribution.Distribution.Library -import org.finos.morphir.ir.printing.PrintIR -import org.finos.morphir.ir.printing.DetailLevel -import org.finos.morphir.ir.printing.FieldNames -import org.finos.morphir.ir.conversion.* -import org.finos.morphir.datamodel.Util.* -import org.finos.morphir.datamodel.* -import org.finos.morphir.ir.sdk.Basics -import org.finos.morphir.ir.Type.UType - -object TypeCheckSpec extends MorphirBaseSpec { - val lib = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") - .asInstanceOf[Library] - - class ListThing(name: String) { - val ref = FQName.fromString(name) - val (pkg, mod, loc) = (ref.getPackagePath, ref.getModulePath, ref.localName) - val value = lib.lookupValueSpecification(PackageName(pkg), ModuleName(mod), loc).get - val listArg = value.inputs(0)._2 - } - val withParam = new ListThing("Morphir.Examples.App:TypeCheckerTests:withParam") - val withInt = new ListThing("Morphir.Examples.App:TypeCheckerTests:withInt") - val listConcept = Concept.List(Concept.Integer) - val toType = ToMorphirType.summon[Concept] - val intListType = toType.withAttributesOf(listConcept).morphirType - - def spec = suite("Exploration")( -// suite("Lookup")( -// test("withParam") { -// assertTrue(PrintIR(withParam.value).toString() == "Yes") -// }, -// test("withInt") { -// assertTrue(PrintIR(withInt.value).toString() == "Yes") -// } -// ), -// suite("listArg")( -// test("withParam") { -// assertTrue(PrintIR(withParam.listArg, DetailLevel.Medium).toString() == "listArg") -// }, -// test("withInt") { -// assertTrue(PrintIR(withInt.listArg, DetailLevel.Medium).toString() == "listArg") -// } -// ), - suite("Int List Type Checks")( - test("Concept") { - val mapped = Utils.typeCheckArg(intListType, withInt.listArg, Map()) - assertTrue(mapped == Right(Map[Name, UType]())) - } - ), - suite("Param List Type Checks")( - test("Concept") { - val mapped = Utils.typeCheckArg(intListType, withParam.listArg, Map()) - assertTrue(mapped == Right(Map(Name("a") -> Basics.intType))) - } - ) - ) - -} From 62b8b222a001427ecc63d54b4707e022c96f0ba6 Mon Sep 17 00:00:00 2001 From: Edward Peters Date: Tue, 22 Aug 2023 09:13:54 -0700 Subject: [PATCH 04/10] Formatting, disable tests --- .../runtime/quick/GatherReferences.scala | 134 +++++++++--------- .../runtime/quick/GatherRefsSpec.scala | 53 +++---- 2 files changed, 90 insertions(+), 97 deletions(-) diff --git a/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala b/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala index 01b85430f..621fdda36 100644 --- a/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala +++ b/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala @@ -13,29 +13,30 @@ import zio.Chunk object GatherReferences { type TypedValue = Value[Unit, UType] - //Gather references from distribution* - //Also from Store? (Yeah, redundancy is okay, and there are - //Helper: Recursively explore value - //Diff vs. Store - def fromStore(store : Store[Unit, UType]) : ReferenceSet = { - store.definitions.map{case (name, value) => value match { - case SDKValue.SDKValueDefinition(definition) => loop(definition.body).withDefinition(name) //TODO: Types! - case _ => ReferenceSet.empty.withDefinition(name) - }}.foldLeft(ReferenceSet.empty)((acc, next) => acc ++ next) ++ + // Gather references from distribution* + // Also from Store? (Yeah, redundancy is okay, and there are + // Helper: Recursively explore value + // Diff vs. Store + def fromStore(store: Store[Unit, UType]): ReferenceSet = + store.definitions.map { case (name, value) => + value match { + case SDKValue.SDKValueDefinition(definition) => loop(definition.body).withDefinition(name) // TODO: Types! + case _ => ReferenceSet.empty.withDefinition(name) + } + }.foldLeft(ReferenceSet.empty)((acc, next) => acc ++ next) ++ store.ctors.keys.foldLeft(ReferenceSet.empty)((acc, next) => acc.withConstructor(next)) - } - def fromEntrySet(entrySet : ReferenceSet, dists : Distribution*) : ReferenceSet = { + def fromEntrySet(entrySet: ReferenceSet, dists: Distribution*): ReferenceSet = { val mapped = dists.map(dist => (dist.asInstanceOf[Library].packageName, dist)).toMap - def f(known : Set[FQName], ref : FQName) : Set[FQName] = { - //if (depth > 100) throw new Exception(s"Still recursing on $next with known values ${known.toList.mkString("\n")}") + def f(known: Set[FQName], ref: FQName): Set[FQName] = { + // if (depth > 100) throw new Exception(s"Still recursing on $next with known values ${known.toList.mkString("\n")}") val (pkg, mod, loc) = (ref.pack, ref.getModulePath, ref.localName) - val qName = QName(mod, loc) + val qName = QName(mod, loc) mapped.get(pkg) match { case Some(dist) => val definition = dist.asInstanceOf[Library].lookupValueDefinition(qName).get val discovered = loop(definition.body).definitions - val newbs = discovered.diff(known) + val newbs = discovered.diff(known) println(s"Exploring $ref found $discovered") newbs.foldLeft(known ++ discovered)((acc, newb) => acc ++ f(acc, newb)) case None => known + ref @@ -44,22 +45,24 @@ object GatherReferences { val found = entrySet.definitions.foldLeft(entrySet.definitions)((acc, newb) => acc ++ f(acc, newb)) ReferenceSet(entrySet.definitions ++ found, Set(), Set()) } - def fromDistributions(dists : Distribution*): ReferenceSet = { - dists.foldLeft(ReferenceSet.empty)((acc : ReferenceSet, dist : Distribution) => acc ++ (dist match{ - case l : Library => fromLibrary(l) - })) - } - def fromLibrary(lib : Library) : ReferenceSet = { + def fromDistributions(dists: Distribution*): ReferenceSet = + dists.foldLeft(ReferenceSet.empty)((acc: ReferenceSet, dist: Distribution) => + acc ++ (dist match { + case l: Library => fromLibrary(l) + }) + ) + def fromLibrary(lib: Library): ReferenceSet = { val packageName = lib.packageName - val valueReferences : List[ReferenceSet] = lib.packageDef.modules.toList.flatMap { case (moduleName, accessControlledModule) => - accessControlledModule.value.values.map { - case (localName, accessControlledValue) => - val fqn = FQName(packageName, moduleName, localName) - val definition = accessControlledValue.value.value - loop(definition.body).withDefinition(fqn) + val valueReferences: List[ReferenceSet] = + lib.packageDef.modules.toList.flatMap { case (moduleName, accessControlledModule) => + accessControlledModule.value.values.map { + case (localName, accessControlledValue) => + val fqn = FQName(packageName, moduleName, localName) + val definition = accessControlledValue.value.value + loop(definition.body).withDefinition(fqn) + } } - } - val ctorReferences : List[ReferenceSet]= + val ctorReferences: List[ReferenceSet] = lib.packageDef.modules.toList.flatMap { case (moduleName, accessControlledModule) => accessControlledModule.value.types.flatMap { case (localName, accessControlledType) => @@ -80,78 +83,81 @@ object GatherReferences { } case class ReferenceSet( - definitions : Set[FQName], - constructors : Set[FQName], - types : Set[FQName] - ){ - def ++ (other : ReferenceSet) : ReferenceSet = { + definitions: Set[FQName], + constructors: Set[FQName], + types: Set[FQName] + ) { + def ++(other: ReferenceSet): ReferenceSet = ReferenceSet( definitions ++ other.definitions, constructors ++ other.constructors, types ++ other.types ) - } - def withConstructor(ctor : FQName) = { + def withConstructor(ctor: FQName) = ReferenceSet( definitions, constructors + ctor, types ) - } - def withDefinition(definition: FQName) = { + def withDefinition(definition: FQName) = ReferenceSet( definitions + definition, constructors, types ) - } } - object ReferenceSet{ + object ReferenceSet { val empty = ReferenceSet(Set(), Set(), Set()) } def loop(ir: TypedValue): ReferenceSet = { val empty = ReferenceSet.empty; - def fold(stuff: Iterable[TypedValue]): ReferenceSet = stuff.foldLeft(empty) { case (acc, next) => acc ++ loop(next) } + def fold(stuff: Iterable[TypedValue]): ReferenceSet = stuff.foldLeft(empty) { case (acc, next) => + acc ++ loop(next) + } ir match { - case Value.Literal(_, lit) => empty + case Value.Literal(_, lit) => empty case Value.Apply(_, function, argument) => loop(function) ++ loop(argument) case Value.Destructure(_, pattern, valueToDestruct, inValue) => loop(valueToDestruct) ++ loop(inValue) ++ patternLoop(pattern) - case Value.Constructor(_, fqn) => empty.withConstructor(fqn) + case Value.Constructor(_, fqn) => empty.withConstructor(fqn) case Value.Field(_, recordValue, _) => loop(recordValue) - case Value.FieldFunction(_, name) => empty + case Value.FieldFunction(_, name) => empty case Value.IfThenElse(_, condition, thenValue, elseValue) => loop(condition) ++ loop(thenValue) ++ loop(elseValue) case Value.Lambda(_, pattern, body) => patternLoop(pattern) ++ loop(body) case Value.LetDefinition(_, _, definition, inValue) => loop(definition.body) ++ loop(inValue) case Value.LetRecursion(_, definitions, inValue) => fold(definitions.map(_._2.body)) ++ loop(inValue) - case Value.List(_, elements) => fold(elements) - case Value.PatternMatch(_, value, cases) => loop(value) ++ cases.foldLeft(empty) { case (acc, (pattern, value)) => acc ++ loop(value) ++ patternLoop(pattern) } - case Value.Record(_, fields) => fold(fields.map(_._2)) - case Value.Reference(_, name) => empty.withDefinition(name) - case Value.Tuple(_, elements) => fold(elements) - case Value.Unit(_) => empty + case Value.List(_, elements) => fold(elements) + case Value.PatternMatch(_, value, cases) => loop(value) ++ cases.foldLeft(empty) { case (acc, (pattern, value)) => + acc ++ loop(value) ++ patternLoop(pattern) + } + case Value.Record(_, fields) => fold(fields.map(_._2)) + case Value.Reference(_, name) => empty.withDefinition(name) + case Value.Tuple(_, elements) => fold(elements) + case Value.Unit(_) => empty case Value.UpdateRecord(_, valueToUpdate, fields) => loop(valueToUpdate) ++ fold(fields.map(_._2)) - case Value.Variable(_, name) => empty + case Value.Variable(_, name) => empty } } - def patternLoop(pattern : Pattern[UType]) : ReferenceSet = { - val empty = ReferenceSet.empty; - def fold(stuff: Chunk[Pattern[UType]]): ReferenceSet = stuff.foldLeft(empty) { case (acc, next) => acc ++ patternLoop(next) } - pattern match { - case _: WildcardPattern[_] => empty - case AsPattern(_, innerPattern, name) =>patternLoop(innerPattern) - case _: UnitPattern[_] => empty - case LiteralPattern(_, _)=> empty - case _: EmptyListPattern[_] => empty - case HeadTailPattern(_, headPattern, tailPattern) => patternLoop(headPattern) ++ patternLoop(tailPattern) - case TuplePattern(_, patterns) => fold(patterns) - case ConstructorPattern(_, patternName, patterns) => empty.withConstructor(patternName) ++fold(patterns) - } + def patternLoop(pattern: Pattern[UType]): ReferenceSet = { + val empty = ReferenceSet.empty; + def fold(stuff: Chunk[Pattern[UType]]): ReferenceSet = stuff.foldLeft(empty) { case (acc, next) => + acc ++ patternLoop(next) + } + pattern match { + case _: WildcardPattern[_] => empty + case AsPattern(_, innerPattern, name) => patternLoop(innerPattern) + case _: UnitPattern[_] => empty + case LiteralPattern(_, _) => empty + case _: EmptyListPattern[_] => empty + case HeadTailPattern(_, headPattern, tailPattern) => patternLoop(headPattern) ++ patternLoop(tailPattern) + case TuplePattern(_, patterns) => fold(patterns) + case ConstructorPattern(_, patternName, patterns) => empty.withConstructor(patternName) ++ fold(patterns) } + } } diff --git a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala index d86a7bca1..4676397f4 100644 --- a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala +++ b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala @@ -20,72 +20,59 @@ import zio.{test as _, *} import scala.collection.immutable.ListMap object GatherRefsSpec extends MorphirBaseSpec { - val dist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") + val dist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") val mattDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/matt-instrument/morphir-ir.json") val maestroDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/maestro-sdk/morphir-ir.json") val mappingDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/mapping-logic/morphir-ir.json") - val example : FQName = FQName.fromString("Morphir.SDK:Basics:and") - val existing = Native.native.keys -// -// class ListThing(name: String) { -// val ref = FQName.fromString(name) -// val (pkg, mod, loc) = (ref.getPackagePath, ref.getModulePath, ref.localName) -// val value = lib.lookupValueSpecification(PackageName(pkg), ModuleName(mod), loc).get -// val listArg = value.inputs(0)._2 -// } -// val withParam = new ListThing("Morphir.Examples.App:TypeCheckerTests:withParam") -// val withInt = new ListThing("Morphir.Examples.App:TypeCheckerTests:withInt") -// val listConcept = Concept.List(Concept.Integer) -// val toType = ToMorphirType.summon[Concept] -// val intListType = toType.withAttributesOf(listConcept).morphirType - + val example: FQName = FQName.fromString("Morphir.SDK:Basics:and") + val existing = Native.native.keys def spec = suite("Exploration")( suite("From Distribution")( test("Everything") { val stuff = GatherReferences.fromDistributions(dist) - val defs = stuff.definitions.map(_.toString).mkString("\n") + val defs = stuff.definitions.map(_.toString).mkString("\n") assertTrue(defs == "") }, test("SDK Defs") { - val stuff = GatherReferences.fromDistributions(dist) - val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) + val stuff = GatherReferences.fromDistributions(dist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") }, - test("SDK Defs from Mapping"){ - val stuff = GatherReferences.fromDistributions(mattDist) - val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) + test("SDK Defs from Mapping") { + val stuff = GatherReferences.fromDistributions(mattDist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") }, test("SDK Defs from Everywhere") { - val stuff = GatherReferences.fromDistributions(mattDist, mappingDist, maestroDist) - val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) + val stuff = GatherReferences.fromDistributions(mattDist, mappingDist, maestroDist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") }, test("Missing Defs from Mapping") { - val stuff = GatherReferences.fromDistributions(mattDist) - val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) + val stuff = GatherReferences.fromDistributions(mattDist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") }, test("Missing SDK Defs from Everywhere") { - val stuff = GatherReferences.fromDistributions(mattDist, mappingDist, maestroDist) - val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) + val stuff = GatherReferences.fromDistributions(mattDist, mappingDist, maestroDist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") }, - test("Only actually used"){ - val stuff = GatherReferences.fromDistributions(mattDist) + test("Only actually used") { + val stuff = GatherReferences.fromDistributions(mattDist) val moreStuff = GatherReferences.fromEntrySet(stuff, mattDist, mappingDist, maestroDist) - val defs = moreStuff.definitions//.filter(_.getPackagePath == example.getPackagePath)//.diff(existing.toSet) + val defs = moreStuff.definitions // .filter(_.getPackagePath == example.getPackagePath)//.diff(existing.toSet) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") } - ), - ) + ) + ) @@ ignore @@ TestAspect.tag("Exploration code, not ready to be actual test") } From 67ac7a0674dda7fc2307f6cbdca0a92ec94629d4 Mon Sep 17 00:00:00 2001 From: Edward Peters Date: Tue, 22 Aug 2023 09:23:11 -0700 Subject: [PATCH 05/10] blank out unused match fields --- .../morphir/runtime/quick/GatherReferences.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala b/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala index 621fdda36..28ecf279e 100644 --- a/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala +++ b/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala @@ -65,12 +65,12 @@ object GatherReferences { val ctorReferences: List[ReferenceSet] = lib.packageDef.modules.toList.flatMap { case (moduleName, accessControlledModule) => accessControlledModule.value.types.flatMap { - case (localName, accessControlledType) => + case (_, accessControlledType) => val definition = accessControlledType.value.value definition match { case T.Definition.CustomType(_, accessControlledCtors) => val ctors = accessControlledCtors.value.toMap - ctors.map { case (ctorName, ctorArgs) => + ctors.map { case (ctorName, _) => val name = FQName(packageName, moduleName, ctorName) ReferenceSet.empty.withConstructor(name) } @@ -119,13 +119,13 @@ object GatherReferences { } ir match { - case Value.Literal(_, lit) => empty + case Value.Literal(_, _) => empty case Value.Apply(_, function, argument) => loop(function) ++ loop(argument) case Value.Destructure(_, pattern, valueToDestruct, inValue) => loop(valueToDestruct) ++ loop(inValue) ++ patternLoop(pattern) case Value.Constructor(_, fqn) => empty.withConstructor(fqn) case Value.Field(_, recordValue, _) => loop(recordValue) - case Value.FieldFunction(_, name) => empty + case Value.FieldFunction(_, _) => empty case Value.IfThenElse(_, condition, thenValue, elseValue) => loop(condition) ++ loop(thenValue) ++ loop(elseValue) case Value.Lambda(_, pattern, body) => patternLoop(pattern) ++ loop(body) @@ -141,7 +141,7 @@ object GatherReferences { case Value.Tuple(_, elements) => fold(elements) case Value.Unit(_) => empty case Value.UpdateRecord(_, valueToUpdate, fields) => loop(valueToUpdate) ++ fold(fields.map(_._2)) - case Value.Variable(_, name) => empty + case Value.Variable(_, _) => empty } } def patternLoop(pattern: Pattern[UType]): ReferenceSet = { @@ -151,7 +151,7 @@ object GatherReferences { } pattern match { case _: WildcardPattern[_] => empty - case AsPattern(_, innerPattern, name) => patternLoop(innerPattern) + case AsPattern(_, innerPattern, _) => patternLoop(innerPattern) case _: UnitPattern[_] => empty case LiteralPattern(_, _) => empty case _: EmptyListPattern[_] => empty From 005e24b36693f9f2bc9a157d57c7c8008f32c02c Mon Sep 17 00:00:00 2001 From: Edward Peters Date: Tue, 22 Aug 2023 09:27:06 -0700 Subject: [PATCH 06/10] Formatting --- .../finos/morphir/runtime/quick/GatherReferences.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala b/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala index 28ecf279e..1c85ed908 100644 --- a/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala +++ b/morphir/runtime/src/org/finos/morphir/runtime/quick/GatherReferences.scala @@ -119,13 +119,13 @@ object GatherReferences { } ir match { - case Value.Literal(_, _) => empty + case Value.Literal(_, _) => empty case Value.Apply(_, function, argument) => loop(function) ++ loop(argument) case Value.Destructure(_, pattern, valueToDestruct, inValue) => loop(valueToDestruct) ++ loop(inValue) ++ patternLoop(pattern) case Value.Constructor(_, fqn) => empty.withConstructor(fqn) case Value.Field(_, recordValue, _) => loop(recordValue) - case Value.FieldFunction(_, _) => empty + case Value.FieldFunction(_, _) => empty case Value.IfThenElse(_, condition, thenValue, elseValue) => loop(condition) ++ loop(thenValue) ++ loop(elseValue) case Value.Lambda(_, pattern, body) => patternLoop(pattern) ++ loop(body) @@ -141,7 +141,7 @@ object GatherReferences { case Value.Tuple(_, elements) => fold(elements) case Value.Unit(_) => empty case Value.UpdateRecord(_, valueToUpdate, fields) => loop(valueToUpdate) ++ fold(fields.map(_._2)) - case Value.Variable(_, _) => empty + case Value.Variable(_, _) => empty } } def patternLoop(pattern: Pattern[UType]): ReferenceSet = { @@ -151,7 +151,7 @@ object GatherReferences { } pattern match { case _: WildcardPattern[_] => empty - case AsPattern(_, innerPattern, _) => patternLoop(innerPattern) + case AsPattern(_, innerPattern, _) => patternLoop(innerPattern) case _: UnitPattern[_] => empty case LiteralPattern(_, _) => empty case _: EmptyListPattern[_] => empty From d12a6d8cb9c7f81a850f3c2dbefcc751ce15d064 Mon Sep 17 00:00:00 2001 From: Edward Peters Date: Tue, 22 Aug 2023 09:52:58 -0700 Subject: [PATCH 07/10] Removed references to instrment IR not in repo --- .../runtime/quick/GatherRefsSpec.scala | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala index 4676397f4..ebb2c228e 100644 --- a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala +++ b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala @@ -21,52 +21,51 @@ import scala.collection.immutable.ListMap object GatherRefsSpec extends MorphirBaseSpec { val dist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") - val mattDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/matt-instrument/morphir-ir.json") - val maestroDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/maestro-sdk/morphir-ir.json") - val mappingDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/mapping-logic/morphir-ir.json") + //Pretend the following is a distinct distribution like an SDK (when using the instrument, it should be one or more such) + val otherDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") val example: FQName = FQName.fromString("Morphir.SDK:Basics:and") val existing = Native.native.keys def spec = suite("Exploration")( suite("From Distribution")( - test("Everything") { + test("Everything from Tests") { val stuff = GatherReferences.fromDistributions(dist) val defs = stuff.definitions.map(_.toString).mkString("\n") assertTrue(defs == "") }, - test("SDK Defs") { + test("SDK Defs from Tests") { val stuff = GatherReferences.fromDistributions(dist) val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") }, - test("SDK Defs from Mapping") { - val stuff = GatherReferences.fromDistributions(mattDist) + test("SDK Defs from Distribution") { + val stuff = GatherReferences.fromDistributions(dist) val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") }, test("SDK Defs from Everywhere") { - val stuff = GatherReferences.fromDistributions(mattDist, mappingDist, maestroDist) + val stuff = GatherReferences.fromDistributions(dist, otherDist) val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") }, - test("Missing Defs from Mapping") { - val stuff = GatherReferences.fromDistributions(mattDist) + test("Missing Defs from Tests") { + val stuff = GatherReferences.fromDistributions(dist) val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") }, test("Missing SDK Defs from Everywhere") { - val stuff = GatherReferences.fromDistributions(mattDist, mappingDist, maestroDist) + val stuff = GatherReferences.fromDistributions(dist, otherDist) val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") }, test("Only actually used") { - val stuff = GatherReferences.fromDistributions(mattDist) - val moreStuff = GatherReferences.fromEntrySet(stuff, mattDist, mappingDist, maestroDist) + val stuff = GatherReferences.fromDistributions(dist) + val moreStuff = GatherReferences.fromEntrySet(stuff, dist, otherDist) val defs = moreStuff.definitions // .filter(_.getPackagePath == example.getPackagePath)//.diff(existing.toSet) val string = defs.map(_.toString).mkString("\n") assertTrue(string == "") From cd664bed028c6c518f1ffee1f6d7108140316a87 Mon Sep 17 00:00:00 2001 From: Edward Peters Date: Tue, 22 Aug 2023 11:44:46 -0700 Subject: [PATCH 08/10] Formatting --- .../src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala index ebb2c228e..ba08d3af8 100644 --- a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala +++ b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala @@ -20,8 +20,8 @@ import zio.{test as _, *} import scala.collection.immutable.ListMap object GatherRefsSpec extends MorphirBaseSpec { - val dist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") - //Pretend the following is a distinct distribution like an SDK (when using the instrument, it should be one or more such) + val dist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") + // Pretend the following is a distinct distribution like an SDK (when using the instrument, it should be one or more such) val otherDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") val example: FQName = FQName.fromString("Morphir.SDK:Basics:and") val existing = Native.native.keys From 75b8833e6f07ba349536b6c84b9e2b461bf9be99 Mon Sep 17 00:00:00 2001 From: EdwardPeters Date: Tue, 22 Aug 2023 12:28:40 -0700 Subject: [PATCH 09/10] Moved file for compilation --- .../morphir/runtime/GatherRefsSpec.scala | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 morphir/runtime/test/jvm/src/org/finos/morphir/runtime/GatherRefsSpec.scala diff --git a/morphir/runtime/test/jvm/src/org/finos/morphir/runtime/GatherRefsSpec.scala b/morphir/runtime/test/jvm/src/org/finos/morphir/runtime/GatherRefsSpec.scala new file mode 100644 index 000000000..ba08d3af8 --- /dev/null +++ b/morphir/runtime/test/jvm/src/org/finos/morphir/runtime/GatherRefsSpec.scala @@ -0,0 +1,77 @@ +package org.finos.morphir.runtime.quick + +import org.finos.morphir.datamodel.* +import org.finos.morphir.datamodel.Util.* +import org.finos.morphir.ir.Type.UType +import org.finos.morphir.ir.conversion.* +import org.finos.morphir.ir.distribution.Distribution.Library +import org.finos.morphir.ir.printing.{DetailLevel, FieldNames, PrintIR} +import org.finos.morphir.ir.sdk.Basics +import org.finos.morphir.ir.{Documented, Module, MorphirIRFile, Type as T, Value as V} +import org.finos.morphir.naming.* +import org.finos.morphir.runtime.* +import org.finos.morphir.testing.MorphirBaseSpec +import zio.prelude.fx.* +import zio.test.Assertion.{equalTo, fails} +import zio.test.TestAspect.{ignore, tag} +import zio.test.{Result as TestResult, *} +import zio.{test as _, *} + +import scala.collection.immutable.ListMap + +object GatherRefsSpec extends MorphirBaseSpec { + val dist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") + // Pretend the following is a distinct distribution like an SDK (when using the instrument, it should be one or more such) + val otherDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") + val example: FQName = FQName.fromString("Morphir.SDK:Basics:and") + val existing = Native.native.keys + + def spec = suite("Exploration")( + suite("From Distribution")( + test("Everything from Tests") { + val stuff = GatherReferences.fromDistributions(dist) + val defs = stuff.definitions.map(_.toString).mkString("\n") + assertTrue(defs == "") + }, + test("SDK Defs from Tests") { + val stuff = GatherReferences.fromDistributions(dist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + }, + test("SDK Defs from Distribution") { + val stuff = GatherReferences.fromDistributions(dist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + }, + test("SDK Defs from Everywhere") { + val stuff = GatherReferences.fromDistributions(dist, otherDist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + }, + test("Missing Defs from Tests") { + val stuff = GatherReferences.fromDistributions(dist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + }, + test("Missing SDK Defs from Everywhere") { + val stuff = GatherReferences.fromDistributions(dist, otherDist) + val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + }, + test("Only actually used") { + val stuff = GatherReferences.fromDistributions(dist) + val moreStuff = GatherReferences.fromEntrySet(stuff, dist, otherDist) + val defs = moreStuff.definitions // .filter(_.getPackagePath == example.getPackagePath)//.diff(existing.toSet) + val string = defs.map(_.toString).mkString("\n") + assertTrue(string == "") + + } + ) + ) @@ ignore @@ TestAspect.tag("Exploration code, not ready to be actual test") + +} From c8027a5e7d723cd4fb3f1b8c9ff69bd0823a4556 Mon Sep 17 00:00:00 2001 From: Edward Peters Date: Tue, 22 Aug 2023 12:42:55 -0700 Subject: [PATCH 10/10] Removed file --- .../runtime/quick/GatherRefsSpec.scala | 77 ------------------- 1 file changed, 77 deletions(-) delete mode 100644 morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala diff --git a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala b/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala deleted file mode 100644 index ba08d3af8..000000000 --- a/morphir/runtime/test/src/org/finos/morphir/runtime/quick/GatherRefsSpec.scala +++ /dev/null @@ -1,77 +0,0 @@ -package org.finos.morphir.runtime.quick - -import org.finos.morphir.datamodel.* -import org.finos.morphir.datamodel.Util.* -import org.finos.morphir.ir.Type.UType -import org.finos.morphir.ir.conversion.* -import org.finos.morphir.ir.distribution.Distribution.Library -import org.finos.morphir.ir.printing.{DetailLevel, FieldNames, PrintIR} -import org.finos.morphir.ir.sdk.Basics -import org.finos.morphir.ir.{Documented, Module, MorphirIRFile, Type as T, Value as V} -import org.finos.morphir.naming.* -import org.finos.morphir.runtime.* -import org.finos.morphir.testing.MorphirBaseSpec -import zio.prelude.fx.* -import zio.test.Assertion.{equalTo, fails} -import zio.test.TestAspect.{ignore, tag} -import zio.test.{Result as TestResult, *} -import zio.{test as _, *} - -import scala.collection.immutable.ListMap - -object GatherRefsSpec extends MorphirBaseSpec { - val dist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") - // Pretend the following is a distinct distribution like an SDK (when using the instrument, it should be one or more such) - val otherDist = EvaluationLibrary.loadDistribution("./examples/morphir-elm-projects/evaluator-tests/morphir-ir.json") - val example: FQName = FQName.fromString("Morphir.SDK:Basics:and") - val existing = Native.native.keys - - def spec = suite("Exploration")( - suite("From Distribution")( - test("Everything from Tests") { - val stuff = GatherReferences.fromDistributions(dist) - val defs = stuff.definitions.map(_.toString).mkString("\n") - assertTrue(defs == "") - }, - test("SDK Defs from Tests") { - val stuff = GatherReferences.fromDistributions(dist) - val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) - val string = defs.map(_.toString).mkString("\n") - assertTrue(string == "") - }, - test("SDK Defs from Distribution") { - val stuff = GatherReferences.fromDistributions(dist) - val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) - val string = defs.map(_.toString).mkString("\n") - assertTrue(string == "") - }, - test("SDK Defs from Everywhere") { - val stuff = GatherReferences.fromDistributions(dist, otherDist) - val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath) - val string = defs.map(_.toString).mkString("\n") - assertTrue(string == "") - }, - test("Missing Defs from Tests") { - val stuff = GatherReferences.fromDistributions(dist) - val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) - val string = defs.map(_.toString).mkString("\n") - assertTrue(string == "") - }, - test("Missing SDK Defs from Everywhere") { - val stuff = GatherReferences.fromDistributions(dist, otherDist) - val defs = stuff.definitions.filter(_.getPackagePath == example.getPackagePath).diff(existing.toSet) - val string = defs.map(_.toString).mkString("\n") - assertTrue(string == "") - }, - test("Only actually used") { - val stuff = GatherReferences.fromDistributions(dist) - val moreStuff = GatherReferences.fromEntrySet(stuff, dist, otherDist) - val defs = moreStuff.definitions // .filter(_.getPackagePath == example.getPackagePath)//.diff(existing.toSet) - val string = defs.map(_.toString).mkString("\n") - assertTrue(string == "") - - } - ) - ) @@ ignore @@ TestAspect.tag("Exploration code, not ready to be actual test") - -}