mirror of
https://github.com/apple/pkl.git
synced 2026-01-11 22:30:54 +01:00
Add methods from List/Map to Listing/Mapping (#683)
* Add `values` to `Mapping` * Add `entries` to `Mapping` * Add `containsValue` to `Mapping` * Add `every` to `Mapping` * Add `any` to `Mapping` * Add `toDynamic` to `Mapping` * Add `lastIndex` to `Listing` * Add `getOrNull` to `Listing` * Add `first` to `Listing` * Add `firstOrNull` to `Listing` * Add `last` to `Listing` * Add `lastOrNull` to `Listing` * Add `single` to `Listing` * Add `singleOrNull` to `Listing` * Add `contains` to `Listing` * Add `any` to `Listing` * Add `every` to `Listing` * Fixup `any` to `Listing` * Revert "Add `toDynamic` to `Mapping`" This reverts commit 5551974ecd8110aa2eb8f546e992c32d3181df9b. * Revert "Add `values` to `Mapping`" This reverts commit 6fc78796 * Revert "Add `entries` to `Mapping`" This reverts commit a7e8dfc4 * Annotate new members with `Since` 0.27 * Fix documentation in `base.pkl` * Add location information to empty/single checks in `Listing` operations * Remove additional variable for laziness preservation * Apply spotless * Apply suggestions from code review Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com> --------- Co-authored-by: Daniel Chao <daniel.h.chao@gmail.com>
This commit is contained in:
committed by
GitHub
parent
71db4d0fae
commit
a03827951c
@@ -15,9 +15,11 @@
|
||||
*/
|
||||
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.LoopNode;
|
||||
import org.pkl.core.ast.PklNode;
|
||||
import org.pkl.core.ast.lambda.*;
|
||||
import org.pkl.core.ast.member.ObjectMember;
|
||||
import org.pkl.core.runtime.*;
|
||||
@@ -44,6 +46,23 @@ public final class ListingNodes {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class lastIndex extends ExternalPropertyNode {
|
||||
@Specialization
|
||||
protected long eval(VmListing self) {
|
||||
return self.getLength() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class getOrNull extends ExternalMethod1Node {
|
||||
@Specialization
|
||||
protected Object eval(VmListing self, long index) {
|
||||
if (index < 0 || index >= self.getLength()) {
|
||||
return VmNull.withoutDefault();
|
||||
}
|
||||
return VmUtils.readMember(self, index);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class isDistinct extends ExternalPropertyNode {
|
||||
@Specialization
|
||||
@TruffleBoundary
|
||||
@@ -89,6 +108,58 @@ public final class ListingNodes {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class first extends ExternalPropertyNode {
|
||||
@Specialization
|
||||
protected Object eval(VmListing self) {
|
||||
checkNonEmpty(self, this);
|
||||
return VmUtils.readMember(self, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class firstOrNull extends ExternalPropertyNode {
|
||||
@Specialization
|
||||
protected Object eval(VmListing self) {
|
||||
if (self.isEmpty()) {
|
||||
return VmNull.withoutDefault();
|
||||
}
|
||||
return VmUtils.readMember(self, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class last extends ExternalPropertyNode {
|
||||
@Specialization
|
||||
protected Object eval(VmListing self) {
|
||||
checkNonEmpty(self, this);
|
||||
return VmUtils.readMember(self, self.getLength() - 1L);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class lastOrNull extends ExternalPropertyNode {
|
||||
@Specialization
|
||||
protected Object eval(VmListing self) {
|
||||
var length = self.getLength();
|
||||
return length == 0 ? VmNull.withoutDefault() : VmUtils.readMember(self, length - 1L);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class single extends ExternalPropertyNode {
|
||||
@Specialization
|
||||
protected Object eval(VmListing self) {
|
||||
checkSingleton(self, this);
|
||||
return VmUtils.readMember(self, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class singleOrNull extends ExternalPropertyNode {
|
||||
@Specialization
|
||||
protected Object eval(VmListing self) {
|
||||
if (self.getLength() != 1) {
|
||||
return VmNull.withoutDefault();
|
||||
}
|
||||
return VmUtils.readMember(self, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class distinctBy extends ExternalMethod1Node {
|
||||
@Child private ApplyVmFunction1Node applyNode = ApplyVmFunction1Node.create();
|
||||
|
||||
@@ -116,6 +187,59 @@ public final class ListingNodes {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class every extends ExternalMethod1Node {
|
||||
@Child private ApplyVmFunction1Node applyNode = ApplyVmFunction1Node.create();
|
||||
|
||||
@Specialization
|
||||
protected boolean eval(VmListing self, VmFunction predicate) {
|
||||
var result = new MutableBoolean(true);
|
||||
self.iterateMemberValues(
|
||||
(key, member, value) -> {
|
||||
if (value == null) {
|
||||
value = VmUtils.readMember(self, key);
|
||||
}
|
||||
result.set(applyNode.executeBoolean(predicate, value));
|
||||
return result.get();
|
||||
});
|
||||
return result.get();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class any extends ExternalMethod1Node {
|
||||
@Child private ApplyVmFunction1Node applyNode = ApplyVmFunction1Node.create();
|
||||
|
||||
@Specialization
|
||||
protected boolean eval(VmListing self, VmFunction predicate) {
|
||||
var result = new MutableBoolean(false);
|
||||
self.iterateMemberValues(
|
||||
(key, member, value) -> {
|
||||
if (value == null) {
|
||||
value = VmUtils.readMember(self, key);
|
||||
}
|
||||
result.set(applyNode.executeBoolean(predicate, value));
|
||||
return !result.get();
|
||||
});
|
||||
return result.get();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class contains extends ExternalMethod1Node {
|
||||
@Specialization
|
||||
protected boolean eval(VmListing self, Object element) {
|
||||
var result = new MutableBoolean(false);
|
||||
self.iterateMemberValues(
|
||||
(key, member, value) -> {
|
||||
if (value == null) {
|
||||
value = VmUtils.readMember(self, key);
|
||||
}
|
||||
result.set(element.equals(value));
|
||||
return !result.get();
|
||||
});
|
||||
LoopNode.reportLoopCount(this, self.getLength());
|
||||
return result.get();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class fold extends ExternalMethod2Node {
|
||||
@Child private ApplyVmFunction2Node applyLambdaNode = ApplyVmFunction2NodeGen.create();
|
||||
|
||||
@@ -194,4 +318,24 @@ public final class ListingNodes {
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkNonEmpty(VmListing self, PklNode node) {
|
||||
if (self.isEmpty()) {
|
||||
CompilerDirectives.transferToInterpreter();
|
||||
throw new VmExceptionBuilder()
|
||||
.evalError("expectedNonEmptyListing")
|
||||
.withLocation(node)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkSingleton(VmListing self, PklNode node) {
|
||||
if (self.getLength() != 1) {
|
||||
CompilerDirectives.transferToInterpreter();
|
||||
throw new VmExceptionBuilder()
|
||||
.evalError("expectedSingleElementListing")
|
||||
.withLocation(node)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ 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.ApplyVmFunction2Node;
|
||||
import org.pkl.core.ast.lambda.ApplyVmFunction2NodeGen;
|
||||
import org.pkl.core.ast.lambda.ApplyVmFunction3Node;
|
||||
import org.pkl.core.ast.lambda.ApplyVmFunction3NodeGen;
|
||||
import org.pkl.core.runtime.*;
|
||||
@@ -27,6 +29,7 @@ import org.pkl.core.stdlib.ExternalMethod1Node;
|
||||
import org.pkl.core.stdlib.ExternalMethod2Node;
|
||||
import org.pkl.core.stdlib.ExternalPropertyNode;
|
||||
import org.pkl.core.util.EconomicMaps;
|
||||
import org.pkl.core.util.MutableBoolean;
|
||||
import org.pkl.core.util.MutableLong;
|
||||
import org.pkl.core.util.MutableReference;
|
||||
|
||||
@@ -86,6 +89,22 @@ public final class MappingNodes {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class containsValue extends ExternalMethod1Node {
|
||||
@Specialization
|
||||
protected boolean eval(VmMapping self, Object value) {
|
||||
var foundValue = new MutableBoolean(false);
|
||||
self.iterateMemberValues(
|
||||
(key, member, memberValue) -> {
|
||||
if (memberValue == null) {
|
||||
memberValue = VmUtils.readMember(self, key);
|
||||
}
|
||||
foundValue.set(value.equals(memberValue));
|
||||
return !foundValue.get();
|
||||
});
|
||||
return foundValue.get();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class getOrNull extends ExternalMethod1Node {
|
||||
@Child private IndirectCallNode callNode = IndirectCallNode.create();
|
||||
|
||||
@@ -110,6 +129,42 @@ public final class MappingNodes {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class every extends ExternalMethod1Node {
|
||||
@Child private ApplyVmFunction2Node applyLambdaNode = ApplyVmFunction2NodeGen.create();
|
||||
|
||||
@Specialization
|
||||
protected boolean eval(VmMapping self, VmFunction function) {
|
||||
var result = new MutableBoolean(true);
|
||||
self.iterateMemberValues(
|
||||
(key, member, value) -> {
|
||||
if (value == null) {
|
||||
value = VmUtils.readMember(self, key);
|
||||
}
|
||||
result.set(applyLambdaNode.executeBoolean(function, key, value));
|
||||
return result.get();
|
||||
});
|
||||
return result.get();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class any extends ExternalMethod1Node {
|
||||
@Child private ApplyVmFunction2Node applyLambdaNode = ApplyVmFunction2NodeGen.create();
|
||||
|
||||
@Specialization
|
||||
protected boolean eval(VmMapping self, VmFunction function) {
|
||||
var result = new MutableBoolean(false);
|
||||
self.iterateMemberValues(
|
||||
(key, member, value) -> {
|
||||
if (value == null) {
|
||||
value = VmUtils.readMember(self, key);
|
||||
}
|
||||
result.set(applyLambdaNode.executeBoolean(function, key, value));
|
||||
return !result.get();
|
||||
});
|
||||
return result.get();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class toMap extends ExternalMethod0Node {
|
||||
@Specialization
|
||||
protected VmMap eval(VmMapping self) {
|
||||
|
||||
@@ -518,6 +518,12 @@ Expected a single-element collection.
|
||||
cannotFlattenCollectionWithNonCollectionElement=\
|
||||
Cannot flatten a collection containing a non-collection element.
|
||||
|
||||
expectedNonEmptyListing=\
|
||||
Expected a non-empty Listing.
|
||||
|
||||
expectedSingleElementListing=\
|
||||
Expected a single-element Listing.
|
||||
|
||||
integerOverflow=\
|
||||
Integer overflow.
|
||||
|
||||
|
||||
@@ -23,6 +23,10 @@ local duplicate: Listing<Person> = (base) {
|
||||
new { name = "Elf Owl" }
|
||||
}
|
||||
|
||||
local altered: Listing<Person> = (base) {
|
||||
[0] { name = "Wood Pigeon" }
|
||||
}
|
||||
|
||||
facts {
|
||||
["isEmpty"] {
|
||||
empty.isEmpty
|
||||
@@ -30,6 +34,14 @@ facts {
|
||||
!base.isEmpty
|
||||
!derived.isEmpty
|
||||
}
|
||||
|
||||
["lastIndex"] {
|
||||
empty.lastIndex == -1
|
||||
empty2.lastIndex == -1
|
||||
base.lastIndex == 2
|
||||
derived.lastIndex == 4
|
||||
duplicate.lastIndex == 5
|
||||
}
|
||||
|
||||
["isDistinct"] {
|
||||
empty.isDistinct
|
||||
@@ -58,6 +70,72 @@ facts {
|
||||
!derived.isDistinctBy((it) -> it.getClass())
|
||||
!duplicate.isDistinctBy((it) -> it.getClass())
|
||||
}
|
||||
|
||||
["getOrNull"] {
|
||||
empty.getOrNull(-1) == null
|
||||
empty.getOrNull(0) == null
|
||||
base.getOrNull(-1) == null
|
||||
for (i, v in base) {
|
||||
base.getOrNull(i) == v
|
||||
}
|
||||
base.getOrNull(base.length) == null
|
||||
}
|
||||
|
||||
["first"] {
|
||||
module.catch(() -> empty.first) == "Expected a non-empty Listing."
|
||||
base.first == base[0]
|
||||
derived.first == base[0]
|
||||
}
|
||||
|
||||
["firstOrNull"] {
|
||||
empty.firstOrNull == null
|
||||
base.firstOrNull == base[0]
|
||||
derived.firstOrNull == base[0]
|
||||
}
|
||||
|
||||
["last"] {
|
||||
module.catch(() -> empty.last) == "Expected a non-empty Listing."
|
||||
base.last == base[2]
|
||||
derived.last == derived[4]
|
||||
}
|
||||
|
||||
["lastOrNull"] {
|
||||
empty.lastOrNull == null
|
||||
base.lastOrNull == base[2]
|
||||
derived.lastOrNull == derived[4]
|
||||
}
|
||||
|
||||
["single"] {
|
||||
module.catch(() -> empty.single) == "Expected a single-element Listing."
|
||||
module.catch(() -> base.single) == "Expected a single-element Listing."
|
||||
new Listing { 42 }.single == 42
|
||||
}
|
||||
|
||||
["singleOrNull"] {
|
||||
empty.singleOrNull == null
|
||||
base.singleOrNull == null
|
||||
new Listing { 42 }.singleOrNull == 42
|
||||
}
|
||||
|
||||
["every"] {
|
||||
!base.every((it) -> it.name.contains("rot"))
|
||||
base.every((it) -> !it.name.isBlank)
|
||||
!((base) { new { name = "EEEEE" } }).every((it) -> it.name.contains("rot"))
|
||||
}
|
||||
|
||||
["any"] {
|
||||
base.any((it) -> it.name.contains("rot"))
|
||||
!base.any((it) -> it.name.contains("inch"))
|
||||
((base) { new { name = "EEEEE" } }).any((it) -> it.name.contains("rot"))
|
||||
}
|
||||
|
||||
["contains"] {
|
||||
!empty.contains(0)
|
||||
base.contains(base[1])
|
||||
derived.contains(base[1])
|
||||
derived.contains(derived[3])
|
||||
!altered.contains(base[0])
|
||||
}
|
||||
}
|
||||
|
||||
examples {
|
||||
|
||||
@@ -57,19 +57,26 @@ facts {
|
||||
!empty.containsKey("default")
|
||||
!empty2.containsKey("Pigeon")
|
||||
}
|
||||
|
||||
|
||||
["containsValue()"] {
|
||||
!empty.containsValue("Any value")
|
||||
for (_, v in derived) {
|
||||
derived.containsValue(v)
|
||||
}
|
||||
}
|
||||
|
||||
["length"] {
|
||||
empty.length == 0
|
||||
base.length == 2
|
||||
derived.length == 3
|
||||
}
|
||||
|
||||
|
||||
["keys (of type string)"] {
|
||||
empty.keys == Set()
|
||||
derived.keys == Set("Pigeon", "Parrot", "Barn Owl")
|
||||
base.keys == Set("Pigeon", "Parrot")
|
||||
}
|
||||
|
||||
|
||||
["keys (of type object)"] {
|
||||
local base2 = new Mapping {
|
||||
[empty] = "one"
|
||||
@@ -82,6 +89,18 @@ facts {
|
||||
base2.keys == Set(empty, base)
|
||||
derived2.keys == Set(empty, base, derived)
|
||||
}
|
||||
|
||||
["every()"] {
|
||||
empty.every((_, _) -> throw("unreachable code"))
|
||||
base.every((k, v) -> k == "Parrot" || v.age > 30)
|
||||
!base.every((k, _) -> k == "Pigeon")
|
||||
}
|
||||
|
||||
["any()"] {
|
||||
base.any((k, _) -> k.contains("rot"))
|
||||
base.any((_, v) -> v.age > 40)
|
||||
!base.any((k, _) -> k.contains("other"))
|
||||
}
|
||||
}
|
||||
|
||||
examples {
|
||||
|
||||
@@ -5,6 +5,13 @@ facts {
|
||||
true
|
||||
true
|
||||
}
|
||||
["lastIndex"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["isDistinct"] {
|
||||
true
|
||||
true
|
||||
@@ -29,6 +36,62 @@ facts {
|
||||
true
|
||||
true
|
||||
}
|
||||
["getOrNull"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["first"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["firstOrNull"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["last"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["lastOrNull"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["single"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["singleOrNull"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["every"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["any"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["contains"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
}
|
||||
examples {
|
||||
["length"] {
|
||||
|
||||
@@ -18,6 +18,12 @@ facts {
|
||||
true
|
||||
true
|
||||
}
|
||||
["containsValue()"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["length"] {
|
||||
true
|
||||
true
|
||||
@@ -32,6 +38,16 @@ facts {
|
||||
true
|
||||
true
|
||||
}
|
||||
["every()"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
["any()"] {
|
||||
true
|
||||
true
|
||||
true
|
||||
}
|
||||
}
|
||||
examples {
|
||||
["getOrNull()"] {
|
||||
|
||||
127
stdlib/base.pkl
127
stdlib/base.pkl
@@ -1813,6 +1813,28 @@ class Listing<out Element> extends Object {
|
||||
/// Tells if this listing is empty, that is, has zero elements.
|
||||
external isEmpty: Boolean
|
||||
|
||||
/// The index of the last element in this listing (same as `length - 1`).
|
||||
///
|
||||
/// Returns `-1` for an empty list.
|
||||
@Since { version = "0.27.0" }
|
||||
external lastIndex: Int
|
||||
|
||||
/// Returns the element at [index].
|
||||
///
|
||||
/// Returns [null] if [index] is outside the bounds of this listing.
|
||||
///
|
||||
/// Facts:
|
||||
/// ```
|
||||
/// new Listing { 3 ; 9 ; 6 }.getOrNull(0) == 3
|
||||
/// new Listing { 3 ; 9 ; 6 }.getOrNull(1) == 9
|
||||
/// new Listing { 3 ; 9 ; 6 }.getOrNull(2) == 6
|
||||
/// new Listing { 3 ; 9 ; 6 }.getOrNull(-1) == null
|
||||
/// new Listing { 3 ; 9 ; 6 }.getOrNull(3) == null
|
||||
/// new Listing { 3 ; 9 ; 6 }.getOrNull(99) == null
|
||||
/// ```
|
||||
@Since { version = "0.27.0" }
|
||||
external function getOrNull(index: Int): Element?
|
||||
|
||||
/// Tells if this listing has no duplicate elements.
|
||||
///
|
||||
/// Facts:
|
||||
@@ -1843,6 +1865,55 @@ class Listing<out Element> extends Object {
|
||||
@AlsoKnownAs { names { "unique" } }
|
||||
external distinct: Listing<Element>
|
||||
|
||||
/// The first element in this listing.
|
||||
///
|
||||
/// Throws if this listing is empty.
|
||||
///
|
||||
/// Facts:
|
||||
/// ```
|
||||
/// new Listing { 1 ; 2 ; 3 }.first == 1
|
||||
/// import("pkl:test").catch(() -> new Listing {}.first)
|
||||
/// ```
|
||||
@Since { version = "0.27.0" }
|
||||
external first: Element
|
||||
|
||||
/// Same as [first] but returns [null] if this listing is empty.
|
||||
@Since { version = "0.27.0" }
|
||||
external firstOrNull: Element?
|
||||
|
||||
/// The last element in this listing.
|
||||
///
|
||||
/// Throws if this listing is empty.
|
||||
///
|
||||
/// Facts:
|
||||
/// ```
|
||||
/// new Listing { 1 ; 2 ; 3 }.last == 3
|
||||
/// import("pkl:test").catch(() -> new Listing {}.last)
|
||||
/// ```
|
||||
@Since { version = "0.27.0" }
|
||||
external last: Element
|
||||
|
||||
/// Same as [last] but returns [null] if this listing is empty.
|
||||
@Since { version = "0.27.0" }
|
||||
external lastOrNull: Element?
|
||||
|
||||
/// The single element in this listing.
|
||||
///
|
||||
/// Throws if this listing does not have exactly one element.
|
||||
///
|
||||
/// Facts:
|
||||
/// ```
|
||||
/// new Listing { 1 }.single == 1
|
||||
/// import("pkl:test").catch(() -> new Listing {}.single)
|
||||
/// import("pkl:test").catch(() -> new Listing { 1 ; 2 ; 3 }.single)
|
||||
/// ```
|
||||
@Since { version = "0.27.0" }
|
||||
external single: Element
|
||||
|
||||
/// Same as [single] but returns [null] if this collection is empty or has more than one element.
|
||||
@Since { version = "0.27.0" }
|
||||
external singleOrNull: Element?
|
||||
|
||||
/// Removes elements that are duplicates after applying [selector] from this listing, preserving the first occurrence.
|
||||
///
|
||||
/// Facts:
|
||||
@@ -1853,6 +1924,30 @@ class Listing<out Element> extends Object {
|
||||
@AlsoKnownAs { names { "uniqueBy" } }
|
||||
external function distinctBy(selector: (Element) -> Any): Listing<Element>
|
||||
|
||||
/// Tells if [predicate] holds for every element of this listing.
|
||||
///
|
||||
/// Returns [true] for an empty listing.
|
||||
@Since { version = "0.27.0" }
|
||||
external function every(predicate: (Element) -> Boolean): Boolean
|
||||
|
||||
/// Tells if [predicate] holds for at least one element of this listing.
|
||||
///
|
||||
/// Returns [false] for an empty listing.
|
||||
@Since { version = "0.27.0" }
|
||||
external function any(predicate: (Element) -> Boolean): Boolean
|
||||
|
||||
/// Tests if [element] is contained in this listing.
|
||||
///
|
||||
/// Facts:
|
||||
/// ```
|
||||
/// new Listing { 1 ; 2 ; 3 }.contains(1)
|
||||
/// new Listing { 1 ; 2 ; 3 }.contains(2)
|
||||
/// new Listing { 1 ; 2 ; 3 }.contains(3)
|
||||
/// !new Listing { 1 ; 2 ; 3 }.contains(4)
|
||||
/// ```
|
||||
@Since { version = "0.27.0" }
|
||||
external function contains(element: Element): Boolean
|
||||
|
||||
/// Folds this listing in iteration order using [operator], starting with [initial].
|
||||
external function fold<Result>(initial: Result, operator: (Result, Element) -> Result): Result
|
||||
|
||||
@@ -1893,6 +1988,10 @@ class Mapping<out Key, out Value> extends Object {
|
||||
|
||||
/// Tells if this mapping contains [key].
|
||||
external function containsKey(key: Any): Boolean
|
||||
|
||||
/// Tells if this mapping contains an entry with the given [value].
|
||||
@Since { version = "0.27.0" }
|
||||
external function containsValue(value: Any): Boolean
|
||||
|
||||
/// Returns the value associated with [key] or [null] if this mapping does not contain [key].
|
||||
///
|
||||
@@ -1901,6 +2000,18 @@ class Mapping<out Key, out Value> extends Object {
|
||||
|
||||
/// Folds the entries of this mapping in iteration order using [operator], starting with [initial].
|
||||
external function fold<Result>(initial: Result, operator: (Result, Key, Value) -> Result): Result
|
||||
|
||||
/// Tells if [predicate] holds for every entry of this mapping.
|
||||
///
|
||||
/// Returns [true] for an empty mapping.
|
||||
@Since { version = "0.27.0" }
|
||||
external function every(predicate: (Key, Value) -> Boolean): Boolean
|
||||
|
||||
/// Tells if [predicate] holds for at least one entry of this mapping.
|
||||
///
|
||||
/// Returns [false] for an empty mapping.
|
||||
@Since { version = "0.27.0" }
|
||||
external function any(predicate: (Key, Value) -> Boolean): Boolean
|
||||
|
||||
/// Converts this mapping to a [Map].
|
||||
external function toMap(): Map<Key, Value>
|
||||
@@ -2035,7 +2146,7 @@ abstract external class Collection<out Element> extends Any {
|
||||
/// Facts:
|
||||
/// ```
|
||||
/// List(1, 2, 3).first == 1
|
||||
/// (import "pkl:test").catch(() -> List().first)
|
||||
/// import("pkl:test").catch(() -> List().first)
|
||||
/// ```
|
||||
@AlsoKnownAs { names { "head" } }
|
||||
abstract first: Element
|
||||
@@ -2051,7 +2162,7 @@ abstract external class Collection<out Element> extends Any {
|
||||
/// Facts:
|
||||
/// ```
|
||||
/// List(1, 2, 3).rest == List(2, 3)
|
||||
/// (import "pkl:test").catch(() -> List().rest)
|
||||
/// import("pkl:test").catch(() -> List().rest)
|
||||
/// ```
|
||||
@AlsoKnownAs { names { "tail" } }
|
||||
abstract rest: Collection<Element>
|
||||
@@ -2067,7 +2178,7 @@ abstract external class Collection<out Element> extends Any {
|
||||
/// Facts:
|
||||
/// ```
|
||||
/// List(1, 2, 3).last == 3
|
||||
/// (import "pkl:test").catch(() -> List().last)
|
||||
/// import("pkl:test").catch(() -> List().last)
|
||||
/// ```
|
||||
abstract last: Element
|
||||
|
||||
@@ -2140,7 +2251,7 @@ abstract external class Collection<out Element> extends Any {
|
||||
/// ```
|
||||
/// List(1, 2, 3).indexOf(2) == 1
|
||||
/// List(1, 2, 2).indexOf(2) == 1
|
||||
/// (import "pkl:test").catch(() -> List(1, 2, 3).indexOf(4))
|
||||
/// import("pkl:test").catch(() -> List(1, 2, 3).indexOf(4))
|
||||
/// ```
|
||||
abstract function indexOf(element: Any): Int
|
||||
|
||||
@@ -2155,7 +2266,7 @@ abstract external class Collection<out Element> extends Any {
|
||||
/// ```
|
||||
/// List(1, 2, 3).lastIndexOf(2) == 1
|
||||
/// List(1, 2, 2).lastIndexOf(2) == 2
|
||||
/// (import "pkl:test").catch(() -> List(1, 2, 3).lastIndexOf(4))
|
||||
/// import("pkl:test").catch(() -> List(1, 2, 3).lastIndexOf(4))
|
||||
/// ```
|
||||
abstract function lastIndexOf(element: Any): Int
|
||||
|
||||
@@ -2170,7 +2281,7 @@ abstract external class Collection<out Element> extends Any {
|
||||
/// ```
|
||||
/// List(5, 6, 7).find((n) -> n.isEven) == 6
|
||||
/// List(4, 6, 7).find((n) -> n.isEven) == 4
|
||||
/// (import "pkl:test").catch(() -> List(5, 7, 9).find((n) -> n.isEven))
|
||||
/// import("pkl:test").catch(() -> List(5, 7, 9).find((n) -> n.isEven))
|
||||
/// ```
|
||||
abstract function find(predicate: (Element) -> Boolean): Element
|
||||
|
||||
@@ -2200,7 +2311,7 @@ abstract external class Collection<out Element> extends Any {
|
||||
/// ```
|
||||
/// List(5, 6, 7).findIndex((n) -> n.isEven) == 1
|
||||
/// List(4, 6, 8).findIndex((n) -> n.isEven) == 0
|
||||
/// (import "pkl:test").catch(() -> List(5, 7, 9).findLast((n) -> n.isEven))
|
||||
/// import("pkl:test").catch(() -> List(5, 7, 9).findLast((n) -> n.isEven))
|
||||
/// ```
|
||||
@AlsoKnownAs { names { "indexWhere" }}
|
||||
abstract function findIndex(predicate: (Element) -> Boolean): Int
|
||||
@@ -2217,7 +2328,7 @@ abstract external class Collection<out Element> extends Any {
|
||||
/// ```
|
||||
/// List(5, 6, 7).findLastIndex((n) -> n.isEven) == 1
|
||||
/// List(4, 6, 8).findLastIndex((n) -> n.isEven) == 2
|
||||
/// (import "pkl:test").catch(() -> List(5, 7, 9).findLastIndex((n) -> n.isEven))
|
||||
/// import("pkl:test").catch(() -> List(5, 7, 9).findLastIndex((n) -> n.isEven))
|
||||
/// ```
|
||||
@AlsoKnownAs { names { "lastIndexWhere" }}
|
||||
abstract function findLastIndex(predicate: (Element) -> Boolean): Int
|
||||
|
||||
Reference in New Issue
Block a user