- rewritten/fixed buildconfig

- less noise
- cosmetics in CLI tool
This commit is contained in:
Sergey Chernov 2025-06-10 02:06:03 +04:00
parent 323c455a50
commit fffa3d31bb
8 changed files with 103 additions and 86 deletions

View File

@ -1,6 +1,40 @@
# OO implementation in Lyng # OO implementation in Lyng
Basic principles: Short introduction
class Point(x,y) {
fun length() { sqrt(x*x + y*y) }
}
assert( Point is Class )
val p = Point(3,4)
assert(p is Point)
assertEquals(5, p.length())
// we can access the fields:
assert( p.x == 3 )
assert( p.y == 4 )
// we can assign new values to fields:
p.x = 1
p.y = 1
assertEquals(sqrt(2), p.length())
>>> void
Let's see in details. The statement `class Point(x,y)` creates a class,
with two field, which are mutable and publicly visible.`(x,y)` here
is the [argument list], same as when defining a function. All together creates a class with
a _constructor_ that requires two parameters for fields. So when creating it with
`Point(10, 20)` we say _calling Point constructor_ with these parameters.
Form now on `Point` is a class, it's type is `Class`, and we can create instances with it as in the
example above.
Class point has a _method_, or a _member function_ `length()` that uses its _fields_ `x` and `y` to
calculate the magnitude.
## Basic principles:
- Everything is an instance of some class - Everything is an instance of some class
- Every class except Obj has at least one parent - Every class except Obj has at least one parent
@ -71,41 +105,6 @@ Regular methods are called on instances as usual `instance.method()`. The method
2. parents method: no guarantee but we enumerate parents in order of appearance; 2. parents method: no guarantee but we enumerate parents in order of appearance;
3. possible extension methods (scoped) 3. possible extension methods (scoped)
# Defining a new class
The class is a some data record with named fields and fixed order, in fact. To define a class,
just Provide a name and a record like this:
// creating new class with main constructor
// with all fields public and mutable:
struct Point(x,y)
assert( Point is Class )
// now we can create instance
val p1 = Point(3,4)
// is is of the newly created type:
assert( p1 is Point )
// we can read and write its fields:
assert( p1.x == 3 )
assert( p1.y == 4 )
p1.y++
assert( p1.y == 5 )
>>> void
Let's see in details. The statement `struct Point(x,y)` creates a struct, or public class,
with two field, which are mutable and publicly visible, because it is _struct_. `(x,y)` here
is the [argument list], same as when defining a function. All together creates a class with
a _constructor_ that requires two parameters for fields. So when creating it with
`Point(10, 20)` we say _calling Point constructor_ with these parameters.
Such declaration is identical to `class Point(var x,var y)` which does exactly the same.
TBD TBD
[argument list](declaring_arguments.md) [argument list](declaring_arguments.md)

View File

@ -1,17 +1,40 @@
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING
import com.vanniktech.maven.publish.SonatypeHost import com.vanniktech.maven.publish.SonatypeHost
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.JvmTarget
group = "net.sergeych"
version = "0.2.1-SNAPSHOT"
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0")
classpath("com.codingfeline.buildkonfig:buildkonfig-gradle-plugin:latest_version")
}
}
plugins { plugins {
alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidLibrary) alias(libs.plugins.androidLibrary)
alias(libs.plugins.vanniktech.mavenPublish) alias(libs.plugins.vanniktech.mavenPublish)
kotlin("plugin.serialization") version "2.1.20" kotlin("plugin.serialization") version "2.1.20"
id("com.codingfeline.buildkonfig") version "0.17.1"
} }
group = "net.sergeych" buildkonfig {
version = "0.2.0-SNAPSHOT" packageName = "net.sergeych.lyng"
// objectName = "YourAwesomeConfig"
// exposeObjectWithName = "YourAwesomePublicConfig"
defaultConfigs {
buildConfigField(STRING, "bcprovider", "codingfeline")
buildConfigField(STRING, "version", version.toString())
}
}
kotlin { kotlin {
jvm() jvm()
@ -110,40 +133,40 @@ mavenPublishing {
} }
} }
} }
//
val projectVersion by project.extra(provider { //val projectVersion by project.extra(provider {
// Compute value lazily // // Compute value lazily
(version as String) // (version as String)
}) //})
//
val generateBuildConfig by tasks.registering { //val generateBuildConfig by tasks.registering {
// Declare outputs safely // // Declare outputs safely
val outputDir = layout.buildDirectory.dir("generated/buildConfig/commonMain/kotlin") // val outputDir = layout.buildDirectory.dir("generated/buildConfig/commonMain/kotlin")
outputs.dir(outputDir) // outputs.dir(outputDir)
//
val version = projectVersion.get() // val version = projectVersion.get()
//
// Inputs: Version is tracked as an input // // Inputs: Version is tracked as an input
inputs.property("version", version) // inputs.property("version", version)
//
doLast { // doLast {
val packageName = "net.sergeych.lyng.buildconfig" // val packageName = "net.sergeych.lyng.buildconfig"
val packagePath = packageName.replace('.', '/') // val packagePath = packageName.replace('.', '/')
val buildConfigFile = outputDir.get().file("$packagePath/BuildConfig.kt").asFile // val buildConfigFile = outputDir.get().file("$packagePath/BuildConfig.kt").asFile
//
buildConfigFile.parentFile?.mkdirs() // buildConfigFile.parentFile?.mkdirs()
buildConfigFile.writeText( // buildConfigFile.writeText(
""" // """
|package $packageName // |package $packageName
| // |
|object BuildConfig { // |object BuildConfig {
| const val VERSION = "$version" // | const val VERSION = "$version"
|} // |}
""".trimMargin() // """.trimMargin()
) // )
} // }
} //}
//
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach { //tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
dependsOn(generateBuildConfig) // dependsOn(generateBuildConfig)
} //}

