mirror of
https://github.com/apple/pkl.git
synced 2026-03-28 20:01:55 +01:00
Initial commit
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Copyright © 2024 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.codegen.kotlin
|
||||
|
||||
import java.nio.file.Path
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import org.pkl.commons.cli.CliBaseOptions
|
||||
import org.pkl.commons.readString
|
||||
|
||||
class CliKotlinCodeGeneratorTest {
|
||||
@Test
|
||||
fun `module inheritance`(@TempDir tempDir: Path) {
|
||||
val module1 =
|
||||
PklModule(
|
||||
"org.mod1",
|
||||
"""
|
||||
open module org.mod1
|
||||
|
||||
pigeon: Person
|
||||
|
||||
class Person {
|
||||
name: String
|
||||
age: Int
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
val module2 =
|
||||
PklModule(
|
||||
"org.mod2",
|
||||
"""
|
||||
module org.mod2
|
||||
|
||||
extends "mod1.pkl"
|
||||
|
||||
parrot: Person
|
||||
"""
|
||||
)
|
||||
|
||||
val module1File = module1.writeToDisk(tempDir.resolve("org/mod1.pkl"))
|
||||
val module2File = module2.writeToDisk(tempDir.resolve("org/mod2.pkl"))
|
||||
val outputDir = tempDir.resolve("output")
|
||||
|
||||
val generator =
|
||||
CliKotlinCodeGenerator(
|
||||
CliKotlinCodeGeneratorOptions(
|
||||
CliBaseOptions(listOf(module1File.toUri(), module2File.toUri())),
|
||||
outputDir
|
||||
)
|
||||
)
|
||||
|
||||
generator.run()
|
||||
|
||||
val module1KotlinFile = outputDir.resolve("kotlin/org/Mod1.kt")
|
||||
assertThat(module1KotlinFile).exists()
|
||||
|
||||
val module2KotlinFile = outputDir.resolve("kotlin/org/Mod2.kt")
|
||||
assertThat(module2KotlinFile).exists()
|
||||
|
||||
assertContains(
|
||||
"""
|
||||
open class Mod1(
|
||||
open val pigeon: Person
|
||||
) {
|
||||
"""
|
||||
.trimIndent(),
|
||||
module1KotlinFile.readString()
|
||||
)
|
||||
|
||||
assertContains(
|
||||
"""
|
||||
class Mod2(
|
||||
pigeon: Mod1.Person,
|
||||
val parrot: Mod1.Person
|
||||
) : Mod1(pigeon) {
|
||||
"""
|
||||
.trimIndent(),
|
||||
module2KotlinFile.readString()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `class name clashes`(@TempDir tempDir: Path) {
|
||||
val module1 =
|
||||
PklModule(
|
||||
"org.mod1",
|
||||
"""
|
||||
module org.mod1
|
||||
|
||||
class Person {
|
||||
name: String
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
val module2 =
|
||||
PklModule(
|
||||
"org.mod2",
|
||||
"""
|
||||
module org.mod2
|
||||
|
||||
import "mod1.pkl"
|
||||
|
||||
person1: mod1.Person
|
||||
person2: Person
|
||||
|
||||
class Person {
|
||||
age: Int
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
val module1PklFile = module1.writeToDisk(tempDir.resolve("org/mod1.pkl"))
|
||||
val module2PklFile = module2.writeToDisk(tempDir.resolve("org/mod2.pkl"))
|
||||
val outputDir = tempDir.resolve("output")
|
||||
|
||||
val generator =
|
||||
CliKotlinCodeGenerator(
|
||||
CliKotlinCodeGeneratorOptions(
|
||||
CliBaseOptions(listOf(module1PklFile.toUri(), module2PklFile.toUri())),
|
||||
outputDir
|
||||
)
|
||||
)
|
||||
|
||||
generator.run()
|
||||
|
||||
val module2KotlinFile = outputDir.resolve("kotlin/org/Mod2.kt")
|
||||
assertContains(
|
||||
"""
|
||||
data class Mod2(
|
||||
val person1: Mod1.Person,
|
||||
val person2: Person
|
||||
)
|
||||
"""
|
||||
.trimIndent(),
|
||||
module2KotlinFile.readString()
|
||||
)
|
||||
}
|
||||
|
||||
private fun assertContains(part: String, code: String) {
|
||||
val trimmedPart = part.trim().trimMargin()
|
||||
if (!code.contains(trimmedPart)) {
|
||||
// check for equality to get better error output (ide diff dialog)
|
||||
assertThat(code).isEqualTo(trimmedPart)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright © 2024 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.codegen.kotlin
|
||||
|
||||
import javax.script.ScriptEngineManager
|
||||
import javax.script.ScriptException
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.text.RegexOption.MULTILINE
|
||||
import kotlin.text.RegexOption.UNIX_LINES
|
||||
import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
|
||||
|
||||
class CompilationFailedException(msg: String?, cause: Throwable? = null) :
|
||||
RuntimeException(msg, cause)
|
||||
|
||||
object InMemoryKotlinCompiler {
|
||||
init {
|
||||
// prevent "Unable to load JNA library" warning
|
||||
setIdeaIoUseFallback()
|
||||
}
|
||||
|
||||
// Implementation notes:
|
||||
// * all [sourceFiles] are currently combined into a single file
|
||||
// * implementation makes assumptions about structure of generated source files
|
||||
fun compile(sourceFiles: Map<String, String>): Map<String, KClass<*>> {
|
||||
fun String.findClasses(
|
||||
prefix: String = "",
|
||||
nameGroup: Int = 2,
|
||||
bodyGroup: Int = 4,
|
||||
regex: String =
|
||||
"^(data |open |enum )?class\\s+(\\w+) *(\\([^)]*\\))?.*$\\n((^ .*\\n|^$\\n)*)",
|
||||
transform: (String, String) -> Sequence<Pair<String, String>> = { name, body ->
|
||||
sequenceOf(Pair(name, prefix + name)) + body.findClasses("$prefix$name.")
|
||||
}
|
||||
): Sequence<Pair<String, String>> = // (simpleName1, qualifiedName1), ...
|
||||
Regex(regex, setOf(MULTILINE, UNIX_LINES)).findAll(this).flatMap {
|
||||
transform(it.groupValues[nameGroup], it.groupValues[bodyGroup].trimIndent())
|
||||
}
|
||||
|
||||
fun String.findOuterObjects(): Sequence<Pair<String, String>> = // (simpleName, qualifiedName)
|
||||
findClasses("", 1, 2, "^object\\s+(\\w+).*$\n((^ .*$\n|^$\n)*)") { name, body ->
|
||||
body.findClasses("$name.")
|
||||
}
|
||||
|
||||
val (importLines, remainder) =
|
||||
sourceFiles.entries
|
||||
.flatMap { (_, text) -> text.lines() }
|
||||
.partition { it.startsWith("import") }
|
||||
val importBlock = importLines.sorted().distinct()
|
||||
val (packageLines, code) = remainder.partition { it.startsWith("package") }
|
||||
val packageBlock = packageLines.distinct()
|
||||
assert(
|
||||
packageBlock.size <= 1
|
||||
) // everything is in the same package and/or there is no package line
|
||||
val sourceText = listOf(packageBlock, importBlock, code).flatten().joinToString("\n")
|
||||
|
||||
val (simpleNames, qualifiedNames) =
|
||||
sourceText.findClasses().plus(sourceText.findOuterObjects()).unzip()
|
||||
val instrumentation =
|
||||
"listOf<kotlin.reflect.KClass<*>>(${qualifiedNames.joinToString(",") { "$it::class" }})"
|
||||
|
||||
// create new engine for each compilation
|
||||
// (otherwise we sometimes get kotlin compiler exceptions)
|
||||
val engine = ScriptEngineManager().getEngineByExtension("kts")!!
|
||||
val classes =
|
||||
try {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
engine.eval("$sourceText\n\n$instrumentation") as List<KClass<*>>
|
||||
} catch (e: ScriptException) {
|
||||
throw CompilationFailedException(e.message, e)
|
||||
}
|
||||
|
||||
return simpleNames.zip(classes).toMap()
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright © 2024 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.codegen.kotlin
|
||||
|
||||
import java.nio.file.Path
|
||||
import org.pkl.commons.createParentDirectories
|
||||
import org.pkl.commons.writeString
|
||||
|
||||
data class PklModule(val name: String, val content: String) {
|
||||
fun writeToDisk(path: Path): Path {
|
||||
return path.createParentDirectories().writeString(content)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
|
||||
@@ -0,0 +1,159 @@
|
||||
package my
|
||||
|
||||
import java.util.Objects
|
||||
import kotlin.Any
|
||||
import kotlin.Boolean
|
||||
import kotlin.Int
|
||||
import kotlin.Long
|
||||
import kotlin.String
|
||||
import kotlin.text.StringBuilder
|
||||
import org.pkl.core.Duration
|
||||
|
||||
object Mod {
|
||||
private fun appendProperty(
|
||||
builder: StringBuilder,
|
||||
name: String,
|
||||
value: Any?
|
||||
) {
|
||||
builder.append("\n ").append(name).append(" = ")
|
||||
val lines = value.toString().split("\n")
|
||||
builder.append(lines[0])
|
||||
for (i in 1..lines.lastIndex) {
|
||||
builder.append("\n ").append(lines[i])
|
||||
}
|
||||
}
|
||||
|
||||
open class Foo(
|
||||
open val one: Long
|
||||
) {
|
||||
open fun copy(one: Long = this.one): Foo = Foo(one)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (this.javaClass != other?.javaClass) return false
|
||||
other as Foo
|
||||
if (this.one != other.one) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = 1
|
||||
result = 31 * result + Objects.hashCode(this.one)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val builder = StringBuilder(100)
|
||||
builder.append(Foo::class.java.simpleName).append(" {")
|
||||
appendProperty(builder, "one", this.one)
|
||||
builder.append("\n}")
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
||||
|
||||
open class None(
|
||||
one: Long
|
||||
) : Foo(one) {
|
||||
open override fun copy(one: Long): None = None(one)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (this.javaClass != other?.javaClass) return false
|
||||
other as None
|
||||
if (this.one != other.one) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = 1
|
||||
result = 31 * result + Objects.hashCode(this.one)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val builder = StringBuilder(100)
|
||||
builder.append(None::class.java.simpleName).append(" {")
|
||||
appendProperty(builder, "one", this.one)
|
||||
builder.append("\n}")
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
||||
|
||||
open class Bar(
|
||||
one: Long,
|
||||
open val two: String
|
||||
) : None(one) {
|
||||
open fun copy(one: Long = this.one, two: String = this.two): Bar = Bar(one, two)
|
||||
|
||||
open override fun copy(one: Long): Bar = Bar(one, two)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (this.javaClass != other?.javaClass) return false
|
||||
other as Bar
|
||||
if (this.one != other.one) return false
|
||||
if (this.two != other.two) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = 1
|
||||
result = 31 * result + Objects.hashCode(this.one)
|
||||
result = 31 * result + Objects.hashCode(this.two)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val builder = StringBuilder(150)
|
||||
builder.append(Bar::class.java.simpleName).append(" {")
|
||||
appendProperty(builder, "one", this.one)
|
||||
appendProperty(builder, "two", this.two)
|
||||
builder.append("\n}")
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
||||
|
||||
class Baz(
|
||||
one: Long,
|
||||
two: String,
|
||||
val three: Duration
|
||||
) : Bar(one, two) {
|
||||
fun copy(
|
||||
one: Long = this.one,
|
||||
two: String = this.two,
|
||||
three: Duration = this.three
|
||||
): Baz = Baz(one, two, three)
|
||||
|
||||
override fun copy(one: Long, two: String): Baz = Baz(one, two, three)
|
||||
|
||||
override fun copy(one: Long): Baz = Baz(one, two, three)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (this.javaClass != other?.javaClass) return false
|
||||
other as Baz
|
||||
if (this.one != other.one) return false
|
||||
if (this.two != other.two) return false
|
||||
if (this.three != other.three) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = 1
|
||||
result = 31 * result + Objects.hashCode(this.one)
|
||||
result = 31 * result + Objects.hashCode(this.two)
|
||||
result = 31 * result + Objects.hashCode(this.three)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val builder = StringBuilder(200)
|
||||
builder.append(Baz::class.java.simpleName).append(" {")
|
||||
appendProperty(builder, "one", this.one)
|
||||
appendProperty(builder, "two", this.two)
|
||||
appendProperty(builder, "three", this.three)
|
||||
builder.append("\n}")
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package my
|
||||
|
||||
import java.util.Objects
|
||||
import kotlin.Any
|
||||
import kotlin.Boolean
|
||||
import kotlin.Int
|
||||
import kotlin.String
|
||||
import kotlin.text.StringBuilder
|
||||
|
||||
/**
|
||||
* type alias comment.
|
||||
* *emphasized* `code`.
|
||||
*/
|
||||
typealias Email = String
|
||||
|
||||
/**
|
||||
* module comment.
|
||||
* *emphasized* `code`.
|
||||
*/
|
||||
data class Mod(
|
||||
/**
|
||||
* module property comment.
|
||||
* *emphasized* `code`.
|
||||
*/
|
||||
val pigeon: Person
|
||||
) {
|
||||
/**
|
||||
* class comment.
|
||||
* *emphasized* `code`.
|
||||
*/
|
||||
open class Product(
|
||||
/**
|
||||
* class property comment.
|
||||
* *emphasized* `code`.
|
||||
*/
|
||||
open val price: String
|
||||
) {
|
||||
open fun copy(price: String = this.price): Product = Product(price)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (this.javaClass != other?.javaClass) return false
|
||||
other as Product
|
||||
if (this.price != other.price) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = 1
|
||||
result = 31 * result + Objects.hashCode(this.price)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val builder = StringBuilder(100)
|
||||
builder.append(Product::class.java.simpleName).append(" {")
|
||||
appendProperty(builder, "price", this.price)
|
||||
builder.append("\n}")
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* class comment.
|
||||
* *emphasized* `code`.
|
||||
*/
|
||||
data class Person(
|
||||
/**
|
||||
* class property comment.
|
||||
* *emphasized* `code`.
|
||||
*/
|
||||
val name: String
|
||||
)
|
||||
|
||||
companion object {
|
||||
private fun appendProperty(
|
||||
builder: StringBuilder,
|
||||
name: String,
|
||||
value: Any?
|
||||
) {
|
||||
builder.append("\n ").append(name).append(" = ")
|
||||
val lines = value.toString().split("\n")
|
||||
builder.append(lines[0])
|
||||
for (i in 1..lines.lastIndex) {
|
||||
builder.append("\n ").append(lines[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
package my
|
||||
|
||||
import java.util.Objects
|
||||
import kotlin.Any
|
||||
import kotlin.Boolean
|
||||
import kotlin.Double
|
||||
import kotlin.Int
|
||||
import kotlin.Long
|
||||
import kotlin.Pair
|
||||
import kotlin.String
|
||||
import kotlin.collections.Collection
|
||||
import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
import kotlin.collections.Set
|
||||
import kotlin.text.Regex
|
||||
import kotlin.text.StringBuilder
|
||||
import org.pkl.core.DataSize
|
||||
import org.pkl.core.DataSizeUnit
|
||||
import org.pkl.core.Duration
|
||||
import org.pkl.core.DurationUnit
|
||||
|
||||
object Mod {
|
||||
private fun appendProperty(
|
||||
builder: StringBuilder,
|
||||
name: String,
|
||||
value: Any?
|
||||
) {
|
||||
builder.append("\n ").append(name).append(" = ")
|
||||
val lines = value.toString().split("\n")
|
||||
builder.append(lines[0])
|
||||
for (i in 1..lines.lastIndex) {
|
||||
builder.append("\n ").append(lines[i])
|
||||
}
|
||||
}
|
||||
|
||||
open class PropertyTypes(
|
||||
open val boolean: Boolean,
|
||||
open val int: Long,
|
||||
open val float: Double,
|
||||
open val string: String,
|
||||
open val duration: Duration,
|
||||
open val durationUnit: DurationUnit,
|
||||
open val dataSize: DataSize,
|
||||
open val dataSizeUnit: DataSizeUnit,
|
||||
open val nullable: String?,
|
||||
open val nullable2: String?,
|
||||
open val pair: Pair<Any?, Any?>,
|
||||
open val pair2: Pair<String, Other>,
|
||||
open val coll: Collection<Any?>,
|
||||
open val coll2: Collection<Other>,
|
||||
open val list: List<Any?>,
|
||||
open val list2: List<Other>,
|
||||
open val set: Set<Any?>,
|
||||
open val set2: Set<Other>,
|
||||
open val map: Map<Any?, Any?>,
|
||||
open val map2: Map<String, Other>,
|
||||
open val container: Map<Any?, Any?>,
|
||||
open val container2: Map<String, Other>,
|
||||
open val other: Other,
|
||||
open val regex: Regex,
|
||||
open val any: Any?,
|
||||
open val nonNull: Any,
|
||||
open val enum: Direction
|
||||
) {
|
||||
open fun copy(
|
||||
boolean: Boolean = this.boolean,
|
||||
int: Long = this.int,
|
||||
float: Double = this.float,
|
||||
string: String = this.string,
|
||||
duration: Duration = this.duration,
|
||||
durationUnit: DurationUnit = this.durationUnit,
|
||||
dataSize: DataSize = this.dataSize,
|
||||
dataSizeUnit: DataSizeUnit = this.dataSizeUnit,
|
||||
nullable: String? = this.nullable,
|
||||
nullable2: String? = this.nullable2,
|
||||
pair: Pair<Any?, Any?> = this.pair,
|
||||
pair2: Pair<String, Other> = this.pair2,
|
||||
coll: Collection<Any?> = this.coll,
|
||||
coll2: Collection<Other> = this.coll2,
|
||||
list: List<Any?> = this.list,
|
||||
list2: List<Other> = this.list2,
|
||||
set: Set<Any?> = this.set,
|
||||
set2: Set<Other> = this.set2,
|
||||
map: Map<Any?, Any?> = this.map,
|
||||
map2: Map<String, Other> = this.map2,
|
||||
container: Map<Any?, Any?> = this.container,
|
||||
container2: Map<String, Other> = this.container2,
|
||||
other: Other = this.other,
|
||||
regex: Regex = this.regex,
|
||||
any: Any? = this.any,
|
||||
nonNull: Any = this.nonNull,
|
||||
enum: Direction = this.enum
|
||||
): PropertyTypes = PropertyTypes(boolean, int, float, string, duration, durationUnit, dataSize,
|
||||
dataSizeUnit, nullable, nullable2, pair, pair2, coll, coll2, list, list2, set, set2, map,
|
||||
map2, container, container2, other, regex, any, nonNull, enum)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (this.javaClass != other?.javaClass) return false
|
||||
other as PropertyTypes
|
||||
if (this.boolean != other.boolean) return false
|
||||
if (this.int != other.int) return false
|
||||
if (this.float != other.float) return false
|
||||
if (this.string != other.string) return false
|
||||
if (this.duration != other.duration) return false
|
||||
if (this.durationUnit != other.durationUnit) return false
|
||||
if (this.dataSize != other.dataSize) return false
|
||||
if (this.dataSizeUnit != other.dataSizeUnit) return false
|
||||
if (this.nullable != other.nullable) return false
|
||||
if (this.nullable2 != other.nullable2) return false
|
||||
if (this.pair != other.pair) return false
|
||||
if (this.pair2 != other.pair2) return false
|
||||
if (this.coll != other.coll) return false
|
||||
if (this.coll2 != other.coll2) return false
|
||||
if (this.list != other.list) return false
|
||||
if (this.list2 != other.list2) return false
|
||||
if (this.set != other.set) return false
|
||||
if (this.set2 != other.set2) return false
|
||||
if (this.map != other.map) return false
|
||||
if (this.map2 != other.map2) return false
|
||||
if (this.container != other.container) return false
|
||||
if (this.container2 != other.container2) return false
|
||||
if (this.other != other.other) return false
|
||||
if (this.regex.pattern != other.regex.pattern) return false
|
||||
if (this.any != other.any) return false
|
||||
if (this.nonNull != other.nonNull) return false
|
||||
if (this.enum != other.enum) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = 1
|
||||
result = 31 * result + Objects.hashCode(this.boolean)
|
||||
result = 31 * result + Objects.hashCode(this.int)
|
||||
result = 31 * result + Objects.hashCode(this.float)
|
||||
result = 31 * result + Objects.hashCode(this.string)
|
||||
result = 31 * result + Objects.hashCode(this.duration)
|
||||
result = 31 * result + Objects.hashCode(this.durationUnit)
|
||||
result = 31 * result + Objects.hashCode(this.dataSize)
|
||||
result = 31 * result + Objects.hashCode(this.dataSizeUnit)
|
||||
result = 31 * result + Objects.hashCode(this.nullable)
|
||||
result = 31 * result + Objects.hashCode(this.nullable2)
|
||||
result = 31 * result + Objects.hashCode(this.pair)
|
||||
result = 31 * result + Objects.hashCode(this.pair2)
|
||||
result = 31 * result + Objects.hashCode(this.coll)
|
||||
result = 31 * result + Objects.hashCode(this.coll2)
|
||||
result = 31 * result + Objects.hashCode(this.list)
|
||||
result = 31 * result + Objects.hashCode(this.list2)
|
||||
result = 31 * result + Objects.hashCode(this.set)
|
||||
result = 31 * result + Objects.hashCode(this.set2)
|
||||
result = 31 * result + Objects.hashCode(this.map)
|
||||
result = 31 * result + Objects.hashCode(this.map2)
|
||||
result = 31 * result + Objects.hashCode(this.container)
|
||||
result = 31 * result + Objects.hashCode(this.container2)
|
||||
result = 31 * result + Objects.hashCode(this.other)
|
||||
result = 31 * result + Objects.hashCode(this.regex)
|
||||
result = 31 * result + Objects.hashCode(this.any)
|
||||
result = 31 * result + Objects.hashCode(this.nonNull)
|
||||
result = 31 * result + Objects.hashCode(this.enum)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val builder = StringBuilder(1400)
|
||||
builder.append(PropertyTypes::class.java.simpleName).append(" {")
|
||||
appendProperty(builder, "boolean", this.boolean)
|
||||
appendProperty(builder, "int", this.int)
|
||||
appendProperty(builder, "float", this.float)
|
||||
appendProperty(builder, "string", this.string)
|
||||
appendProperty(builder, "duration", this.duration)
|
||||
appendProperty(builder, "durationUnit", this.durationUnit)
|
||||
appendProperty(builder, "dataSize", this.dataSize)
|
||||
appendProperty(builder, "dataSizeUnit", this.dataSizeUnit)
|
||||
appendProperty(builder, "nullable", this.nullable)
|
||||
appendProperty(builder, "nullable2", this.nullable2)
|
||||
appendProperty(builder, "pair", this.pair)
|
||||
appendProperty(builder, "pair2", this.pair2)
|
||||
appendProperty(builder, "coll", this.coll)
|
||||
appendProperty(builder, "coll2", this.coll2)
|
||||
appendProperty(builder, "list", this.list)
|
||||
appendProperty(builder, "list2", this.list2)
|
||||
appendProperty(builder, "set", this.set)
|
||||
appendProperty(builder, "set2", this.set2)
|
||||
appendProperty(builder, "map", this.map)
|
||||
appendProperty(builder, "map2", this.map2)
|
||||
appendProperty(builder, "container", this.container)
|
||||
appendProperty(builder, "container2", this.container2)
|
||||
appendProperty(builder, "other", this.other)
|
||||
appendProperty(builder, "regex", this.regex)
|
||||
appendProperty(builder, "any", this.any)
|
||||
appendProperty(builder, "nonNull", this.nonNull)
|
||||
appendProperty(builder, "enum", this.enum)
|
||||
builder.append("\n}")
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
||||
|
||||
open class Other(
|
||||
open val name: String
|
||||
) {
|
||||
open fun copy(name: String = this.name): Other = Other(name)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (this.javaClass != other?.javaClass) return false
|
||||
other as Other
|
||||
if (this.name != other.name) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = 1
|
||||
result = 31 * result + Objects.hashCode(this.name)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val builder = StringBuilder(100)
|
||||
builder.append(Other::class.java.simpleName).append(" {")
|
||||
appendProperty(builder, "name", this.name)
|
||||
builder.append("\n}")
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
||||
|
||||
enum class Direction(
|
||||
val value: String
|
||||
) {
|
||||
NORTH("north"),
|
||||
|
||||
EAST("east"),
|
||||
|
||||
SOUTH("south"),
|
||||
|
||||
WEST("west");
|
||||
|
||||
override fun toString() = value
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user