mirror of
https://github.com/fluencelabs/aqua.git
synced 2025-06-26 21:11:36 +00:00
Module and Use expressions (#245)
* Module and Use expressions * UseFromExpr * ImportFromExpr * PubExpr * Export, declares * Collecting all the needed info WIP * Got all the needed data * Tests fixed * HeaderSem * HeaderSem wip * Everything except `export`/`declares` should be working * Compile bug fixed * Fix readme: cli/assembly * Handle declares, exports * Compile only exports in AquaRes * Call services imported from modules * Import consts, types, services from modules * Resolve arrows from modules * Bugfix
This commit is contained in:
@ -1,8 +1,10 @@
|
||||
package aqua.linker
|
||||
|
||||
case class AquaModule[I, E, T](id: I, dependsOn: Map[I, E], body: T) {
|
||||
case class AquaModule[I, E, T](id: I, imports: Map[String, I], dependsOn: Map[I, E], body: T) {
|
||||
def map[TT](f: T => TT): AquaModule[I, E, TT] = copy(body = f(body))
|
||||
|
||||
def mapWithId[TT](f: (I, T) => TT): AquaModule[I, E, TT] = copy(body = f(id, body))
|
||||
|
||||
def mapErr[EE](f: E => EE): AquaModule[I, EE, T] =
|
||||
copy(dependsOn = dependsOn.view.mapValues(f).toMap)
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package aqua.linker
|
||||
|
||||
import cats.data.{NonEmptyChain, Validated, ValidatedNec}
|
||||
import cats.kernel.{Monoid, Semigroup}
|
||||
import cats.syntax.monoid._
|
||||
import cats.syntax.semigroup._
|
||||
import scribe.Logging
|
||||
|
||||
import scala.annotation.tailrec
|
||||
@ -50,9 +50,10 @@ object Linker extends Logging {
|
||||
}
|
||||
}
|
||||
|
||||
def link[I, E, T: Monoid](
|
||||
def link[I, E, T: Semigroup](
|
||||
modules: Modules[I, E, T => T],
|
||||
cycleError: List[AquaModule[I, E, T => T]] => E
|
||||
cycleError: List[AquaModule[I, E, T => T]] => E,
|
||||
empty: I => T
|
||||
): ValidatedNec[E, Map[I, T]] =
|
||||
if (modules.dependsOn.nonEmpty) Validated.invalid(modules.dependsOn.values.reduce(_ ++ _))
|
||||
else {
|
||||
@ -60,7 +61,7 @@ object Linker extends Logging {
|
||||
|
||||
Validated.fromEither(
|
||||
result
|
||||
.map(_.view.filterKeys(modules.exports).mapValues(_.apply(Monoid[T].empty)).toMap)
|
||||
.map(_.collect { case (i, f) if modules.exports(i) => i -> f(empty(i)) })
|
||||
.left
|
||||
.map(NonEmptyChain.one)
|
||||
)
|
||||
|
@ -28,6 +28,9 @@ case class Modules[I, E, T](
|
||||
def map[TT](f: T => TT): Modules[I, E, TT] =
|
||||
copy(loaded = loaded.view.mapValues(_.map(f)).toMap)
|
||||
|
||||
def mapModuleToBody[TT](f: AquaModule[I, E, T] => TT): Modules[I, E, TT] =
|
||||
copy(loaded = loaded.view.mapValues(v => v.map(_ => f(v))).toMap)
|
||||
|
||||
def mapErr[EE](f: E => EE): Modules[I, EE, T] =
|
||||
copy(
|
||||
loaded = loaded.view.mapValues(_.mapErr(f)).toMap,
|
||||
|
@ -15,6 +15,7 @@ class LinkerSpec extends AnyFlatSpec with Matchers {
|
||||
.add(
|
||||
AquaModule[String, String, String => String](
|
||||
"mod1",
|
||||
Map.empty,
|
||||
Map("mod2" -> "unresolved mod2 in mod1"),
|
||||
_ ++ " | mod1"
|
||||
),
|
||||
@ -24,17 +25,19 @@ class LinkerSpec extends AnyFlatSpec with Matchers {
|
||||
|
||||
Linker.link[String, String, String](
|
||||
withMod1,
|
||||
cycle => cycle.map(_.id).mkString(" -> ")
|
||||
cycle => cycle.map(_.id).mkString(" -> "),
|
||||
_ => ""
|
||||
) should be(Validated.invalidNec("unresolved mod2 in mod1"))
|
||||
|
||||
val withMod2 =
|
||||
withMod1.add(AquaModule("mod2", Map.empty, _ ++ " | mod2"))
|
||||
withMod1.add(AquaModule("mod2", Map.empty, Map.empty, _ ++ " | mod2"))
|
||||
|
||||
withMod2.isResolved should be(true)
|
||||
|
||||
Linker.link[String, String, String](
|
||||
withMod2,
|
||||
cycle => cycle.map(_.id + "?").mkString(" -> ")
|
||||
cycle => cycle.map(_.id + "?").mkString(" -> "),
|
||||
_ => ""
|
||||
) should be(Validated.validNec(Map("mod1" -> " | mod2 | mod1")))
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user