From f158074c4ecb7d02236786a809c7c387bbb65d3b Mon Sep 17 00:00:00 2001 From: InversionSpaces Date: Wed, 27 Sep 2023 11:29:06 +0200 Subject: [PATCH] fix(compiler): Handle errors from result handling [fixes LNG-247] (#913) Move args and return under try --- .../aqua/compiler/AquaCompilerSpec.scala | 20 ++-- .../transform/pre/FuncPreTransformer.scala | 33 +++++-- .../aqua/model/transform/TransformSpec.scala | 98 ++++++++++--------- 3 files changed, 87 insertions(+), 64 deletions(-) diff --git a/compiler/src/test/scala/aqua/compiler/AquaCompilerSpec.scala b/compiler/src/test/scala/aqua/compiler/AquaCompilerSpec.scala index 7aca7caf..cb7d82c7 100644 --- a/compiler/src/test/scala/aqua/compiler/AquaCompilerSpec.scala +++ b/compiler/src/test/scala/aqua/compiler/AquaCompilerSpec.scala @@ -159,10 +159,10 @@ class AquaCompilerSpec extends AnyFlatSpec with Matchers { val retVar = VarModel("ret", ScalarType.string) val expected = - SeqRes.wrap( - getDataSrv("-relay-", "-relay-", ScalarType.string), - getDataSrv("peers", peers.name, peers.`type`), - XorRes.wrap( + XorRes.wrap( + SeqRes.wrap( + getDataSrv("-relay-", "-relay-", ScalarType.string), + getDataSrv("peers", peers.name, peers.`type`), RestrictionRes(results.name, resultsType).wrap( SeqRes.wrap( ParRes.wrap( @@ -203,9 +203,9 @@ class AquaCompilerSpec extends AnyFlatSpec with Matchers { ).leaf ) ), - errorCall(transformCfg, 0, initPeer) + respCall(transformCfg, flatResult, initPeer) ), - respCall(transformCfg, flatResult, initPeer) + errorCall(transformCfg, 0, initPeer) ) exec.body.equalsOrShowDiff(expected) shouldBe (true) @@ -276,8 +276,8 @@ class AquaCompilerSpec extends AnyFlatSpec with Matchers { val resCanonVM = VarModel("-res-fix-0", CanonStreamType(ScalarType.string)) val resFlatVM = VarModel("-res-flat-0", ArrayType(ScalarType.string)) - val expected = SeqRes.wrap( - XorRes.wrap( + val expected = XorRes.wrap( + SeqRes.wrap( RestrictionRes(resVM.name, resStreamType).wrap( SeqRes.wrap( // res <- foo() @@ -303,9 +303,9 @@ class AquaCompilerSpec extends AnyFlatSpec with Matchers { ).leaf ) ), - errorCall(transformCfg, 0, initPeer) + respCall(transformCfg, resFlatVM, initPeer) ), - respCall(transformCfg, resFlatVM, initPeer) + errorCall(transformCfg, 0, initPeer) ) barfoo.body.equalsOrShowDiff(expected) should be(true) diff --git a/model/transform/src/main/scala/aqua/model/transform/pre/FuncPreTransformer.scala b/model/transform/src/main/scala/aqua/model/transform/pre/FuncPreTransformer.scala index 96854965..145a1c57 100644 --- a/model/transform/src/main/scala/aqua/model/transform/pre/FuncPreTransformer.scala +++ b/model/transform/src/main/scala/aqua/model/transform/pre/FuncPreTransformer.scala @@ -9,7 +9,22 @@ import aqua.types.* import cats.syntax.show.* import cats.syntax.option.* -// TODO: doc +/** + * Pre-transformer for top functions: + * - Get arguments + * - Get relay + * - Generate callbacks for function arguments + * - Handle result + * - Handle error + * + * @param argsProvider - provides arguments + * @param resultsHandler - handles results + * @param errorHandler - handles errors + * @param callback - generates callback for function argument + * @param relayVarName - name of the relay variable + * @param wrapCallableName - name of the generated wrapper function + * @param arrowCallbackPrefix - prefix for generated callbacks names + */ case class FuncPreTransformer( argsProvider: ArgsProvider, resultsHandler: ResultsHandler, @@ -50,7 +65,7 @@ case class FuncPreTransformer( * removes function return * * @param func Function to transform - * @return + * @return Transformed function */ def preTransform(func: FuncArrow): FuncArrow = { val returnType = ProductType(func.ret.map(_.`type`).map { @@ -93,13 +108,13 @@ case class FuncPreTransformer( val call = CallArrowRawTag.func(func.funcName, funcCall).leaf - val body = SeqTag.wrap( - provideArgs ++ List( - TryTag.wrap( - call, - handleError - ) - ) ++ handleResults + val body = TryTag.wrap( + SeqTag.wrap( + provideArgs + .appended(call) + .appendedAll(handleResults) + ), + handleError ) FuncArrow( diff --git a/model/transform/src/test/scala/aqua/model/transform/TransformSpec.scala b/model/transform/src/test/scala/aqua/model/transform/TransformSpec.scala index 24eae401..b0475e67 100644 --- a/model/transform/src/test/scala/aqua/model/transform/TransformSpec.scala +++ b/model/transform/src/test/scala/aqua/model/transform/TransformSpec.scala @@ -48,29 +48,28 @@ class TransformSpec extends AnyFlatSpec with Matchers { val procFC = fc.value.body - val expectedFC = + val expectedFC = XorRes.wrap( SeqRes.wrap( dataCall(bc, "-relay-", initPeer), XorRes.wrap( - XorRes.wrap( - SeqRes.wrap( - through(relayV), - through(otherRelay), - callRes(1, otherPeer), - through(otherRelay), - through(relayV) - ), - SeqRes.wrap( - through(otherRelay), - through(relayV), - through(initPeer), - failErrorRes - ) + SeqRes.wrap( + through(relayV), + through(otherRelay), + callRes(1, otherPeer), + through(otherRelay), + through(relayV) ), - errorCall(bc, 0, initPeer) + SeqRes.wrap( + through(otherRelay), + through(relayV), + through(initPeer), + failErrorRes + ) ), respCall(bc, ret, initPeer) - ) + ), + errorCall(bc, 0, initPeer) + ) procFC.equalsOrShowDiff(expectedFC) should be(true) @@ -80,9 +79,21 @@ class TransformSpec extends AnyFlatSpec with Matchers { val ret = LiteralRaw.quote("return this") + /** + * func ret() -> string: + * srv0.fn0() + * on "other-peer": + * srv1.fn1() + * <- "return this" + */ val func: FuncArrow = FuncArrow( "ret", - SeqTag.wrap(callOp(0).leaf, OnTag(otherPeer, Chain.empty).wrap(callOp(1).leaf)), + SeqTag.wrap( + callOp(0).leaf, + OnTag(otherPeer, Chain.empty).wrap( + callOp(1).leaf + ) + ), stringArrow, ret :: Nil, Map.empty, @@ -96,29 +107,26 @@ class TransformSpec extends AnyFlatSpec with Matchers { val procFC = fc.value.body - val expectedFC = + val expectedFC = XorRes.wrap( SeqRes.wrap( dataCall(bc, "-relay-", initPeer), + callRes(0, initPeer), XorRes.wrap( SeqRes.wrap( - callRes(0, initPeer), - XorRes.wrap( - SeqRes.wrap( - through(relayV), - callRes(1, otherPeer), - through(relayV) - ), - SeqRes.wrap( - through(relayV), - through(initPeer), - failErrorRes - ) - ) + through(relayV), + callRes(1, otherPeer), + through(relayV) ), - errorCall(bc, 0, initPeer) + SeqRes.wrap( + through(relayV), + through(initPeer), + failErrorRes + ) ), respCall(bc, ret, initPeer) - ) + ), + errorCall(bc, 0, initPeer) + ) procFC.equalsOrShowDiff(expectedFC) should be(true) @@ -126,13 +134,13 @@ class TransformSpec extends AnyFlatSpec with Matchers { "transform.forClient" should "link funcs correctly" in { /* - func one() -> u64: - variable <- Demo.get42() - <- variable + func f1() -> string: + v <- srv1.fn1() + <- v - func two() -> u64: - variable <- one() - <- variable + func f2() -> string: + v <- f1() + <- v */ val f1: FuncArrow = @@ -163,13 +171,13 @@ class TransformSpec extends AnyFlatSpec with Matchers { val procFC = Transform.funcRes(f2, bc).value.body - val expectedFC = SeqRes.wrap( - dataCall(bc, "-relay-", initPeer), - XorRes.wrap( + val expectedFC = XorRes.wrap( + SeqRes.wrap( + dataCall(bc, "-relay-", initPeer), callRes(1, initPeer), - errorCall(bc, 0, initPeer) + respCall(bc, VarRaw("v", ScalarType.string), initPeer) ), - respCall(bc, VarRaw("v", ScalarType.string), initPeer) + errorCall(bc, 0, initPeer) ) procFC.equalsOrShowDiff(expectedFC) should be(true)