Skip to content

Commit

Permalink
Parse arbitrary exprs after "import" and "importStr"
Browse files Browse the repository at this point in the history
Fixes #138

The spec is not very clear on this but this behavior is consistent with the C++ and Go implementations.
  • Loading branch information
szeiger committed Sep 1, 2022
1 parent a3516ad commit f546c0b
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 4 deletions.
8 changes: 6 additions & 2 deletions sjsonnet/src/sjsonnet/Expr.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package sjsonnet

import java.util.BitSet

import java.util.{Arrays, BitSet}
import scala.collection.mutable

/**
Expand Down Expand Up @@ -116,6 +115,11 @@ object Expr{
case class AssertExpr(pos: Position, asserted: Member.AssertStmt, returned: Expr) extends Expr
case class LocalExpr(pos: Position, bindings: Array[Bind], returned: Expr) extends Expr {
override def toString = s"LocalExpr($pos, ${arrStr(bindings)}, $returned)"
override def equals(o: Any): Boolean = o match {
case o: LocalExpr =>
pos == o.pos && Arrays.equals(bindings.asInstanceOf[Array[AnyRef]], o.bindings.asInstanceOf[Array[AnyRef]]) && returned == o.returned
case _ => false
}
}

case class Bind(pos: Position, name: String, args: Params, rhs: Expr) extends Member
Expand Down
9 changes: 7 additions & 2 deletions sjsonnet/src/sjsonnet/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,15 @@ class Parser(val currentFile: Path) {
)

def local[_: P] = P( localExpr )
def importStr[_: P](pos: Position) = P( string.map(Expr.ImportStr(pos, _)) )
def `import`[_: P](pos: Position) = P( string.map(Expr.Import(pos, _)) )
def importStr[_: P](pos: Position) = P( importExpr.map(Expr.ImportStr(pos, _)) )
def `import`[_: P](pos: Position) = P( importExpr.map(Expr.Import(pos, _)) )
def error[_: P](pos: Position) = P(expr.map(Expr.Error(pos, _)) )

def importExpr[_: P]: P[String] = P(expr.flatMap {
case Val.Str(_, s) => Pass(s)
case _ => Fail.opaque("string literal (computed imports are not allowed)")
})

def unaryOpExpr[_: P](pos: Position, op: Char) = P(
expr1.map{ e =>
def k2 = op match{
Expand Down
8 changes: 8 additions & 0 deletions sjsonnet/test/src/sjsonnet/ParserTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,13 @@ object ParserTests extends TestSuite{
test("givenDuplicateFieldsInListComprehension_expectError") {
parseErr("""{ ["bar"]: x for x in [1, 2]}""") ==> """Expected no duplicate field: "bar" :1:29, found "}""""
}
test("computedImports") {
parse("""local foo = import "foo"; 0""") ==>
LocalExpr(pos(6), Array(Bind(pos(6), "foo", null, Import(pos(12), "foo"))), Num(pos(26),0.0))
parse("""local foo = (import "foo") + bar; 0""") ==>
LocalExpr(pos(6), Array(Bind(pos(6), "foo", null, BinaryOp(pos(27), Import(pos(13), "foo"), 3, Id(pos(29), "bar")))), Num(pos(34),0.0))
parseErr("""local foo = import ("foo" + bar); 0""") ==> """Expected string literal (computed imports are not allowed):1:33, found "; 0""""
parseErr("""local foo = import "foo" + bar; 0""") ==> """Expected string literal (computed imports are not allowed):1:31, found "; 0""""
}
}
}

0 comments on commit f546c0b

Please sign in to comment.