mirror of
https://github.com/apple/pkl.git
synced 2026-04-22 08:18:32 +02:00
Allow trailing commas in comma-separated syntax elements (#1137)
This commit is contained in:
9
pkl-core/src/test/files/LanguageSnippetTests/input/parser/constraintsTrailingComma.pkl
vendored
Normal file
9
pkl-core/src/test/files/LanguageSnippetTests/input/parser/constraintsTrailingComma.pkl
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
res1: Int(isEven, isNonZero, isBetween(-10, 10), ) = 6
|
||||
res2: Int(
|
||||
isEven, isNonZero, isBetween(-10, 10),
|
||||
) = 6
|
||||
res3: Int(
|
||||
isEven,
|
||||
isNonZero,
|
||||
isBetween(-10, 10),
|
||||
) = 6
|
||||
43
pkl-core/src/test/files/LanguageSnippetTests/input/parser/lambdaTrailingCommas.pkl
vendored
Normal file
43
pkl-core/src/test/files/LanguageSnippetTests/input/parser/lambdaTrailingCommas.pkl
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
local lA1 = (a, b, c,) -> true
|
||||
local lA2 = (
|
||||
a, b, c,
|
||||
) -> true
|
||||
local lA3 = (
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
) -> true
|
||||
|
||||
local lB1 = (a: Int, b: Int, c: Int,) -> true
|
||||
local lB2 = (
|
||||
a: Int, b: Int, c: Int,
|
||||
) -> true
|
||||
local lB3 = (
|
||||
a: Int,
|
||||
b: Int,
|
||||
c: Int,
|
||||
) -> true
|
||||
|
||||
local lC1: (Dynamic,) -> Dynamic = new Mixin { a, -> x = true }
|
||||
local lC2: (Dynamic,) -> Dynamic = new Mixin { a, ->
|
||||
x = true
|
||||
}
|
||||
local lC3: (Dynamic,) -> Dynamic = new Mixin {
|
||||
a, -> x = true
|
||||
}
|
||||
local lC4: (Dynamic,) -> Dynamic = new Mixin {
|
||||
a, ->
|
||||
x = true
|
||||
}
|
||||
|
||||
local lD1: (Dynamic,) -> Dynamic = new Mixin { a: Dynamic, -> x = true }
|
||||
local lD2: (Dynamic,) -> Dynamic = new Mixin { a: Dynamic, ->
|
||||
x = true
|
||||
}
|
||||
local lD3: (Dynamic,) -> Dynamic = new Mixin {
|
||||
a: Dynamic, -> x = true
|
||||
}
|
||||
local lD4: (Dynamic,) -> Dynamic = new Mixin {
|
||||
a: Dynamic, ->
|
||||
x = true
|
||||
}
|
||||
157
pkl-core/src/test/files/LanguageSnippetTests/input/parser/methodTrailingCommas.pkl
vendored
Normal file
157
pkl-core/src/test/files/LanguageSnippetTests/input/parser/methodTrailingCommas.pkl
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
function moduleMethodA1(a, b, c, ) = true
|
||||
function moduleMethodA2(
|
||||
a, b, c,
|
||||
) = true
|
||||
function moduleMethodA3(
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
) = true
|
||||
function moduleMethodB1(a: Int, b: Int, c: Int, ) = true
|
||||
function moduleMethodB2(
|
||||
a: Int, b: Int, c: Int,
|
||||
) = true
|
||||
function moduleMethodB3(
|
||||
a: Int,
|
||||
b: Int,
|
||||
c: Int,
|
||||
) = true
|
||||
|
||||
class A {
|
||||
function classMethodA1(a, b, c, ) = true
|
||||
function classMethodA2(
|
||||
a, b, c,
|
||||
) = true
|
||||
function classMethodA3(
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
) = true
|
||||
function classMethodB1(a: Int, b: Int, c: Int, ) = true
|
||||
function classMethodB2(
|
||||
a: Int, b: Int, c: Int,
|
||||
) = true
|
||||
function classMethodB3(
|
||||
a: Int,
|
||||
b: Int,
|
||||
c: Int,
|
||||
) = true
|
||||
}
|
||||
|
||||
moduleMethodA1Call1 = moduleMethodA1(1, 2, 3, )
|
||||
moduleMethodA1Call2 = moduleMethodA1(
|
||||
1, 2, 3,
|
||||
)
|
||||
moduleMethodA1Call3 = moduleMethodA1(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
moduleMethodA2Call1 = moduleMethodA2(1, 2, 3, )
|
||||
moduleMethodA2Call2 = moduleMethodA2(
|
||||
1, 2, 3,
|
||||
)
|
||||
moduleMethodA2Call3 = moduleMethodA2(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
|
||||
moduleMethodA3Call1 = moduleMethodA3(1, 2, 3, )
|
||||
moduleMethodA3Call2 = moduleMethodA3(
|
||||
1, 2, 3,
|
||||
)
|
||||
moduleMethodA3Call3 = moduleMethodA3(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
|
||||
moduleMethodB1Call1 = moduleMethodB1(1, 2, 3, )
|
||||
moduleMethodB1Call2 = moduleMethodB1(
|
||||
1, 2, 3,
|
||||
)
|
||||
moduleMethodB1Call3 = moduleMethodB1(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
moduleMethodB2Call1 = moduleMethodB2(1, 2, 3, )
|
||||
moduleMethodB2Call2 = moduleMethodB2(
|
||||
1, 2, 3,
|
||||
)
|
||||
moduleMethodB2Call3 = moduleMethodB2(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
|
||||
moduleMethodB3Call1 = moduleMethodB3(1, 2, 3, )
|
||||
moduleMethodB3Call2 = moduleMethodB3(
|
||||
1, 2, 3,
|
||||
)
|
||||
moduleMethodB3Call3 = moduleMethodB3(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
|
||||
local a: A = new {}
|
||||
|
||||
classMethodA1Call1 = a.classMethodA1(1, 2, 3, )
|
||||
classMethodA1Call2 = a.classMethodA1(
|
||||
1, 2, 3,
|
||||
)
|
||||
classMethodA1Call3 = a.classMethodA1(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
classMethodA2Call1 = a.classMethodA2(1, 2, 3, )
|
||||
classMethodA2Call2 = a.classMethodA2(
|
||||
1, 2, 3,
|
||||
)
|
||||
classMethodA2Call3 = a.classMethodA2(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
|
||||
classMethodA3Call1 = a.classMethodA3(1, 2, 3, )
|
||||
classMethodA3Call2 = a.classMethodA3(
|
||||
1, 2, 3,
|
||||
)
|
||||
classMethodA3Call3 = a.classMethodA3(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
|
||||
classMethodB1Call1 = a.classMethodB1(1, 2, 3, )
|
||||
classMethodB1Call2 = a.classMethodB1(
|
||||
1, 2, 3,
|
||||
)
|
||||
classMethodB1Call3 = a.classMethodB1(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
classMethodB2Call1 = a.classMethodB2(1, 2, 3, )
|
||||
classMethodB2Call2 = a.classMethodB2(
|
||||
1, 2, 3,
|
||||
)
|
||||
classMethodB2Call3 = a.classMethodB2(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
|
||||
classMethodB3Call1 = a.classMethodB3(1, 2, 3, )
|
||||
classMethodB3Call2 = a.classMethodB3(
|
||||
1, 2, 3,
|
||||
)
|
||||
classMethodB3Call3 = a.classMethodB3(
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
3
pkl-core/src/test/files/LanguageSnippetTests/input/parser/trailingCommas.pkl
vendored
Normal file
3
pkl-core/src/test/files/LanguageSnippetTests/input/parser/trailingCommas.pkl
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
res1: Mapping<String, String,>(!isEmpty) = new Mapping<String, String,> {
|
||||
["hello"] = "world"
|
||||
}
|
||||
3
pkl-core/src/test/files/LanguageSnippetTests/output/parser/constraintsTrailingComma.pcf
vendored
Normal file
3
pkl-core/src/test/files/LanguageSnippetTests/output/parser/constraintsTrailingComma.pcf
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
res1 = 6
|
||||
res2 = 6
|
||||
res3 = 6
|
||||
36
pkl-core/src/test/files/LanguageSnippetTests/output/parser/methodTrailingCommas.pcf
vendored
Normal file
36
pkl-core/src/test/files/LanguageSnippetTests/output/parser/methodTrailingCommas.pcf
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
moduleMethodA1Call1 = true
|
||||
moduleMethodA1Call2 = true
|
||||
moduleMethodA1Call3 = true
|
||||
moduleMethodA2Call1 = true
|
||||
moduleMethodA2Call2 = true
|
||||
moduleMethodA2Call3 = true
|
||||
moduleMethodA3Call1 = true
|
||||
moduleMethodA3Call2 = true
|
||||
moduleMethodA3Call3 = true
|
||||
moduleMethodB1Call1 = true
|
||||
moduleMethodB1Call2 = true
|
||||
moduleMethodB1Call3 = true
|
||||
moduleMethodB2Call1 = true
|
||||
moduleMethodB2Call2 = true
|
||||
moduleMethodB2Call3 = true
|
||||
moduleMethodB3Call1 = true
|
||||
moduleMethodB3Call2 = true
|
||||
moduleMethodB3Call3 = true
|
||||
classMethodA1Call1 = true
|
||||
classMethodA1Call2 = true
|
||||
classMethodA1Call3 = true
|
||||
classMethodA2Call1 = true
|
||||
classMethodA2Call2 = true
|
||||
classMethodA2Call3 = true
|
||||
classMethodA3Call1 = true
|
||||
classMethodA3Call2 = true
|
||||
classMethodA3Call3 = true
|
||||
classMethodB1Call1 = true
|
||||
classMethodB1Call2 = true
|
||||
classMethodB1Call3 = true
|
||||
classMethodB2Call1 = true
|
||||
classMethodB2Call2 = true
|
||||
classMethodB2Call3 = true
|
||||
classMethodB3Call1 = true
|
||||
classMethodB3Call2 = true
|
||||
classMethodB3Call3 = true
|
||||
3
pkl-core/src/test/files/LanguageSnippetTests/output/parser/trailingCommas.pcf
vendored
Normal file
3
pkl-core/src/test/files/LanguageSnippetTests/output/parser/trailingCommas.pcf
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
res1 {
|
||||
["hello"] = "world"
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pkl.core.parser
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pkl.core.Evaluator
|
||||
import org.pkl.parser.Parser
|
||||
|
||||
// tests type argument and parameter parsing with trailing commas that cannot be tested with
|
||||
// snippets because these constructs are currently only allowed in the stdlib
|
||||
class TrailingCommasTest {
|
||||
private val evaluator = Evaluator.preconfigured()
|
||||
|
||||
@Test
|
||||
fun `class type parameter lists parse correctly`() {
|
||||
val module =
|
||||
Parser()
|
||||
.parseModule(
|
||||
"""
|
||||
class Foo<
|
||||
Key,
|
||||
Value,
|
||||
>
|
||||
|
||||
class Bar<
|
||||
Key,
|
||||
Value,
|
||||
> {
|
||||
baz: Key
|
||||
buzz: Value
|
||||
}
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val fooClass = module.classes.find { it.name.value == "Foo" }
|
||||
assertThat(fooClass).isNotNull
|
||||
assertThat(fooClass!!.typeParameterList?.parameters?.first()?.identifier?.value)
|
||||
.isEqualTo("Key")
|
||||
assertThat(fooClass.typeParameterList?.parameters?.last()?.identifier?.value).isEqualTo("Value")
|
||||
|
||||
val barClass = module.classes.find { it.name.value == "Bar" }
|
||||
assertThat(barClass).isNotNull
|
||||
assertThat(barClass!!.typeParameterList?.parameters?.first()?.identifier?.value)
|
||||
.isEqualTo("Key")
|
||||
assertThat(barClass.typeParameterList?.parameters?.last()?.identifier?.value).isEqualTo("Value")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `method type parameter lists parse correctly`() {
|
||||
val module =
|
||||
Parser()
|
||||
.parseModule(
|
||||
"""
|
||||
function foo<
|
||||
A,
|
||||
B,
|
||||
>(a: A, b: B,): Value? = "\(a):\(b)"
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
|
||||
val fooMethod = module.methods.find { it.name.value == "foo" }
|
||||
assertThat(fooMethod).isNotNull
|
||||
assertThat(fooMethod!!.typeParameterList?.parameters?.first()?.identifier?.value).isEqualTo("A")
|
||||
assertThat(fooMethod.typeParameterList?.parameters?.last()?.identifier?.value).isEqualTo("B")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user