From 8f06ac1cba7f4ce8588c1df1befd6bb99d957f2a Mon Sep 17 00:00:00 2001 From: Dima Date: Tue, 2 Apr 2024 12:04:01 +0300 Subject: [PATCH] fix(compiler): Redeclare imports [LNG-344] (#1109) --- aqua-src/antithesis.aqua | 41 +++---------------- aqua-src/import.aqua | 8 +++- .../aqua/examples/redeclare/import.aqua | 4 ++ .../aqua/examples/redeclare/redeclare.aqua | 3 ++ .../aqua/examples/redeclare/useDeclare.aqua | 5 +++ .../aqua/semantics/header/ModuleSem.scala | 22 +++++----- .../rules/types/TypesInterpreter.scala | 2 +- 7 files changed, 36 insertions(+), 49 deletions(-) create mode 100644 integration-tests/aqua/examples/redeclare/import.aqua create mode 100644 integration-tests/aqua/examples/redeclare/redeclare.aqua create mode 100644 integration-tests/aqua/examples/redeclare/useDeclare.aqua diff --git a/aqua-src/antithesis.aqua b/aqua-src/antithesis.aqua index b3d16738..fd2d33ec 100644 --- a/aqua-src/antithesis.aqua +++ b/aqua-src/antithesis.aqua @@ -1,39 +1,8 @@ -aqua A +aqua Main -export streamTry, streamFor +import someFunc from "import.aqua" -service FailureSrv("failure"): - fail(msg: string) +export someFunc -func streamTry() -> i8: - on HOST_PEER_ID: - try: - stream: *i8 - anotherStream = stream - stream <<- 1 - anotherStream <<- 1 - FailureSrv.fail("try") - catch e: - stream = *[88,88,88] - stream <<- 2 - FailureSrv.fail("catch") - otherwise: - stream: *i8 - stream <<- 3 - - stream: *i8 - stream <<- 4 - - <- stream! - -service StreamService("test-service"): - store(numbers: []u32, n: u32) - -func callService(stream: *u32, n: u32): - stream <<- 1 - StreamService.store(stream, n) - -func streamFor(): - arr = [1,2,3,4,5] - for a <- arr: - callService(*[], a) \ No newline at end of file +func a() -> string: + <- "srrt" diff --git a/aqua-src/import.aqua b/aqua-src/import.aqua index 0e10769c..473a02fb 100644 --- a/aqua-src/import.aqua +++ b/aqua-src/import.aqua @@ -1,6 +1,10 @@ -service GetStr("multiret-test"): - retStr(s: *string, a: *string) +aqua Import declares someFunc +service GetStr("multiret-test"): + retStr(s: []string, a: []string) + +func someFunc() -> string: + <- "some func call" func foo_wrapper(): GetStr.retStr(nil, nil) diff --git a/integration-tests/aqua/examples/redeclare/import.aqua b/integration-tests/aqua/examples/redeclare/import.aqua new file mode 100644 index 00000000..92095920 --- /dev/null +++ b/integration-tests/aqua/examples/redeclare/import.aqua @@ -0,0 +1,4 @@ +aqua Import declares someFunc + +func someFunc() -> string: + <- "some func" \ No newline at end of file diff --git a/integration-tests/aqua/examples/redeclare/redeclare.aqua b/integration-tests/aqua/examples/redeclare/redeclare.aqua new file mode 100644 index 00000000..97abf316 --- /dev/null +++ b/integration-tests/aqua/examples/redeclare/redeclare.aqua @@ -0,0 +1,3 @@ +aqua Redeclare declares someFunc + +import someFunc from "import.aqua" \ No newline at end of file diff --git a/integration-tests/aqua/examples/redeclare/useDeclare.aqua b/integration-tests/aqua/examples/redeclare/useDeclare.aqua new file mode 100644 index 00000000..7c9b9dc0 --- /dev/null +++ b/integration-tests/aqua/examples/redeclare/useDeclare.aqua @@ -0,0 +1,5 @@ +aqua UseDeclare declares someFunc + +import someFunc from "redeclare.aqua" + +export someFunc \ No newline at end of file diff --git a/semantics/src/main/scala/aqua/semantics/header/ModuleSem.scala b/semantics/src/main/scala/aqua/semantics/header/ModuleSem.scala index 8b09b8ec..2bb0fb82 100644 --- a/semantics/src/main/scala/aqua/semantics/header/ModuleSem.scala +++ b/semantics/src/main/scala/aqua/semantics/header/ModuleSem.scala @@ -11,6 +11,7 @@ import cats.kernel.Semigroup import cats.syntax.foldable.* import cats.syntax.functor.* import cats.syntax.option.* +import cats.syntax.semigroup.* import cats.syntax.validated.* import cats.{Comonad, Monoid} @@ -30,31 +31,32 @@ class ModuleSem[S[_]: Comonad, C: Picker](expr: ModuleExpr[S])(using name.value, shouldDeclare ), - (ctx, _) => + (ctx, initCtx) => + val sumCtx = ctx |+| initCtx // When file is handled, check that all the declarations exists if (declareAll.nonEmpty) - ctx.setModule(name.value, declares = ctx.all).validNec - else + val allDeclared = ctx.all ++ initCtx.all + sumCtx.setModule(name.value, declares = allDeclared).validNec + else { + // summarize contexts to allow redeclaration of imports ( declareNames.fproductLeft(_.value) ::: declareCustom.fproductLeft(_.value) ).map { case (n, t) => - ctx - .pick(n, None, ctx.module.nonEmpty) + sumCtx + .pick(n, None, sumCtx.module.nonEmpty) .toValidNec( error( t, s"`$n` is expected to be declared, but declaration is not found in the file" ) - ) - .void + ).void }.combineAll.as { val tokens = declareNames.map(n => n.value -> n) ++ declareCustom.map(a => a.value -> a) - val ctxWithDeclaresLoc = ctx.addOccurences(tokens) + val ctxWithDeclaresLoc = sumCtx.addOccurences(tokens) // TODO: why module name and declares is lost? where is it lost? ctxWithDeclaresLoc.setModule(name.value, declares = shouldDeclare) } - - + } ) word.value.fold( diff --git a/semantics/src/main/scala/aqua/semantics/rules/types/TypesInterpreter.scala b/semantics/src/main/scala/aqua/semantics/rules/types/TypesInterpreter.scala index 3fccd37e..7769aab9 100644 --- a/semantics/src/main/scala/aqua/semantics/rules/types/TypesInterpreter.scala +++ b/semantics/src/main/scala/aqua/semantics/rules/types/TypesInterpreter.scala @@ -729,7 +729,7 @@ class TypesInterpreter[S[_], X](using report .error( token, - s"Name `${name}` was already defined here" + s"Name `$name` was already defined here" ) .as(ifDefined) case None => ifNotDefined