Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix default value evaluation in toTyped() #575

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
import org.pkl.core.ast.ExpressionNode;
import org.pkl.core.runtime.Identifier;
import org.pkl.core.runtime.VmMap;
import org.pkl.core.runtime.VmObjectLike;
import org.pkl.core.runtime.VmUtils;

/** Delegates to the equally named key of the map stored in extra storage. */
public final class DelegateToExtraStorageMapOrParentNode extends ExpressionNode {
@Override
public Object executeGeneric(VirtualFrame frame) {
var receiver = (VmObjectLike) VmUtils.getReceiver(frame);
var owner = VmUtils.getOwner(frame);
var delegate = (VmMap) owner.getExtraStorage();
var memberKey = VmUtils.getMemberKey(frame);
Expand All @@ -33,6 +35,6 @@ public Object executeGeneric(VirtualFrame frame) {
if (result != null) return result;
var parent = owner.getParent();
assert parent != null;
return VmUtils.readMember(parent, memberKey);
return VmUtils.readMember(receiver, parent, memberKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@
public final class DelegateToExtraStorageObjOrParentNode extends ExpressionNode {
@Override
public Object executeGeneric(VirtualFrame frame) {
var receiver = (VmObjectLike) VmUtils.getReceiver(frame);
var owner = VmUtils.getOwner(frame);
var delegate = (VmObjectLike) owner.getExtraStorage();
var memberKey = VmUtils.getMemberKey(frame);
var result = VmUtils.readMemberOrNull(delegate, memberKey);
if (result != null) return result;
var parent = owner.getParent();
assert parent != null;
return VmUtils.readMember(parent, memberKey);
return VmUtils.readMember(receiver, parent, memberKey);
}
}
36 changes: 36 additions & 0 deletions pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ public static Object readMember(VmObjectLike receiver, Object memberKey) {
throw new VmExceptionBuilder().cannotFindMember(receiver, memberKey).build();
}

@TruffleBoundary
public static Object readMember(VmObjectLike receiver, VmObjectLike parent, Object memberKey) {
var result = readMemberOrNull(receiver, parent, memberKey);
if (result != null) return result;

throw new VmExceptionBuilder().cannotFindMember(receiver, memberKey).build();
}

@TruffleBoundary
public static @Nullable Object readMemberOrNull(
VmObjectLike receiver, Object memberKey, boolean checkType) {
Expand All @@ -208,6 +216,12 @@ public static Object readMember(VmObjectLike receiver, Object memberKey) {
return readMemberOrNull(receiver, memberKey, true, IndirectCallNode.getUncached());
}

@TruffleBoundary
public static @Nullable Object readMemberOrNull(
VmObjectLike receiver, VmObjectLike parent, Object memberKey) {
return readMemberOrNull(receiver, parent, memberKey, true, IndirectCallNode.getUncached());
}

/**
* Before calling this method, always try `VmObject.getCachedValue()`. (This method writes to the
* cache, but doesn't read from it.)
Expand Down Expand Up @@ -248,6 +262,28 @@ public static Object readMember(
return null;
}

@TruffleBoundary
public static @Nullable Object readMemberOrNull(
VmObjectLike receiver,
VmObjectLike parent,
Object memberKey,
boolean checkType,
IndirectCallNode callNode) {
assert (!(memberKey instanceof Identifier identifier) || !identifier.isLocalProp())
: "Must use ReadLocalPropertyNode for local properties.";

final var cachedValue = receiver.getCachedValue(memberKey);
if (cachedValue != null) return cachedValue;

for (var owner = parent; owner != null; owner = owner.getParent()) {
var member = owner.getMember(memberKey);
if (member == null) continue;
return VmUtils.doReadMember(receiver, owner, memberKey, member, checkType, callNode);
}

return null;
}

/**
* Before calling this method, always try `VmObject.getCachedValue()`. (This method writes to the
* cache, but doesn't read from it.)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
amends "../snippetTest.pkl"

examples {
["toTyped()"] {
pigeonDyn.toTyped(Person)
pigeonMap.toTyped(Person)
}

["toTyped() and amends"] {
(pigeonDyn.toTyped(Person)) { name = "NewPigeon"}
(pigeonMap.toTyped(Person)) { name = "NewPigeon"}
}
}

local class Person {
name: String = "Default"
nick = name
}

local pigeonDyn = new Dynamic {
local n = "Pigeon"
name = n
}

local pigeonMap = Map("name", "Pigeon")
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
examples {
["toTyped()"] {
new {
name = "Pigeon"
nick = "Pigeon"
}
new {
name = "Pigeon"
nick = "Pigeon"
}
}
["toTyped() and amends"] {
new {
name = "NewPigeon"
nick = "NewPigeon"
}
new {
name = "NewPigeon"
nick = "NewPigeon"
}
}
}