fix: Allow spaces after aqua header (#1112)

* Allow spaces after aqua header

* Fix test, add spaces after star to parsing
This commit is contained in:
InversionSpaces 2024-04-02 11:55:25 +02:00 committed by GitHub
parent 8f06ac1cba
commit 9dc9e55973
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 61 additions and 20 deletions

View File

@ -10,8 +10,10 @@ import aqua.parser.lift.Span.{P0ToSpan, PToSpan}
import cats.Comonad import cats.Comonad
import cats.parse.Parser import cats.parse.Parser
import cats.syntax.applicative.*
import cats.syntax.comonad.* import cats.syntax.comonad.*
import cats.syntax.functor.* import cats.syntax.functor.*
import cats.syntax.option.*
import cats.~> import cats.~>
case class ModuleExpr[F[_]]( case class ModuleExpr[F[_]](
@ -69,7 +71,7 @@ object ModuleExpr extends HeaderExpr.Companion {
comma[NameOrAb[Span.S]](nameOrAb).map(_.toList) comma[NameOrAb[Span.S]](nameOrAb).map(_.toList)
private val nameOrAbListOrAll: Parser[Either[List[NameOrAb[Span.S]], Token[Span.S]]] = private val nameOrAbListOrAll: Parser[Either[List[NameOrAb[Span.S]], Token[Span.S]]] =
nameOrAbList.map(Left(_)) | `star`.lift.map(Token.lift(_)).map(Right(_)) nameOrAbList.map(Left(_)) | (`star` <* ` *`).lift.map(Token.lift(_)).map(Right(_))
private val moduleWord: Parser[Word[Span.S]] = private val moduleWord: Parser[Word[Span.S]] =
(`module`.as(Word.Kind.Module).lift.backtrack | (`module`.as(Word.Kind.Module).lift.backtrack |
@ -79,7 +81,9 @@ object ModuleExpr extends HeaderExpr.Companion {
( (
(` *`.with1 *> moduleWord) ~ (` *`.with1 *> moduleWord) ~
(` ` *> Ability.dotted) ~ (` ` *> Ability.dotted) ~
(` declares ` *> nameOrAbListOrAll).? (` declares ` *> nameOrAbListOrAll).backtrack
.map(_.some)
.orElse(` *`.as(none)) // Allow trailing spaces
).map { ).map {
case ((word, name), None) => case ((word, name), None) =>
ModuleExpr(word, name, None, Nil, Nil) ModuleExpr(word, name, None, Nil, Nil)

View File

@ -13,17 +13,62 @@ import org.scalatest.matchers.should.Matchers
class ModuleSpec extends AnyFlatSpec with Matchers with AquaSpec { class ModuleSpec extends AnyFlatSpec with Matchers with AquaSpec {
import AquaSpec.* import AquaSpec.*
"module header" should "be parsed" in { val myModule = ModuleExpr(
ModuleExpr.p.parseAll("aqua MyModule").value.mapK(spanToId) should be( ModuleExpr.Word[Id](Id(ModuleExpr.Word.Kind.Aqua)),
ModuleExpr( toAb("MyModule"),
ModuleExpr.Word[Id](Id(ModuleExpr.Word.Kind.Aqua)), None,
toAb("MyModule"), Nil,
None, Nil
Nil, )
Nil
) val declaresAll = myModule.copy(
declareAll = Some(Token.lift[Id, Unit](()))
)
def declares(symbols: List[String]) =
myModule.copy(
declareNames = symbols.filter(_.headOption.exists(_.isLower)).map(toName),
declareCustom = symbols.filter(_.headOption.exists(_.isUpper)).map(toAb)
) )
def parseModuleExpr(expr: String): ModuleExpr[Id] =
ModuleExpr.p
.parseAll(expr)
.value
.mapK(spanToId)
"module expr" should "be parsed" in {
parseModuleExpr("aqua MyModule") should be(myModule)
}
it should "be parsed with spaces in the end" in {
(0 to 10).foreach(sp => parseModuleExpr("aqua MyModule" + " ".repeat(sp)) should be(myModule))
}
it should "be parsed with spaces in the beginning" in {
(0 to 10).foreach(sp => parseModuleExpr(" ".repeat(sp) + "aqua MyModule") should be(myModule))
}
it should "be parsed with `declares *`" in {
parseModuleExpr("aqua MyModule declares *") should be(declaresAll)
}
it should "be parsed with `declares *` with spaces in the end" in {
(0 to 10).foreach(sp =>
parseModuleExpr("aqua MyModule declares *" + " ".repeat(sp)) should be(declaresAll)
)
}
it should "be parsed with `declares`" in {
List("a", "myFunc", "MyService", "MyAbility", "CONST").inits.takeWhile(_.nonEmpty).foreach {
decl =>
parseModuleExpr(s"aqua MyModule declares " + decl.mkString(", ")) should be(
declares(decl)
)
}
}
"module header" should "be parsed" in {
Header.p Header.p
.parseAll(s"""aqua MyModule declares * .parseAll(s"""aqua MyModule declares *
|""".stripMargin) |""".stripMargin)
@ -31,15 +76,7 @@ class ModuleSpec extends AnyFlatSpec with Matchers with AquaSpec {
.headers .headers
.headOption .headOption
.get .get
.mapK(spanToId) should be( .mapK(spanToId) should be(declaresAll)
ModuleExpr(
ModuleExpr.Word[Id](Id(ModuleExpr.Word.Kind.Aqua)),
toAb("MyModule"),
Some(Token.lift[Id, Unit](())),
Nil,
Nil
)
)
} }
} }