From 18af04c2ecc609e2676bdedd9a202603043d23f4 Mon Sep 17 00:00:00 2001 From: Jen Basch Date: Mon, 1 Jun 2026 20:27:19 -0700 Subject: [PATCH] Correctly count regular members of `Dynamic` (#1632) Previously, `VmDynamic.isHiddenOrLocalProperty` didn't correctly identify locals whose cache key is an `ObjectMember` instead of an `Identifier`, causing `VmDynamic. getRegularMemberCount` to return an incorrect value. This caused some renderers to produce incorrect output. Resolves #1631 --- .../java/org/pkl/core/runtime/VmDynamic.java | 5 ++- .../test/kotlin/org/pkl/core/EvaluatorTest.kt | 44 ++++++++++++++++++- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmDynamic.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmDynamic.java index e10938d1..c8915f18 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmDynamic.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmDynamic.java @@ -158,7 +158,8 @@ public final class VmDynamic extends VmObject { } private boolean isHiddenOrLocalProperty(Object key) { - return key instanceof Identifier - && (key == Identifier.DEFAULT || ((Identifier) key).isLocalProp()); + return key instanceof ObjectMember member && member.isLocal() + || key instanceof Identifier identifier + && (key == Identifier.DEFAULT || identifier.isLocalProp()); } } diff --git a/pkl-core/src/test/kotlin/org/pkl/core/EvaluatorTest.kt b/pkl-core/src/test/kotlin/org/pkl/core/EvaluatorTest.kt index 91c4f939..733eed6c 100644 --- a/pkl-core/src/test/kotlin/org/pkl/core/EvaluatorTest.kt +++ b/pkl-core/src/test/kotlin/org/pkl/core/EvaluatorTest.kt @@ -635,7 +635,7 @@ class EvaluatorTest { } @Test - fun `nested pkl-binary rendiring produces correct results`() { + fun `nested pkl-binary rendering produces correct results`() { val evaluator = with(EvaluatorBuilder.preconfigured()) { allowedResources.add(Pattern.compile("b64:")) @@ -696,6 +696,48 @@ class EvaluatorTest { } } + @Test + fun `objects with object locals are encoded correctly`() { + val data = + evaluator.evaluateOutputBytes( + text( + """ + import "pkl:pklbinary" + + dynamic: Dynamic = new { + local foo = new Test {} + bar = foo + } + listing: Listing = new { + local foo = new Test {} + foo + } + mapping: Mapping = new { + local foo = new Test {} + ["bar"] = foo + } + `class`: MyClass = new { + local foo = new Test {} + bar = foo + } + + class MyClass { + bar: Test + } + + class Test + + output { + renderer = new pklbinary.Renderer {} + } + """ + .trimIndent() + ) + ) + + assertThatCode { PklBinaryDecoder.decode(data) }.doesNotThrowAnyException() + } + @Test fun `power assertions work with test facts with unavailable source section`() { val evaluator =