mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-12 17:55:33 +00:00
Savepoint
This commit is contained in:
parent
9aec470d38
commit
a73996d8de
@ -3,7 +3,7 @@ package aqua.model.inline
|
||||
import aqua.model.*
|
||||
import aqua.model.inline.Inline.MergeMode.*
|
||||
import aqua.model.inline.raw.*
|
||||
import aqua.model.inline.state.{Arrows, Counter, Exports, Mangler}
|
||||
import aqua.model.inline.state.{Counter, Exports, Mangler}
|
||||
import aqua.raw.ops.*
|
||||
import aqua.raw.value.*
|
||||
import aqua.types.{ArrayType, LiteralType, OptionType, StreamType}
|
||||
@ -23,21 +23,26 @@ object RawValueInliner extends Logging {
|
||||
|
||||
import aqua.model.inline.Inline.*
|
||||
|
||||
private[inline] def unfold[S: Mangler: Exports: Arrows](
|
||||
private[inline] def unfold[S: Mangler: Exports](
|
||||
raw: ValueRaw,
|
||||
propertiesAllowed: Boolean = true
|
||||
): State[S, (ValueModel, Inline)] = for {
|
||||
): State[S, (Exports.Export, Inline)] = for {
|
||||
optimized <- StateT.liftF(Optimization.optimize(raw))
|
||||
_ <- StateT.liftF(Eval.later(logger.trace("OPTIMIZIED " + optimized)))
|
||||
result <- optimized match {
|
||||
case VarRaw(name, t) =>
|
||||
for {
|
||||
exports <- Exports[S].exports
|
||||
model = VarModel(name, t, Chain.empty).resolveWith(exports)
|
||||
} yield model -> Inline.empty
|
||||
maybeExport <- Exports[S].get(name)
|
||||
model = VarModel(name, t)
|
||||
exp = maybeExport.getOrElse(
|
||||
Exports.Export.Value(model)
|
||||
)
|
||||
} yield exp -> Inline.empty
|
||||
|
||||
case LiteralRaw(value, t) =>
|
||||
State.pure(LiteralModel(value, t) -> Inline.empty)
|
||||
val model = LiteralModel(value, t)
|
||||
val exp = Exports.Export.Value(model)
|
||||
State.pure(exp -> Inline.empty)
|
||||
|
||||
case alr: ApplyPropertyRaw =>
|
||||
ApplyPropertiesRawInliner(alr, propertiesAllowed)
|
||||
@ -115,7 +120,7 @@ object RawValueInliner extends Logging {
|
||||
): State[S, (CallModel, Option[OpModel.Tree])] = {
|
||||
valueListToModel(call.args).flatMap { args =>
|
||||
if (flatStreamArguments)
|
||||
args.map{ arg =>
|
||||
args.map { arg =>
|
||||
TagInliner.flat(arg._1, arg._2, true)
|
||||
}.sequence
|
||||
else
|
||||
|
@ -6,7 +6,8 @@ import aqua.model.ValueModel.Ability
|
||||
import aqua.model.inline.Inline
|
||||
import aqua.model.inline.Inline.MergeMode.*
|
||||
import aqua.model.inline.RawValueInliner.unfold
|
||||
import aqua.model.inline.state.{Arrows, Exports, Mangler}
|
||||
import aqua.model.inline.state.Exports.Export
|
||||
import aqua.model.inline.state.{Exports, Mangler}
|
||||
import aqua.raw.value.*
|
||||
import aqua.types.*
|
||||
|
||||
@ -24,7 +25,7 @@ import scribe.Logging
|
||||
object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Logging {
|
||||
|
||||
// in perspective literals can have properties and functors (like `nil` with length)
|
||||
def flatLiteralWithProperties[S: Mangler: Exports: Arrows](
|
||||
def flatLiteralWithProperties[S: Mangler: Exports](
|
||||
literal: LiteralModel,
|
||||
inl: Inline,
|
||||
properties: Chain[PropertyModel]
|
||||
@ -45,7 +46,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
|
||||
}
|
||||
}
|
||||
|
||||
private def unfoldAbilityProperty[S: Mangler: Exports: Arrows](
|
||||
private def unfoldAbilityProperty[S: Mangler: Exports](
|
||||
varModel: VarModel,
|
||||
abilityType: NamedType,
|
||||
p: PropertyRaw
|
||||
@ -112,7 +113,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
|
||||
)
|
||||
}
|
||||
|
||||
private[inline] def unfoldProperty[S: Mangler: Exports: Arrows](
|
||||
private[inline] def unfoldProperty[S: Mangler: Exports](
|
||||
varModel: VarModel,
|
||||
p: PropertyRaw
|
||||
): State[S, (VarModel, Inline)] =
|
||||
@ -172,7 +173,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
|
||||
private case class PropertyRawWithModel(raw: PropertyRaw, model: Option[PropertyModel])
|
||||
|
||||
// Unfold properties that we can process in parallel
|
||||
private def optimizeProperties[S: Mangler: Exports: Arrows](
|
||||
private def optimizeProperties[S: Mangler: Exports](
|
||||
properties: Chain[PropertyRaw]
|
||||
): State[S, (Chain[PropertyRawWithModel], Inline)] = {
|
||||
properties.map {
|
||||
@ -211,7 +212,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
|
||||
}.sequence.map(_.toList.unzip.bimap(Chain.fromSeq, _.combineAll))
|
||||
}
|
||||
|
||||
private def unfoldProperties[S: Mangler: Exports: Arrows](
|
||||
private def unfoldProperties[S: Mangler: Exports](
|
||||
prevInline: Inline,
|
||||
vm: VarModel,
|
||||
properties: Chain[PropertyRaw],
|
||||
@ -263,7 +264,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
|
||||
/**
|
||||
* Unfold `stream[idx]`
|
||||
*/
|
||||
private def unfoldStreamGate[S: Mangler: Exports: Arrows](
|
||||
private def unfoldStreamGate[S: Mangler: Exports](
|
||||
streamName: String,
|
||||
streamType: StreamType,
|
||||
idx: ValueRaw
|
||||
@ -325,21 +326,18 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
|
||||
mergeMode = SeqMode
|
||||
)
|
||||
|
||||
private def unfoldRawWithProperties[S: Mangler: Exports: Arrows](
|
||||
private def unfoldRawWithProperties[S: Mangler: Exports](
|
||||
raw: ValueRaw,
|
||||
properties: Chain[PropertyRaw],
|
||||
propertiesAllowed: Boolean
|
||||
): State[S, (ValueModel, Inline)] =
|
||||
): State[S, (Export, Inline)] =
|
||||
(raw, properties.uncons) match {
|
||||
/**
|
||||
* To inline
|
||||
*/
|
||||
case (
|
||||
vr @ VarRaw(_, st @ StreamType(_)),
|
||||
Some(IntoIndexRaw(idx, _), otherProperties)
|
||||
) =>
|
||||
unfold(vr).flatMap {
|
||||
case (VarModel(nameVM, _, _), inl) =>
|
||||
case (Export.Value(VarModel(nameVM, _, _)), inl) =>
|
||||
for {
|
||||
gateInlined <- unfoldStreamGate(nameVM, st, idx)
|
||||
(gateVM, gateInline) = gateInlined
|
||||
@ -362,12 +360,8 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
|
||||
unfoldProperties(prevInline, vm, properties, propertiesAllowed)
|
||||
// To coerce types
|
||||
.map(identity)
|
||||
case (l: LiteralModel, inline) =>
|
||||
flatLiteralWithProperties(
|
||||
l,
|
||||
inline,
|
||||
Chain.empty
|
||||
).flatMap { (varModel, prevInline) =>
|
||||
case (l: LiteralModel, inl) =>
|
||||
flatLiteralWithProperties(l, inl, Chain.empty).flatMap { (varModel, prevInline) =>
|
||||
unfoldProperties(prevInline, varModel, properties, propertiesAllowed).map {
|
||||
case (v, i) =>
|
||||
v -> i
|
||||
@ -389,10 +383,10 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
|
||||
flatten = VarModel(nn, varModel.`type`)
|
||||
} yield flatten -> Inline.tree(FlattenModel(varModel, flatten.name).leaf)
|
||||
|
||||
override def apply[S: Mangler: Exports: Arrows](
|
||||
override def apply[S: Mangler: Exports](
|
||||
apr: ApplyPropertyRaw,
|
||||
propertiesAllowed: Boolean
|
||||
): State[S, (ValueModel, Inline)] = {
|
||||
): State[S, (Export, Inline)] = {
|
||||
val (raw, properties) = apr.unwind
|
||||
unfoldRawWithProperties(raw, properties, propertiesAllowed)
|
||||
}
|
||||
|
@ -1,142 +0,0 @@
|
||||
package aqua.model.inline.state
|
||||
|
||||
import aqua.model.ValueModel
|
||||
import aqua.model.{ArgsCall, FuncArrow}
|
||||
import aqua.raw.arrow.FuncRaw
|
||||
import aqua.types.*
|
||||
|
||||
import cats.data.State
|
||||
import cats.instances.list.*
|
||||
import cats.syntax.functor.*
|
||||
import cats.syntax.option.*
|
||||
import cats.syntax.show.*
|
||||
import cats.syntax.traverse.*
|
||||
|
||||
/**
|
||||
* State algebra for resolved arrows
|
||||
*
|
||||
* @tparam S
|
||||
* State
|
||||
*/
|
||||
trait Arrows[S] extends Scoped[S] {
|
||||
self =>
|
||||
def save(name: String, arrow: FuncArrow): State[S, Unit]
|
||||
|
||||
/**
|
||||
* Arrow is resolved – save it to the state [[S]]
|
||||
*
|
||||
* @param arrow resolved arrow
|
||||
* @param topology captured topology
|
||||
*/
|
||||
final def resolved(
|
||||
arrow: FuncRaw,
|
||||
topology: Option[String]
|
||||
)(using Exports[S]): State[S, Unit] =
|
||||
for {
|
||||
arrs <- arrows
|
||||
capturedVars <- Exports[S].gather(arrow.capturedVars.toSeq)
|
||||
capturedArrows = arrs.filterKeys(arrow.capturedVars).toMap ++
|
||||
Arrows.arrowsByValues(arrs, capturedVars)
|
||||
funcArrow = FuncArrow.fromRaw(arrow, capturedArrows, capturedVars, topology)
|
||||
_ <- save(arrow.name, funcArrow)
|
||||
} yield ()
|
||||
|
||||
/**
|
||||
* Save arrows to the state [[S]]
|
||||
*
|
||||
* @param arrows
|
||||
* Resolved arrows, accessible by key name which could differ from arrow's name
|
||||
*/
|
||||
final def resolved(arrows: Map[String, FuncArrow]): State[S, Unit] =
|
||||
arrows.toList.traverse(save).void
|
||||
|
||||
/**
|
||||
* All arrows available for use in scope
|
||||
*/
|
||||
val arrows: State[S, Map[String, FuncArrow]]
|
||||
|
||||
/**
|
||||
* Pick a subset of arrows by names
|
||||
*
|
||||
* @param names
|
||||
* What arrows should be taken
|
||||
*/
|
||||
def pickArrows(names: Set[String]): State[S, Map[String, FuncArrow]] =
|
||||
arrows.map(_.view.filterKeys(names).toMap)
|
||||
|
||||
/**
|
||||
* Take arrows selected by the function call arguments
|
||||
*
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
def argsArrows(args: ArgsCall): State[S, Map[String, FuncArrow]] =
|
||||
arrows.map(args.arrowArgsMap)
|
||||
|
||||
/**
|
||||
* Changes the [[S]] type to [[R]]
|
||||
*
|
||||
* @param f
|
||||
* Lens getter
|
||||
* @param g
|
||||
* Lens setter
|
||||
* @tparam R
|
||||
* New state type
|
||||
*/
|
||||
def transformS[R](f: R => S, g: (R, S) => R): Arrows[R] = new Arrows[R] {
|
||||
|
||||
override def save(name: String, arrow: FuncArrow): State[R, Unit] =
|
||||
self.save(name, arrow).transformS(f, g)
|
||||
|
||||
override val arrows: State[R, Map[String, FuncArrow]] = self.arrows.transformS(f, g)
|
||||
|
||||
override val purge: State[R, R] =
|
||||
self.purgeR(f, g)
|
||||
|
||||
override protected def fill(s: R): State[R, Unit] =
|
||||
self.fillR(s, f, g)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
object Arrows {
|
||||
|
||||
/**
|
||||
* Retrieve all arrows that correspond to values
|
||||
*/
|
||||
def arrowsByValues(
|
||||
arrows: Map[String, FuncArrow],
|
||||
values: Map[String, ValueModel]
|
||||
): Map[String, FuncArrow] = {
|
||||
val arrowKeys = arrows.keySet ++ arrows.values.map(_.funcName)
|
||||
val varsKeys = values.keySet ++ values.values.collect { case ValueModel.Arrow(vm, _) =>
|
||||
vm.name
|
||||
}
|
||||
val keys = arrowKeys.intersect(varsKeys)
|
||||
|
||||
arrows.filter { case (arrowName, arrow) =>
|
||||
keys.contains(arrowName) || keys.contains(arrow.funcName)
|
||||
}
|
||||
}
|
||||
|
||||
def apply[S](implicit arrows: Arrows[S]): Arrows[S] = arrows
|
||||
|
||||
// Default implementation with the most straightforward state – just a Map
|
||||
object Simple extends Arrows[Map[String, FuncArrow]] {
|
||||
|
||||
override def save(name: String, arrow: FuncArrow): State[Map[String, FuncArrow], Unit] =
|
||||
State.modify(_ + (name -> arrow))
|
||||
|
||||
override val arrows: State[Map[String, FuncArrow], Map[String, FuncArrow]] =
|
||||
State.get
|
||||
|
||||
override val purge: State[Map[String, FuncArrow], Map[String, FuncArrow]] =
|
||||
for {
|
||||
s <- State.get
|
||||
_ <- State.set(Map.empty)
|
||||
} yield s
|
||||
|
||||
override protected def fill(s: Map[String, FuncArrow]): State[Map[String, FuncArrow], Unit] =
|
||||
State.set(s)
|
||||
}
|
||||
}
|
@ -1,260 +1,107 @@
|
||||
package aqua.model.inline.state
|
||||
|
||||
import aqua.model.FuncArrow
|
||||
import aqua.model.ValueModel.Ability
|
||||
import aqua.model.{LiteralModel, ValueModel, VarModel}
|
||||
import aqua.types.ServiceType
|
||||
import aqua.types.{AbilityType, GeneralAbilityType, NamedType}
|
||||
|
||||
import cats.data.{NonEmptyList, State}
|
||||
|
||||
/**
|
||||
* Exports – trace values available in the scope
|
||||
* @tparam S
|
||||
* State
|
||||
* @tparam S - State
|
||||
*/
|
||||
trait Exports[S] extends Scoped[S] {
|
||||
self =>
|
||||
|
||||
/**
|
||||
* [[value]] is accessible as [[exportName]]
|
||||
* @param exportName
|
||||
* Name
|
||||
* @param value
|
||||
* Value
|
||||
* [[exp]] is accessible as [[name]]
|
||||
* @param name - Name
|
||||
* @param exp - Export
|
||||
*/
|
||||
def resolved(exportName: String, value: ValueModel): State[S, Unit]
|
||||
|
||||
/**
|
||||
* [[value]] is accessible as [[abilityExportName]].[[fieldName]]
|
||||
*
|
||||
* @param abilityExportName
|
||||
* Ability Name
|
||||
* @param fieldName
|
||||
* Field Name
|
||||
* @param value
|
||||
* Value
|
||||
*/
|
||||
def resolveAbilityField(
|
||||
abilityExportName: String,
|
||||
fieldName: String,
|
||||
value: ValueModel
|
||||
): State[S, Unit]
|
||||
|
||||
/**
|
||||
* Rename ability prefix to new one
|
||||
*/
|
||||
def copyWithAbilityPrefix(prefix: String, newPrefix: String): State[S, Unit]
|
||||
|
||||
/**
|
||||
* Get name of last linked VarModel. If the last element is not VarModel, return None
|
||||
*/
|
||||
def getLastVarName(name: String): State[S, Option[String]]
|
||||
|
||||
/**
|
||||
* Rename names in variables
|
||||
*/
|
||||
def renameVariables(renames: Map[String, String]): State[S, Unit]
|
||||
def resolved(name: String, exp: Exports.Export): State[S, Unit]
|
||||
|
||||
/**
|
||||
* Resolve the whole map of exports
|
||||
* @param exports
|
||||
* name -> value
|
||||
* @param exports - name -> export
|
||||
*/
|
||||
def resolved(exports: Map[String, ValueModel]): State[S, Unit]
|
||||
def resolved(exports: Map[String, Exports.Export]): State[S, Unit]
|
||||
|
||||
/**
|
||||
* Get all export keys
|
||||
* Rename names in variables
|
||||
* @param renames - oldName -> newName
|
||||
*/
|
||||
def getKeys: State[S, Set[String]]
|
||||
def renameExports(renames: Map[String, String]): State[S, Unit]
|
||||
|
||||
/**
|
||||
* Get ability field from export
|
||||
* @param name variable ability name
|
||||
* @param field ability field
|
||||
* Get export by name
|
||||
* @param name - Name
|
||||
*/
|
||||
def getAbilityField(name: String, field: String): State[S, Option[ValueModel]]
|
||||
|
||||
/**
|
||||
* Get all the values available in the scope
|
||||
*/
|
||||
val exports: State[S, Map[String, ValueModel]]
|
||||
|
||||
final def gather(names: Seq[String]): State[S, Map[String, ValueModel]] =
|
||||
exports.map(Exports.gatherFrom(names, _))
|
||||
def get(name: String): State[S, Option[Exports.Export]]
|
||||
|
||||
/**
|
||||
* Change [[S]] to [[R]]
|
||||
*/
|
||||
def transformS[R](f: R => S, g: (R, S) => R): Exports[R] = new Exports[R] {
|
||||
|
||||
override def resolved(exportName: String, value: ValueModel): State[R, Unit] =
|
||||
self.resolved(exportName, value).transformS(f, g)
|
||||
override def resolved(name: String, exp: Exports.Export): State[R, Unit] =
|
||||
self.resolved(name, exp).transformS(f, g)
|
||||
|
||||
override def resolved(exports: Map[String, ValueModel]): State[R, Unit] =
|
||||
override def resolved(exports: Map[String, Exports.Export]): State[R, Unit] =
|
||||
self.resolved(exports).transformS(f, g)
|
||||
|
||||
override def resolveAbilityField(
|
||||
abilityExportName: String,
|
||||
fieldName: String,
|
||||
value: ValueModel
|
||||
): State[R, Unit] =
|
||||
self.resolveAbilityField(abilityExportName, fieldName, value).transformS(f, g)
|
||||
override def renameExports(renames: Map[String, String]): State[R, Unit] =
|
||||
self.renameExports(renames).transformS(f, g)
|
||||
|
||||
override def copyWithAbilityPrefix(prefix: String, newPrefix: String): State[R, Unit] =
|
||||
self.copyWithAbilityPrefix(prefix, newPrefix).transformS(f, g)
|
||||
|
||||
override def getLastVarName(name: String): State[R, Option[String]] =
|
||||
self.getLastVarName(name).transformS(f, g)
|
||||
|
||||
override def renameVariables(renames: Map[String, String]): State[R, Unit] =
|
||||
self.renameVariables(renames).transformS(f, g)
|
||||
|
||||
override def getKeys: State[R, Set[String]] =
|
||||
self.getKeys.transformS(f, g)
|
||||
|
||||
override def getAbilityField(name: String, field: String): State[R, Option[ValueModel]] =
|
||||
self.getAbilityField(name, field).transformS(f, g)
|
||||
|
||||
override val exports: State[R, Map[String, ValueModel]] =
|
||||
self.exports.transformS(f, g)
|
||||
|
||||
override val purge: State[R, R] =
|
||||
self.purgeR(f, g)
|
||||
|
||||
override protected def fill(s: R): State[R, Unit] =
|
||||
self.fillR(s, f, g)
|
||||
override def get(name: String): State[R, Option[Exports.Export]] =
|
||||
self.get(name).transformS(f, g)
|
||||
}
|
||||
}
|
||||
|
||||
object Exports {
|
||||
|
||||
enum Export {
|
||||
case Value(value: ValueModel)
|
||||
case Arrow(arrow: FuncArrow)
|
||||
case Ability(abilityType: AbilityType, values: Map[String, Export])
|
||||
case Service(serviceType: ServiceType, arrows: Map[String, Arrow])
|
||||
case Context(values: Map[String, Export])
|
||||
}
|
||||
|
||||
object Export {
|
||||
|
||||
extension (c: Export.Context) {
|
||||
|
||||
def resolved(name: String, exp: Export): Export.Context =
|
||||
c.copy(values = c.values + (name -> exp))
|
||||
|
||||
def resolved(exports: Map[String, Export]): Export.Context =
|
||||
c.copy(values = c.values ++ exports)
|
||||
|
||||
def renameExports(renames: Map[String, String]): Export.Context =
|
||||
c.copy(values = c.values.map { case (name, exp) =>
|
||||
renames.getOrElse(name, name) -> exp
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
def apply[S](using exports: Exports[S]): Exports[S] = exports
|
||||
|
||||
/**
|
||||
* Gather all the values that are related to the given names
|
||||
* (ability fields)
|
||||
*
|
||||
* @param names names of variables
|
||||
* @param state exports state
|
||||
*/
|
||||
def gatherFrom(
|
||||
names: Seq[String],
|
||||
state: Map[String, ValueModel]
|
||||
): Map[String, ValueModel] = {
|
||||
val related = for {
|
||||
variable <- names
|
||||
exp <- state.get(variable).toList
|
||||
at <- exp.`type` match {
|
||||
case at: GeneralAbilityType => at :: Nil
|
||||
case _ => Nil
|
||||
}
|
||||
field <- at.allFields.toNel.toList
|
||||
(fieldName, _) = field
|
||||
} yield AbilityType.fullName(variable, fieldName)
|
||||
object Simple extends Exports[Export.Context] {
|
||||
|
||||
state.filterKeys(names.toSet ++ related).toMap
|
||||
}
|
||||
type ST[A] = State[Export.Context, A]
|
||||
|
||||
// Get last linked VarModel
|
||||
def getLastValue(name: String, state: Map[String, ValueModel]): Option[ValueModel] = {
|
||||
state.get(name) match {
|
||||
case Some(vm @ VarModel(n, _, _)) =>
|
||||
if (name == n) Option(vm)
|
||||
else getLastValue(n, state).orElse(Option(vm))
|
||||
case lm @ Some(LiteralModel(_, _)) =>
|
||||
lm
|
||||
case _ =>
|
||||
None
|
||||
}
|
||||
}
|
||||
override def resolved(name: String, exp: Export): ST[Unit] =
|
||||
State.modify(_.resolved(name, exp))
|
||||
|
||||
object Simple extends Exports[Map[String, ValueModel]] {
|
||||
override def resolved(exports: Map[String, Export]): ST[Unit] =
|
||||
State.modify(_.resolved(exports))
|
||||
|
||||
// Make links from one set of abilities to another (for ability assignment)
|
||||
private def getAbilityPairs(
|
||||
oldName: String,
|
||||
newName: String,
|
||||
at: NamedType,
|
||||
state: Map[String, ValueModel]
|
||||
): NonEmptyList[(String, ValueModel)] = {
|
||||
at.fields.toNel.flatMap {
|
||||
case (n, at @ AbilityType(_, _)) =>
|
||||
val newFullName = AbilityType.fullName(newName, n)
|
||||
val oldFullName = AbilityType.fullName(oldName, n)
|
||||
getAbilityPairs(oldFullName, newFullName, at, state)
|
||||
case (n, t) =>
|
||||
val newFullName = AbilityType.fullName(newName, n)
|
||||
val oldFullName = AbilityType.fullName(oldName, n)
|
||||
// put link on last variable in chain
|
||||
val lastVar = Exports.getLastValue(oldFullName, state)
|
||||
NonEmptyList.of((newFullName, lastVar.getOrElse(VarModel(oldFullName, t))))
|
||||
}
|
||||
}
|
||||
override def renameExports(renames: Map[String, String]): ST[Unit] =
|
||||
State.modify(_.renameExports(renames))
|
||||
|
||||
override def resolved(
|
||||
exportName: String,
|
||||
value: ValueModel
|
||||
): State[Map[String, ValueModel], Unit] = State.modify { state =>
|
||||
value match {
|
||||
case Ability(vm, at) if vm.properties.isEmpty =>
|
||||
val pairs = getAbilityPairs(vm.name, exportName, at, state)
|
||||
state ++ pairs.toList.toMap + (exportName -> value)
|
||||
case _ => state + (exportName -> value)
|
||||
}
|
||||
}
|
||||
|
||||
override def getLastVarName(name: String): State[Map[String, ValueModel], Option[String]] =
|
||||
State.get.map(st => getLastValue(name, st).collect { case VarModel(name, _, _) => name })
|
||||
|
||||
override def resolved(exports: Map[String, ValueModel]): State[Map[String, ValueModel], Unit] =
|
||||
State.modify(_ ++ exports)
|
||||
|
||||
override def resolveAbilityField(
|
||||
abilityExportName: String,
|
||||
fieldName: String,
|
||||
value: ValueModel
|
||||
): State[Map[String, ValueModel], Unit] =
|
||||
State.modify(_ + (AbilityType.fullName(abilityExportName, fieldName) -> value))
|
||||
|
||||
override def copyWithAbilityPrefix(
|
||||
prefix: String,
|
||||
newPrefix: String
|
||||
): State[Map[String, ValueModel], Unit] =
|
||||
State.modify { state =>
|
||||
state.flatMap {
|
||||
case (k, v) if k.startsWith(prefix) =>
|
||||
List(k.replaceFirst(prefix, newPrefix) -> v, k -> v)
|
||||
case (k, v) => List(k -> v)
|
||||
}
|
||||
}
|
||||
|
||||
override def renameVariables(
|
||||
renames: Map[String, String]
|
||||
): State[Map[String, ValueModel], Unit] =
|
||||
State.modify {
|
||||
_.map {
|
||||
case (k, vm @ VarModel(name, _, _)) if renames.contains(name) =>
|
||||
k -> vm.copy(name = renames.getOrElse(name, name))
|
||||
case (k, v) => k -> v
|
||||
}
|
||||
}
|
||||
|
||||
override def getKeys: State[Map[String, ValueModel], Set[String]] = State.get.map(_.keySet)
|
||||
|
||||
override def getAbilityField(
|
||||
name: String,
|
||||
field: String
|
||||
): State[Map[String, ValueModel], Option[ValueModel]] =
|
||||
State.get.map(_.get(AbilityType.fullName(name, field)))
|
||||
|
||||
override val exports: State[Map[String, ValueModel], Map[String, ValueModel]] =
|
||||
State.get
|
||||
|
||||
override val purge: State[Map[String, ValueModel], Map[String, ValueModel]] =
|
||||
for {
|
||||
s <- State.get
|
||||
_ <- State.set(Map.empty)
|
||||
} yield s
|
||||
|
||||
override protected def fill(s: Map[String, ValueModel]): State[Map[String, ValueModel], Unit] =
|
||||
State.set(s)
|
||||
override def get(name: String): ST[Option[Export]] =
|
||||
State.inspect(_.values.get(name))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user