mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 22:50:18 +00:00
Imports bugfixes (#249)
This commit is contained in:
parent
b9af20339b
commit
3de8571be9
@ -1,3 +1,10 @@
|
|||||||
|
module Ret
|
||||||
|
|
||||||
|
import Service from "service.aqua"
|
||||||
|
|
||||||
|
use "error.aqua"
|
||||||
|
export GetStr, tupleFunc, Service as S
|
||||||
|
|
||||||
service GetStr("multiret-test"):
|
service GetStr("multiret-test"):
|
||||||
retStr: string -> string
|
retStr: string -> string
|
||||||
|
|
||||||
@ -10,6 +17,7 @@ const someStr = "some-str"
|
|||||||
func tupleFunc() -> string, u8:
|
func tupleFunc() -> string, u8:
|
||||||
str <- GetStr.retStr(someStr)
|
str <- GetStr.retStr(someStr)
|
||||||
n <- GetNum.retNum()
|
n <- GetNum.retNum()
|
||||||
|
Err.Peer.is_connected("Connected?")
|
||||||
<- str, n
|
<- str, n
|
||||||
|
|
||||||
func multiReturnFunc(somethingToReturn: []u8, smthOption: ?string) -> []string, u8, string, []u8, ?string, u8:
|
func multiReturnFunc(somethingToReturn: []u8, smthOption: ?string) -> []string, u8, string, []u8, ?string, u8:
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
module Err declares Peer, Op, include
|
||||||
|
|
||||||
service Peer("peer"):
|
service Peer("peer"):
|
||||||
is_connected: string -> bool
|
is_connected: string -> bool
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
module Srv declares *
|
||||||
|
|
||||||
import "chatApp.aqua"
|
import "chatApp.aqua"
|
||||||
|
|
||||||
service Service("affinidi/chat"):
|
service Service("affinidi/chat"):
|
||||||
|
@ -12,6 +12,7 @@ object Test extends IOApp.Simple {
|
|||||||
implicit val aio: AquaIO[IO] = new AquaFilesIO[IO]
|
implicit val aio: AquaIO[IO] = new AquaFilesIO[IO]
|
||||||
|
|
||||||
override def run: IO[Unit] =
|
override def run: IO[Unit] =
|
||||||
|
IO.println("Start ms: " + System.currentTimeMillis()) *>
|
||||||
AquaPathCompiler
|
AquaPathCompiler
|
||||||
.compileFilesTo[IO](
|
.compileFilesTo[IO](
|
||||||
Path("./aqua-src"),
|
Path("./aqua-src"),
|
||||||
@ -25,6 +26,6 @@ object Test extends IOApp.Simple {
|
|||||||
errs.map(System.err.println): Unit
|
errs.map(System.err.println): Unit
|
||||||
case Validated.Valid(res) =>
|
case Validated.Valid(res) =>
|
||||||
res.map(println): Unit
|
res.map(println): Unit
|
||||||
}
|
} <* IO.println("End ms : " + System.currentTimeMillis())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,16 @@ object AquaRes {
|
|||||||
ctx.exports
|
ctx.exports
|
||||||
.map(ex =>
|
.map(ex =>
|
||||||
AquaRes(
|
AquaRes(
|
||||||
funcs = Chain.fromSeq(ex.funcs.values.toSeq).map(Transform.fn(_, conf)),
|
funcs = Chain
|
||||||
services = Chain.fromSeq(ex.services.values.toSeq).map(ServiceRes.fromModel(_))
|
.fromSeq(ex.funcs.map { case (fnName, fn) =>
|
||||||
|
fn.copy(funcName = fnName)
|
||||||
|
}.toSeq)
|
||||||
|
.map(Transform.fn(_, conf)),
|
||||||
|
services = Chain
|
||||||
|
.fromSeq(ex.services.map { case (srvName, srv) =>
|
||||||
|
srv.copy(name = srvName)
|
||||||
|
}.toSeq)
|
||||||
|
.map(ServiceRes.fromModel(_))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.getOrElse(blank)
|
.getOrElse(blank)
|
||||||
|
@ -14,7 +14,7 @@ case class UseExpr[F[_]](
|
|||||||
object UseExpr extends HeaderExpr.Leaf {
|
object UseExpr extends HeaderExpr.Leaf {
|
||||||
|
|
||||||
override def p[F[_]: LiftParser: Comonad]: Parser[HeaderExpr[F]] =
|
override def p[F[_]: LiftParser: Comonad]: Parser[HeaderExpr[F]] =
|
||||||
(`use` *> Value
|
(`use` *> ` ` *> Value
|
||||||
.string[F] ~ (` as ` *> Ability.ab[F]).?).map { case (filename, asModule) =>
|
.string[F] ~ (` as ` *> Ability.ab[F]).?).map { case (filename, asModule) =>
|
||||||
UseExpr(filename, asModule)
|
UseExpr(filename, asModule)
|
||||||
}
|
}
|
||||||
|
@ -103,5 +103,5 @@ object Token {
|
|||||||
P.repSep0(p, `,` <* ` \n+`.rep0)
|
P.repSep0(p, `,` <* ` \n+`.rep0)
|
||||||
|
|
||||||
def asOpt[T](p: P[T]): P[(T, Option[T])] =
|
def asOpt[T](p: P[T]): P[(T, Option[T])] =
|
||||||
p ~ (` as ` *> p).?
|
p ~ (` as `.backtrack *> p).?
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import cats.Id
|
|||||||
import org.scalatest.flatspec.AnyFlatSpec
|
import org.scalatest.flatspec.AnyFlatSpec
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|
||||||
class AbilitIdExprSpec extends AnyFlatSpec with Matchers with AquaSpec {
|
class AbilityIdExprSpec extends AnyFlatSpec with Matchers with AquaSpec {
|
||||||
import AquaSpec._
|
import AquaSpec._
|
||||||
|
|
||||||
"abilities" should "be parsed" in {
|
"abilities" should "be parsed" in {
|
46
parser/src/test/scala/aqua/parser/head/FromSpec.scala
Normal file
46
parser/src/test/scala/aqua/parser/head/FromSpec.scala
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package aqua.parser.head
|
||||||
|
|
||||||
|
import aqua.AquaSpec
|
||||||
|
import aqua.parser.expr.AbilityIdExpr
|
||||||
|
import aqua.parser.lexer.{Literal, Token}
|
||||||
|
import aqua.parser.lift.LiftParser.Implicits.*
|
||||||
|
import aqua.types.LiteralType
|
||||||
|
import cats.Id
|
||||||
|
import cats.data.NonEmptyList
|
||||||
|
import org.scalatest.flatspec.AnyFlatSpec
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|
||||||
|
class FromSpec extends AnyFlatSpec with Matchers with AquaSpec {
|
||||||
|
|
||||||
|
import AquaSpec.*
|
||||||
|
|
||||||
|
"from expression" should "be parsed" in {
|
||||||
|
FromExpr.nameOrAbAs[Id].parseAll("Ability").value should be(Right(toAb("Ability") -> None))
|
||||||
|
FromExpr.nameOrAbAs[Id].parseAll("Ability as Ab").value should be(
|
||||||
|
Right(toAb("Ability") -> Some(toAb("Ab")))
|
||||||
|
)
|
||||||
|
FromExpr.nameOrAbAs[Id].parseAll("function").value should be(
|
||||||
|
Left(toName("function") -> None)
|
||||||
|
)
|
||||||
|
FromExpr.nameOrAbAs[Id].parseAll("function as fn").value should be(
|
||||||
|
Left(toName("function") -> Some(toName("fn")))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
"from list" should "be parsed" in {
|
||||||
|
Token.comma(FromExpr.nameOrAbAs[Id]).parseAll("Ability").value.head should be(
|
||||||
|
Right(toAb("Ability") -> None)
|
||||||
|
)
|
||||||
|
Token.comma(FromExpr.nameOrAbAs[Id]).parseAll("Ability as Ab").value.head should be(
|
||||||
|
Right(toAb("Ability") -> Some(toAb("Ab")))
|
||||||
|
)
|
||||||
|
|
||||||
|
FromExpr.importFrom[Id].parseAll("Ability as Ab from").value should be(
|
||||||
|
NonEmptyList.one(Right(toAb("Ability") -> Some(toAb("Ab"))))
|
||||||
|
)
|
||||||
|
FromExpr.importFrom[Id].parseAll("Ability from").value should be(
|
||||||
|
NonEmptyList.one(Right(toAb("Ability") -> None))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
parser/src/test/scala/aqua/parser/head/ImportFromSpec.scala
Normal file
45
parser/src/test/scala/aqua/parser/head/ImportFromSpec.scala
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package aqua.parser.head
|
||||||
|
|
||||||
|
import aqua.AquaSpec
|
||||||
|
import aqua.parser.expr.AbilityIdExpr
|
||||||
|
import aqua.parser.lexer.{Literal, Token}
|
||||||
|
import aqua.parser.lift.LiftParser.Implicits.*
|
||||||
|
import aqua.types.LiteralType
|
||||||
|
import cats.Id
|
||||||
|
import cats.data.NonEmptyList
|
||||||
|
import org.scalatest.flatspec.AnyFlatSpec
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
|
||||||
|
class ImportFromSpec extends AnyFlatSpec with Matchers with AquaSpec {
|
||||||
|
import AquaSpec.*
|
||||||
|
|
||||||
|
"import from" should "be parsed" in {
|
||||||
|
FromExpr.nameOrAbAs[Id].parseAll("")
|
||||||
|
|
||||||
|
ImportFromExpr.p[Id].parseAll("import MyModule from \"file.aqua\"").value should be(
|
||||||
|
ImportFromExpr(
|
||||||
|
NonEmptyList.one(Right(toAb("MyModule") -> None)),
|
||||||
|
toStr("file.aqua")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
HeadExpr
|
||||||
|
.ast[Id]
|
||||||
|
.parseAll(s"""import MyModule, func as fn from "file.aqua"
|
||||||
|
|""".stripMargin)
|
||||||
|
.value
|
||||||
|
.tail
|
||||||
|
.value
|
||||||
|
.headOption
|
||||||
|
.get
|
||||||
|
.head should be(
|
||||||
|
ImportFromExpr(
|
||||||
|
NonEmptyList.fromListUnsafe(
|
||||||
|
Right(toAb("MyModule") -> None) :: Left(toName("func") -> Some(toName("fn"))) :: Nil
|
||||||
|
),
|
||||||
|
toStr("file.aqua")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
parser/src/test/scala/aqua/parser/head/ModuleSpec.scala
Normal file
40
parser/src/test/scala/aqua/parser/head/ModuleSpec.scala
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package aqua.parser.head
|
||||||
|
|
||||||
|
import aqua.AquaSpec
|
||||||
|
import aqua.parser.expr.AbilityIdExpr
|
||||||
|
import aqua.parser.lexer.{Literal, Token}
|
||||||
|
import aqua.types.LiteralType
|
||||||
|
import cats.Id
|
||||||
|
import org.scalatest.flatspec.AnyFlatSpec
|
||||||
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import aqua.parser.lift.LiftParser.Implicits.*
|
||||||
|
|
||||||
|
class ModuleSpec extends AnyFlatSpec with Matchers with AquaSpec {
|
||||||
|
import AquaSpec.*
|
||||||
|
|
||||||
|
"module header" should "be parsed" in {
|
||||||
|
ModuleExpr.p[Id].parseAll("module MyModule").value should be(
|
||||||
|
ModuleExpr(
|
||||||
|
toAb("MyModule"),
|
||||||
|
None,
|
||||||
|
Nil,
|
||||||
|
Nil
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
HeadExpr
|
||||||
|
.ast[Id]
|
||||||
|
.parseAll(s"""module MyModule declares *
|
||||||
|
|""".stripMargin)
|
||||||
|
.value
|
||||||
|
.head should be(
|
||||||
|
ModuleExpr(
|
||||||
|
toAb("MyModule"),
|
||||||
|
Some(Token.lift[Id, Unit](())),
|
||||||
|
Nil,
|
||||||
|
Nil
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -66,13 +66,23 @@ object HeaderSem {
|
|||||||
ctx
|
ctx
|
||||||
.pick(n.value, rn.map(_.value))
|
.pick(n.value, rn.map(_.value))
|
||||||
.map(validNec)
|
.map(validNec)
|
||||||
.getOrElse(error(n, s"Imported file has no ${n.value} declaration"))
|
.getOrElse(
|
||||||
|
error(
|
||||||
|
n,
|
||||||
|
s"Imported file declares [${ctx.declares.mkString(", ")}], no ${n.value} declared. Try adding `declares *` to that file."
|
||||||
|
)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{ case (n, rn) =>
|
{ case (n, rn) =>
|
||||||
ctx
|
ctx
|
||||||
.pick(n.value, rn.map(_.value))
|
.pick(n.value, rn.map(_.value))
|
||||||
.map(validNec)
|
.map(validNec)
|
||||||
.getOrElse(error(n, s"Imported file has no ${n.value} declaration"))
|
.getOrElse(
|
||||||
|
error(
|
||||||
|
n,
|
||||||
|
s"Imported file declares [${ctx.declares.mkString(", ")}], no ${n.value} declared. Try adding `declares *` to that file."
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -86,7 +96,7 @@ object HeaderSem {
|
|||||||
.fold[ResAC[S]](
|
.fold[ResAC[S]](
|
||||||
error(
|
error(
|
||||||
tkn,
|
tkn,
|
||||||
"Used module has no `module` header. Please add `module` header or use ... as ModuleName, or switch to import"
|
s"Used module has no `module` header. Please add `module` header or use ... as ModuleName, or switch to import"
|
||||||
)
|
)
|
||||||
)(modName => validNec(acm.empty.copy(abilities = Map(modName -> ctx))))
|
)(modName => validNec(acm.empty.copy(abilities = Map(modName -> ctx))))
|
||||||
|
|
||||||
@ -94,12 +104,13 @@ object HeaderSem {
|
|||||||
val onExpr: PartialFunction[HeaderExpr[S], Res[S]] = {
|
val onExpr: PartialFunction[HeaderExpr[S], Res[S]] = {
|
||||||
// Module header, like `module A declares *`
|
// Module header, like `module A declares *`
|
||||||
case ModuleExpr(name, declareAll, declareNames, declareCustom) =>
|
case ModuleExpr(name, declareAll, declareNames, declareCustom) =>
|
||||||
|
val shouldDeclare = declareNames.map(_.value).toSet ++ declareCustom.map(_.value)
|
||||||
validNec(
|
validNec(
|
||||||
HeaderSem[S](
|
HeaderSem[S](
|
||||||
// Save module header info
|
// Save module header info
|
||||||
acm.empty.copy(
|
acm.empty.copy(
|
||||||
module = Some(name.value),
|
module = Some(name.value),
|
||||||
declares = declareNames.map(_.value).toSet ++ declareCustom.map(_.value)
|
declares = shouldDeclare
|
||||||
),
|
),
|
||||||
ctx =>
|
ctx =>
|
||||||
// When file is handled, check that all the declarations exists
|
// When file is handled, check that all the declarations exists
|
||||||
@ -124,7 +135,10 @@ object HeaderSem {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}.combineAll
|
}.combineAll
|
||||||
.map(_ => ctx)
|
.map(_ =>
|
||||||
|
// TODO: why module name and declares is lost? where is it lost?
|
||||||
|
ctx.copy(module = Some(name.value), declares = shouldDeclare)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user