LNG-78 parser error on negative array indexes (#538)

This commit is contained in:
Dima 2022-07-12 21:59:58 +03:00 committed by GitHub
parent 4f21f0a0bd
commit 792e174641
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 17 deletions

View File

@ -20,18 +20,20 @@ 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](
raw: CollectionRaw, raw: CollectionRaw,
lambdaAllowed: Boolean lambdaAllowed: Boolean
): State[S, (ValueModel, Inline)] = ): State[S, (ValueModel, Inline)] =
for { for {
streamName <- Mangler[S].findAndForbidName(( streamName <- Mangler[S].findAndForbidName(
raw.boxType match { (
case _: StreamType => "stream" raw.boxType match {
case _: ArrayType => "array" case _: StreamType => "stream"
case _: OptionType => "option" case _: ArrayType => "array"
} case _: OptionType => "option"
) + "-inline") }
) + "-inline"
)
stream = VarModel(streamName, StreamType(raw.elementType)) stream = VarModel(streamName, StreamType(raw.elementType))
streamExp = CallModel.Export(stream.name, stream.`type`) streamExp = CallModel.Export(stream.name, stream.`type`)

View File

@ -13,6 +13,7 @@ import scala.language.postfixOps
import cats.~> import cats.~>
import aqua.parser.lift.Span import aqua.parser.lift.Span
import aqua.parser.lift.Span.{P0ToSpan, PToSpan} import aqua.parser.lift.Span.{P0ToSpan, PToSpan}
import aqua.types.LiteralType
sealed trait LambdaOp[F[_]] extends Token[F] { sealed trait LambdaOp[F[_]] extends Token[F] {
def mapK[K[_]: Comonad](fk: F ~> K): LambdaOp[K] def mapK[K[_]: Comonad](fk: F ~> K): LambdaOp[K]
@ -39,16 +40,18 @@ object LambdaOp {
private val parseField: P[LambdaOp[Span.S]] = private val parseField: P[LambdaOp[Span.S]] =
(`.` *> `name`).lift.map(IntoField(_)) (`.` *> `name`).lift.map(IntoField(_))
private val nonNegativeIntP0: P0[Int] =
Numbers.nonNegativeIntString.map(_.toInt).?.map(_.getOrElse(0))
private val parseIdx: P[LambdaOp[Span.S]] = private val parseIdx: P[LambdaOp[Span.S]] =
P.defer( (P.defer(
(ValueToken.`value`.between(`[`, `]`) | (exclamation *> ValueToken.num)) (ValueToken.`value`.between(`[`, `]`) | (exclamation *> ValueToken.num))
.map(v => IntoIndex(v, Some(v))) .map(v => IntoIndex(v, Some(v)))
.backtrack .backtrack
) | ) | exclamation.lift.map(e => IntoIndex(Token.lift[Span.S, Unit](e), None))).flatMap { ii =>
exclamation.lift.map(e => IntoIndex(Token.lift[Span.S, Unit](e), None)) ii.idx match {
case Some(LiteralToken(_, lt)) if lt == LiteralType.signed =>
P.fail.withContext("Collection indexes must be non-negative")
case _ => P.pure(ii)
}
}
private val parseOp: P[LambdaOp[Span.S]] = private val parseOp: P[LambdaOp[Span.S]] =
P.oneOf(parseField.backtrack :: parseIdx :: Nil) P.oneOf(parseField.backtrack :: parseIdx :: Nil)

View File

@ -17,6 +17,9 @@ class LambdaOpSpec extends AnyFlatSpec with Matchers with EitherValues {
opsP(".field") should be(NonEmptyList.of(IntoField[Id]("field"))) opsP(".field") should be(NonEmptyList.of(IntoField[Id]("field")))
opsP(".field.sub") should be(NonEmptyList.of(IntoField[Id]("field"), IntoField[Id]("sub"))) opsP(".field.sub") should be(NonEmptyList.of(IntoField[Id]("field"), IntoField[Id]("sub")))
LambdaOp.ops.parseAll("[-1]").isLeft shouldBe true
LambdaOp.ops.parseAll("!-1").isLeft shouldBe true
} }
} }