Skip to content

Commit

Permalink
Implement methods as AggregateDefinition similar to field
Browse files Browse the repository at this point in the history
Signed-off-by: reidspencer <reid.spencer@yoppworks.com>
  • Loading branch information
reid-spencer committed Sep 22, 2023
1 parent d15a1ae commit 249666b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ trait Types {

sealed trait TypeDefinition extends Definition

sealed trait AggregateDefinition extends TypeDefinition {
def typeEx: TypeExpression
}

/** Base trait of an expression that defines a type
*/
sealed trait TypeExpression extends RiddlValue {
Expand Down Expand Up @@ -245,6 +249,7 @@ trait Types {
brief: Option[LiteralString] = Option.empty[LiteralString],
description: Option[Description] = None
) extends LeafDefinition
with AggregateDefinition
with AlwaysEmpty
with TypeDefinition
with SagaDefinition
Expand Down Expand Up @@ -286,41 +291,43 @@ trait Types {
loc: At,
id: Identifier,
args: Seq[MethodArgument] = Seq.empty[MethodArgument],
result: TypeExpression,
typeEx: TypeExpression,
brief: Option[LiteralString] = Option.empty[LiteralString],
description: Option[Description] = None
) extends LeafDefinition
with AggregateDefinition
with AlwaysEmpty
with TypeDefinition
with SagaDefinition
with StateDefinition
with FunctionDefinition
with ProjectorDefinition {
override def format: String = s"${id.format}(${args.map(_.format).mkString(", ")}): ${result.format}"
override def format: String = s"${id.format}(${args.map(_.format).mkString(", ")}): ${typeEx.format}"
final val kind: String = "Field"
}

/** A type expression that contains an aggregation of fields
*
* This is used as the base trait of Aggregations and Messages
*/
trait AggregateTypeExpression extends TypeExpression with Container[Field] {
def fields: Seq[Field]
final lazy val contents: Seq[Field] = fields
override def format: String = s"{ ${fields.map(_.format).mkString(", ")} }"
trait AggregateTypeExpression extends TypeExpression with Container[AggregateDefinition] {
def contents: Seq[AggregateDefinition]
lazy val fields: Seq[Field] = contents.filter(_.isInstanceOf[Field]).asInstanceOf[Seq[Field]]
lazy val methods: Seq[Method] = contents.filter(_.isInstanceOf[Method]).asInstanceOf[Seq[Method]]
override def format: String = s"{ ${contents.map(_.format).mkString(", ")} }"
override def isAssignmentCompatible(other: TypeExpression): Boolean = {

other match {
case oate: AggregateTypeExpression =>
val validity: Seq[Boolean] = for
ofield <- oate.fields
myField <- fields.find(_.id.value == ofield.id.value)
ofield <- oate.contents
myField <- contents.find(_.id.value == ofield.id.value)
myTypEx = myField.typeEx
oTypeEx = ofield.typeEx
yield {
myTypEx.isAssignmentCompatible(oTypeEx)
}
(validity.size == oate.fields.size) && validity.forall(_ == true)
(validity.size == oate.contents.size) && validity.forall(_ == true)
case _ =>
super.isAssignmentCompatible(other)
}
Expand All @@ -334,7 +341,8 @@ trait Types {
* @param fields
* The fields of the aggregation
*/
case class Aggregation(loc: At, fields: Seq[Field] = Seq.empty[Field]) extends AggregateTypeExpression
case class Aggregation(loc: At, contents: Seq[AggregateDefinition] = Seq.empty[AggregateDefinition]) extends
AggregateTypeExpression

object Aggregation {
def empty(loc: At = At.empty): Aggregation = { Aggregation(loc) }
Expand Down Expand Up @@ -436,7 +444,7 @@ trait Types {
case class AggregateUseCaseTypeExpression(
loc: At,
usecase: AggregateUseCase,
fields: Seq[Field] = Seq.empty[Field]
contents: Seq[AggregateDefinition] = Seq.empty[AggregateDefinition]
) extends AggregateTypeExpression {
override def format: String = {
usecase.format.toLowerCase() + " " + super.format
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,20 +376,36 @@ private[parsing] trait TypeParser extends CommonParser {
def field[u: P]: P[Field] = {
P(
location ~ identifier ~ is ~ fieldTypeExpression ~ briefly ~ description
)
.map(tpl => (Field.apply _).tupled(tpl))
).map(tpl => (Field.apply _).tupled(tpl))
}

def arguments[u:P]: P[Seq[MethodArgument]] = {
P(
(
location ~ identifier.map(_.value) ~ Punctuation.colon ~ fieldTypeExpression
).map(tpl => (MethodArgument.apply _).tupled(tpl))
).rep(min=0, Punctuation.comma)
}

def fields[u: P]: P[Seq[Field]] = {
def method[u: P]: P[Method] = {
P(
location ~ identifier ~ Punctuation.roundOpen ~ arguments ~ Punctuation.roundClose ~
is ~ fieldTypeExpression ~ briefly ~ description
).map(tpl => (Method.apply _).tupled(tpl))
}


def aggregateDefinitions[u:P]: P[Seq[AggregateDefinition]] = {
P(
Punctuation.undefinedMark.!.map(_ => Seq.empty[Field]) |
field.rep(min = 0, Punctuation.comma)
undefined(Seq.empty[AggregateDefinition]) |
(field | method).rep(min = 1, Punctuation.comma)
)
}

def aggregation[u: P]: P[Aggregation] = {
P(location ~ Keywords.fields.? ~ open ~ fields ~ close).map { case (loc, fields) =>
Aggregation(loc, fields)
P(location ~ open ~ aggregateDefinitions.? ~ close).map {
case (loc, Some(contents)) => Aggregation(loc, contents)
case (loc, None) => Aggregation(loc, Seq.empty[AggregateDefinition])
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ class ResolutionPassTest extends ResolvingTest {
"""domain A {
| type T is { tp: A.TPrime } // Refers to T.TPrime
| type TPrime is { t: A.T } // Refers to A.T cyclically
| command DoIt is {}
| command DoIt is { }
| context C {
| entity E {
| record fields is {
Expand Down

0 comments on commit 249666b

Please sign in to comment.