mirror of
https://github.com/apple/pkl.git
synced 2026-04-22 16:28:34 +02:00
Implement canonical formatter (#1107)
CLI commands also added: `pkl format check` and `pkl format apply`.
This commit is contained in:
36
pkl-formatter/gradle.lockfile
Normal file
36
pkl-formatter/gradle.lockfile
Normal file
@@ -0,0 +1,36 @@
|
||||
# This is a Gradle generated file for dependency locking.
|
||||
# Manual edits can break the build and are not advised.
|
||||
# This file is expected to be part of source control.
|
||||
net.bytebuddy:byte-buddy:1.15.11=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata
|
||||
org.assertj:assertj-core:3.27.3=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-common:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:2.0.21=kotlinBuildToolsApiClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.0.21=kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-native-prebuilt:2.0.21=kotlinNativeBundleConfiguration
|
||||
org.jetbrains.kotlin:kotlin-reflect:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.0.21=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.21=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:2.0.21=apiDependenciesMetadata,compileClasspath,implementationDependenciesMetadata,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains:annotations:13.0=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.13.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-engine:5.13.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-params:5.13.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.13.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-engine:1.13.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-launcher:1.13.0=testRuntimeClasspath
|
||||
org.junit:junit-bom:5.13.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
empty=annotationProcessor,compileOnlyDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions
|
||||
48
pkl-formatter/pkl-formatter.gradle.kts
Normal file
48
pkl-formatter/pkl-formatter.gradle.kts
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
plugins {
|
||||
pklAllProjects
|
||||
pklKotlinLibrary
|
||||
pklPublishLibrary
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.pklParser)
|
||||
|
||||
testImplementation(projects.pklCommonsTest)
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
inputs
|
||||
.dir("src/test/files/FormatterSnippetTests/input")
|
||||
.withPropertyName("formatterSnippetTestsInput")
|
||||
.withPathSensitivity(PathSensitivity.RELATIVE)
|
||||
inputs
|
||||
.dir("src/test/files/FormatterSnippetTests/output")
|
||||
.withPropertyName("formatterSnippetTestsOutput")
|
||||
.withPathSensitivity(PathSensitivity.RELATIVE)
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
named<MavenPublication>("library") {
|
||||
pom {
|
||||
url.set("https://github.com/apple/pkl/tree/main/pkl-formatter")
|
||||
description.set("Formatter for Pkl")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1258
pkl-formatter/src/main/kotlin/org/pkl/formatter/Builder.kt
Normal file
1258
pkl-formatter/src/main/kotlin/org/pkl/formatter/Builder.kt
Normal file
File diff suppressed because it is too large
Load Diff
53
pkl-formatter/src/main/kotlin/org/pkl/formatter/Formatter.kt
Normal file
53
pkl-formatter/src/main/kotlin/org/pkl/formatter/Formatter.kt
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.formatter
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import org.pkl.formatter.ast.ForceLine
|
||||
import org.pkl.formatter.ast.Nodes
|
||||
import org.pkl.parser.GenericParser
|
||||
|
||||
/** A formatter for Pkl files that applies canonical formatting rules. */
|
||||
class Formatter {
|
||||
/**
|
||||
* Formats a Pkl file from the given file path.
|
||||
*
|
||||
* @param path the path to the Pkl file to format
|
||||
* @return the formatted Pkl source code as a string
|
||||
* @throws java.io.IOException if the file cannot be read
|
||||
*/
|
||||
fun format(path: Path): String {
|
||||
return format(Files.readString(path))
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given Pkl source code text.
|
||||
*
|
||||
* @param text the Pkl source code to format
|
||||
* @return the formatted Pkl source code as a string
|
||||
*/
|
||||
fun format(text: String): String {
|
||||
val parser = GenericParser()
|
||||
val builder = Builder(text)
|
||||
val gen = Generator()
|
||||
val ast = parser.parseModule(text)
|
||||
val formatAst = builder.format(ast)
|
||||
// force a line at the end of the file
|
||||
gen.generate(Nodes(listOf(formatAst, ForceLine)))
|
||||
return gen.toString()
|
||||
}
|
||||
}
|
||||
149
pkl-formatter/src/main/kotlin/org/pkl/formatter/Generator.kt
Normal file
149
pkl-formatter/src/main/kotlin/org/pkl/formatter/Generator.kt
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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.formatter
|
||||
|
||||
import org.pkl.formatter.ast.Empty
|
||||
import org.pkl.formatter.ast.ForceLine
|
||||
import org.pkl.formatter.ast.ForceWrap
|
||||
import org.pkl.formatter.ast.FormatNode
|
||||
import org.pkl.formatter.ast.Group
|
||||
import org.pkl.formatter.ast.IfWrap
|
||||
import org.pkl.formatter.ast.Indent
|
||||
import org.pkl.formatter.ast.Line
|
||||
import org.pkl.formatter.ast.MultilineStringGroup
|
||||
import org.pkl.formatter.ast.Nodes
|
||||
import org.pkl.formatter.ast.Space
|
||||
import org.pkl.formatter.ast.SpaceOrLine
|
||||
import org.pkl.formatter.ast.Text
|
||||
import org.pkl.formatter.ast.Wrap
|
||||
|
||||
internal class Generator {
|
||||
private val buf: StringBuilder = StringBuilder()
|
||||
private var indent: Int = 0
|
||||
private var size: Int = 0
|
||||
private val wrapped: MutableSet<Int> = mutableSetOf()
|
||||
private var shouldAddIndent = false
|
||||
|
||||
fun generate(node: FormatNode) {
|
||||
node(node, Wrap.DETECT)
|
||||
}
|
||||
|
||||
private fun node(node: FormatNode, wrap: Wrap) {
|
||||
when (node) {
|
||||
is Empty -> {}
|
||||
is Nodes -> node.nodes.forEach { node(it, wrap) }
|
||||
is Group -> {
|
||||
val width = node.nodes.sumOf { it.width(wrapped) }
|
||||
val wrap =
|
||||
if (size + width > MAX) {
|
||||
wrapped += node.id
|
||||
Wrap.ENABLED
|
||||
} else {
|
||||
Wrap.DETECT
|
||||
}
|
||||
node.nodes.forEach { node(it, wrap) }
|
||||
}
|
||||
is ForceWrap -> {
|
||||
wrapped += node.id
|
||||
val wrap = Wrap.ENABLED
|
||||
node.nodes.forEach { node(it, wrap) }
|
||||
}
|
||||
is IfWrap -> {
|
||||
if (wrapped.contains(node.id)) {
|
||||
node(node.ifWrap, Wrap.ENABLED)
|
||||
} else {
|
||||
node(node.ifNotWrap, wrap)
|
||||
}
|
||||
}
|
||||
is Text -> text(node.text)
|
||||
is Line -> {
|
||||
if (wrap.isEnabled()) {
|
||||
newline()
|
||||
}
|
||||
}
|
||||
is ForceLine -> newline()
|
||||
is SpaceOrLine -> {
|
||||
if (wrap.isEnabled()) {
|
||||
newline()
|
||||
} else {
|
||||
text(" ")
|
||||
}
|
||||
}
|
||||
is Space -> text(" ")
|
||||
is Indent -> {
|
||||
if (wrap.isEnabled() && node.nodes.isNotEmpty()) {
|
||||
size += INDENT.length
|
||||
indent++
|
||||
node.nodes.forEach { node(it, wrap) }
|
||||
indent--
|
||||
} else {
|
||||
node.nodes.forEach { node(it, wrap) }
|
||||
}
|
||||
}
|
||||
is MultilineStringGroup -> {
|
||||
val indentLength = indent * INDENT.length
|
||||
val offset = (indentLength + 1) - node.endQuoteCol
|
||||
var previousNewline = false
|
||||
for ((i, child) in node.nodes.withIndex()) {
|
||||
when {
|
||||
child is ForceLine -> newline(shouldIndent = false) // don't indent
|
||||
child is Text &&
|
||||
previousNewline &&
|
||||
child.text.isBlank() &&
|
||||
child.text.length == indentLength &&
|
||||
node.nodes[i + 1] is ForceLine -> {}
|
||||
child is Text && previousNewline && offset != 0 -> text(reposition(child.text, offset))
|
||||
else -> node(child, Wrap.DETECT) // always detect wrapping
|
||||
}
|
||||
previousNewline = child is ForceLine
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun text(value: String) {
|
||||
if (shouldAddIndent) {
|
||||
repeat(times = indent) { buf.append(INDENT) }
|
||||
shouldAddIndent = false
|
||||
}
|
||||
size += value.length
|
||||
buf.append(value)
|
||||
}
|
||||
|
||||
private fun newline(shouldIndent: Boolean = true) {
|
||||
size = INDENT.length * indent
|
||||
buf.append('\n')
|
||||
shouldAddIndent = shouldIndent
|
||||
}
|
||||
|
||||
private fun reposition(text: String, offset: Int): String {
|
||||
return if (offset > 0) {
|
||||
" ".repeat(offset) + text
|
||||
} else {
|
||||
text.drop(-offset)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return buf.toString()
|
||||
}
|
||||
|
||||
companion object {
|
||||
// max line length
|
||||
const val MAX = 100
|
||||
private const val INDENT = " "
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.formatter
|
||||
|
||||
internal class NaturalOrderComparator(private val ignoreCase: Boolean = false) :
|
||||
Comparator<String> {
|
||||
|
||||
override fun compare(s1: String, s2: String): Int {
|
||||
var i = 0
|
||||
var j = 0
|
||||
|
||||
while (i < s1.length && j < s2.length) {
|
||||
val c1 = if (ignoreCase) s1[i].lowercaseChar() else s1[i]
|
||||
val c2 = if (ignoreCase) s2[j].lowercaseChar() else s2[j]
|
||||
|
||||
if (c1.isDigit() && c2.isDigit()) {
|
||||
val (num1, nextI) = getNumber(s1, i)
|
||||
val (num2, nextJ) = getNumber(s2, j)
|
||||
|
||||
val numComparison = num1.compareTo(num2)
|
||||
if (numComparison != 0) {
|
||||
return numComparison
|
||||
}
|
||||
i = nextI
|
||||
j = nextJ
|
||||
} else {
|
||||
val charComparison = c1.compareTo(c2)
|
||||
if (charComparison != 0) {
|
||||
return charComparison
|
||||
}
|
||||
i++
|
||||
j++
|
||||
}
|
||||
}
|
||||
|
||||
return s1.length.compareTo(s2.length)
|
||||
}
|
||||
|
||||
private fun getNumber(s: String, startIndex: Int): LongAndInt {
|
||||
var i = startIndex
|
||||
val start = i
|
||||
|
||||
while (i < s.length && s[i].isDigit()) {
|
||||
i++
|
||||
}
|
||||
val numStr = s.substring(start, i)
|
||||
val number = numStr.toLongOrNull() ?: 0L
|
||||
return LongAndInt(number, i)
|
||||
}
|
||||
|
||||
// use this instead of Pair to avoid boxing
|
||||
private data class LongAndInt(val l: Long, var i: Int)
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.formatter.ast
|
||||
|
||||
import org.pkl.formatter.Generator
|
||||
|
||||
enum class Wrap {
|
||||
ENABLED,
|
||||
DETECT;
|
||||
|
||||
fun isEnabled(): Boolean = this == ENABLED
|
||||
}
|
||||
|
||||
sealed interface FormatNode {
|
||||
fun width(wrapped: Set<Int>): Int =
|
||||
when (this) {
|
||||
is Nodes -> nodes.sumOf { it.width(wrapped) }
|
||||
is Group -> nodes.sumOf { it.width(wrapped) }
|
||||
is Indent -> nodes.sumOf { it.width(wrapped) }
|
||||
is ForceWrap -> nodes.sumOf { it.width(wrapped + id) }
|
||||
is IfWrap -> if (id in wrapped) ifWrap.width(wrapped) else ifNotWrap.width(wrapped)
|
||||
is Text -> text.length
|
||||
is SpaceOrLine,
|
||||
is Space -> 1
|
||||
is ForceLine,
|
||||
is MultilineStringGroup -> Generator.MAX
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
data class Text(val text: String) : FormatNode
|
||||
|
||||
object Empty : FormatNode
|
||||
|
||||
object Line : FormatNode
|
||||
|
||||
object ForceLine : FormatNode
|
||||
|
||||
object SpaceOrLine : FormatNode
|
||||
|
||||
object Space : FormatNode
|
||||
|
||||
data class Indent(val nodes: List<FormatNode>) : FormatNode
|
||||
|
||||
data class Nodes(val nodes: List<FormatNode>) : FormatNode
|
||||
|
||||
data class Group(val id: Int, val nodes: List<FormatNode>) : FormatNode
|
||||
|
||||
data class ForceWrap(val id: Int, val nodes: List<FormatNode>) : FormatNode
|
||||
|
||||
data class MultilineStringGroup(val endQuoteCol: Int, val nodes: List<FormatNode>) : FormatNode
|
||||
|
||||
data class IfWrap(val id: Int, val ifWrap: FormatNode, val ifNotWrap: FormatNode) : FormatNode
|
||||
10
pkl-formatter/src/test/files/FormatterSnippetTests/input/class-bodies.pkl
vendored
Normal file
10
pkl-formatter/src/test/files/FormatterSnippetTests/input/class-bodies.pkl
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
class Foo {
|
||||
|
||||
}
|
||||
|
||||
class Bar
|
||||
{
|
||||
qux = 1
|
||||
}
|
||||
|
||||
class Baz { prop = 0; prop2 = 1 }
|
||||
16
pkl-formatter/src/test/files/FormatterSnippetTests/input/comma-termination.pkl
vendored
Normal file
16
pkl-formatter/src/test/files/FormatterSnippetTests/input/comma-termination.pkl
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
function fun(a, b, c, d) = a
|
||||
|
||||
noTrailingCommas = fun(1, 2, 3, 4,)
|
||||
|
||||
trailingCommas = fun("loooooooooooooooooooongString", "loooooooooooooooongString", "looooooooooooooooongString", "notTooLong")
|
||||
|
||||
noTrailingCommaObjParams {
|
||||
fooooooooooooooooooooooooooooooooo, baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar, baaaaaaaaaaaaaaaaaaaaaz ->
|
||||
1 + 1
|
||||
}
|
||||
|
||||
trailingCommaInLambdas = (fooooooooooooooooooooooooooooooooo, baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar, baaaaaaaaaaaaaaaaaaaaaz) -> 1
|
||||
|
||||
trailingCommaInConstraints: String(isSomethingSomethingSomething, isSomethingElse, isSomethingSomethingSomethingElse)
|
||||
|
||||
trailingCommaInTypeParameters: Mapping<SomethingSomethingSomethingSomething, SomethingSomething | SomethingElse>
|
||||
31
pkl-formatter/src/test/files/FormatterSnippetTests/input/comment-interleaved.pkl
vendored
Normal file
31
pkl-formatter/src/test/files/FormatterSnippetTests/input/comment-interleaved.pkl
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
module comment.interleaved
|
||||
|
||||
local test: Int|String =
|
||||
if (true)
|
||||
1 // It's the same as "100%"
|
||||
else
|
||||
"8%"
|
||||
|
||||
foo: ( // some comment
|
||||
* String(
|
||||
// if dtstart is defined and a datetime, until must also be a datetime if defined
|
||||
true
|
||||
)
|
||||
|Int
|
||||
// trailing comment
|
||||
)?
|
||||
|
||||
foo2: (// some comment
|
||||
Int, // other comment
|
||||
String
|
||||
) ->Int
|
||||
|
||||
bar = ( // some comment
|
||||
10 + 10
|
||||
// another comment
|
||||
)
|
||||
|
||||
bar2 = ( // some comment
|
||||
foo, bar
|
||||
// another comment
|
||||
) -> foo + bar
|
||||
8
pkl-formatter/src/test/files/FormatterSnippetTests/input/dangling-doc-comment.pkl
vendored
Normal file
8
pkl-formatter/src/test/files/FormatterSnippetTests/input/dangling-doc-comment.pkl
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
module dangling
|
||||
|
||||
/// Doc comment.
|
||||
///
|
||||
/// for this field
|
||||
// sepearted by a stray comment
|
||||
/// but continues here.
|
||||
some: String
|
||||
14
pkl-formatter/src/test/files/FormatterSnippetTests/input/doc-comments.pkl
vendored
Normal file
14
pkl-formatter/src/test/files/FormatterSnippetTests/input/doc-comments.pkl
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
//// line 1
|
||||
///// line 2
|
||||
foo = 1
|
||||
|
||||
/// line 1
|
||||
///
|
||||
///
|
||||
/// line 2
|
||||
bar = 1
|
||||
|
||||
///line 1
|
||||
///line 2
|
||||
baz = 1
|
||||
25
pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-binary.pkl
vendored
Normal file
25
pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-binary.pkl
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
foo {
|
||||
123123123123 + 123123123123 * 123123123123 - 123123123123 / 123123123123 + 123123123123 ** 123123123123
|
||||
2
|
||||
3
|
||||
4
|
||||
}
|
||||
|
||||
bar = clazz.superclass == null || clazz.superclass.reflectee == Module || clazz.superclass.reflectee == Typed
|
||||
|
||||
baz =
|
||||
new Listing {
|
||||
1
|
||||
2
|
||||
} |> mixin1 |> mixin2
|
||||
|
||||
qux =
|
||||
(baz) {
|
||||
1
|
||||
2
|
||||
} {
|
||||
3
|
||||
4
|
||||
}
|
||||
|
||||
minus = superLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongVariable - 100000
|
||||
5
pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-chain.pkl
vendored
Normal file
5
pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-chain.pkl
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
res = myList.map((it) -> it.partition).filter((it) -> someList.contains(it))
|
||||
|
||||
res2 = myList.map(lambda1).filter(lambda2)
|
||||
|
||||
res3 = myList.map((it) -> it.partition)
|
||||
7
pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-if.pkl
vendored
Normal file
7
pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-if.pkl
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
foo =
|
||||
if (someCondition) 10000
|
||||
else
|
||||
if (someOtherCondition) 20000
|
||||
else
|
||||
if (someAnotherCondition) 30000
|
||||
else 4
|
||||
11
pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-let.pkl
vendored
Normal file
11
pkl-formatter/src/test/files/FormatterSnippetTests/input/expr-let.pkl
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
foo = let (vaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaariable = 10) 1 * 1
|
||||
|
||||
bar = let (someVariable = new Listing {
|
||||
1
|
||||
}) 1 * 1
|
||||
|
||||
baz =
|
||||
let (someVariable = 10000000)
|
||||
let (someOtherVariable = 2000000)
|
||||
let (someAnotherVariable = 3000000) someVariable + someOtherVariable + someAnotherVariable
|
||||
19
pkl-formatter/src/test/files/FormatterSnippetTests/input/imports.pkl
vendored
Normal file
19
pkl-formatter/src/test/files/FormatterSnippetTests/input/imports.pkl
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// top level comment
|
||||
|
||||
import "@foo/Foo.pkl" as foo
|
||||
import* "**.pkl"
|
||||
import "pkl:math"
|
||||
|
||||
import "package://example.com/myPackage@1.0.0#/Qux.pkl"
|
||||
import* "file:///tmp/*.pkl"
|
||||
|
||||
|
||||
import "https://example.com/baz.pkl"
|
||||
import "module2.pkl"
|
||||
import "pkl:reflect"
|
||||
import "..."
|
||||
import* "@foo/**.pkl"
|
||||
import "@bar/Bar.pkl"
|
||||
import "Module12.pkl"
|
||||
import "module11.pkl"
|
||||
import "module1.pkl"
|
||||
51
pkl-formatter/src/test/files/FormatterSnippetTests/input/indentation.pkl
vendored
Normal file
51
pkl-formatter/src/test/files/FormatterSnippetTests/input/indentation.pkl
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
foo = new {
|
||||
bar = 1
|
||||
}
|
||||
|
||||
class Foo {
|
||||
baz: Int
|
||||
}
|
||||
|
||||
bar =
|
||||
new Listing {
|
||||
1
|
||||
2
|
||||
}
|
||||
|
||||
baz =
|
||||
(foo) {
|
||||
2
|
||||
3
|
||||
}
|
||||
|
||||
qux =
|
||||
(x, y) -> new Listing {
|
||||
x
|
||||
y
|
||||
}
|
||||
|
||||
forGen = new Listing {
|
||||
for (someVar in new Listing {
|
||||
1
|
||||
2
|
||||
}) {
|
||||
[someVar] = someVar
|
||||
}
|
||||
}
|
||||
|
||||
objParams: Listing<Int> =
|
||||
new {
|
||||
default {
|
||||
key -> key + 1
|
||||
}
|
||||
}
|
||||
|
||||
objParams2: Listing<Int> = new {
|
||||
default { someVeryLongParameter1, someVeryLongParameter2, someVeryLongParameter3, someVeryLongParameter4 ->
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
parenType: (ReaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongType(reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalylongConstraint))
|
||||
|
||||
functionType: (ReaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongType,ReaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongType2) -> String
|
||||
64
pkl-formatter/src/test/files/FormatterSnippetTests/input/line-breaks.pkl
vendored
Normal file
64
pkl-formatter/src/test/files/FormatterSnippetTests/input/line-breaks.pkl
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
module
|
||||
foo.bar.baz
|
||||
amends
|
||||
"bar.pkl"
|
||||
|
||||
import
|
||||
"@foo/Foo.pkl"
|
||||
as foo
|
||||
|
||||
local
|
||||
open
|
||||
class Bar {}
|
||||
|
||||
const
|
||||
local
|
||||
baz = 10
|
||||
|
||||
local
|
||||
function
|
||||
fun(x) =
|
||||
x
|
||||
|
||||
const local prooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooperty: String = "foo"
|
||||
|
||||
local function function2(parameter1: Parameter1Type, parameter2: Parameter2Type, parameter3: Parameter3Type, parameter4: Parameter4Type): String = ""
|
||||
|
||||
local const function function3(parameter1: String|Int, parameter2: String|Int): Mapping<String|Int, String> =
|
||||
new {}
|
||||
|
||||
prop = function2(loooooooooooooooooogParameter1, loooooooooooooooooogParameter2, loooooooooooooooooogParameter3, loooooooooooooooooogParameter4)
|
||||
|
||||
prop2: String
|
||||
|Int
|
||||
|Boolean
|
||||
|
||||
funcParam = fun(
|
||||
(x, y) -> new Listing {
|
||||
x
|
||||
y
|
||||
})
|
||||
|
||||
funcParam2 = aFun(foo, 10 * 10, anotherVariable, if (true) 100000 else 200000, (param1, param2) -> param1 * param2)
|
||||
|
||||
funcParam3 = aFun(foo, 10 * 10, anotherVariable, 200000, (param1, param2) -> param1 * param2)
|
||||
|
||||
funcParam4 = aFun(foo, 10 * 10, anotherVariable, if (true) 100000 else 200000, new Listing {
|
||||
1
|
||||
2
|
||||
})
|
||||
|
||||
open local class SomeReallyInterestingClassName<in SomeInParameter, out SomeOutParameter> extends AnotherInterestingClassName {
|
||||
foo: Int
|
||||
}
|
||||
|
||||
local function resourceMapping(type): Mapping<String, unknown> =
|
||||
new Mapping { default = (key) -> (type) { metadata { name = key } } }
|
||||
|
||||
local const function biiiiiiiiiiiiiiiiiiiiiiiiigFunction(param1: String, param2: String(!isBlank)): Boolean
|
||||
|
||||
local const function someFunction(param1: String, param2: String(!isBlank)): Boolean
|
||||
|
||||
local function render(currentIndent: String) =
|
||||
"\(currentIndent)@\(identifier.render(currentIndent))" +
|
||||
if (body == null) "" else " " + body.render(currentIndent)
|
||||
20
pkl-formatter/src/test/files/FormatterSnippetTests/input/line-breaks2.pkl
vendored
Normal file
20
pkl-formatter/src/test/files/FormatterSnippetTests/input/line-breaks2.pkl
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
module reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaly.loooooooooooooooooooooooooooooooog.naaaaaaaaaaaaaaaaaaaaaaaaaame
|
||||
extends "reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongModule.pkl"
|
||||
|
||||
import "reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongModule.pkl" as foo
|
||||
|
||||
local open class LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName {}
|
||||
|
||||
local open class ReaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongName {}
|
||||
|
||||
const hidden loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName = 99
|
||||
|
||||
const hidden reallyLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName = 99
|
||||
|
||||
const local function looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName(x: Int, y) = x + y
|
||||
|
||||
typealias Foo = LooooooooooooooooooooooooongTypeName|AnotherLooooooooooooooooooooooooongTypeName|OtherLooooooooooooooooooooooooongTypeName
|
||||
|
||||
bar: Boolean|Mapping<LooooooooooooooooooooooooooooongTypeName, AnotherLooooooooooooooooooooooooooooongTypeName>(loooooooooooooooooooogConstraint)
|
||||
|
||||
hidden foobar: LongType(someVeryyyyyyyloooong, requirements.might.be.even_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooonger)
|
||||
18
pkl-formatter/src/test/files/FormatterSnippetTests/input/line-width.pkl
vendored
Normal file
18
pkl-formatter/src/test/files/FormatterSnippetTests/input/line-width.pkl
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
module reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaly.loooooooooooooooooooooooooooooooog.naaaaaaaaaaaaaaaaaaaaaaaaaaaaame
|
||||
extends "reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongModule.pkl"
|
||||
|
||||
local reallyLongVariableName = true
|
||||
local anotherReallyLongName = 1
|
||||
local evenLongerVariableName = 2
|
||||
|
||||
/// this property has a reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaly long doc comment
|
||||
property = if (reallyLongVariableName) anotherReallyLongName else evenLongerVariableName + anotherReallyLongName
|
||||
|
||||
longString = "reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaly long string"
|
||||
|
||||
shortProperty = 1
|
||||
|
||||
reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongVariableName = 10
|
||||
|
||||
reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongVariableName2 =
|
||||
if (reallyLongVariableName) anotherReallyLongName else evenLongerVariableName + anotherReallyLongName
|
||||
4
pkl-formatter/src/test/files/FormatterSnippetTests/input/map-function.pkl
vendored
Normal file
4
pkl-formatter/src/test/files/FormatterSnippetTests/input/map-function.pkl
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
foo = Map(1000, "some random string", 20000, "another random string", 30000, "yet another random string")
|
||||
|
||||
incorrect = Map("This has", 1000000, "an incorrect number", 2000000, "of parameters", 30000000, "passed to Map")
|
||||
3
pkl-formatter/src/test/files/FormatterSnippetTests/input/modifiers.pkl
vendored
Normal file
3
pkl-formatter/src/test/files/FormatterSnippetTests/input/modifiers.pkl
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
hidden const foo = 1
|
||||
|
||||
open local class Foo {}
|
||||
13
pkl-formatter/src/test/files/FormatterSnippetTests/input/module-definitions.pkl
vendored
Normal file
13
pkl-formatter/src/test/files/FormatterSnippetTests/input/module-definitions.pkl
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// comment
|
||||
// one
|
||||
|
||||
|
||||
/// doc comment
|
||||
|
||||
open
|
||||
module
|
||||
foo
|
||||
.bar
|
||||
|
||||
amends
|
||||
"baz.pkl"
|
||||
29
pkl-formatter/src/test/files/FormatterSnippetTests/input/multi-line-strings.pkl
vendored
Normal file
29
pkl-formatter/src/test/files/FormatterSnippetTests/input/multi-line-strings.pkl
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
foo = """
|
||||
asd \(new {
|
||||
bar = 1
|
||||
}) asd
|
||||
"""
|
||||
|
||||
bar = """
|
||||
line 1
|
||||
line 2
|
||||
line3
|
||||
"""
|
||||
|
||||
baz = """
|
||||
\n
|
||||
\(bar)
|
||||
line
|
||||
\u{123}
|
||||
"""
|
||||
|
||||
// remove unneeded spaces
|
||||
qux = """
|
||||
foo
|
||||
|
||||
bar
|
||||
|
||||
baz
|
||||
|
||||
\(foo)
|
||||
"""
|
||||
22
pkl-formatter/src/test/files/FormatterSnippetTests/input/object-members.pkl
vendored
Normal file
22
pkl-formatter/src/test/files/FormatterSnippetTests/input/object-members.pkl
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
foo: Listing<Int> = new {1 2 3; 4;5 6 7}
|
||||
|
||||
bar: Listing<Int> = new { 1 2
|
||||
3
|
||||
4
|
||||
}
|
||||
|
||||
lineIsTooBig: Listing<Int> = new { 999999; 1000000; 1000001; 1000002; 1000003; 1000004; 1000005; 1000006; 1000007; 1000008; 1000009 }
|
||||
|
||||
lineIsTooBig2 { 999999; 1000000; 1000001; 1000002; 1000003; 1000004; 1000005; 1000006; 1000007; 1000008; 1000009; 1000010 }
|
||||
|
||||
baz = new Dynamic {
|
||||
1 2
|
||||
3 4
|
||||
|
||||
["foo"] = 3; bar = 30
|
||||
|
||||
|
||||
baz = true
|
||||
}
|
||||
|
||||
qux = new Dynamic {1 2 3 prop="prop"; [0]=9}
|
||||
12
pkl-formatter/src/test/files/FormatterSnippetTests/input/prefixes.pkl
vendored
Normal file
12
pkl-formatter/src/test/files/FormatterSnippetTests/input/prefixes.pkl
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
/// Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong doc comment
|
||||
@Annotation { looooooooooooooooooooooooooooooooooooooooooooooooooongVariableName = 10 }
|
||||
typealias Foo = String
|
||||
|
||||
/// Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong doc comment
|
||||
@Annotation { looooooooooooooooooooooooooooooooooooooooooooooooooongVariableName = 10 }
|
||||
foo = "should fit in a single line"
|
||||
|
||||
/// Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong doc comment
|
||||
@Annotation { looooooooooooooooooooooooooooooooooooooooooooooooooongVariableName = 10 }
|
||||
function bar(x): String = "result: \(x)"
|
||||
23
pkl-formatter/src/test/files/FormatterSnippetTests/input/spaces.pkl
vendored
Normal file
23
pkl-formatter/src/test/files/FormatterSnippetTests/input/spaces.pkl
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import"foo.pkl"
|
||||
|
||||
bar=new Listing < Int > ( !isEmpty ){1;2}//a bar
|
||||
|
||||
typealias Typealias=(String,Int)->Boolean
|
||||
|
||||
///a baz
|
||||
///returns its parameter
|
||||
baz = (x,y,z)->x+y+z
|
||||
|
||||
function fun ( x:Int ? ,b :Boolean )= if(b)/***return x**/x else x+bar [0 ]
|
||||
|
||||
prop = trace (1) + super . foo + module .foo
|
||||
|
||||
prop2 {
|
||||
for(x in List(1)) {
|
||||
when(x == 1){
|
||||
x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
choices: "foo" | * "bar" | String
|
||||
6
pkl-formatter/src/test/files/FormatterSnippetTests/input/type-aliases.pkl
vendored
Normal file
6
pkl-formatter/src/test/files/FormatterSnippetTests/input/type-aliases.pkl
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
typealias
|
||||
Foo
|
||||
=
|
||||
String
|
||||
|
||||
typealias VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongTypeAlias = String(!isEmpty)
|
||||
9
pkl-formatter/src/test/files/FormatterSnippetTests/input/when.pkl
vendored
Normal file
9
pkl-formatter/src/test/files/FormatterSnippetTests/input/when.pkl
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
foo {
|
||||
when (true)
|
||||
{
|
||||
bar = 1
|
||||
}
|
||||
else {
|
||||
bar = 2
|
||||
}
|
||||
}
|
||||
11
pkl-formatter/src/test/files/FormatterSnippetTests/output/class-bodies.pkl
vendored
Normal file
11
pkl-formatter/src/test/files/FormatterSnippetTests/output/class-bodies.pkl
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
class Foo {}
|
||||
|
||||
class Bar {
|
||||
qux = 1
|
||||
}
|
||||
|
||||
class Baz {
|
||||
prop = 0
|
||||
|
||||
prop2 = 1
|
||||
}
|
||||
35
pkl-formatter/src/test/files/FormatterSnippetTests/output/comma-termination.pkl
vendored
Normal file
35
pkl-formatter/src/test/files/FormatterSnippetTests/output/comma-termination.pkl
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
function fun(a, b, c, d) = a
|
||||
|
||||
noTrailingCommas = fun(1, 2, 3, 4)
|
||||
|
||||
trailingCommas =
|
||||
fun(
|
||||
"loooooooooooooooooooongString",
|
||||
"loooooooooooooooongString",
|
||||
"looooooooooooooooongString",
|
||||
"notTooLong",
|
||||
)
|
||||
|
||||
noTrailingCommaObjParams {
|
||||
fooooooooooooooooooooooooooooooooo,
|
||||
baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar,
|
||||
baaaaaaaaaaaaaaaaaaaaaz ->
|
||||
1 + 1
|
||||
}
|
||||
|
||||
trailingCommaInLambdas = (
|
||||
fooooooooooooooooooooooooooooooooo,
|
||||
baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar,
|
||||
baaaaaaaaaaaaaaaaaaaaaz,
|
||||
) -> 1
|
||||
|
||||
trailingCommaInConstraints: String(
|
||||
isSomethingSomethingSomething,
|
||||
isSomethingElse,
|
||||
isSomethingSomethingSomethingElse,
|
||||
)
|
||||
|
||||
trailingCommaInTypeParameters: Mapping<
|
||||
SomethingSomethingSomethingSomething,
|
||||
SomethingSomething | SomethingElse,
|
||||
>
|
||||
34
pkl-formatter/src/test/files/FormatterSnippetTests/output/comment-interleaved.pkl
vendored
Normal file
34
pkl-formatter/src/test/files/FormatterSnippetTests/output/comment-interleaved.pkl
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
module comment.interleaved
|
||||
|
||||
local test: Int | String =
|
||||
if (true)
|
||||
1 // It's the same as "100%"
|
||||
else
|
||||
"8%"
|
||||
|
||||
foo: ( // some comment
|
||||
*String(
|
||||
// if dtstart is defined and a datetime, until must also be a datetime if defined
|
||||
true,
|
||||
)
|
||||
| Int
|
||||
// trailing comment
|
||||
)?
|
||||
|
||||
foo2: ( // some comment
|
||||
Int, // other comment
|
||||
String,
|
||||
) ->
|
||||
Int
|
||||
|
||||
bar =
|
||||
( // some comment
|
||||
10 + 10
|
||||
// another comment
|
||||
)
|
||||
|
||||
bar2 = ( // some comment
|
||||
foo,
|
||||
bar
|
||||
// another comment
|
||||
) -> foo + bar
|
||||
8
pkl-formatter/src/test/files/FormatterSnippetTests/output/dangling-doc-comment.pkl
vendored
Normal file
8
pkl-formatter/src/test/files/FormatterSnippetTests/output/dangling-doc-comment.pkl
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
module dangling
|
||||
|
||||
/// Doc comment.
|
||||
///
|
||||
/// for this field
|
||||
// sepearted by a stray comment
|
||||
/// but continues here.
|
||||
some: String
|
||||
13
pkl-formatter/src/test/files/FormatterSnippetTests/output/doc-comments.pkl
vendored
Normal file
13
pkl-formatter/src/test/files/FormatterSnippetTests/output/doc-comments.pkl
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/// / line 1
|
||||
/// // line 2
|
||||
foo = 1
|
||||
|
||||
/// line 1
|
||||
///
|
||||
///
|
||||
/// line 2
|
||||
bar = 1
|
||||
|
||||
/// line 1
|
||||
/// line 2
|
||||
baz = 1
|
||||
34
pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-binary.pkl
vendored
Normal file
34
pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-binary.pkl
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
foo {
|
||||
123123123123
|
||||
+ 123123123123 * 123123123123 -
|
||||
123123123123 / 123123123123
|
||||
+ 123123123123 ** 123123123123
|
||||
2
|
||||
3
|
||||
4
|
||||
}
|
||||
|
||||
bar =
|
||||
clazz.superclass == null
|
||||
|| clazz.superclass.reflectee == Module
|
||||
|| clazz.superclass.reflectee == Typed
|
||||
|
||||
baz =
|
||||
new Listing {
|
||||
1
|
||||
2
|
||||
}
|
||||
|> mixin1
|
||||
|> mixin2
|
||||
|
||||
qux = (baz) {
|
||||
1
|
||||
2
|
||||
} {
|
||||
3
|
||||
4
|
||||
}
|
||||
|
||||
minus =
|
||||
superLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongVariable -
|
||||
100000
|
||||
8
pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-chain.pkl
vendored
Normal file
8
pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-chain.pkl
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
res =
|
||||
myList
|
||||
.map((it) -> it.partition)
|
||||
.filter((it) -> someList.contains(it))
|
||||
|
||||
res2 = myList.map(lambda1).filter(lambda2)
|
||||
|
||||
res3 = myList.map((it) -> it.partition)
|
||||
9
pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-if.pkl
vendored
Normal file
9
pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-if.pkl
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
foo =
|
||||
if (someCondition)
|
||||
10000
|
||||
else if (someOtherCondition)
|
||||
20000
|
||||
else if (someAnotherCondition)
|
||||
30000
|
||||
else
|
||||
4
|
||||
18
pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-let.pkl
vendored
Normal file
18
pkl-formatter/src/test/files/FormatterSnippetTests/output/expr-let.pkl
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
foo =
|
||||
let (vaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaariable =
|
||||
10
|
||||
)
|
||||
1 * 1
|
||||
|
||||
bar =
|
||||
let (someVariable = new Listing {
|
||||
1
|
||||
}
|
||||
)
|
||||
1 * 1
|
||||
|
||||
baz =
|
||||
let (someVariable = 10000000)
|
||||
let (someOtherVariable = 2000000)
|
||||
let (someAnotherVariable = 3000000)
|
||||
someVariable + someOtherVariable + someAnotherVariable
|
||||
21
pkl-formatter/src/test/files/FormatterSnippetTests/output/imports.pkl
vendored
Normal file
21
pkl-formatter/src/test/files/FormatterSnippetTests/output/imports.pkl
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// top level comment
|
||||
|
||||
import "https://example.com/baz.pkl"
|
||||
import "package://example.com/myPackage@1.0.0#/Qux.pkl"
|
||||
import "pkl:math"
|
||||
import "pkl:reflect"
|
||||
|
||||
import "@bar/Bar.pkl"
|
||||
import "@foo/Foo.pkl" as foo
|
||||
|
||||
import "..."
|
||||
import "module1.pkl"
|
||||
import "module2.pkl"
|
||||
import "module11.pkl"
|
||||
import "Module12.pkl"
|
||||
|
||||
import* "file:///tmp/*.pkl"
|
||||
|
||||
import* "@foo/**.pkl"
|
||||
|
||||
import* "**.pkl"
|
||||
61
pkl-formatter/src/test/files/FormatterSnippetTests/output/indentation.pkl
vendored
Normal file
61
pkl-formatter/src/test/files/FormatterSnippetTests/output/indentation.pkl
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
foo = new {
|
||||
bar = 1
|
||||
}
|
||||
|
||||
class Foo {
|
||||
baz: Int
|
||||
}
|
||||
|
||||
bar = new Listing {
|
||||
1
|
||||
2
|
||||
}
|
||||
|
||||
baz = (foo) {
|
||||
2
|
||||
3
|
||||
}
|
||||
|
||||
qux = (x, y) -> new Listing {
|
||||
x
|
||||
y
|
||||
}
|
||||
|
||||
forGen = new Listing {
|
||||
for (
|
||||
someVar in new Listing {
|
||||
1
|
||||
2
|
||||
}
|
||||
) {
|
||||
[someVar] = someVar
|
||||
}
|
||||
}
|
||||
|
||||
objParams: Listing<Int> = new {
|
||||
default { key ->
|
||||
key + 1
|
||||
}
|
||||
}
|
||||
|
||||
objParams2: Listing<Int> = new {
|
||||
default {
|
||||
someVeryLongParameter1,
|
||||
someVeryLongParameter2,
|
||||
someVeryLongParameter3,
|
||||
someVeryLongParameter4 ->
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
parenType: (
|
||||
ReaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongType(
|
||||
reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalylongConstraint,
|
||||
)
|
||||
)
|
||||
|
||||
functionType: (
|
||||
ReaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongType,
|
||||
ReaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongType2,
|
||||
) ->
|
||||
String
|
||||
75
pkl-formatter/src/test/files/FormatterSnippetTests/output/line-breaks.pkl
vendored
Normal file
75
pkl-formatter/src/test/files/FormatterSnippetTests/output/line-breaks.pkl
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
module foo.bar.baz
|
||||
|
||||
amends "bar.pkl"
|
||||
|
||||
import "@foo/Foo.pkl" as foo
|
||||
|
||||
open local class Bar {}
|
||||
|
||||
local const baz = 10
|
||||
|
||||
local function fun(x) = x
|
||||
|
||||
local const prooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooperty: String =
|
||||
"foo"
|
||||
|
||||
local function function2(
|
||||
parameter1: Parameter1Type,
|
||||
parameter2: Parameter2Type,
|
||||
parameter3: Parameter3Type,
|
||||
parameter4: Parameter4Type,
|
||||
): String = ""
|
||||
|
||||
local const function function3(
|
||||
parameter1: String | Int,
|
||||
parameter2: String | Int,
|
||||
): Mapping<String | Int, String> = new {}
|
||||
|
||||
prop =
|
||||
function2(
|
||||
loooooooooooooooooogParameter1,
|
||||
loooooooooooooooooogParameter2,
|
||||
loooooooooooooooooogParameter3,
|
||||
loooooooooooooooooogParameter4,
|
||||
)
|
||||
|
||||
prop2: String | Int | Boolean
|
||||
|
||||
funcParam =
|
||||
fun((x, y) -> new Listing {
|
||||
x
|
||||
y
|
||||
})
|
||||
|
||||
funcParam2 =
|
||||
aFun(foo, 10 * 10, anotherVariable, if (true) 100000 else 200000, (param1, param2) ->
|
||||
param1 * param2
|
||||
)
|
||||
|
||||
funcParam3 = aFun(foo, 10 * 10, anotherVariable, 200000, (param1, param2) -> param1 * param2)
|
||||
|
||||
funcParam4 =
|
||||
aFun(foo, 10 * 10, anotherVariable, if (true) 100000 else 200000, new Listing {
|
||||
1
|
||||
2
|
||||
})
|
||||
|
||||
open local class SomeReallyInterestingClassName<in SomeInParameter, out SomeOutParameter>
|
||||
extends AnotherInterestingClassName {
|
||||
foo: Int
|
||||
}
|
||||
|
||||
local function resourceMapping(type): Mapping<String, unknown> = new Mapping {
|
||||
default = (key) -> (type) { metadata { name = key } }
|
||||
}
|
||||
|
||||
local const function biiiiiiiiiiiiiiiiiiiiiiiiigFunction(
|
||||
param1: String,
|
||||
param2: String(!isBlank),
|
||||
): Boolean
|
||||
|
||||
local const function someFunction(param1: String, param2: String(!isBlank)): Boolean
|
||||
|
||||
local function render(currentIndent: String) =
|
||||
"\(currentIndent)@\(identifier.render(currentIndent))"
|
||||
+ if (body == null) "" else " " + body.render(currentIndent)
|
||||
42
pkl-formatter/src/test/files/FormatterSnippetTests/output/line-breaks2.pkl
vendored
Normal file
42
pkl-formatter/src/test/files/FormatterSnippetTests/output/line-breaks2.pkl
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
module
|
||||
reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaly
|
||||
.loooooooooooooooooooooooooooooooog
|
||||
.naaaaaaaaaaaaaaaaaaaaaaaaaame
|
||||
|
||||
extends
|
||||
"reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongModule.pkl"
|
||||
|
||||
import
|
||||
"reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongModule.pkl"
|
||||
as foo
|
||||
|
||||
open local class LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName {}
|
||||
|
||||
open local class ReaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongName {}
|
||||
|
||||
hidden const loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName =
|
||||
99
|
||||
|
||||
hidden const reallyLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName =
|
||||
99
|
||||
|
||||
local const function looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName(
|
||||
x: Int,
|
||||
y,
|
||||
) = x + y
|
||||
|
||||
typealias Foo =
|
||||
LooooooooooooooooooooooooongTypeName
|
||||
| AnotherLooooooooooooooooooooooooongTypeName
|
||||
| OtherLooooooooooooooooooooooooongTypeName
|
||||
|
||||
bar: Boolean
|
||||
| Mapping<
|
||||
LooooooooooooooooooooooooooooongTypeName,
|
||||
AnotherLooooooooooooooooooooooooooooongTypeName,
|
||||
>(loooooooooooooooooooogConstraint)
|
||||
|
||||
hidden foobar: LongType(
|
||||
someVeryyyyyyyloooong,
|
||||
requirements.might.be.even_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooonger,
|
||||
)
|
||||
32
pkl-formatter/src/test/files/FormatterSnippetTests/output/line-width.pkl
vendored
Normal file
32
pkl-formatter/src/test/files/FormatterSnippetTests/output/line-width.pkl
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
module
|
||||
reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaly
|
||||
.loooooooooooooooooooooooooooooooog
|
||||
.naaaaaaaaaaaaaaaaaaaaaaaaaaaaame
|
||||
|
||||
extends
|
||||
"reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongModule.pkl"
|
||||
|
||||
local reallyLongVariableName = true
|
||||
local anotherReallyLongName = 1
|
||||
local evenLongerVariableName = 2
|
||||
|
||||
/// this property has a reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaly long doc comment
|
||||
property =
|
||||
if (reallyLongVariableName)
|
||||
anotherReallyLongName
|
||||
else
|
||||
evenLongerVariableName + anotherReallyLongName
|
||||
|
||||
longString =
|
||||
"reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaly long string"
|
||||
|
||||
shortProperty = 1
|
||||
|
||||
reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongVariableName =
|
||||
10
|
||||
|
||||
reaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalyLongVariableName2 =
|
||||
if (reallyLongVariableName)
|
||||
anotherReallyLongName
|
||||
else
|
||||
evenLongerVariableName + anotherReallyLongName
|
||||
14
pkl-formatter/src/test/files/FormatterSnippetTests/output/map-function.pkl
vendored
Normal file
14
pkl-formatter/src/test/files/FormatterSnippetTests/output/map-function.pkl
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
foo =
|
||||
Map(
|
||||
1000, "some random string",
|
||||
20000, "another random string",
|
||||
30000, "yet another random string",
|
||||
)
|
||||
|
||||
incorrect =
|
||||
Map(
|
||||
"This has", 1000000,
|
||||
"an incorrect number", 2000000,
|
||||
"of parameters", 30000000,
|
||||
"passed to Map",
|
||||
)
|
||||
3
pkl-formatter/src/test/files/FormatterSnippetTests/output/modifiers.pkl
vendored
Normal file
3
pkl-formatter/src/test/files/FormatterSnippetTests/output/modifiers.pkl
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
hidden const foo = 1
|
||||
|
||||
open local class Foo {}
|
||||
7
pkl-formatter/src/test/files/FormatterSnippetTests/output/module-definitions.pkl
vendored
Normal file
7
pkl-formatter/src/test/files/FormatterSnippetTests/output/module-definitions.pkl
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// comment
|
||||
// one
|
||||
|
||||
/// doc comment
|
||||
open module foo.bar
|
||||
|
||||
amends "baz.pkl"
|
||||
33
pkl-formatter/src/test/files/FormatterSnippetTests/output/multi-line-strings.pkl
vendored
Normal file
33
pkl-formatter/src/test/files/FormatterSnippetTests/output/multi-line-strings.pkl
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
foo =
|
||||
"""
|
||||
asd \(new {
|
||||
bar = 1
|
||||
}) asd
|
||||
"""
|
||||
|
||||
bar =
|
||||
"""
|
||||
line 1
|
||||
line 2
|
||||
line3
|
||||
"""
|
||||
|
||||
baz =
|
||||
"""
|
||||
\n
|
||||
\(bar)
|
||||
line
|
||||
\u{123}
|
||||
"""
|
||||
|
||||
// remove unneeded spaces
|
||||
qux =
|
||||
"""
|
||||
foo
|
||||
|
||||
bar
|
||||
|
||||
baz
|
||||
|
||||
\(foo)
|
||||
"""
|
||||
51
pkl-formatter/src/test/files/FormatterSnippetTests/output/object-members.pkl
vendored
Normal file
51
pkl-formatter/src/test/files/FormatterSnippetTests/output/object-members.pkl
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
foo: Listing<Int> = new { 1; 2; 3; 4; 5; 6; 7 }
|
||||
|
||||
bar: Listing<Int> = new {
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
}
|
||||
|
||||
lineIsTooBig: Listing<Int> = new {
|
||||
999999
|
||||
1000000
|
||||
1000001
|
||||
1000002
|
||||
1000003
|
||||
1000004
|
||||
1000005
|
||||
1000006
|
||||
1000007
|
||||
1000008
|
||||
1000009
|
||||
}
|
||||
|
||||
lineIsTooBig2 {
|
||||
999999
|
||||
1000000
|
||||
1000001
|
||||
1000002
|
||||
1000003
|
||||
1000004
|
||||
1000005
|
||||
1000006
|
||||
1000007
|
||||
1000008
|
||||
1000009
|
||||
1000010
|
||||
}
|
||||
|
||||
baz = new Dynamic {
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
|
||||
["foo"] = 3
|
||||
bar = 30
|
||||
|
||||
baz = true
|
||||
}
|
||||
|
||||
qux = new Dynamic { 1; 2; 3; prop = "prop"; [0] = 9 }
|
||||
11
pkl-formatter/src/test/files/FormatterSnippetTests/output/prefixes.pkl
vendored
Normal file
11
pkl-formatter/src/test/files/FormatterSnippetTests/output/prefixes.pkl
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/// Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong doc comment
|
||||
@Annotation { looooooooooooooooooooooooooooooooooooooooooooooooooongVariableName = 10 }
|
||||
typealias Foo = String
|
||||
|
||||
/// Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong doc comment
|
||||
@Annotation { looooooooooooooooooooooooooooooooooooooooooooooooooongVariableName = 10 }
|
||||
foo = "should fit in a single line"
|
||||
|
||||
/// Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong doc comment
|
||||
@Annotation { looooooooooooooooooooooooooooooooooooooooooooooooooongVariableName = 10 }
|
||||
function bar(x): String = "result: \(x)"
|
||||
23
pkl-formatter/src/test/files/FormatterSnippetTests/output/spaces.pkl
vendored
Normal file
23
pkl-formatter/src/test/files/FormatterSnippetTests/output/spaces.pkl
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import "foo.pkl"
|
||||
|
||||
bar = new Listing<Int>(!isEmpty) { 1; 2 } //a bar
|
||||
|
||||
typealias Typealias = (String, Int) -> Boolean
|
||||
|
||||
/// a baz
|
||||
/// returns its parameter
|
||||
baz = (x, y, z) -> x + y + z
|
||||
|
||||
function fun(x: Int?, b: Boolean) = if (b) /***return x**/ x else x + bar[0]
|
||||
|
||||
prop = trace(1) + super.foo + module.foo
|
||||
|
||||
prop2 {
|
||||
for (x in List(1)) {
|
||||
when (x == 1) {
|
||||
x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
choices: "foo" | *"bar" | String
|
||||
4
pkl-formatter/src/test/files/FormatterSnippetTests/output/type-aliases.pkl
vendored
Normal file
4
pkl-formatter/src/test/files/FormatterSnippetTests/output/type-aliases.pkl
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
typealias Foo = String
|
||||
|
||||
typealias VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongTypeAlias =
|
||||
String(!isEmpty)
|
||||
7
pkl-formatter/src/test/files/FormatterSnippetTests/output/when.pkl
vendored
Normal file
7
pkl-formatter/src/test/files/FormatterSnippetTests/output/when.pkl
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
foo {
|
||||
when (true) {
|
||||
bar = 1
|
||||
} else {
|
||||
bar = 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright © 2024-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.formatter
|
||||
|
||||
import org.junit.platform.commons.annotation.Testable
|
||||
|
||||
@Testable class FormatterSnippetTests
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.formatter
|
||||
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.isRegularFile
|
||||
import kotlin.reflect.KClass
|
||||
import org.pkl.commons.test.InputOutputTestEngine
|
||||
import org.pkl.parser.ParserError
|
||||
|
||||
abstract class AbstractFormatterSnippetTestsEngine : InputOutputTestEngine() {
|
||||
|
||||
private val snippetsDir: Path =
|
||||
rootProjectDir.resolve("pkl-formatter/src/test/files/FormatterSnippetTests")
|
||||
|
||||
private val expectedOutputDir: Path = snippetsDir.resolve("output")
|
||||
|
||||
/** Convenience for development; this selects which snippet test(s) to run. */
|
||||
// language=regexp
|
||||
internal val selection: String = ""
|
||||
|
||||
override val includedTests: List<Regex> = listOf(Regex(".*$selection\\.pkl"))
|
||||
|
||||
override val inputDir: Path = snippetsDir.resolve("input")
|
||||
|
||||
override val isInputFile: (Path) -> Boolean = { it.isRegularFile() }
|
||||
|
||||
override fun expectedOutputFileFor(inputFile: Path): Path {
|
||||
val relativePath = relativize(inputFile, inputDir).toString()
|
||||
return expectedOutputDir.resolve(relativePath)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun relativize(path: Path, base: Path): Path {
|
||||
if (System.getProperty("os.name").contains("Windows")) {
|
||||
if (path.isAbsolute && base.isAbsolute && (path.root != base.root)) {
|
||||
return path
|
||||
}
|
||||
}
|
||||
return base.relativize(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FormatterSnippetTestsEngine : AbstractFormatterSnippetTestsEngine() {
|
||||
override val testClass: KClass<*> = FormatterSnippetTests::class
|
||||
|
||||
override fun generateOutputFor(inputFile: Path): Pair<Boolean, String> {
|
||||
val formatter = Formatter()
|
||||
val (success, output) =
|
||||
try {
|
||||
val res = formatter.format(inputFile)
|
||||
true to res
|
||||
} catch (_: ParserError) {
|
||||
false to ""
|
||||
}
|
||||
|
||||
return success to output
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.formatter
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.pkl.parser.GenericParserError
|
||||
|
||||
class FormatterTest {
|
||||
|
||||
@Test
|
||||
fun `multiline string - wrong start quote`() {
|
||||
val ex =
|
||||
assertThrows<GenericParserError> {
|
||||
format(
|
||||
"""
|
||||
foo = ""${'"'}line1
|
||||
line 2
|
||||
""${'"'}
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
assertThat(ex.message).contains("The content of a multi-line string must begin on a new line")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `multiline string - wrong end quote`() {
|
||||
val ex =
|
||||
assertThrows<GenericParserError> {
|
||||
format(
|
||||
"""
|
||||
foo = ""${'"'}
|
||||
line1
|
||||
line 2""${'"'}
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
assertThat(ex.message)
|
||||
.contains("The closing delimiter of a multi-line string must begin on a new line")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `multiline string - wrong indentation`() {
|
||||
val ex =
|
||||
assertThrows<GenericParserError> {
|
||||
format(
|
||||
"""
|
||||
foo = ""${'"'}
|
||||
line1
|
||||
line 2
|
||||
""${'"'}
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
assertThat(ex.message)
|
||||
.contains("Line must match or exceed indentation of the String's last line.")
|
||||
}
|
||||
|
||||
private fun format(code: String): String {
|
||||
return Formatter().format(code.trimIndent())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.pkl.formatter.FormatterSnippetTestsEngine
|
||||
Reference in New Issue
Block a user