Add getOrDefault method to Listing and Mapping (#1053)

This PR adds methods to Listing and Mapping that can be used to retrieve members. If the member for the index/key isn't present, it applies default to the index/key. In both cases, this is essentially sugar for getOrNull(<index/key>) ?? default.apply(<index/key>).

Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
This commit is contained in:
Jen Basch
2025-07-22 15:45:49 -07:00
committed by GitHub
parent 306a3b0fc2
commit 85e4f133a4
7 changed files with 65 additions and 2 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 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.
@@ -18,6 +18,7 @@ package org.pkl.core.stdlib.base;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.LoopNode;
import org.pkl.core.ast.PklNode;
import org.pkl.core.ast.lambda.*;
@@ -62,6 +63,20 @@ public final class ListingNodes {
}
}
public abstract static class getOrDefault extends ExternalMethod1Node {
@Child private IndirectCallNode callNode = IndirectCallNode.create();
@Child private ApplyVmFunction1Node applyNode = ApplyVmFunction1Node.create();
@Specialization
protected Object eval(VmListing self, long index) {
if (index < 0 || index >= self.getLength()) {
var defaultFunction = (VmFunction) VmUtils.readMember(self, Identifier.DEFAULT, callNode);
return applyNode.execute(defaultFunction, index);
}
return VmUtils.readMember(self, index);
}
}
public abstract static class isDistinct extends ExternalPropertyNode {
@Specialization
@TruffleBoundary

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 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.
@@ -19,6 +19,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import java.util.HashSet;
import org.pkl.core.ast.lambda.ApplyVmFunction1Node;
import org.pkl.core.ast.lambda.ApplyVmFunction2Node;
import org.pkl.core.ast.lambda.ApplyVmFunction2NodeGen;
import org.pkl.core.ast.lambda.ApplyVmFunction3Node;
@@ -114,6 +115,22 @@ public final class MappingNodes {
}
}
public abstract static class getOrDefault extends ExternalMethod1Node {
@Child private IndirectCallNode callNode = IndirectCallNode.create();
@Child private ApplyVmFunction1Node applyNode = ApplyVmFunction1Node.create();
@Specialization
protected Object eval(VmMapping self, Object key) {
var value = VmUtils.readMemberOrNull(self, key, callNode);
if (value != null) {
return value;
}
var defaultFunction = (VmFunction) VmUtils.readMember(self, Identifier.DEFAULT, callNode);
return applyNode.execute(defaultFunction, key);
}
}
public abstract static class fold extends ExternalMethod2Node {
@Child private ApplyVmFunction3Node applyLambdaNode = ApplyVmFunction3NodeGen.create();

View File

@@ -29,3 +29,7 @@ res4 = (res3) {
name = "Barn Owl"
}
}
res5 = (res4.getOrDefault(99)) {
name = "Bald Eagle"
}

View File

@@ -38,3 +38,7 @@ res3: Mapping<String, Person> = new {
age = 60
}
}
res4 = (res3.getOrDefault("Bald Eagle")) {
age = 99
}

View File

@@ -38,3 +38,7 @@ res4 {
age = 5
}
}
res5 {
name = "Bald Eagle"
age = 99
}

View File

@@ -32,3 +32,7 @@ res3 {
age = 60
}
}
res4 {
name = "Bald Eagle"
age = 99
}