Merge branch 'refs/heads/main' into chore/use-fcli-for-nox

This commit is contained in:
DieMyst 2024-03-07 20:38:19 +07:00
commit 90f5b8c815
37 changed files with 424 additions and 210 deletions

View File

@ -17,7 +17,6 @@ import aqua.io.*
import aqua.js.{FunctionDefJs, ServiceDefJs, VarJson} import aqua.js.{FunctionDefJs, ServiceDefJs, VarJson}
import aqua.logging.{LogFormatter, LogLevels} import aqua.logging.{LogFormatter, LogLevels}
import aqua.model.AquaContext import aqua.model.AquaContext
import aqua.model.transform.{Transform, TransformConfig}
import aqua.parser.lexer.{LiteralToken, Token} import aqua.parser.lexer.{LiteralToken, Token}
import aqua.parser.{ArrowReturnError, BlockIndentError, LexerError, ParserError} import aqua.parser.{ArrowReturnError, BlockIndentError, LexerError, ParserError}
import aqua.raw.ops.Call import aqua.raw.ops.Call

View File

@ -3,7 +3,6 @@ package api.types
import aqua.api.AquaAPIConfig import aqua.api.AquaAPIConfig
import aqua.api.TargetType.* import aqua.api.TargetType.*
import aqua.js.{FunctionDefJs, ServiceDefJs} import aqua.js.{FunctionDefJs, ServiceDefJs}
import aqua.model.transform.TransformConfig
import cats.data.Validated.{invalidNec, validNec} import cats.data.Validated.{invalidNec, validNec}
import cats.data.{Chain, NonEmptyChain, Validated, ValidatedNec} import cats.data.{Chain, NonEmptyChain, Validated, ValidatedNec}

View File

