improved lazy delegate; added with(newThis) {} to stdlib

This commit is contained in:
sergeych committed 2026-01-05 22:25:46 +01:00
1 parent f792c73b8f
commit 41a3617850
6 files changed
+85 -8

No files matched your search

+6 -5
View File
@@ -17,6 +17,7 @@
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
group = "net.sergeych"
@@ -65,11 +66,11 @@ kotlin {
browser()
nodejs()
}
// @OptIn(ExperimentalWasmDsl::class)
// wasmJs() {
// browser()
// nodejs()
// }
@OptIn(ExperimentalWasmDsl::class)
wasmJs() {
browser()
nodejs()
}
// Suppress Beta warning for expect/actual classes across all targets
targets.configureEach {
+19 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2025 Sergey S. Chernov real.sergeych@gmail.com
* Copyright 2026 Sergey S. Chernov real.sergeych@gmail.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -113,4 +113,22 @@ class StdlibTest {
assertEquals(5, (1..10).toList().count { it % 2 == 1 } )
""")
}
@Test
fun testWith() = runTest {
eval("""
class Person(val name, var age)
val p = Person("Alice", 30)
val result = with(p) {
assertEquals("Alice", name)
assertEquals(30, age)
age = 31
"done"
}
assertEquals("done", result)
assertEquals(31, p.age)
""".trimIndent())
}
}
@@ -287,4 +287,40 @@ class DelegationTest {
""".trimIndent())
}
@Test
fun testThisInLazy() = runTest {
eval("""
class A {
val numbers = [1,2,3]
val tags by lazy { this.numbers }
}
class B {
val a by lazy { A() }
val test by lazy { a.tags + [4] }
}
assertEquals( [1,2,3], A().tags)
assertEquals( [1,2,3,4], B().test)
""")
}
@Test
fun testScopeInLazy() = runTest {
val s1 = Script.newScope()
s1.eval("""
class A {
val tags by lazy { GLOBAL_NUMBERS }
}
""".trimIndent())
// on the same scope, it will see my GLOBAL_NUMBERS:
s1.eval("""
val GLOBAL_NUMBERS = [1,2,3]
class B {
val a by lazy { A() }
val test by lazy { a.tags + [4] }
}
assertEquals( [1,2,3], A().tags)
assertEquals( [1,2,3,4], B().test)
""")
}
}
+11 -1
View File
@@ -310,6 +310,16 @@ interface Delegate {
fun bind(name, access, thisRef) = this
}
/*
Executes the block with `this` set to self and
returns what the block returns.
*/
fun with(self, block) {
var result = Unset
self.apply { result = block() }
result
}
/*
Standard implementation of a lazy-initialized property delegate.
The provided creator lambda is called once on the first access to compute the value.
@@ -325,7 +335,7 @@ class lazy(creatorParam) : Delegate {
}
override fun getValue(thisRef, name) {
if (value == Unset) value = creator()
if (value == Unset) value = with(thisRef,creator)
value
}
}