Skip to content

Commit

Permalink
Parse arbitrary exprs after "import" and "importStr" (#153)
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.

---------

Co-authored-by: Li Haoyi <32282535+lihaoyi-databricks@users.noreply.github.com>
  • Loading branch information
szeiger and lihaoyi-databricks authored May 31, 2023
1 parent 05d403f commit 7504e1a
Show file tree
Hide file tree
Showing 3 changed files with 23 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
10 changes: 10 additions & 0 deletions sjsonnet/test/src/sjsonnet/ParserTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ 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""""
}

test("id starts with number") {
parseErr("""{1_n: "foo",}""") ==> """Expected "}":1:2, found "1_n: \"foo\"""""
}
Expand Down

0 comments on commit 7504e1a

Please sign in to comment.