Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions sjsonnet/src/sjsonnet/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ class Parser(

def field[$: P](currentDepth: Int): P[Expr.Member.Field] = {
P(
(Pos ~~ fieldname(currentDepth + 1) ~/ "+".!.? ~ ("(" ~ params(
(Pos ~~ fieldname(currentDepth + 1) ~/ "+".!.? ~ ("(" ~/ params(
currentDepth + 1
) ~ ")").? ~ fieldKeySep ~/ expr(currentDepth + 1)).map { case (pos, name, plus, p, h2, e) =>
Expr.Member.Field(pos, name, plus.nonEmpty, p.orNull, h2, e)
Expand Down Expand Up @@ -1045,18 +1045,27 @@ class Parser(
def params[$: P]: P[Expr.Params] = params(0)

def params[$: P](currentDepth: Int): P[Expr.Params] = {
P((id ~ ("=" ~ expr(currentDepth + 1)).?).rep(sep = ",") ~ ",".?).flatMapX { x =>
val ctx = implicitly[P[?]]
P(
(Pos ~~ id ~ ("=" ~ expr(currentDepth + 1)).?).rep(sep = ",") ~ ",".?
).flatMapX { x =>
val seen = collection.mutable.Set.empty[String]
var overlap: String = null
for ((k, _) <- x) {
if (seen(k)) overlap = k
else seen.add(k)
var overlap: (Position, String) = null
for ((pos, k, _) <- x) {
if (overlap == null) {
if (seen(k)) overlap = (pos, k)
else seen.add(k)
}
}
if (overlap == null) {
val names = x.map(_._1).toArray[String]
val exprs = x.map(_._2.orNull).toArray[Expr]
val names = x.map(_._2).toArray[String]
val exprs = x.map(_._3.orNull).toArray[Expr]
Pass(Expr.Params(names, exprs))
} else Fail.opaque("no duplicate parameter: " + overlap)
} else {
ctx.cut = true
ctx.index = overlap._1.offset
Fail.opaque("no duplicate parameter: " + overlap._2)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
sjsonnet.ParseError: Expected no duplicate parameter: x:17:14, found ") x\n"
at [<root>].(error.function_duplicate_param.jsonnet:17:14)
sjsonnet.ParseError: Expected no duplicate parameter: x:17:13, found "x) x\n"
at [<root>].(error.function_duplicate_param.jsonnet:17:13)

10 changes: 10 additions & 0 deletions sjsonnet/test/src/sjsonnet/ParserTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ object ParserTests extends TestSuite {
test("duplicateFields") {
parseErr("{ a: 1, a: 2 }") ==> """Expected no duplicate field: a:1:14, found "}""""
}
test("duplicateParams") {
parseErr("(function(x, x, x) x)(null, 3, 2)") ==>
"""Expected no duplicate parameter: x:1:14, found "x, x) x)(n""""
parseErr("local f(x, x) = x; f(1, 2)") ==>
"Expected no duplicate parameter: x:1:12, found \"x) = x; f(\""
parseErr("{ f(x, x): x }.f(1, 2)") ==>
"Expected no duplicate parameter: x:1:8, found \"x): x }.f(\""
parseErr("{ local f(x, x) = x, a: f(1, 2) }") ==>
"Expected no duplicate parameter: x:1:14, found \"x) = x, a:\""
}
test("localInObj") {
parse("""{
|local x = 1,
Expand Down
Loading