View File

@ -745,7 +745,6 @@ class Compiler(
bodyInit?.execute(this) bodyInit?.execute(this)
// export public // export public
for( (name,record) in objects ) { for( (name,record) in objects ) {
println("-- $name $record")
when(record.visibility) { when(record.visibility) {
Visibility.Public -> { Visibility.Public -> {
thisObj.publicFields += name thisObj.publicFields += name
@ -770,7 +769,6 @@ class Compiler(
f.name, f.name,
statement { statement {
val context = (thisObj as ObjInstance).instanceContext val context = (thisObj as ObjInstance).instanceContext
println("called on $thisObj")
context[f.name]?.value ?: raiseError("field is not initialized: ${f.name}") context[f.name]?.value ?: raiseError("field is not initialized: ${f.name}")
}, },
true, true,

View File

@ -23,8 +23,6 @@ class ObjClass(
override suspend fun compareTo(context: Context, other: Obj): Int = if (other === this) 0 else -1 override suspend fun compareTo(context: Context, other: Obj): Int = if (other === this) 0 else -1
override suspend fun callOn(context: Context): Obj { override suspend fun callOn(context: Context): Obj {
println("callOn $this constructing....")
println("on context: $context")
val instance = ObjInstance(this) val instance = ObjInstance(this)
instance.instanceContext = context.copy(newThisObj = instance,args = context.args) instance.instanceContext = context.copy(newThisObj = instance,args = context.args)
if (instanceConstructor != null) { if (instanceConstructor != null) {

View File

@ -1,5 +1,4 @@
package net.sergeych.lyng package net.sergeych.lyng
import net.sergeych.lyng.buildconfig.BuildConfig
val LyngVersion = BuildConfig.VERSION val LyngVersion = BuildKonfig.version

View File

@ -24,7 +24,7 @@ val baseContext = Context().apply {
} }
} }
class LyngCLI(val launcher: (suspend () -> Unit) -> Unit) : CliktCommand() { class Lyng(val launcher: (suspend () -> Unit) -> Unit) : CliktCommand() {
override val printHelpOnEmptyArgs = true override val printHelpOnEmptyArgs = true

View File

@ -2,8 +2,8 @@ package net.sergeych.lyng_cli
import com.github.ajalt.clikt.core.main import com.github.ajalt.clikt.core.main
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import net.sergeych.LyngCLI import net.sergeych.Lyng
fun main(args: Array<String>) { fun main(args: Array<String>) {
LyngCLI({ runBlocking { it() } }).main(args) Lyng({ runBlocking { it() } }).main(args)
} }

View File

@ -1,7 +1,7 @@
import com.github.ajalt.clikt.core.main import com.github.ajalt.clikt.core.main
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import net.sergeych.LyngCLI import net.sergeych.Lyng
fun main(args: Array<String>) { fun main(args: Array<String>) {
LyngCLI( { runBlocking { it() } }).main(args) Lyng( { runBlocking { it() } }).main(args)
} }