@ -18,9 +18,10 @@ object Test extends IOApp.Simple {
.compilePath( .compilePath(
"./aqua-src/antithesis.aqua", "./aqua-src/antithesis.aqua",
Imports.fromMap(Map("/" -> Map("" -> List("./aqua")))), Imports.fromMap(Map("/" -> Map("" -> List("./aqua")))),
AquaAPIConfig(targetType = TypeScriptType), AquaAPIConfig(targetType = TypeScriptType, noXor = true),
TypeScriptBackend(false, "IFluenceClient$$") TypeScriptBackend(false, "IFluenceClient$$")
).timed )
.timed
.flatMap { case (duration, res) => .flatMap { case (duration, res) =>
println("Compilation time: " + duration.toMillis) println("Compilation time: " + duration.toMillis)
val (warnings, result) = res.value.run val (warnings, result) = res.value.run

View File

@ -55,14 +55,16 @@ object APICompilation {
LogLevels.levelFromString(aquaConfig.logLevel), LogLevels.levelFromString(aquaConfig.logLevel),
Constants.parse(aquaConfig.constants) Constants.parse(aquaConfig.constants)
).tupled.toResult.flatTraverse { case (level, constants) => ).tupled.toResult.flatTraverse { case (level, constants) =>
val transformConfig = aquaConfig.getTransformConfig.copy(constants = constants) val transformConfig = aquaConfig.getTransformConfig
val config = aquaConfig.getCompilerConfig.copy(constants = constants)
LogFormatter.initLogger(Some(level)) LogFormatter.initLogger(Some(level))
new FuncCompiler[IO]( new FuncCompiler[IO](
Some(RelativePath(Path(pathStr))), Some(RelativePath(Path(pathStr))),
imports.toIO, imports.toIO,
transformConfig transformConfig,
config
).compile().map { contextV => ).compile().map { contextV =>
for { for {
context <- contextV.toResult context <- contextV.toResult
@ -140,7 +142,7 @@ object APICompilation {
LogFormatter.initLogger(Some(level)) LogFormatter.initLogger(Some(level))
val transformConfig = aquaConfig.getTransformConfig val transformConfig = aquaConfig.getTransformConfig
val config = AquaCompilerConf(constants ++ transformConfig.constantsList) val config = aquaConfig.getCompilerConfig.copy(constants = constants)
CompilerAPI CompilerAPI
.compile[IO, AquaFileError, FileModuleId, FileSpan.F]( .compile[IO, AquaFileError, FileModuleId, FileSpan.F](

View File

@ -1,4 +1,6 @@
package aqua.api package aqua.api
import aqua.compiler.AquaCompilerConf
import aqua.model.transform.TransformConfig import aqua.model.transform.TransformConfig
enum TargetType: enum TargetType:
@ -8,7 +10,7 @@ case class AquaAPIConfig(
targetType: TargetType = TargetType.AirType, targetType: TargetType = TargetType.AirType,
logLevel: String = "info", logLevel: String = "info",
constants: List[String] = Nil, constants: List[String] = Nil,
noXor: Boolean = false, // TODO: Remove noXor: Boolean = false,
noRelay: Boolean = false, noRelay: Boolean = false,
tracing: Boolean = false, tracing: Boolean = false,
noEmptyResponse: Boolean = true noEmptyResponse: Boolean = true
@ -17,10 +19,18 @@ case class AquaAPIConfig(
def getTransformConfig: TransformConfig = { def getTransformConfig: TransformConfig = {
val config = TransformConfig( val config = TransformConfig(
tracing = Option.when(tracing)(TransformConfig.TracingConfig.default), tracing = Option.when(tracing)(TransformConfig.TracingConfig.default),
noEmptyResponse = noEmptyResponse noEmptyResponse = noEmptyResponse,
noXor = noXor
) )
if (noRelay) config.copy(relayVarName = None) if (noRelay) config.copy(relayVarName = None)
else config else config
} }
def getCompilerConfig: AquaCompilerConf = {
val config = AquaCompilerConf()
if (noRelay) config.copy(relayVarName = None)
else config
}
} }

View File

@ -22,14 +22,14 @@ import scribe.Logging
class FuncCompiler[F[_]: Files: AquaIO: Async]( class FuncCompiler[F[_]: Files: AquaIO: Async](
input: Option[AquaPath], input: Option[AquaPath],
imports: Imports, imports: Imports,
transformConfig: TransformConfig transformConfig: TransformConfig,
config: AquaCompilerConf
) extends Logging { ) extends Logging {
type Result = [A] =>> CompileResult[FileModuleId, AquaFileError, FileSpan.F][A] type Result = [A] =>> CompileResult[FileModuleId, AquaFileError, FileSpan.F][A]
private def compileToContext( private def compileToContext(
path: Path, path: Path
config: AquaCompilerConf = AquaCompilerConf(transformConfig.constantsList)
): F[Result[Chain[AquaContext]]] = { ): F[Result[Chain[AquaContext]]] = {
val sources = new AquaFileSources[F](path, imports) val sources = new AquaFileSources[F](path, imports)
CompilerAPI.compileToContext[F, AquaFileError, FileModuleId, FileSpan.F]( CompilerAPI.compileToContext[F, AquaFileError, FileModuleId, FileSpan.F](

View File

@ -1,48 +1,15 @@
aqua Main aqua Main
export bugLNG346 export main
ability Promise: service Srv("srv"):
yield() -> string call(x: i32) -> i32
func done_nil() -> string: func main(a: i32, b: i32) -> i32:
<- "" res: *i32
if a > b:
on "peer" via "relay":
res <- Srv.call(a)
func done() -> Promise: <- res!
<- Promise(yield = done_nil)
ability Compute:
yield() -> string
alias WorkerYield: -> string
alias Yield: WorkerYield -> Promise
func wait_for() -> Yield:
wait = func (cb: -> string) -> Promise:
yield = func () -> string:
e <- cb()
<- e
<- Promise(yield = yield)
<- wait
ability Function:
run(dealId: string) -> string
func simple{Compute}(yield: Yield) -> Function:
deal_run = func () -> string:
c_yield = func () -> string:
<- Compute.yield()
yieeld <- yield(c_yield)
res <- yieeld.yield()
<- res
<- Function(run = deal_run)
func bugLNG346() -> string:
res: *string
yieeld = func () -> string:
res <<- "hello"
<- ""
c = Compute(yield = yieeld)
fn = simple{c}(wait_for())
r <- fn.run("")
<- res!

View File

@ -6,5 +6,9 @@ import aqua.raw.ConstantRaw
* What should compiler care about during compilation before generator backend takes its role * What should compiler care about during compilation before generator backend takes its role
* *
* @param constantsList List of known constants * @param constantsList List of known constants
* @param relayVarName Name of the relay variable
*/ */
case class AquaCompilerConf(constantsList: List[ConstantRaw]) case class AquaCompilerConf(
constants: List[ConstantRaw] = Nil,
relayVarName: Option[String] = Some("-relay-")
)

View File

@ -4,7 +4,7 @@ import aqua.backend.Backend
import aqua.compiler.AquaError.* import aqua.compiler.AquaError.*
import aqua.model.AquaContext import aqua.model.AquaContext
import aqua.parser.{Ast, ParserError} import aqua.parser.{Ast, ParserError}
import aqua.raw.RawContext import aqua.raw.{ConstantRaw, RawContext}
import aqua.semantics.header.{HeaderHandler, HeaderSem} import aqua.semantics.header.{HeaderHandler, HeaderSem}
import aqua.semantics.rules.locations.{DummyLocationsInterpreter, LocationsAlgebra} import aqua.semantics.rules.locations.{DummyLocationsInterpreter, LocationsAlgebra}
import aqua.semantics.{FileId, RawSemantics} import aqua.semantics.{FileId, RawSemantics}
@ -48,7 +48,7 @@ object CompilerAPI extends Logging {
.implicits( .implicits(
RawContext.blank.copy( RawContext.blank.copy(
parts = Chain parts = Chain
.fromSeq(config.constantsList) .fromSeq(config.constants ++ ConstantRaw.defaultConstants(config.relayVarName))
.map(const => RawContext.blank -> const) .map(const => RawContext.blank -> const)
) )
) )

View File

@ -883,4 +883,94 @@ class AquaCompilerSpec extends AnyFlatSpec with Matchers with Inside {
} }
} }
} }
it should "not generate error propagation in `if` with `noXor = true`" in {
val src = Map(
"index.aqua" ->
"""aqua Test
|
|export main
|
|service Srv("srv"):
| call()
|
|func main(a: i32):
| if a > 0:
| Srv.call()
|""".stripMargin
)
val transformCfg = TransformConfig(noEmptyResponse = true, relayVarName = None, noXor = true)
insideRes(src, transformCfg = transformCfg)("main") { case main :: Nil =>
val aArg = VarModel("-a-arg-", ScalarType.i32)
val gt = CallModel.Export("gt", ScalarType.bool)
val expected = XorRes.wrap(
SeqRes.wrap(
getDataSrv("a", aArg.name, aArg.baseType),
CallServiceRes(
LiteralModel.quote("cmp"),
"gt",
CallRes(aArg :: LiteralModel.number(0) :: Nil, Some(gt)),
initPeer
).leaf,
XorRes.wrap(
MatchMismatchRes(gt.asVar, LiteralModel.bool(true), true).wrap(
CallServiceRes(
LiteralModel.quote("srv"),
"call",
CallRes(Nil, None),
initPeer
).leaf
)
)
),
errorCall(transformCfg, 0, initPeer)
)
main.body.equalsOrShowDiff(expected) should be(true)
}
}
it should "not generate error propagation in `on` with `noXor = true`" in {
val src = Map(
"index.aqua" ->
"""aqua Test
|
|export main
|
|service Srv("srv"):
| call()
|
|func main():
| on "peer" via "relay":
| Srv.call()
| Srv.call()
|""".stripMargin
)
val transformCfg = TransformConfig(noEmptyResponse = true, relayVarName = None, noXor = true)
insideRes(src, transformCfg = transformCfg)("main") { case main :: Nil =>
def call(peer: ValueModel) =
CallServiceRes(
LiteralModel.quote("srv"),
"call",
CallRes(Nil, None),
peer
).leaf
val expected = XorRes.wrap(
SeqRes.wrap(
through(LiteralModel.quote("relay")),
call(LiteralModel.quote("peer")),
through(LiteralModel.quote("relay")),
call(initPeer)
),
errorCall(transformCfg, 0, initPeer)
)
main.body.equalsOrShowDiff(expected) should be(true)
}
}
} }

View File

@ -2,10 +2,11 @@ package aqua.lsp
import aqua.compiler.{AquaCompiler, AquaCompilerConf, AquaError, AquaSources} import aqua.compiler.{AquaCompiler, AquaCompilerConf, AquaError, AquaSources}
import aqua.parser.{Ast, ParserError} import aqua.parser.{Ast, ParserError}
import aqua.raw.RawContext import aqua.raw.{ConstantRaw, RawContext}
import aqua.semantics.FileId
import aqua.semantics.header.{HeaderHandler, HeaderSem} import aqua.semantics.header.{HeaderHandler, HeaderSem}
import aqua.semantics.rules.locations.LocationsAlgebra import aqua.semantics.rules.locations.LocationsAlgebra
import aqua.semantics.FileId
import cats.data.Validated.validNec import cats.data.Validated.validNec
import cats.data.{Chain, State, Validated, ValidatedNec} import cats.data.{Chain, State, Validated, ValidatedNec}
import cats.syntax.either.* import cats.syntax.either.*
@ -24,7 +25,7 @@ object LSPCompiler {
LspContext.blank.copy(raw = LspContext.blank.copy(raw =
RawContext.blank.copy( RawContext.blank.copy(
parts = Chain parts = Chain
.fromSeq(config.constantsList) .fromSeq(config.constants ++ ConstantRaw.defaultConstants(config.relayVarName))
.map(const => RawContext.blank -> const) .map(const => RawContext.blank -> const)
) )
) )

View File

@ -3,7 +3,7 @@ package aqua.model.inline
import aqua.errors.Errors.internalError import aqua.errors.Errors.internalError
import aqua.model import aqua.model
import aqua.model.* import aqua.model.*
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.raw.ops.RawTag import aqua.raw.ops.RawTag
import aqua.raw.value.{ValueRaw, VarRaw} import aqua.raw.value.{ValueRaw, VarRaw}
import aqua.types.* import aqua.types.*
@ -27,7 +27,7 @@ import scribe.Logging
*/ */
object ArrowInliner extends Logging { object ArrowInliner extends Logging {
def callArrow[S: Exports: Arrows: Mangler]( def callArrow[S: Exports: Arrows: Mangler: Config](
arrow: FuncArrow, arrow: FuncArrow,
call: CallModel call: CallModel
): State[S, OpModel.Tree] = ): State[S, OpModel.Tree] =
@ -43,7 +43,7 @@ object ArrowInliner extends Logging {
) )
// push results to streams if they are exported to streams // push results to streams if they are exported to streams
private def pushStreamResults[S: Mangler: Exports: Arrows]( private def pushStreamResults[S: Mangler: Exports: Arrows: Config](
outsideStreamNames: Set[String], outsideStreamNames: Set[String],
exportTo: List[CallModel.Export], exportTo: List[CallModel.Export],
results: List[ValueRaw] results: List[ValueRaw]
@ -140,7 +140,7 @@ object ArrowInliner extends Logging {
} }
// Apply a callable function, get its fully resolved body & optional value, if any // Apply a callable function, get its fully resolved body & optional value, if any
private def inline[S: Mangler: Arrows: Exports]( private def inline[S: Mangler: Arrows: Exports: Config](
fn: FuncArrow, fn: FuncArrow,
call: CallModel, call: CallModel,
outsideDeclaredStreams: Set[String] outsideDeclaredStreams: Set[String]
@ -542,7 +542,7 @@ object ArrowInliner extends Logging {
_ <- Exports[S].resolved(exportsResolved) _ <- Exports[S].resolved(exportsResolved)
} yield (fn.copy(body = treeWithCanons, ret = ret), SeqModel.wrap(canons)) } yield (fn.copy(body = treeWithCanons, ret = ret), SeqModel.wrap(canons))
private[inline] def callArrowRet[S: Exports: Arrows: Mangler]( private[inline] def callArrowRet[S: Exports: Arrows: Mangler: Config](
arrow: FuncArrow, arrow: FuncArrow,
call: CallModel call: CallModel
): State[S, (OpModel.Tree, List[ValueModel])] = for { ): State[S, (OpModel.Tree, List[ValueModel])] = for {

View File

@ -1,15 +1,15 @@
package aqua.model.inline package aqua.model.inline
import aqua.model.*
import aqua.model.inline.RawValueInliner.unfold import aqua.model.inline.RawValueInliner.unfold
import aqua.model.inline.raw.RawInliner import aqua.model.inline.raw.RawInliner
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.model.*
import aqua.raw.value.MakeStructRaw import aqua.raw.value.MakeStructRaw
import aqua.types.{StreamMapType, StructType} import aqua.types.{StreamMapType, StructType}
import cats.data.{Chain, NonEmptyMap, State} import cats.data.{Chain, NonEmptyMap, State}
import cats.syntax.foldable.*
import cats.syntax.bifunctor.* import cats.syntax.bifunctor.*
import cats.syntax.foldable.*
import cats.syntax.functor.* import cats.syntax.functor.*
object MakeStructRawInliner extends RawInliner[MakeStructRaw] { object MakeStructRawInliner extends RawInliner[MakeStructRaw] {
@ -58,7 +58,7 @@ object MakeStructRawInliner extends RawInliner[MakeStructRaw] {
constructThroughMap(mapName, mapType, CallModel.Export(resultName, resultType), fields) constructThroughMap(mapName, mapType, CallModel.Export(resultName, resultType), fields)
} }
override def apply[S: Mangler: Exports: Arrows]( override def apply[S: Mangler: Exports: Arrows: Config](
raw: MakeStructRaw, raw: MakeStructRaw,
propertiesAllowed: Boolean propertiesAllowed: Boolean
): State[S, (ValueModel, Inline)] = { ): State[S, (ValueModel, Inline)] = {

View File

@ -3,7 +3,7 @@ package aqua.model.inline
import aqua.model.* import aqua.model.*
import aqua.model.inline.Inline.MergeMode.* import aqua.model.inline.Inline.MergeMode.*
import aqua.model.inline.raw.* import aqua.model.inline.raw.*
import aqua.model.inline.state.{Arrows, Counter, Exports, Mangler} import aqua.model.inline.state.*
import aqua.raw.ops.* import aqua.raw.ops.*
import aqua.raw.value.* import aqua.raw.value.*
import aqua.types.{ArrayType, LiteralType, OptionType, StreamType} import aqua.types.{ArrayType, LiteralType, OptionType, StreamType}
@ -23,7 +23,7 @@ object RawValueInliner extends Logging {
import aqua.model.inline.Inline.* import aqua.model.inline.Inline.*
private[inline] def unfold[S: Mangler: Exports: Arrows]( private[inline] def unfold[S: Mangler: Exports: Arrows: Config](
raw: ValueRaw, raw: ValueRaw,
propertiesAllowed: Boolean = true propertiesAllowed: Boolean = true
): State[S, (ValueModel, Inline)] = for { ): State[S, (ValueModel, Inline)] = for {
@ -69,7 +69,7 @@ object RawValueInliner extends Logging {
} }
} yield result } yield result
private[inline] def inlineToTree[S: Mangler: Exports: Arrows]( private[inline] def inlineToTree[S: Mangler: Exports: Arrows: Config](
inline: Inline inline: Inline
): State[S, List[OpModel.Tree]] = ): State[S, List[OpModel.Tree]] =
(inline.mergeMode match { (inline.mergeMode match {
@ -77,7 +77,7 @@ object RawValueInliner extends Logging {
case ParMode => inline.predo.toList case ParMode => inline.predo.toList
}).pure }).pure
private[inline] def toModel[S: Mangler: Exports: Arrows]( private[inline] def toModel[S: Mangler: Exports: Arrows: Config](
unfoldF: State[S, (ValueModel, Inline)] unfoldF: State[S, (ValueModel, Inline)]
): State[S, (ValueModel, Option[OpModel.Tree])] = ): State[S, (ValueModel, Option[OpModel.Tree])] =
for { for {
@ -92,7 +92,7 @@ object RawValueInliner extends Logging {
_ = logger.trace("map was: " + map) _ = logger.trace("map was: " + map)
} yield vm -> parDesugarPrefix(ops.filterNot(_ == EmptyModel.leaf)) } yield vm -> parDesugarPrefix(ops.filterNot(_ == EmptyModel.leaf))
def valueToModel[S: Mangler: Exports: Arrows]( def valueToModel[S: Mangler: Exports: Arrows: Config](
value: ValueRaw, value: ValueRaw,
propertiesAllowed: Boolean = true propertiesAllowed: Boolean = true
): State[S, (ValueModel, Option[OpModel.Tree])] = for { ): State[S, (ValueModel, Option[OpModel.Tree])] = for {
@ -100,7 +100,7 @@ object RawValueInliner extends Logging {
model <- toModel(unfold(value, propertiesAllowed)) model <- toModel(unfold(value, propertiesAllowed))
} yield model } yield model
def valueListToModel[S: Mangler: Exports: Arrows]( def valueListToModel[S: Mangler: Exports: Arrows: Config](
values: List[ValueRaw] values: List[ValueRaw]
): State[S, List[(ValueModel, Option[OpModel.Tree])]] = ): State[S, List[(ValueModel, Option[OpModel.Tree])]] =
values.traverse(valueToModel(_)) values.traverse(valueToModel(_))
@ -109,7 +109,7 @@ object RawValueInliner extends Logging {
* Unfold all arguments and make CallModel * Unfold all arguments and make CallModel
* @param flatStreamArguments canonicalize and flatten all stream arguments if true * @param flatStreamArguments canonicalize and flatten all stream arguments if true
*/ */
def callToModel[S: Mangler: Exports: Arrows]( def callToModel[S: Mangler: Exports: Arrows: Config](
call: Call, call: Call,
flatStreamArguments: Boolean flatStreamArguments: Boolean
): State[S, (CallModel, Option[OpModel.Tree])] = { ): State[S, (CallModel, Option[OpModel.Tree])] = {
@ -122,7 +122,7 @@ object RawValueInliner extends Logging {
State.pure(args) State.pure(args)
} }
exportTo <- call.exportTo.traverse { exportTo <- call.exportTo.traverse {
case c@Call.Export(_, _, isExistingStream) if isExistingStream => case c @ Call.Export(_, _, isExistingStream) if isExistingStream =>
// process streams, because they can be stored in Exports outside function/closure with different name // process streams, because they can be stored in Exports outside function/closure with different name
valueToModel(c.toRaw) valueToModel(c.toRaw)
case ce => case ce =>

View File

@ -3,8 +3,8 @@ package aqua.model.inline
import aqua.errors.Errors.internalError import aqua.errors.Errors.internalError
import aqua.model.* import aqua.model.*
import aqua.model.inline.raw.{CallArrowRawInliner, CallServiceRawInliner} import aqua.model.inline.raw.{CallArrowRawInliner, CallServiceRawInliner}
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.model.inline.tag.IfTagInliner import aqua.model.inline.tag.*
import aqua.raw.ops.* import aqua.raw.ops.*
import aqua.raw.value.* import aqua.raw.value.*
import aqua.types.{CanonStreamType, CollectionType, StreamType} import aqua.types.{CanonStreamType, CollectionType, StreamType}
@ -193,35 +193,16 @@ object TagInliner extends Logging {
* @tparam S Current state * @tparam S Current state
* @return Model (if any), and prefix (if any) * @return Model (if any), and prefix (if any)
*/ */
def tagToModel[S: Mangler: Arrows: Exports]( def tagToModel[S: Mangler: Arrows: Exports: Config](
tag: RawTag tag: RawTag
): State[S, TagInlined[S]] = ): State[S, TagInlined[S]] =
tag match { tag match {
case OnTag(peerId, via, strategy) => case OnTag(peerId, via, strategy) =>
for { OnTagInliner(peerId, via, strategy).inlined.map(inlined =>
peerIdDe <- valueToModel(peerId) TagInlined.Mapping(
viaDe <- valueListToModel(via.toList) toModel = inlined.toModel,
viaDeFlattened <- viaDe.traverse { case (vm, tree) => prefix = inlined.prefix
flat(vm, tree) )
}
(pid, pif) = peerIdDe
(viaD, viaF) = viaDeFlattened.unzip
.bimap(Chain.fromSeq, _.flatten)
strat = strategy.map { case OnTag.ReturnStrategy.Relay =>
OnModel.ReturnStrategy.Relay
}
toModel = (children: Chain[OpModel.Tree]) =>
XorModel.wrap(
OnModel(pid, viaD, strat).wrap(
children
),
// This will return to previous topology
// and propagate error up
FailModel(ValueModel.error).leaf
)
} yield TagInlined.Mapping(
toModel = toModel,
prefix = parDesugarPrefix(viaF.prependedAll(pif))
) )
case IfTag(valueRaw) => case IfTag(valueRaw) =>
@ -471,7 +452,7 @@ object TagInliner extends Logging {
inlined <- headInlined.build(children) inlined <- headInlined.build(children)
} yield inlined } yield inlined
def handleTree[S: Exports: Mangler: Arrows]( def handleTree[S: Exports: Mangler: Arrows: Config](
tree: RawTag.Tree tree: RawTag.Tree
): State[S, OpModel.Tree] = ): State[S, OpModel.Tree] =
traverseS(tree, tagToModel(_)) traverseS(tree, tagToModel(_))

View File

@ -2,32 +2,32 @@ package aqua.model.inline.raw
import aqua.errors.Errors.internalError import aqua.errors.Errors.internalError
import aqua.model.* import aqua.model.*
import aqua.model.inline.raw.RawInliner
import aqua.model.inline.TagInliner
import aqua.model.inline.state.{Arrows, Exports, Mangler}
import aqua.raw.value.{AbilityRaw, LiteralRaw, MakeStructRaw}
import cats.data.{NonEmptyList, NonEmptyMap, State}
import aqua.model.inline.Inline import aqua.model.inline.Inline
import aqua.model.inline.Inline.MergeMode
import aqua.model.inline.RawValueInliner.{unfold, valueToModel} import aqua.model.inline.RawValueInliner.{unfold, valueToModel}
import aqua.types.{ArrowType, ScalarType, Type} import aqua.model.inline.TagInliner
import aqua.model.inline.raw.RawInliner
import aqua.model.inline.state.*
import aqua.raw.value.ApplyBinaryOpRaw import aqua.raw.value.ApplyBinaryOpRaw
import aqua.raw.value.ApplyBinaryOpRaw.Op import aqua.raw.value.ApplyBinaryOpRaw.Op
import aqua.raw.value.ApplyBinaryOpRaw.Op.* import aqua.raw.value.ApplyBinaryOpRaw.Op.*
import aqua.model.inline.Inline.MergeMode import aqua.raw.value.{AbilityRaw, LiteralRaw, MakeStructRaw}
import aqua.types.LiteralType
import aqua.types.{ArrowType, ScalarType, Type}
import cats.data.Chain import cats.data.Chain
import cats.syntax.traverse.* import cats.data.{NonEmptyList, NonEmptyMap, State}
import cats.syntax.monoid.*
import cats.syntax.functor.*
import cats.syntax.flatMap.*
import cats.syntax.apply.*
import cats.syntax.foldable.*
import cats.syntax.applicative.* import cats.syntax.applicative.*
import aqua.types.LiteralType import cats.syntax.apply.*
import cats.syntax.flatMap.*
import cats.syntax.foldable.*
import cats.syntax.functor.*
import cats.syntax.monoid.*
import cats.syntax.traverse.*
object ApplyBinaryOpRawInliner extends RawInliner[ApplyBinaryOpRaw] { object ApplyBinaryOpRawInliner extends RawInliner[ApplyBinaryOpRaw] {
override def apply[S: Mangler: Exports: Arrows]( override def apply[S: Mangler: Exports: Arrows: Config](
raw: ApplyBinaryOpRaw, raw: ApplyBinaryOpRaw,
propertiesAllowed: Boolean propertiesAllowed: Boolean
): State[S, (ValueModel, Inline)] = for { ): State[S, (ValueModel, Inline)] = for {
@ -83,7 +83,7 @@ object ApplyBinaryOpRawInliner extends RawInliner[ApplyBinaryOpRaw] {
} }
} yield result } yield result
private def inlineEqOp[S: Mangler: Exports: Arrows]( private def inlineEqOp[S: Mangler: Exports: Arrows: Config](
lmodel: ValueModel, lmodel: ValueModel,
rmodel: ValueModel, rmodel: ValueModel,
linline: Inline, linline: Inline,
@ -106,7 +106,7 @@ object ApplyBinaryOpRawInliner extends RawInliner[ApplyBinaryOpRaw] {
case _ => fullInlineEqOp(lmodel, rmodel, linline, rinline, op, resType) case _ => fullInlineEqOp(lmodel, rmodel, linline, rinline, op, resType)
} }
private def fullInlineEqOp[S: Mangler: Exports: Arrows]( private def fullInlineEqOp[S: Mangler: Exports: Arrows: Config](
lmodel: ValueModel, lmodel: ValueModel,
rmodel: ValueModel, rmodel: ValueModel,
linline: Inline, linline: Inline,
@ -152,7 +152,7 @@ object ApplyBinaryOpRawInliner extends RawInliner[ApplyBinaryOpRaw] {
result(name, resType, predo) result(name, resType, predo)
} }
private def inlineBoolOp[S: Mangler: Exports: Arrows]( private def inlineBoolOp[S: Mangler: Exports: Arrows: Config](
lmodel: ValueModel, lmodel: ValueModel,
rmodel: ValueModel, rmodel: ValueModel,
linline: Inline, linline: Inline,
@ -178,7 +178,7 @@ object ApplyBinaryOpRawInliner extends RawInliner[ApplyBinaryOpRaw] {
case _ => fullInlineBoolOp(lmodel, rmodel, linline, rinline, op, resType) case _ => fullInlineBoolOp(lmodel, rmodel, linline, rinline, op, resType)
} }
private def fullInlineBoolOp[S: Mangler: Exports: Arrows]( private def fullInlineBoolOp[S: Mangler: Exports: Arrows: Config](
lmodel: ValueModel, lmodel: ValueModel,
rmodel: ValueModel, rmodel: ValueModel,
linline: Inline, linline: Inline,
@ -230,7 +230,7 @@ object ApplyBinaryOpRawInliner extends RawInliner[ApplyBinaryOpRaw] {
result(name, resType, predo) result(name, resType, predo)
} }
private def inlineCmpOp[S: Mangler: Exports: Arrows]( private def inlineCmpOp[S: Mangler: Exports: Arrows: Config](
lmodel: ValueModel, lmodel: ValueModel,
rmodel: ValueModel, rmodel: ValueModel,
linline: Inline, linline: Inline,
@ -276,7 +276,7 @@ object ApplyBinaryOpRawInliner extends RawInliner[ApplyBinaryOpRaw] {
result(fn, resType, predo) result(fn, resType, predo)
} }
private def inlineMathOp[S: Mangler: Exports: Arrows]( private def inlineMathOp[S: Mangler: Exports: Arrows: Config](
lmodel: ValueModel, lmodel: ValueModel,
rmodel: ValueModel, rmodel: ValueModel,
linline: Inline, linline: Inline,

View File

@ -3,7 +3,7 @@ package aqua.model.inline.raw
import aqua.model.inline.Inline import aqua.model.inline.Inline
import aqua.model.inline.Inline.MergeMode.* import aqua.model.inline.Inline.MergeMode.*
import aqua.model.inline.RawValueInliner.unfold import aqua.model.inline.RawValueInliner.unfold
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.model.{ import aqua.model.{
CallModel, CallModel,
CanonicalizeModel, CanonicalizeModel,
@ -24,7 +24,7 @@ import scribe.Logging
object ApplyFunctorRawInliner extends Logging { object ApplyFunctorRawInliner extends Logging {
def apply[S: Mangler: Exports: Arrows]( def apply[S: Mangler: Exports: Arrows: Config](
value: ValueModel, value: ValueModel,
functor: FunctorRaw functor: FunctorRaw
): State[S, (VarModel, Inline)] = { ): State[S, (VarModel, Inline)] = {

View File

@ -4,10 +4,11 @@ import aqua.errors.Errors.internalError
import aqua.model.* import aqua.model.*
import aqua.model.inline.Inline.MergeMode.* import aqua.model.inline.Inline.MergeMode.*
import aqua.model.inline.RawValueInliner.unfold import aqua.model.inline.RawValueInliner.unfold
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.model.inline.{Inline, MakeStructRawInliner} import aqua.model.inline.{Inline, MakeStructRawInliner}
import aqua.raw.value.IntoCopyRaw import aqua.raw.value.IntoCopyRaw
import aqua.types.{StreamMapType, StructType} import aqua.types.{StreamMapType, StructType}
import cats.data.{Chain, NonEmptyMap, State} import cats.data.{Chain, NonEmptyMap, State}
import cats.syntax.foldable.* import cats.syntax.foldable.*
import cats.syntax.functor.* import cats.syntax.functor.*
@ -40,10 +41,16 @@ object ApplyIntoCopyRawInliner extends Logging {
} }
MakeStructRawInliner MakeStructRawInliner
.constructThroughMap(mapName, mapType, CallModel.Export(resultName, resultType), fields, nonCopiedValues) .constructThroughMap(
mapName,
mapType,
CallModel.Export(resultName, resultType),
fields,
nonCopiedValues
)
} }
def apply[S: Mangler: Exports: Arrows]( def apply[S: Mangler: Exports: Arrows: Config](
value: VarModel, value: VarModel,
intoCopy: IntoCopyRaw intoCopy: IntoCopyRaw
): State[S, (VarModel, Inline)] = { ): State[S, (VarModel, Inline)] = {

View File

@ -6,7 +6,7 @@ import aqua.model.ValueModel.Ability
import aqua.model.inline.Inline import aqua.model.inline.Inline
import aqua.model.inline.Inline.MergeMode.* import aqua.model.inline.Inline.MergeMode.*
import aqua.model.inline.RawValueInliner.unfold import aqua.model.inline.RawValueInliner.unfold
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.raw.value.* import aqua.raw.value.*
import aqua.types.* import aqua.types.*
@ -24,7 +24,7 @@ import scribe.Logging
object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Logging { object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Logging {
// in perspective literals can have properties and functors (like `nil` with length) // in perspective literals can have properties and functors (like `nil` with length)
def flatLiteralWithProperties[S: Mangler: Exports: Arrows]( def flatLiteralWithProperties[S: Mangler: Exports: Arrows: Config](
literal: LiteralModel, literal: LiteralModel,
inl: Inline, inl: Inline,
properties: Chain[PropertyModel] properties: Chain[PropertyModel]
@ -45,7 +45,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
} }
} }
private def unfoldAbilityProperty[S: Mangler: Exports: Arrows]( private def unfoldAbilityProperty[S: Mangler: Exports: Arrows: Config](
varModel: VarModel, varModel: VarModel,
abilityType: NamedType, abilityType: NamedType,
p: PropertyRaw p: PropertyRaw
@ -112,7 +112,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
) )
} }
private[inline] def unfoldProperty[S: Mangler: Exports: Arrows]( private[inline] def unfoldProperty[S: Mangler: Exports: Arrows: Config](
varModel: VarModel, varModel: VarModel,
p: PropertyRaw p: PropertyRaw
): State[S, (VarModel, Inline)] = ): State[S, (VarModel, Inline)] =
@ -172,7 +172,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
private case class PropertyRawWithModel(raw: PropertyRaw, model: Option[PropertyModel]) private case class PropertyRawWithModel(raw: PropertyRaw, model: Option[PropertyModel])
// Unfold properties that we can process in parallel // Unfold properties that we can process in parallel
private def optimizeProperties[S: Mangler: Exports: Arrows]( private def optimizeProperties[S: Mangler: Exports: Arrows: Config](
properties: Chain[PropertyRaw] properties: Chain[PropertyRaw]
): State[S, (Chain[PropertyRawWithModel], Inline)] = { ): State[S, (Chain[PropertyRawWithModel], Inline)] = {
properties.map { properties.map {
@ -211,7 +211,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
}.sequence.map(_.toList.unzip.bimap(Chain.fromSeq, _.combineAll)) }.sequence.map(_.toList.unzip.bimap(Chain.fromSeq, _.combineAll))
} }
private def unfoldProperties[S: Mangler: Exports: Arrows]( private def unfoldProperties[S: Mangler: Exports: Arrows: Config](
prevInline: Inline, prevInline: Inline,
vm: VarModel, vm: VarModel,
properties: Chain[PropertyRaw], properties: Chain[PropertyRaw],
@ -263,7 +263,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
/** /**
* Unfold `stream[idx]` * Unfold `stream[idx]`
*/ */
private def unfoldStreamGate[S: Mangler: Exports: Arrows]( private def unfoldStreamGate[S: Mangler: Exports: Arrows: Config](
streamName: String, streamName: String,
streamType: StreamType, streamType: StreamType,
idx: ValueRaw idx: ValueRaw
@ -325,7 +325,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
mergeMode = SeqMode mergeMode = SeqMode
) )
private def unfoldRawWithProperties[S: Mangler: Exports: Arrows]( private def unfoldRawWithProperties[S: Mangler: Exports: Arrows: Config](
raw: ValueRaw, raw: ValueRaw,
properties: Chain[PropertyRaw], properties: Chain[PropertyRaw],
propertiesAllowed: Boolean propertiesAllowed: Boolean
@ -389,7 +389,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
flatten = VarModel(nn, varModel.`type`) flatten = VarModel(nn, varModel.`type`)
} yield flatten -> Inline.tree(FlattenModel(varModel, flatten.name).leaf) } yield flatten -> Inline.tree(FlattenModel(varModel, flatten.name).leaf)
override def apply[S: Mangler: Exports: Arrows]( override def apply[S: Mangler: Exports: Arrows: Config](
apr: ApplyPropertyRaw, apr: ApplyPropertyRaw,
propertiesAllowed: Boolean propertiesAllowed: Boolean
): State[S, (ValueModel, Inline)] = { ): State[S, (ValueModel, Inline)] = {

View File

@ -1,28 +1,28 @@
package aqua.model.inline.raw package aqua.model.inline.raw
import aqua.model.* import aqua.model.*
import aqua.model.inline.raw.RawInliner
import aqua.model.inline.state.{Arrows, Exports, Mangler}
import aqua.raw.value.{AbilityRaw, LiteralRaw, MakeStructRaw}
import cats.data.{NonEmptyList, NonEmptyMap, State}
import aqua.model.inline.Inline import aqua.model.inline.Inline
import aqua.model.inline.RawValueInliner.{unfold, valueToModel} import aqua.model.inline.RawValueInliner.{unfold, valueToModel}
import aqua.types.{ArrowType, ScalarType} import aqua.model.inline.raw.RawInliner
import aqua.model.inline.state.*
import aqua.raw.value.ApplyUnaryOpRaw import aqua.raw.value.ApplyUnaryOpRaw
import aqua.raw.value.ApplyUnaryOpRaw.Op.* import aqua.raw.value.ApplyUnaryOpRaw.Op.*
import aqua.raw.value.{AbilityRaw, LiteralRaw, MakeStructRaw}
import aqua.types.{ArrowType, ScalarType}
import cats.data.Chain import cats.data.Chain
import cats.syntax.traverse.* import cats.data.{NonEmptyList, NonEmptyMap, State}
import cats.syntax.monoid.*
import cats.syntax.functor.*
import cats.syntax.flatMap.*
import cats.syntax.apply.*
import cats.syntax.foldable.*
import cats.syntax.applicative.* import cats.syntax.applicative.*
import cats.syntax.apply.*
import cats.syntax.flatMap.*
import cats.syntax.foldable.*
import cats.syntax.functor.*
import cats.syntax.monoid.*
import cats.syntax.traverse.*
object ApplyUnaryOpRawInliner extends RawInliner[ApplyUnaryOpRaw] { object ApplyUnaryOpRawInliner extends RawInliner[ApplyUnaryOpRaw] {
override def apply[S: Mangler: Exports: Arrows]( override def apply[S: Mangler: Exports: Arrows: Config](
raw: ApplyUnaryOpRaw, raw: ApplyUnaryOpRaw,
propertiesAllowed: Boolean propertiesAllowed: Boolean
): State[S, (ValueModel, Inline)] = for { ): State[S, (ValueModel, Inline)] = for {
@ -40,7 +40,7 @@ object ApplyUnaryOpRawInliner extends RawInliner[ApplyUnaryOpRaw] {
} }
} yield result } yield result
private def fullInline[S: Mangler: Exports: Arrows]( private def fullInline[S: Mangler: Exports: Arrows: Config](
vm: ValueModel, vm: ValueModel,
vinline: Inline, vinline: Inline,
op: ApplyUnaryOpRaw.Op op: ApplyUnaryOpRaw.Op

View File

@ -3,7 +3,7 @@ package aqua.model.inline.raw
import aqua.errors.Errors.internalError import aqua.errors.Errors.internalError
import aqua.model.* import aqua.model.*
import aqua.model.inline.RawValueInliner.callToModel import aqua.model.inline.RawValueInliner.callToModel
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.model.inline.{ArrowInliner, Inline, RawValueInliner} import aqua.model.inline.{ArrowInliner, Inline, RawValueInliner}
import aqua.raw.ops.Call import aqua.raw.ops.Call
import aqua.raw.value.CallArrowRaw import aqua.raw.value.CallArrowRaw
@ -14,7 +14,7 @@ import scribe.Logging
object CallArrowRawInliner extends RawInliner[CallArrowRaw] with Logging { object CallArrowRawInliner extends RawInliner[CallArrowRaw] with Logging {
private[inline] def unfold[S: Mangler: Exports: Arrows]( private[inline] def unfold[S: Mangler: Exports: Arrows: Config](
value: CallArrowRaw, value: CallArrowRaw,
exportTo: List[Call.Export] exportTo: List[Call.Export]
): State[S, (List[ValueModel], Inline)] = { ): State[S, (List[ValueModel], Inline)] = {
@ -31,7 +31,7 @@ object CallArrowRawInliner extends RawInliner[CallArrowRaw] with Logging {
resolveArrow(funcName, call) resolveArrow(funcName, call)
} }
private def resolveFuncArrow[S: Mangler: Exports: Arrows]( private def resolveFuncArrow[S: Mangler: Exports: Arrows: Config](
fn: FuncArrow, fn: FuncArrow,
call: Call call: Call
): State[S, (List[ValueModel], Inline)] = { ): State[S, (List[ValueModel], Inline)] = {
@ -52,7 +52,7 @@ object CallArrowRawInliner extends RawInliner[CallArrowRaw] with Logging {
} }
} }
private def resolveArrow[S: Mangler: Exports: Arrows]( private def resolveArrow[S: Mangler: Exports: Arrows: Config](
funcName: String, funcName: String,
call: Call call: Call
): State[S, (List[ValueModel], Inline)] = for { ): State[S, (List[ValueModel], Inline)] = for {
@ -76,7 +76,7 @@ object CallArrowRawInliner extends RawInliner[CallArrowRaw] with Logging {
}) })
} yield result } yield result
override def apply[S: Mangler: Exports: Arrows]( override def apply[S: Mangler: Exports: Arrows: Config](
raw: CallArrowRaw, raw: CallArrowRaw,
propertiesAllowed: Boolean propertiesAllowed: Boolean
): State[S, (ValueModel, Inline)] = ): State[S, (ValueModel, Inline)] =

View File

@ -3,22 +3,22 @@ package aqua.model.inline.raw
import aqua.model.* import aqua.model.*
import aqua.model.inline.Inline import aqua.model.inline.Inline
import aqua.model.inline.RawValueInliner.{callToModel, valueToModel} import aqua.model.inline.RawValueInliner.{callToModel, valueToModel}
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.raw.ops.Call import aqua.raw.ops.Call
import aqua.raw.value.CallServiceRaw import aqua.raw.value.CallServiceRaw
import cats.data.{Chain, State} import cats.data.{Chain, State}
import scribe.Logging import scribe.Logging
object CallServiceRawInliner extends RawInliner[CallServiceRaw] with Logging { object CallServiceRawInliner extends RawInliner[CallServiceRaw] with Logging {
private[inline] def unfold[S: Mangler: Exports: Arrows]( private[inline] def unfold[S: Mangler: Exports: Arrows: Config](
value: CallServiceRaw, value: CallServiceRaw,
exportTo: List[Call.Export] exportTo: List[Call.Export]
): State[S, (List[ValueModel], Inline)] = Exports[S].exports.flatMap { exports => ): State[S, (List[ValueModel], Inline)] = Exports[S].exports.flatMap { exports =>
logger.trace(s"${exportTo.mkString(" ")} $value") logger.trace(s"${exportTo.mkString(" ")} $value")
logger.trace(Console.BLUE + s"call service id ${value.serviceId}" + Console.RESET) logger.trace(Console.BLUE + s"call service id ${value.serviceId}" + Console.RESET)
val call = Call(value.arguments, exportTo) val call = Call(value.arguments, exportTo)
for { for {
@ -40,7 +40,7 @@ object CallServiceRawInliner extends RawInliner[CallServiceRaw] with Logging {
} yield values.values.toList -> inline } yield values.values.toList -> inline
} }
override def apply[S: Mangler: Exports: Arrows]( override def apply[S: Mangler: Exports: Arrows: Config](
raw: CallServiceRaw, raw: CallServiceRaw,
propertiesAllowed: Boolean propertiesAllowed: Boolean
): State[S, (ValueModel, Inline)] = ): State[S, (ValueModel, Inline)] =

View File

@ -3,7 +3,7 @@ package aqua.model.inline.raw
import aqua.model.* import aqua.model.*
import aqua.model.inline.Inline import aqua.model.inline.Inline
import aqua.model.inline.RawValueInliner.valueToModel import aqua.model.inline.RawValueInliner.valueToModel
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.raw.value.CollectionRaw import aqua.raw.value.CollectionRaw
import aqua.types.StreamMapType import aqua.types.StreamMapType
import aqua.types.{ArrayType, CanonStreamType, OptionType, StreamType} import aqua.types.{ArrayType, CanonStreamType, OptionType, StreamType}
@ -12,7 +12,7 @@ import cats.data.{Chain, State}
object CollectionRawInliner extends RawInliner[CollectionRaw] { object CollectionRawInliner extends RawInliner[CollectionRaw] {
override def apply[S: Mangler: Exports: Arrows]( override def apply[S: Mangler: Exports: Arrows: Config](
raw: CollectionRaw, raw: CollectionRaw,
propertiesAllowed: Boolean propertiesAllowed: Boolean
): State[S, (ValueModel, Inline)] = ): State[S, (ValueModel, Inline)] =

View File

@ -3,7 +3,7 @@ package aqua.model.inline.raw
import aqua.model.ValueModel.Ability import aqua.model.ValueModel.Ability
import aqua.model.inline.Inline import aqua.model.inline.Inline
import aqua.model.inline.RawValueInliner.unfold import aqua.model.inline.RawValueInliner.unfold
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.model.{SeqModel, ValueModel, VarModel} import aqua.model.{SeqModel, ValueModel, VarModel}
import aqua.raw.value.AbilityRaw import aqua.raw.value.AbilityRaw
import aqua.types.AbilityType import aqua.types.AbilityType
@ -15,7 +15,7 @@ import cats.syntax.functor.*
object MakeAbilityRawInliner extends RawInliner[AbilityRaw] { object MakeAbilityRawInliner extends RawInliner[AbilityRaw] {
private def updateFields[S: Mangler: Exports: Arrows]( private def updateFields[S: Mangler: Exports: Arrows: Config](
name: String, name: String,
fields: NonEmptyMap[String, (ValueModel, Inline)] fields: NonEmptyMap[String, (ValueModel, Inline)]
): State[S, Unit] = ): State[S, Unit] =
@ -27,7 +27,7 @@ object MakeAbilityRawInliner extends RawInliner[AbilityRaw] {
Exports[S].resolveAbilityField(name, n, vm) Exports[S].resolveAbilityField(name, n, vm)
}.as(()) }.as(())
override def apply[S: Mangler: Exports: Arrows]( override def apply[S: Mangler: Exports: Arrows: Config](
raw: AbilityRaw, raw: AbilityRaw,
propertiesAllowed: Boolean propertiesAllowed: Boolean
): State[S, (ValueModel, Inline)] = { ): State[S, (ValueModel, Inline)] = {

View File

@ -2,13 +2,14 @@ package aqua.model.inline.raw
import aqua.model.ValueModel import aqua.model.ValueModel
import aqua.model.inline.Inline import aqua.model.inline.Inline
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.raw.value.ValueRaw import aqua.raw.value.ValueRaw
import cats.data.State import cats.data.State
trait RawInliner[T <: ValueRaw] { trait RawInliner[T <: ValueRaw] {
def apply[S: Mangler: Exports: Arrows]( def apply[S: Mangler: Exports: Arrows: Config](
raw: T, raw: T,
propertiesAllowed: Boolean = true propertiesAllowed: Boolean = true
): State[S, (ValueModel, Inline)] ): State[S, (ValueModel, Inline)]

View File

@ -3,17 +3,17 @@ package aqua.model.inline.raw
import aqua.errors.Errors.internalError import aqua.errors.Errors.internalError
import aqua.model.* import aqua.model.*
import aqua.model.inline.Inline import aqua.model.inline.Inline
import aqua.model.inline.state.{Arrows, Exports, Mangler}
import aqua.model.inline.RawValueInliner.unfold import aqua.model.inline.RawValueInliner.unfold
import aqua.model.inline.state.*
import aqua.types.{ArrayType, CanonStreamType, ScalarType, StreamType} import aqua.types.{ArrayType, CanonStreamType, ScalarType, StreamType}
import cats.data.State
import cats.data.Chain import cats.data.Chain
import cats.data.State
import cats.instances.stream
import cats.syntax.applicative.*
import cats.syntax.monoid.* import cats.syntax.monoid.*
import cats.syntax.option.* import cats.syntax.option.*
import cats.syntax.applicative.*
import scribe.Logging import scribe.Logging
import cats.instances.stream
object StreamGateInliner extends Logging { object StreamGateInliner extends Logging {
@ -88,7 +88,7 @@ object StreamGateInliner extends Logging {
) )
} }
def apply[S: Mangler: Exports: Arrows]( def apply[S: Mangler: Exports: Arrows: Config](
streamName: String, streamName: String,
streamType: StreamType, streamType: StreamType,
sizeModel: ValueModel sizeModel: ValueModel

View File

@ -3,7 +3,7 @@ package aqua.model.inline.raw
import aqua.model.* import aqua.model.*
import aqua.model.inline.Inline import aqua.model.inline.Inline
import aqua.model.inline.RawValueInliner.valueToModel import aqua.model.inline.RawValueInliner.valueToModel
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.*
import aqua.raw.value.StreamRaw import aqua.raw.value.StreamRaw
import cats.data.{Chain, State} import cats.data.{Chain, State}
@ -11,7 +11,7 @@ import cats.syntax.traverse.*
object StreamRawInliner extends RawInliner[StreamRaw] { object StreamRawInliner extends RawInliner[StreamRaw] {
override def apply[S: Mangler: Exports: Arrows]( override def apply[S: Mangler: Exports: Arrows: Config](
raw: StreamRaw, raw: StreamRaw,
propertiesAllowed: Boolean propertiesAllowed: Boolean
): State[S, (ValueModel, Inline)] = { ): State[S, (ValueModel, Inline)] = {

View File

@ -0,0 +1,41 @@
package aqua.model.inline.state
import cats.data.{Reader, State}
/**
* Representation that `S` contains configuration for inlining
*/
trait Config[S] {
self =>
/**
* Flag that disables error propagation mechanics in inlined code
*/
def noErrorPropagation: Reader[S, Boolean]
final def transform[R](f: R => S): Config[R] = new Config[R] {
override def noErrorPropagation: Reader[R, Boolean] =
self.noErrorPropagation.local(f)
}
}
object Config {
case class Values(noErrorPropagation: Boolean = false)
object Values {
lazy val default: Values = Values()
}
given Config[Values] = new Config[Values] {
override def noErrorPropagation: Reader[Values, Boolean] =
Reader(_.noErrorPropagation)
}
def apply[S: Config]: Config[S] =
implicitly[Config[S]]
def noErrorPropagation[S: Config]: Reader[S, Boolean] =
Config[S].noErrorPropagation
}

View File

@ -1,11 +1,12 @@
package aqua.model.inline.state package aqua.model.inline.state
import aqua.mangler.ManglerState import aqua.mangler.ManglerState
import aqua.model.{FuncArrow, ValueModel}
import aqua.model.inline.state.{Arrows, Counter, Exports, Mangler} import aqua.model.inline.state.{Arrows, Counter, Exports, Mangler}
import aqua.model.{FuncArrow, ValueModel}
import aqua.raw.arrow.FuncRaw import aqua.raw.arrow.FuncRaw
import aqua.raw.value.{ValueRaw, VarRaw} import aqua.raw.value.{ValueRaw, VarRaw}
import aqua.types.ArrowType import aqua.types.ArrowType
import cats.data.{Chain, State} import cats.data.{Chain, State}
import cats.instances.list.* import cats.instances.list.*
import cats.syntax.traverse.* import cats.syntax.traverse.*
@ -27,7 +28,8 @@ case class InliningState(
noNames: ManglerState = ManglerState(), noNames: ManglerState = ManglerState(),
resolvedExports: Map[String, ValueModel] = Map.empty, resolvedExports: Map[String, ValueModel] = Map.empty,
resolvedArrows: Map[String, FuncArrow] = Map.empty, resolvedArrows: Map[String, FuncArrow] = Map.empty,
instructionCounter: Int = 0 instructionCounter: Int = 0,
config: Config.Values = Config.Values.default
) )
object InliningState { object InliningState {
@ -44,4 +46,6 @@ object InliningState {
given Exports[InliningState] = given Exports[InliningState] =
Exports.Simple.transformS(_.resolvedExports, (acc, ex) => acc.copy(resolvedExports = ex)) Exports.Simple.transformS(_.resolvedExports, (acc, ex) => acc.copy(resolvedExports = ex))
given Config[InliningState] =
Config[Config.Values].transform(_.config)
} }

View File

@ -1,25 +1,28 @@
package aqua.model.inline.tag package aqua.model.inline.tag
import aqua.raw.value.{ApplyBinaryOpRaw, ValueRaw} import aqua.helpers.syntax.reader.*
import aqua.raw.value.ApplyBinaryOpRaw.Op as BinOp
import aqua.model.ValueModel
import aqua.model.* import aqua.model.*
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.ValueModel
import aqua.model.inline.Inline.parDesugarPrefixOpt
import aqua.model.inline.RawValueInliner.valueToModel import aqua.model.inline.RawValueInliner.valueToModel
import aqua.model.inline.TagInliner.canonicalizeIfStream import aqua.model.inline.TagInliner.canonicalizeIfStream
import aqua.model.inline.Inline.parDesugarPrefixOpt import aqua.model.inline.state.*
import cats.data.{Chain, State} import aqua.raw.value.ApplyBinaryOpRaw.Op as BinOp
import cats.syntax.flatMap.* import aqua.raw.value.{ApplyBinaryOpRaw, ValueRaw}
import cats.syntax.apply.*
import cats.Eval import cats.Eval
import cats.data.Reader
import cats.data.{Chain, State}
import cats.syntax.apply.*
import cats.syntax.flatMap.*
final case class IfTagInliner( final case class IfTagInliner(
valueRaw: ValueRaw valueRaw: ValueRaw
) { ) {
import IfTagInliner.* import IfTagInliner.*
def inlined[S: Mangler: Exports: Arrows]: State[S, IfTagInlined] = def inlined[S: Mangler: Exports: Arrows: Config]: State[S, IfTagInlined] = for {
(valueRaw match { cond <- (valueRaw match {
// Optimize in case last operation is equality check // Optimize in case last operation is equality check
case ApplyBinaryOpRaw(op @ (BinOp.Eq | BinOp.Neq), left, right, _) => case ApplyBinaryOpRaw(op @ (BinOp.Eq | BinOp.Neq), left, right, _) =>
( (
@ -41,12 +44,36 @@ final case class IfTagInliner(
(prefix, valueModel, compareModel, shouldMatch) (prefix, valueModel, compareModel, shouldMatch)
} }
}).map { case (prefix, leftValue, rightValue, shouldMatch) => })
IfTagInlined( (prefix, leftValue, rightValue, shouldMatch) = cond
prefix, noProp <- Config[S].noErrorPropagation.toState
toModel(leftValue, rightValue, shouldMatch) model = if (noProp) toModelNoProp else toModel
) } yield IfTagInlined(
} prefix,
model(leftValue, rightValue, shouldMatch)
)
private def toModelNoProp(
leftValue: ValueModel,
rightValue: ValueModel,
shouldMatch: Boolean
)(children: Chain[OpModel.Tree]): OpModel.Tree =
children
.filterNot(_.head == EmptyModel)
.uncons
.map { case (ifBody, elseBody) =>
XorModel.wrap(
MatchMismatchModel(
leftValue,
rightValue,
shouldMatch
).wrap(ifBody),
SeqModel.wrap(
elseBody
)
)
}
.getOrElse(EmptyModel.leaf)
private def toModel( private def toModel(
leftValue: ValueModel, leftValue: ValueModel,

View File

@ -0,0 +1,68 @@
package aqua.model.inline.tag
import aqua.helpers.syntax.reader.*
import aqua.model.*
import aqua.model.inline.Inline.parDesugarPrefix
import aqua.model.inline.RawValueInliner.{valueListToModel, valueToModel}
import aqua.model.inline.TagInliner.flat
import aqua.model.inline.state.*
import aqua.raw.ops.OnTag
import aqua.raw.value.ValueRaw
import cats.data.{Chain, State}
import cats.syntax.bifunctor.*
import cats.syntax.traverse.*
final case class OnTagInliner(
peerId: ValueRaw,
via: Chain[ValueRaw],
strategy: Option[OnTag.ReturnStrategy]
) {
import OnTagInliner.*
def inlined[S: Mangler: Exports: Arrows: Config]: State[S, OnTagInlined] =
for {
peerIdDe <- valueToModel(peerId)
viaDe <- valueListToModel(via.toList)
viaDeFlattened <- viaDe.traverse(flat.tupled)
(pid, pif) = peerIdDe
(viaD, viaF) = viaDeFlattened.unzip.bimap(Chain.fromSeq, _.flatten)
strat = strategy.map { case OnTag.ReturnStrategy.Relay =>
OnModel.ReturnStrategy.Relay
}
noProp <- Config[S].noErrorPropagation.toState
model = if (noProp) toModelNoProp else toModel
} yield OnTagInlined(
prefix = parDesugarPrefix(viaF.prependedAll(pif)),
toModel = model(pid, viaD, strat)
)
private def toModelNoProp(
pid: ValueModel,
via: Chain[ValueModel],
strat: Option[OnModel.ReturnStrategy]
)(children: Chain[OpModel.Tree]): OpModel.Tree =
OnModel(pid, via, strat).wrap(children)
private def toModel(
pid: ValueModel,
via: Chain[ValueModel],
strat: Option[OnModel.ReturnStrategy]
)(children: Chain[OpModel.Tree]): OpModel.Tree =
XorModel.wrap(
OnModel(pid, via, strat).wrap(
children
),
// This will return to previous topology
// and propagate error up
FailModel(ValueModel.error).leaf
)
}
object OnTagInliner {
final case class OnTagInlined(
prefix: Option[OpModel.Tree],
toModel: Chain[OpModel.Tree] => OpModel.Tree
)
}

View File

@ -51,7 +51,7 @@ object ConstantRaw {
def hostPeerId(relayVarName: Option[String]): ConstantRaw = def hostPeerId(relayVarName: Option[String]): ConstantRaw =
ConstantRaw( ConstantRaw(
"HOST_PEER_ID", "HOST_PEER_ID",
relayVarName.fold[ValueRaw](ValueRaw.InitPeerId)(r => VarRaw(r, ScalarType.string)), relayVarName.fold(ValueRaw.InitPeerId)(r => VarRaw(r, ScalarType.string)),
false false
) )

View File

@ -1,12 +1,13 @@
package aqua.res package aqua.res
import aqua.model.*
import aqua.raw.value.{LiteralRaw, ValueRaw}
import aqua.types.*
import aqua.types.{ArrayType, CanonStreamType, StreamType} import aqua.types.{ArrayType, CanonStreamType, StreamType}
import cats.Eval import cats.Eval
import cats.data.{Chain, NonEmptyList} import cats.data.{Chain, NonEmptyList}
import cats.free.Cofree import cats.free.Cofree
import aqua.raw.value.{LiteralRaw, ValueRaw}
import aqua.model.*
import aqua.types.*
/** /**
* Helpers for translating [[OpModel]] to [[ResolvedOp]] * Helpers for translating [[OpModel]] to [[ResolvedOp]]
@ -22,8 +23,8 @@ object MakeRes {
def hop(onPeer: ValueModel): ResolvedOp.Tree = { def hop(onPeer: ValueModel): ResolvedOp.Tree = {
// Those names can't be produced from compilation // Those names can't be produced from compilation
// so they are safe to use // so they are safe to use
val streamName = "-ephemeral-stream-" val streamName = "-hop-"
val canonName = "-ephemeral-canon-" val canonName = "-hopc-"
val elementType = BottomType val elementType = BottomType
val streamType = StreamType(elementType) val streamType = StreamType(elementType)
val canonType = CanonStreamType(elementType) val canonType = CanonStreamType(elementType)

View File

@ -2,7 +2,7 @@ package aqua.model.transform
import aqua.model.* import aqua.model.*
import aqua.model.inline.ArrowInliner import aqua.model.inline.ArrowInliner
import aqua.model.inline.state.InliningState import aqua.model.inline.state.{Config, InliningState}
import aqua.model.transform.TransformConfig.TracingConfig import aqua.model.transform.TransformConfig.TracingConfig
import aqua.model.transform.funcop.* import aqua.model.transform.funcop.*
import aqua.model.transform.pre.* import aqua.model.transform.pre.*
@ -48,6 +48,7 @@ object Transform extends Logging {
private def funcToModelTree( private def funcToModelTree(
func: FuncArrow, func: FuncArrow,
preTransformer: FuncPreTransformer, preTransformer: FuncPreTransformer,
conf: TransformConfig,
funcArgName: String = "_func" funcArgName: String = "_func"
): Eval[OpModel.Tree] = { ): Eval[OpModel.Tree] = {
@ -66,7 +67,10 @@ object Transform extends Logging {
val call = CallModel(funcArg :: Nil, Nil) val call = CallModel(funcArg :: Nil, Nil)
// <funcArgName> resolves to func // <funcArgName> resolves to func
val initState = InliningState(resolvedArrows = Map(funcArgName -> func)) val initState = InliningState(
resolvedArrows = Map(funcArgName -> func),
config = Config.Values(noErrorPropagation = conf.noXor)
)
// Inlining `funcAround(<funcArgName>)` // Inlining `funcAround(<funcArgName>)`
ArrowInliner ArrowInliner
@ -118,7 +122,7 @@ object Transform extends Logging {
for { for {
// Pre transform and inline the function // Pre transform and inline the function
model <- funcToModelTree(func, preTransformer) model <- funcToModelTree(func, preTransformer, conf)
// Post transform the function. // Post transform the function.
// We should wrap `model` with `onInitPeer` here // We should wrap `model` with `onInitPeer` here
// so that TagInliner would not wrap it with `xor`. // so that TagInliner would not wrap it with `xor`.

View File

@ -20,6 +20,7 @@ import cats.kernel.Monoid
* @param relayVarName - name of the relay variable * @param relayVarName - name of the relay variable
* @param tracing - tracing configuration * @param tracing - tracing configuration
* @param constants - list of constants * @param constants - list of constants
* @param noXor - if true, do not generate generate `xor`s for error propagation
*/ */
case class TransformConfig( case class TransformConfig(
getDataService: String = "getDataSrv", getDataService: String = "getDataSrv",
@ -30,16 +31,12 @@ case class TransformConfig(
noEmptyResponse: Boolean = false, noEmptyResponse: Boolean = false,
relayVarName: Option[String] = Some("-relay-"), relayVarName: Option[String] = Some("-relay-"),
tracing: Option[TransformConfig.TracingConfig] = None, tracing: Option[TransformConfig.TracingConfig] = None,
constants: List[ConstantRaw] = Nil noXor: Boolean = false
) { ) {
val errorId: ValueRaw = LiteralRaw.quote(errorFuncName) val errorId: ValueRaw = LiteralRaw.quote(errorFuncName)
val errorHandlingSrvId: ValueRaw = LiteralRaw.quote(errorHandlingService) val errorHandlingSrvId: ValueRaw = LiteralRaw.quote(errorHandlingService)
val callbackSrvId: ValueRaw = LiteralRaw.quote(callbackService) val callbackSrvId: ValueRaw = LiteralRaw.quote(callbackService)
val dataSrvId: ValueRaw = LiteralRaw.quote(getDataService) val dataSrvId: ValueRaw = LiteralRaw.quote(getDataService)
val constantsList: List[ConstantRaw] =
ConstantRaw.defaultConstants(relayVarName) ::: constants
} }
object TransformConfig { object TransformConfig {

View File

@ -2,9 +2,9 @@ package aqua.model.transform.funcop
import aqua.model.OpModel import aqua.model.OpModel
import cats.Eval
import cats.data.Chain import cats.data.Chain
import cats.free.Cofree import cats.free.Cofree
import cats.Eval
/** /**
* Base type for [[OpModel.Tree]] -> [[OpModel.Tree]] transformation * Base type for [[OpModel.Tree]] -> [[OpModel.Tree]] transformation
@ -23,7 +23,7 @@ trait OpTransform {
.lift(op, children) .lift(op, children)
.getOrElse( .getOrElse(
Eval.now( Eval.now(
op.wrap(children.toList: _*) op.wrap(children.toList*)
) )
) )
) )

View File

@ -0,0 +1,10 @@
package aqua.helpers.syntax
import cats.data.{Reader, State}
object reader {
extension [S, A](r: Reader[S, A]) {
def toState: State[S, A] = State.inspect(r.run)
}
}