mirror of
https://github.com/apple/pkl.git
synced 2026-01-11 14:20:35 +01:00
3692 lines
121 KiB
Plaintext
3692 lines
121 KiB
Plaintext
//===----------------------------------------------------------------------===//
|
|
// 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.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Fundamental properties, methods, and classes for writing Pkl programs.
|
|
///
|
|
/// Members of this module are automatically available in every Pkl module.
|
|
@ModuleInfo { minPklVersion = "0.31.0" }
|
|
module pkl.base
|
|
|
|
// math import used for doc comments
|
|
import "pkl:jsonnet"
|
|
import "pkl:math"
|
|
import "pkl:pklbinary"
|
|
import "pkl:protobuf"
|
|
import "pkl:xml"
|
|
|
|
/// The top type of the type hierarchy.
|
|
///
|
|
/// Every type is a subtype of [Any].
|
|
///
|
|
/// The following operators are supported for all values:
|
|
///
|
|
/// ```
|
|
/// value1 == value2 // equality
|
|
/// value1 != value2 // inequality
|
|
/// value.member // member access
|
|
/// value?.member // conditional member access; returns `value.member` if `value` is non-null and `null` otherwise
|
|
/// value ?? default // null coalescing; returns `value` if `value` is non-null and `default` otherwise
|
|
/// value!! // non-null assertion; throws if `value` is `null`, and returns `value` otherwise
|
|
/// value is String // type test
|
|
/// value as String // type cast; throws an error unless `value is String`
|
|
/// ```
|
|
abstract external class Any {
|
|
/// Returns the class of [this].
|
|
external function getClass(): Class
|
|
|
|
/// Returns a string representation of [this].
|
|
///
|
|
/// This method is used to convert the values of string interpolation expressions to strings.
|
|
external function toString(): String
|
|
|
|
/// Returns `this |> transform` if [this] is non-null, and [null] otherwise.
|
|
///
|
|
/// This method is the complement of the `??` operator and the equivalent of an `Option` type's
|
|
/// `map` and `flatMap` methods.
|
|
external function ifNonNull<Result>(transform: (NonNull) -> Result): Result?
|
|
}
|
|
|
|
/// The type of [null] and null values created with [Null()].
|
|
///
|
|
/// All null values are pairwise equal according to `==`.
|
|
external class Null extends Any
|
|
|
|
/// A non-null value.
|
|
typealias NonNull = Any(!(this is Null))
|
|
|
|
/// The runtime representation of a class.
|
|
external class Class<out Type> extends Any {
|
|
/// The unqualified name of this class.
|
|
external simpleName: String
|
|
}
|
|
|
|
/// The runtime representation of a type alias.
|
|
external class TypeAlias extends Any
|
|
|
|
/// Base class for modules.
|
|
abstract external class Module {
|
|
/// Returns the relative, descendent directory path between this module and [other].
|
|
///
|
|
/// Throws if no such path exists.
|
|
///
|
|
/// For example, if module `mod1` has path `/dir1/mod1.pkl`, and module `mod2` has path
|
|
/// `/dir1/dir2/dir3/mod2.pkl`, then `mod1.relativePathTo(mod2)` will return
|
|
/// `List("dir2", "dir3")`.
|
|
///
|
|
/// A common use case is to compute the directory path between a template located at the root of a
|
|
/// hierarchy (say `rootModule.pkl`) and the currently evaluated module (accessible via the
|
|
/// `module` keyword):
|
|
/// ```
|
|
/// import "rootModule.pkl" // self-import
|
|
/// path = rootModule.relativePathTo(module)
|
|
/// ```
|
|
external function relativePathTo(other: Module): List<String>
|
|
|
|
/// The output of this module.
|
|
///
|
|
/// Defaults to all module properties rendered as either Pcf or the format specified on the
|
|
/// command line.
|
|
hidden output: ModuleOutput = new {
|
|
value = outer
|
|
renderer =
|
|
let (format = read?("prop:pkl.outputFormat") ?? "pcf")
|
|
if (format == "json")
|
|
new JsonRenderer {}
|
|
else if (format == "jsonnet")
|
|
new jsonnet.Renderer {}
|
|
else if (format == "pcf")
|
|
new PcfRenderer {}
|
|
else if (format == "plist")
|
|
new PListRenderer {}
|
|
else if (format == "properties")
|
|
new PropertiesRenderer {}
|
|
else if (format == "textproto")
|
|
new protobuf.Renderer {}
|
|
else if (format == "xml")
|
|
new xml.Renderer {}
|
|
else if (format == "yaml")
|
|
new YamlRenderer {}
|
|
else if (format == "pkl-binary")
|
|
new pklbinary.Renderer {}
|
|
else
|
|
throw(
|
|
"Unknown output format: `\(format)`. Supported formats are `json`, `jsonnet`, `pcf`, `plist`, `properties`, `textproto`, `xml`, `yaml`, `pkl-binary`."
|
|
)
|
|
text =
|
|
if (renderer is ValueRenderer)
|
|
renderer.renderDocument(value)
|
|
else
|
|
throw("Unable to render text when renderer is a BytesRenderer")
|
|
bytes =
|
|
if (renderer is BytesRenderer) renderer.renderDocument(value) else text.encodeToBytes("UTF-8")
|
|
}
|
|
}
|
|
|
|
/// Base class for annotation types.
|
|
abstract class Annotation
|
|
|
|
/// Indicates that the annotated member was introduced in [version].
|
|
class Since extends Annotation {
|
|
/// The version that the annotated member was introduced in.
|
|
version: String
|
|
}
|
|
|
|
/// Indicates that the annotated member is deprecated and will likely be removed in the future.
|
|
class Deprecated extends Annotation {
|
|
/// The version in which the annotated member became deprecated.
|
|
since: String?
|
|
|
|
/// A message explaining how to deal with the deprecation.
|
|
///
|
|
/// The message may contain member links, should end with a period, and should not contain line
|
|
/// breaks.
|
|
///
|
|
/// Example: `"Use [String.codePoints] instead."`
|
|
message: String?
|
|
|
|
/// The code fragment to replace usages of the deprecated member with.
|
|
///
|
|
/// Setting this property instructs tools to automatically replace usages of the deprecated
|
|
/// member.
|
|
/// For human instructions, use [message].
|
|
///
|
|
/// Examples:
|
|
/// ```
|
|
/// // replace usages of a deprecated class or type alias with `Inventory`
|
|
/// replaceWith = "Inventory"
|
|
/// // replace usages of a deprecated property or method with `inventory`
|
|
/// replaceWith = "inventory"
|
|
/// // replace usages of a deprecated property or method with `store.inventory`
|
|
/// // and an import of `store`, which must resolve to an import of the current module
|
|
/// replaceWith = "store.inventory"
|
|
/// // replace usages of a deprecated property or method with `order(42)`
|
|
/// replaceWith = "order(42)"
|
|
/// // replace usages of a deprecated method (that has a parameter named `amount`) with `order(amount)`
|
|
/// replaceWith = "order(amount)"
|
|
/// ```
|
|
@SourceCode { language = "PklExpr" }
|
|
replaceWith: String?
|
|
}
|
|
|
|
/// Lists alternative names that the annotated member is known under.
|
|
///
|
|
/// The alternative names will be included in Pkldoc's search index.
|
|
class AlsoKnownAs extends Annotation {
|
|
/// The alternative names for the annotated member.
|
|
names: Listing<String>
|
|
}
|
|
|
|
/// Indicates that the annotated member should not be advertised by Pkldoc and other tools.
|
|
class Unlisted extends Annotation
|
|
|
|
/// Indicates to Pkldoc that the annotated module is an example for how to use [subjects].
|
|
class DocExample extends Annotation {
|
|
/// The fully qualified names of the modules that are the subjects of the example.
|
|
subjects: Listing<String>
|
|
}
|
|
|
|
/// Indicates that the annotated property's string value contains source code written in [language].
|
|
class SourceCode extends Annotation {
|
|
/// The language that the source code is written in.
|
|
///
|
|
/// Examples:
|
|
/// - `"x = 42"` is valid source code for language `"Pkl"`.
|
|
/// - `"42"` is valid source code for language `"PklExpr"`.
|
|
/// - `"42"` is valid source code for language `"Pkl"` with [prefix] `"x = "`.
|
|
language: "Go"
|
|
| "HTML"
|
|
| "Java"
|
|
| "JavaScript"
|
|
| "Markdown"
|
|
| "Pkl"
|
|
| "PklExpr"
|
|
| "Python"
|
|
| "Ruby"
|
|
| "SQL"
|
|
| "Swift"
|
|
| String
|
|
|
|
/// A source code prefix to help tools understand the source code.
|
|
///
|
|
/// For example, an expression may not be considered valid unless wrapped in a statement.
|
|
prefix: String?
|
|
|
|
/// A source code suffix to help tools understand the source code.
|
|
///
|
|
/// For example, an expression may not be considered valid unless wrapped in a statement.
|
|
suffix: String?
|
|
}
|
|
|
|
/// Metadata for a module.
|
|
///
|
|
/// To annotate a module, place the annotation
|
|
/// before the `module`, `amends`, or `extends` keyword, whichever comes first.
|
|
///
|
|
/// ```
|
|
/// @ModuleInfo { minPklVersion = "1.2.3"; author = "author@apple.com" }
|
|
/// module myModule
|
|
/// ```
|
|
///
|
|
/// All library modules should have a [ModuleInfo] annotation.
|
|
class ModuleInfo extends Annotation {
|
|
/// The minimum Pkl version required by this module.
|
|
///
|
|
/// The expected format is `"major.minor.patch"`.
|
|
///
|
|
/// This version constraint is enforced by the Pkl runtime.
|
|
minPklVersion: String(matches(Regex(#"\d{1,2}\.\d{1,2}\.\d{1,2}"#)))
|
|
}
|
|
|
|
/// A representation of a rendered output.
|
|
open class FileOutput {
|
|
/// The value to render.
|
|
value: Any?
|
|
|
|
/// The renderer for [value].
|
|
renderer: BaseValueRenderer = new PcfRenderer {}
|
|
|
|
/// The textual rendered output.
|
|
text: String =
|
|
if (renderer is ValueRenderer)
|
|
renderer.renderDocument(value)
|
|
else
|
|
throw("unabled to render text when renderer is a BytesRenderer")
|
|
|
|
/// The underlying byte output.
|
|
///
|
|
/// If unset, defaults to the UTF-8 encoding of [text].
|
|
@Since { version = "0.29.0" }
|
|
bytes: Bytes =
|
|
if (renderer is BytesRenderer) renderer.renderDocument(value) else text.encodeToBytes("UTF-8")
|
|
}
|
|
|
|
/// The contents and appearance of a module's output.
|
|
class ModuleOutput extends FileOutput {
|
|
/// The files to be produced by this module when rendering in multiple file output mode.
|
|
///
|
|
/// Keys determine file paths, and may include subdirectories.
|
|
/// [FileOutput.text] determines file contents.
|
|
///
|
|
/// Example:
|
|
/// ```
|
|
/// output {
|
|
/// files {
|
|
/// ["foo/bar.yml"] {
|
|
/// value = new { bar = "bar" }
|
|
/// renderer = new YamlRenderer {}
|
|
/// }
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// A file can be set to the `output` of another module.
|
|
/// For example:
|
|
/// ```
|
|
/// output {
|
|
/// files {
|
|
/// ["foo.yml"] = import("foo.pkl").output
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
files: Mapping<String, FileOutput>?
|
|
}
|
|
|
|
/// Base class for rendering Pkl values in some output format.
|
|
@Since { version = "0.30.0" }
|
|
abstract class BaseValueRenderer {
|
|
/// Value converters to apply before values are rendered.
|
|
///
|
|
/// A value converter is a function that converts a value to another value
|
|
/// immediately before the value is rendered (and after the value has been type-checked).
|
|
/// The converted value is then rendered by the renderer's hardwired rendering logic.
|
|
///
|
|
/// When a converter returns a value of type [Object], [Collection], [Map], or [Pair],
|
|
/// converters are recursively applied to the returned value's components (object properties,
|
|
/// list elements, etc.).
|
|
///
|
|
/// At most one converter is applied per value.
|
|
/// If multiple converters are applicable, a winner is chosen as follows:
|
|
/// - A converter with [String] key wins over a converter with [Class] key.
|
|
/// - Between multiple [String] key converters, the converter defined earlier
|
|
/// (according to the mapping's definition order) wins.
|
|
/// - Between multiple [Class] key converters, the most specific class (according to class
|
|
/// hierarchy) wins.
|
|
///
|
|
/// A converter's key specifies which values the converter should be applied to.
|
|
/// A converter with [Class] key is applied to values of that class, including values of its
|
|
/// subclasses.
|
|
/// A converter with [String] key is applied to values whose path matches the *path spec*
|
|
/// described by the string.
|
|
///
|
|
/// Path specs can have the following components:
|
|
/// - `^` matches the top-level value passed to `renderDocument()` or `renderValue()` (often the
|
|
/// module object)
|
|
/// - `pigeon` matches property `pigeon` at any hierarchy level
|
|
/// - `[pigeon]` matches map(ping) entry with String key `"pigeon"` at any hierarchy level
|
|
/// - `*` matches any property
|
|
/// - `[*]` matches any list(ing) element or map(ping) entry
|
|
///
|
|
/// Here are some examples of valid property paths:
|
|
/// - `"server"`
|
|
/// - `"server.timeout"`
|
|
/// - `"^server.timeout"` (matches `server.timeout`, but not `racks[12345].server.timeout`)
|
|
/// - `"racks[12345].server"`
|
|
/// - `"racks[*].server`
|
|
///
|
|
/// Paths are matched against path specs component-wise in reverse order.
|
|
/// For example, paths `server.timeout` and `racks[*].server.timeout`
|
|
/// both match path spec `server.timeout`, whereas path `server.timeout.millis` does not.
|
|
converters: Mapping<Class | String, (unknown) -> Any>
|
|
|
|
/// The file extension associated with this output format,
|
|
/// or [null] if this format does not have an extension.
|
|
extension: String?
|
|
}
|
|
|
|
/// Base class for rendering Pkl values in some textual output format.
|
|
///
|
|
/// A renderer's output is guaranteed to be well-formed unless [RenderDirective] is part of the
|
|
/// input.
|
|
abstract class ValueRenderer extends BaseValueRenderer {
|
|
/// Renders [value] as a complete document.
|
|
///
|
|
/// Some renderers impose restrictions on which types of values can be rendered as document.
|
|
///
|
|
/// A typical implementation of this method renders a document header/footer
|
|
/// and otherwise delegates to [renderValue()].
|
|
abstract function renderDocument(value: Any): String
|
|
|
|
/// Renders [value].
|
|
abstract function renderValue(value: Any): String
|
|
}
|
|
|
|
/// Base class for rendering Pkl values in some binary output format.
|
|
///
|
|
/// A renderer's output is guaranteed to be well-formed unless [RenderDirective] is part of the
|
|
/// input.
|
|
@Since { version = "0.30.0" }
|
|
abstract class BytesRenderer extends BaseValueRenderer {
|
|
/// Renders [value] as a complete document.
|
|
///
|
|
/// Some renderers impose restrictions on which types of values can be rendered as document.
|
|
///
|
|
/// A typical implementation of this method renders a document header/footer
|
|
/// and otherwise delegates to [renderValue()].
|
|
abstract function renderDocument(value: Any): Bytes
|
|
|
|
/// Renders [value].
|
|
abstract function renderValue(value: Any): Bytes
|
|
}
|
|
|
|
/// Renders values as Pcf, a static subset of Pkl.
|
|
class PcfRenderer extends ValueRenderer {
|
|
extension = "pcf"
|
|
|
|
/// The characters to use for indenting output.
|
|
/// Defaults to two spaces.
|
|
indent: String = " "
|
|
|
|
/// Whether to skip rendering properties whose value is [null].
|
|
omitNullProperties: Boolean = false
|
|
|
|
/// Whether to use custom string delimiters for string values.
|
|
///
|
|
/// If [true], custom string delimiters (such as `#"..."#`) are preferred
|
|
/// over escaping quotes and backslashes.
|
|
useCustomStringDelimiters: Boolean = false
|
|
|
|
external function renderDocument(value: Any): String
|
|
|
|
external function renderValue(value: Any): String
|
|
}
|
|
|
|
/// Directs a [ValueRenderer] to output [text] as-is in place of this directive.
|
|
///
|
|
/// [RenderDirective] is an escape hatch for exceptional cases.
|
|
/// It gives full control over how a value is rendered
|
|
/// without having to manipulate `output.text` as a whole.
|
|
/// It is the user's responsibility to ensure that the resulting output is well-formed.
|
|
///
|
|
/// Example:
|
|
/// ```
|
|
/// name = "Pigeon"
|
|
/// hobby = "singing"
|
|
///
|
|
/// output {
|
|
/// renderer = new JsonRenderer {
|
|
/// converters {
|
|
/// // render String values without quotes (not valid JSON)
|
|
/// [String] = (str) -> new RenderDirective { text = str }
|
|
/// }
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// Output:
|
|
/// ```
|
|
/// {
|
|
/// "name": Pigeon
|
|
/// "hobby": singing
|
|
/// }
|
|
/// ```
|
|
class RenderDirective {
|
|
/// The text to output as-is (without escaping or quoting).
|
|
text: String
|
|
|
|
/// The bytes to output as-is (without escaping or quoting).
|
|
///
|
|
/// Only used by [BytesRenderer], ignored by [ValueRenderer].
|
|
@Since { version = "0.30.0" }
|
|
bytes: Bytes = text.encodeToBytes("UTF-8")
|
|
}
|
|
|
|
/// Directs [PcfRenderer] to output additional text [before] and/or [after] rendering a [value].
|
|
class PcfRenderDirective {
|
|
/// The text to output before rendering [value].
|
|
before: String?
|
|
|
|
/// The value to render.
|
|
value: Any
|
|
|
|
/// The text to output after rendering [value].
|
|
after: String?
|
|
}
|
|
|
|
/// Renders values as JSON.
|
|
class JsonRenderer extends ValueRenderer {
|
|
extension = "json"
|
|
|
|
/// The characters to use for indenting output.
|
|
indent: String = " "
|
|
|
|
/// Whether to omit JSON object fields whose value is `null`.
|
|
omitNullProperties: Boolean = true
|
|
|
|
/// Renders [value] as a JSON document.
|
|
///
|
|
/// Every JSON value is a valid JSON document.
|
|
external function renderDocument(value: Any): String
|
|
|
|
external function renderValue(value: Any): String
|
|
}
|
|
|
|
/// Renders values as YAML.
|
|
///
|
|
/// To render a YAML stream, set [isStream] to [true].
|
|
class YamlRenderer extends ValueRenderer {
|
|
extension = "yaml"
|
|
|
|
/// The YAML version used by consumers of the rendered documents.
|
|
///
|
|
/// - `"compat"` - YAML 1.1 _or_ 1.2 (default)
|
|
/// - `"1.1"` - YAML 1.1
|
|
/// - `"1.2"` - YAML 1.2 (Core schema)
|
|
///
|
|
/// At present, the mode only affects which String values are quoted in YAML.
|
|
/// For example, `x = "yes"` is rendered as `x: 'yes'` in modes `"compat"` and `"1.1"`,
|
|
/// and as `x: yes` in mode `"1.2"`.
|
|
mode: "compat" | "1.1" | "1.2" = "compat"
|
|
|
|
/// The number of spaces to use for indenting output.
|
|
indentWidth: Int(this > 1) = 2
|
|
|
|
/// Whether to skip rendering properties whose value is [null].
|
|
omitNullProperties: Boolean = true
|
|
|
|
/// If [true], [renderDocument] expects an argument of type [Listing] or [Collection]
|
|
/// and renders it as YAML stream.
|
|
isStream: Boolean = false
|
|
|
|
/// Renders [value] as a YAML document.
|
|
///
|
|
/// Every YAML value is a valid YAML document.
|
|
external function renderDocument(value: Any): String
|
|
|
|
/// Renders [value] as YAML value.
|
|
external function renderValue(value: Any): String
|
|
}
|
|
|
|
/// Renders values as
|
|
/// [XML property lists](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/PropertyLists/UnderstandXMLPlist/UnderstandXMLPlist.html).
|
|
///
|
|
/// XML property lists do not support [null] values.
|
|
/// This renderer handles [null] values as follows:
|
|
/// - Object and map properties whose value is [null] are skipped.
|
|
/// - [null] values occurring in a list or set result in an error.
|
|
class PListRenderer extends ValueRenderer {
|
|
extension = "plist"
|
|
|
|
/// The characters to use for indenting output.
|
|
indent: String = " "
|
|
|
|
external function renderDocument(value: Any): String
|
|
|
|
external function renderValue(value: Any): String
|
|
}
|
|
|
|
/// Renders values as
|
|
/// [Java Properties](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html).
|
|
///
|
|
/// Pkl object properties and keys of type [Boolean], [String], [Int], and [Float]
|
|
/// are flattened into dot-separated Java property keys.
|
|
///
|
|
/// Pkl values of type [Boolean], [String], [Int], and [Float] are rendered as Java property values.
|
|
///
|
|
/// To render Pkl values of other types, convert them to one of the above types with [converters].
|
|
///
|
|
/// Example:
|
|
/// ```
|
|
/// person {
|
|
/// name = "Pigeon"
|
|
/// age = 42
|
|
/// hobbies = List("surfing", "fire making")
|
|
/// }
|
|
///
|
|
/// output {
|
|
/// renderer = new PropertiesRenderer {
|
|
/// converters {
|
|
/// // render lists as comma-separated values
|
|
/// [List] = (it) -> it.join(",")
|
|
/// }
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// The above example produces the following output:
|
|
/// ```
|
|
/// person.name = Pigeon
|
|
/// person.age = 42
|
|
/// person.hobbies = surfing,fire making
|
|
/// ```
|
|
class PropertiesRenderer extends ValueRenderer {
|
|
extension = "properties"
|
|
|
|
/// Whether to skip rendering properties whose value is [null].
|
|
omitNullProperties: Boolean = true
|
|
|
|
/// Whether to render characters outside the printable US-ASCII charset range as
|
|
/// [Unicode escapes](https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.3).
|
|
restrictCharset: Boolean = false
|
|
|
|
external function renderDocument(value: Any): String
|
|
|
|
external function renderValue(value: Any): String
|
|
}
|
|
|
|
/// An external (file, HTTP, etc.) resource.
|
|
///
|
|
/// Usually, a [Resource] is obtained via a `read()` expression, such as `read("some/file")`.
|
|
///
|
|
/// When created directly, either of [bytes] or [base64] can be set, and the other will be
|
|
/// computed in terms of the set value.
|
|
class Resource {
|
|
/// The URI of this resource.
|
|
uri: Uri
|
|
|
|
/// The text content of this resource.
|
|
text: String
|
|
|
|
/// The content of this resource in Base64 encoding.
|
|
base64: String = bytes.base64
|
|
|
|
/// The bytes of this resource.
|
|
@Since { version = "0.29.0" }
|
|
hidden bytes: Bytes = base64.base64DecodedBytes
|
|
|
|
/// The [MD5](https://en.wikipedia.org/wiki/MD5)
|
|
/// hash of this resource as hexadecimal string.
|
|
///
|
|
/// MD5 is cryptographically broken and should not be used for secure applications.
|
|
@Deprecated { since = "0.29.0"; message = "Use bytes.md5 instead" }
|
|
hidden fixed md5: String = bytes.md5
|
|
|
|
/// The [SHA-1](https://en.wikipedia.org/wiki/SHA-1)
|
|
/// hash of this resource as hexadecimal string.
|
|
///
|
|
/// SHA-1 is cryptographically broken and should not be used for secure applications.
|
|
@Deprecated { since = "0.29.0"; message = "Use bytes.sha1 instead" }
|
|
hidden fixed sha1: String = bytes.sha1
|
|
|
|
/// The [SHA-256](https://en.wikipedia.org/wiki/SHA-2)
|
|
/// cryptographic hash of this resource as hexadecimal string.
|
|
@Deprecated { since = "0.29.0"; message = "Use bytes.sha256 instead" }
|
|
hidden fixed sha256: String = bytes.sha256
|
|
|
|
/// The first 64 bits of the [SHA-256](https://en.wikipedia.org/wiki/SHA-2)
|
|
/// cryptographic hash of this resource.
|
|
@Deprecated { since = "0.29.0"; message = "Use bytes.sha256Int instead" }
|
|
hidden fixed sha256Int: Int = bytes.sha256Int
|
|
}
|
|
|
|
/// Common base class of [Int] and [Float].
|
|
///
|
|
/// ## Arithmetic Operators
|
|
/// ```
|
|
/// -a // negation
|
|
/// a + b // addition
|
|
/// a - b // subtraction
|
|
/// a * b // multiplication
|
|
/// a / b // division
|
|
/// a ~/ b // integer division
|
|
/// a % b // remainder
|
|
/// a ** b // exponentiation
|
|
/// ```
|
|
///
|
|
/// ## Comparison Operators
|
|
/// ```
|
|
/// a == b // equality
|
|
/// a != b // inequality
|
|
/// a < b // less than
|
|
/// a > b // greater than
|
|
/// a <= b // less than or equal
|
|
/// a >= b // greater than or equal
|
|
/// ```
|
|
///
|
|
/// ## Number vs. Float
|
|
/// To allow transparent use of [Float] and [Int],
|
|
/// use [Number] instead of [Float] in type annotations.
|
|
abstract external class Number extends Any {
|
|
/// A [Duration] with value [this] and unit `"ns"` (nanoseconds).
|
|
abstract ns: Duration
|
|
|
|
/// A [Duration] with value [this] and unit `"us"` (microseconds).
|
|
abstract us: Duration
|
|
|
|
/// A [Duration] with value [this] and unit `"ms"` (milliseconds).
|
|
abstract ms: Duration
|
|
|
|
/// A [Duration] with value [this] and unit `"s"` (seconds).
|
|
abstract s: Duration
|
|
|
|
/// A [Duration] with value [this] and unit `"min"` (minutes).
|
|
abstract min: Duration
|
|
|
|
/// A [Duration] with value [this] and unit `"h"` (hours).
|
|
abstract h: Duration
|
|
|
|
/// A [Duration] with value [this] and unit `"d"` (days).
|
|
abstract d: Duration
|
|
|
|
/// A [DataSize] with value [this] and unit `"b"` (bytes).
|
|
abstract b: DataSize
|
|
|
|
/// A [DataSize] with value [this] and unit `"kb"` (kilobytes).
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.kb == 1000.b
|
|
/// ```
|
|
abstract kb: DataSize
|
|
|
|
/// A [DataSize] with value [this] and unit `"mb"` (megabytes).
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.mb == 1000.kb
|
|
/// ```
|
|
abstract mb: DataSize
|
|
|
|
/// A [DataSize] with value [this] and unit `"gb"` (gigabytes).
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.gb == 1000.mb
|
|
/// ```
|
|
abstract gb: DataSize
|
|
|
|
/// A [DataSize] with value [this] and unit `"tb"` (terabytes).
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.tb == 1000.gb
|
|
/// ```
|
|
abstract tb: DataSize
|
|
|
|
/// A [DataSize] with value [this] and unit `"pb"` (petabytes).
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.pb == 1000.tb
|
|
/// ```
|
|
abstract pb: DataSize
|
|
|
|
/// A [DataSize] with value [this] and unit `"kib"` (kibibytes).
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.kib == 1024.b
|
|
/// ```
|
|
abstract kib: DataSize
|
|
|
|
/// A [DataSize] with value [this] and unit `"mib"` (mebibytes).
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.mib == 1024.kib
|
|
/// ```
|
|
abstract mib: DataSize
|
|
|
|
/// A [DataSize] with value [this] and unit `"gib"` (gibibytes).
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.gib == 1024.mib
|
|
/// ```
|
|
abstract gib: DataSize
|
|
|
|
/// A [DataSize] with value [this] and unit `"tib"` (tebibytes).
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.tib == 1024.gib
|
|
/// ```
|
|
abstract tib: DataSize
|
|
|
|
/// A [DataSize] with value [this] and unit `"pib"` (pebibytes).
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.pib == 1024.tib
|
|
/// ```
|
|
abstract pib: DataSize
|
|
|
|
/// The sign of this number.
|
|
///
|
|
/// Returns `0` for `0`, `0.0`, `-0.0`, and [NaN],
|
|
/// `1` for positive numbers (including [Infinity]),
|
|
/// and `-1` for negative numbers (including `-`[Infinity]).
|
|
abstract sign: Number
|
|
|
|
/// The absolute value of this number.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 42.abs == 42
|
|
/// -42.abs == 42
|
|
/// 0.0.abs == 0.0
|
|
/// (-0.0).abs == 0.0
|
|
/// Infinity.abs == Infinity
|
|
/// (-Infinity).abs == Infinity
|
|
/// NaN.abs == NaN
|
|
/// ```
|
|
abstract abs: Number
|
|
|
|
/// Rounds this number to the next mathematical integer towards [Infinity].
|
|
///
|
|
/// If [this] is an [Int], returns [this].
|
|
/// If [this] is [NaN], [Infinity], -[Infinity], `0.0`, or `-0.0`, returns [this].
|
|
/// Otherwise, returns the smallest [Float] that is greater than or equal to [this]
|
|
/// and is equal to a mathematical integer.
|
|
abstract ceil: Number
|
|
|
|
/// Rounds this number to the next mathematical integer towards -[Infinity].
|
|
///
|
|
/// If [this] is an [Int], returns [this].
|
|
/// If [this] is [NaN], [Infinity], -[Infinity], `0.0`, or `-0.0`, returns [this].
|
|
/// Otherwise, returns the largest [Float] that is less than or equal to [this]
|
|
/// and is equal to a mathematical integer.
|
|
abstract floor: Number
|
|
|
|
/// Rounds this number to the nearest mathematical integer, breaking ties in favor
|
|
/// of the even integer.
|
|
///
|
|
/// If [this] is an [Int], returns [this].
|
|
/// If [this] is [NaN], [Infinity], -[Infinity], `0.0`, or `-0.0`, returns [this].
|
|
/// Otherwise, return the [Float] that is nearest to [this] and is equal to a
|
|
/// mathematical integer. If two mathematical integers are equally near, returns
|
|
/// the even integer.
|
|
abstract function round(): Number
|
|
// https://github.com/julialang/julia/issues/8750#issue-46387044
|
|
|
|
/// Rounds this number to the next mathematical integer towards zero.
|
|
///
|
|
/// If [this] is an [Int], returns [this].
|
|
/// If [this] is [NaN], [Infinity], -[Infinity], `0.0`, or `-0.0`, returns [this].
|
|
/// If [this] is less than zero, returns the smallest [Float] that is greater than or equal to
|
|
/// [this] and is equal to a mathematical integer.
|
|
/// Otherwise, returns the largest [Float] that is less than or equal to [this]
|
|
/// and is equal to a mathematical integer.
|
|
abstract function truncate(): Number
|
|
|
|
/// Converts this number to an [Int].
|
|
///
|
|
/// If [this] is an [Int], returns [this].
|
|
/// If [this] is [NaN], [Infinity], or -[Infinity], throws an error.
|
|
/// Otherwise, returns the [Int] representation for `this.truncate()`.
|
|
/// If `this.truncate()` is not representable in (that is, too large for) [Int], throws an error.
|
|
abstract function toInt(): Int
|
|
|
|
/// Converts this number to a [Float].
|
|
///
|
|
/// If [this] is a [Float], returns [this].
|
|
/// Otherwise, returns the [Float] representation for [this].
|
|
/// If [this] is not representable in [Float], returns the [Float] nearest to [this].
|
|
abstract function toFloat(): Float
|
|
|
|
/// Converts this number to its decimal string representation.
|
|
abstract function toString(): String
|
|
|
|
/// Converts this number to a decimal fixed-point representation with [fractionDigits] digits
|
|
/// after the decimal point.
|
|
abstract function toFixed(fractionDigits: Int(this.isBetween(0, 20))): String
|
|
|
|
/// Converts this number to a duration with [this] value and the given [unit].
|
|
abstract function toDuration(unit: DurationUnit): Duration
|
|
|
|
/// Converts this number to a data size with [this] value and the given [unit].
|
|
abstract function toDataSize(unit: DataSizeUnit): DataSize
|
|
|
|
/// Tells if this number is greater than or equal to zero.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 0.isPositive
|
|
/// (-0).isPositive
|
|
/// 0.0.isPositive
|
|
/// (-0.0).isPositive
|
|
/// 3.isPositive
|
|
/// 3.14.isPositive
|
|
/// Infinity.isPositive
|
|
///
|
|
/// !(-3).isPositive
|
|
/// !(-3.14).isPositive
|
|
/// !(-Infinity).isPositive
|
|
/// !NaN.isPositive
|
|
/// ```
|
|
abstract isPositive: Boolean
|
|
|
|
/// Tells if this number is neither [NaN] nor [isInfinite].
|
|
abstract isFinite: Boolean
|
|
|
|
/// Tells if this number is [Infinity] or -[Infinity].
|
|
abstract isInfinite: Boolean
|
|
|
|
/// Tells if this number is [NaN].
|
|
///
|
|
/// Always use this method when testing for [NaN].
|
|
/// Note that `x == NaN` is *not* a correct way to test for [NaN] because `NaN != NaN` as per the
|
|
/// IEEE spec.
|
|
abstract isNaN: Boolean
|
|
|
|
/// Tells if this number is not 0.
|
|
abstract isNonZero: Boolean
|
|
|
|
/// Tells if this number is greater than or equal to [start] and less than or equal to
|
|
/// [inclusiveEnd].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 3.2.isBetween(2.6, 4)
|
|
/// 3.2.isBetween(2.6, 3.2)
|
|
/// 3.2.isBetween(3.2, 4)
|
|
/// !3.2.isBetween(1, 3.1)
|
|
/// ```
|
|
abstract function isBetween(start: Number, inclusiveEnd: Number): Boolean
|
|
}
|
|
|
|
/// A 64-bit signed integer.
|
|
///
|
|
/// The following operators are supported for [Number]s:
|
|
/// ```
|
|
/// -a // negation
|
|
/// a + b // addition
|
|
/// a - b // subtraction
|
|
/// a * b // multiplication
|
|
/// a / b // division
|
|
/// a ~/ b // truncating division
|
|
/// a % b // remainder
|
|
/// a ** b // exponentiation
|
|
/// ```
|
|
external class Int extends Number {
|
|
external ns: Duration
|
|
external us: Duration
|
|
external ms: Duration
|
|
external s: Duration
|
|
external min: Duration
|
|
external h: Duration
|
|
external d: Duration
|
|
|
|
external b: DataSize
|
|
|
|
external kb: DataSize
|
|
external mb: DataSize
|
|
external gb: DataSize
|
|
external tb: DataSize
|
|
external pb: DataSize
|
|
|
|
external kib: DataSize
|
|
external mib: DataSize
|
|
external gib: DataSize
|
|
external tib: DataSize
|
|
external pib: DataSize
|
|
|
|
external sign: Int
|
|
|
|
external abs: Int
|
|
|
|
external ceil: Int
|
|
|
|
external floor: Int
|
|
|
|
external function round(): Int
|
|
|
|
external function truncate(): Int
|
|
|
|
external function toInt(): Int
|
|
|
|
external function toFloat(): Float
|
|
|
|
external function toString(): String
|
|
|
|
/// Converts this number to a string representation in the given radix.
|
|
///
|
|
/// Digits above 9 are converted to lowercase letters `a` to `z`.
|
|
/// To pad the resulting string with zeros, use [String.padStart()].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// (-1).toRadixString(20) == "-1"
|
|
/// 42.toRadixString(16) == "2a"
|
|
/// ```
|
|
external function toRadixString(radix: Int(this.isBetween(2, 36))): String
|
|
|
|
external function toFixed(fractionDigits: Int(this.isBetween(0, 20))): String
|
|
|
|
external function toDuration(unit: DurationUnit): Duration
|
|
|
|
external function toDataSize(unit: DataSizeUnit): DataSize
|
|
|
|
/// Shifts this integer left by [n] bits.
|
|
external function shl(n: Int): Int
|
|
|
|
/// Shifts this integer right by [n] bits, preserving the sign bit.
|
|
external function shr(n: Int): Int
|
|
|
|
/// Shifts this integer right by [n] bits, setting the sign bit to zero.
|
|
///
|
|
/// This operation is known as *unsigned right shift*.
|
|
external function ushr(n: Int): Int
|
|
|
|
/// Bitwise AND of this integer and [n].
|
|
external function and(n: Int): Int
|
|
|
|
/// Bitwise OR of this integer and [n].
|
|
external function or(n: Int): Int
|
|
|
|
/// Bitwise XOR of this integer and [n].
|
|
external function xor(n: Int): Int
|
|
|
|
/// Bitwise NOT (inverse) of this integer.
|
|
external inv: Int
|
|
|
|
external isPositive: Boolean
|
|
|
|
external isFinite: Boolean
|
|
|
|
external isInfinite: Boolean
|
|
|
|
external isNaN: Boolean
|
|
|
|
/// Tells if this integer is evenly divisible by two.
|
|
external isEven: Boolean
|
|
|
|
/// Tells if this number is not [isEven].
|
|
external isOdd: Boolean
|
|
|
|
external isNonZero: Boolean
|
|
|
|
external function isBetween(start: Number, inclusiveEnd: Number): Boolean
|
|
|
|
/// Returns the Unicode character with code point [this].
|
|
///
|
|
/// Throws if [this] is not a valid code point.
|
|
external function toChar(): Char
|
|
}
|
|
|
|
/// An [Int] value in range [math.minInt8]..[math.maxInt8].
|
|
typealias Int8 = Int(isBetween(-128, 127))
|
|
|
|
/// An [Int] value in range [math.minInt16]..[math.maxInt16].
|
|
typealias Int16 = Int(isBetween(-32768, 32767))
|
|
|
|
/// An [Int] value in range [math.minInt32]..[math.maxInt32].
|
|
typealias Int32 = Int(isBetween(-2147483648, 2147483647))
|
|
|
|
/// An [Int] value in range `0`..[math.maxUInt8].
|
|
typealias UInt8 = Int(isBetween(0, 255))
|
|
|
|
/// An [Int] value in range `0`..[math.maxUInt16].
|
|
typealias UInt16 = Int(isBetween(0, 65535))
|
|
|
|
/// An [Int] value in range `0`..[math.maxUInt32].
|
|
typealias UInt32 = Int(isBetween(0, 4294967295))
|
|
|
|
/// An [Int] value in range `0`..[math.maxUInt].
|
|
///
|
|
/// Note that [math.maxUInt] is equal to [math.maxInt],
|
|
/// not `maxInt * 2 + 1` as one might expect.
|
|
/// That is, [UInt] has half the range of [Int].
|
|
typealias UInt = Int(isPositive)
|
|
|
|
/// A value that can be compared to another value of the same type with `<`, `>`, `<=`, and `>=`.
|
|
typealias Comparable = String | Number | Duration | DataSize
|
|
|
|
/// A 64-bit floating-point number conforming to the IEEE 754 binary64 format.
|
|
///
|
|
/// The following binary operators are supported for [Number]s:
|
|
/// ```
|
|
/// -a // negative
|
|
/// a + b // addition
|
|
/// a - b // subtraction
|
|
/// a * b // multiplication
|
|
/// a / b // division
|
|
/// a ~/ b // integer division
|
|
/// a % b // remainder
|
|
/// a ** b // exponentiation
|
|
/// ```
|
|
///
|
|
/// Tip: To allow transparent use of [Float] and [Int],
|
|
/// use [Number] instead of [Float] in type annotations.
|
|
external class Float extends Number {
|
|
external ns: Duration
|
|
external us: Duration
|
|
external ms: Duration
|
|
external s: Duration
|
|
external min: Duration
|
|
external h: Duration
|
|
external d: Duration
|
|
|
|
external b: DataSize
|
|
|
|
external kb: DataSize
|
|
external mb: DataSize
|
|
external gb: DataSize
|
|
external tb: DataSize
|
|
external pb: DataSize
|
|
|
|
external kib: DataSize
|
|
external mib: DataSize
|
|
external gib: DataSize
|
|
external tib: DataSize
|
|
external pib: DataSize
|
|
|
|
external sign: Float
|
|
|
|
external abs: Float
|
|
|
|
external ceil: Float
|
|
|
|
external floor: Float
|
|
|
|
external function round(): Float
|
|
|
|
external function truncate(): Float
|
|
|
|
external function toInt(): Int
|
|
|
|
external function toFloat(): Float
|
|
|
|
external function toString(): String
|
|
|
|
external function toFixed(fractionDigits: Int(this.isBetween(0, 20))): String
|
|
|
|
external function toDuration(unit: DurationUnit): Duration
|
|
|
|
external function toDataSize(unit: DataSizeUnit): DataSize
|
|
|
|
external isPositive: Boolean
|
|
|
|
external isFinite: Boolean
|
|
|
|
external isInfinite: Boolean
|
|
|
|
external isNaN: Boolean
|
|
|
|
external isNonZero: Boolean
|
|
|
|
external function isBetween(start: Number, inclusiveEnd: Number): Boolean
|
|
}
|
|
|
|
/// The [Float] value that is not a number (NaN).
|
|
external const NaN: Float
|
|
|
|
/// The [Float] value that is positive Infinity. For negative infinity, use -[Infinity].
|
|
external const Infinity: Float
|
|
|
|
/// A boolean value, either [true] or [false].
|
|
///
|
|
/// The following operators are supported for booleans:
|
|
/// ```
|
|
/// !bool // logical negation
|
|
/// bool1 && bool2 // logical conjunction
|
|
/// bool1 || bool2 // logical disjunction
|
|
/// ```
|
|
external class Boolean extends Any {
|
|
/// Tells if exactly one of [this] and [other] is [true] (exclusive or).
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// !true.xor(true)
|
|
/// true.xor(false)
|
|
/// false.xor(true)
|
|
/// !false.xor(false)
|
|
/// ```
|
|
external function xor(other: Boolean): Boolean
|
|
|
|
/// Tells if [this] implies [other] (logical consequence).
|
|
///
|
|
/// *Note*: This function does not short-circuit; [other] is always evaluated.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// true.implies(true)
|
|
/// !true.implies(false)
|
|
/// false.implies(true)
|
|
/// false.implies(false)
|
|
/// ```
|
|
external function implies(other: Boolean): Boolean
|
|
}
|
|
|
|
/// A Unicode character (code point).
|
|
typealias Char = String(length == 1)
|
|
|
|
/// A sequence of Unicode characters (code points).
|
|
///
|
|
/// The following operators are supported for strings:
|
|
/// ```
|
|
/// str[3] // subscript
|
|
/// str1 + str2 // concatenation
|
|
/// ```
|
|
external class String extends Any {
|
|
/// The number of characters in this string.
|
|
///
|
|
/// *Note*: The runtime complexity of this operation is `O(n)`.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "".length == 0
|
|
/// "abc".length == 3
|
|
/// ```
|
|
@AlsoKnownAs { names { "size"; "count" } }
|
|
external length: Int
|
|
|
|
/// The index of the last character in this string (same as `length - 1`).
|
|
///
|
|
/// Returns `-1` for an empty string.
|
|
///
|
|
/// *Note*: The runtime complexity of this operation is `O(n)`.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "".lastIndex == -1
|
|
/// "abc".lastIndex == 2
|
|
/// ```
|
|
external lastIndex: Int
|
|
|
|
/// Tells whether this string is empty.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "".isEmpty
|
|
/// !(" ".isEmpty)
|
|
/// !("abc".isEmpty)
|
|
/// ```
|
|
external isEmpty: Boolean
|
|
|
|
/// Tells whether this string is not empty.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// !"".isNotEmpty
|
|
/// "abc".isNotEmpty
|
|
/// ```
|
|
@Since { version = "0.31.0" }
|
|
external isNotEmpty: Boolean
|
|
|
|
/// Tells if all characters in this string have Unicode property "White_Space".
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "".isBlank
|
|
/// " ".isBlank
|
|
/// "\t\n\r".isBlank
|
|
/// !("abc".isBlank)
|
|
/// ```
|
|
external isBlank: Boolean
|
|
|
|
/// Tells if at least one character is not Unicode "White_Space".
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// !"".isNotBlank
|
|
/// !" ".isNotBlank
|
|
/// "\t\n\r".isNotBlank
|
|
/// "abc".isNotBlank
|
|
/// ```
|
|
@Since { version = "0.31.0" }
|
|
external isNotBlank: Boolean
|
|
|
|
/// Tells if this string is a valid regular expression according to [Regex].
|
|
external isRegex: Boolean
|
|
|
|
/// Tells if this is a valid base64-encoded string.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "AQIDBA==".isBase64
|
|
/// !"hello there".isBase64
|
|
/// ```
|
|
@Since { version = "0.29.0" }
|
|
external isBase64: Boolean
|
|
|
|
/// The [MD5](https://en.wikipedia.org/wiki/MD5)
|
|
/// hash of this string's UTF-8 byte sequence
|
|
/// as hexadecimal string.
|
|
///
|
|
/// MD5 is cryptographically broken and should not be used for secure applications.
|
|
external md5: String
|
|
|
|
/// The [SHA-1](https://en.wikipedia.org/wiki/SHA-1)
|
|
/// hash of this string's UTF-8 byte sequence.
|
|
///
|
|
/// SHA-1 is cryptographically broken and should not be used for secure applications.
|
|
external sha1: String
|
|
|
|
/// The [SHA-256](https://en.wikipedia.org/wiki/SHA-2)
|
|
/// cryptographic hash of this string's UTF-8 byte sequence
|
|
/// as hexadecimal string.
|
|
external sha256: String
|
|
|
|
/// The first 64 bits of the [SHA-256](https://en.wikipedia.org/wiki/SHA-2)
|
|
/// cryptographic hash of this string's UTF-8 byte sequence.
|
|
external sha256Int: Int
|
|
|
|
/// The Base64 encoding of this string's UTF-8 byte sequence.
|
|
external base64: String
|
|
|
|
/// The inverse of [base64].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "abc".base64.base64Decoded == "abc"
|
|
/// ```
|
|
external base64Decoded: String
|
|
|
|
/// Converts this base64-format string into [Bytes].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "AQIDBA==".base64DecodedBytes = Bytes(1, 2, 3, 4)
|
|
/// ```
|
|
@Since { version = "0.29.0" }
|
|
external base64DecodedBytes: Bytes
|
|
|
|
/// The Unicode characters in this string.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "abc".chars == List("a", "b", "c")
|
|
/// ```
|
|
external chars: List<Char>(this.length == length)
|
|
|
|
/// The Unicode code points in this string.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "abc".codePoints == List(0x61, 0x62, 0x63)
|
|
/// ```
|
|
external codePoints: List<Int(isBetween(0, 0x10FFFF))>(this.length == length)
|
|
|
|
/// Returns the character at [index], or [null] if [index] is out of range.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "abcde".getOrNull(-1) == null
|
|
/// "abcde".getOrNull(0) == "a"
|
|
/// "abcde".getOrNull(2) == "c"
|
|
/// "abcde".getOrNull(4) == "e"
|
|
/// "abcde".getOrNull(5) == null
|
|
/// ```
|
|
external function getOrNull(index: Int): Char?
|
|
|
|
/// Returns the substring from [start] until [exclusiveEnd].
|
|
///
|
|
/// Throws if [start] is outside range `0`..[length] or [exclusiveEnd] is outside range
|
|
/// [start]..[length].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "abcde".substring(0, 0) == ""
|
|
/// "abcde".substring(0, 1) == "a"
|
|
/// "abcde".substring(1, 4) == "bcd"
|
|
/// "abcde".substring(4, 5) == "e"
|
|
/// "abcde".substring(5, 5) == ""
|
|
/// ```
|
|
external function substring(start: Int, exclusiveEnd: Int): String
|
|
|
|
/// Returns the substring from [start] until [exclusiveEnd].
|
|
///
|
|
/// Returns [null] if [start] is outside range `0`..[length] or [exclusiveEnd] is outside range
|
|
/// [start]..[length].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "abcde".substringOrNull(0, 0) == ""
|
|
/// "abcde".substringOrNull(0, 1) == "a"
|
|
/// "abcde".substringOrNull(1, 4) == "bcd"
|
|
/// "abcde".substringOrNull(4, 5) == "e"
|
|
/// "abcde".substringOrNull(5, 5) == ""
|
|
///
|
|
/// "abcde".substringOrNull(-1, 3) == null
|
|
/// "abcde".substringOrNull(0, 6) == null
|
|
/// "abcde".substringOrNull(3, 2) == null
|
|
/// ```
|
|
external function substringOrNull(start: Int, exclusiveEnd: Int): String?
|
|
|
|
/// Concatenates [count] copies of this string.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "abc".repeat(0) == ""
|
|
/// "abc".repeat(1) == "abc"
|
|
/// "abc".repeat(3) == "abcabcabc"
|
|
/// ```
|
|
external function repeat(count: UInt): String
|
|
|
|
/// Tells whether this string contains [pattern].
|
|
external function contains(pattern: String | Regex): Boolean
|
|
|
|
/// Tells whether this string matches [regex] in its entirety.
|
|
@AlsoKnownAs { names { "test" } }
|
|
external function matches(regex: Regex): Boolean
|
|
|
|
/// Tells whether this string starts with [pattern].
|
|
external function startsWith(pattern: String | Regex): Boolean
|
|
|
|
/// Tells whether this string ends with [pattern].
|
|
external function endsWith(pattern: String | Regex): Boolean
|
|
|
|
/// Returns the zero-based index of the first occurrence of [pattern]
|
|
/// in this string.
|
|
///
|
|
/// Throws if [pattern] does not occur in this string.
|
|
external function indexOf(pattern: String | Regex): Int
|
|
|
|
/// Returns the zero-based index of the first occurrence of [pattern]
|
|
/// in this string, or [null] if [pattern] does not occur in this string.
|
|
external function indexOfOrNull(pattern: String | Regex): Int?
|
|
|
|
/// Returns the zero-based index of the last occurrence of [pattern]
|
|
/// in this string.
|
|
///
|
|
/// Throws if [pattern] does not occur in this string.
|
|
external function lastIndexOf(pattern: String | Regex): Int
|
|
|
|
/// Returns the zero-based index of the last occurrence of [pattern]
|
|
/// in this string, or [null] if [pattern] does not occur in this string.
|
|
external function lastIndexOfOrNull(pattern: String | Regex): Int?
|
|
|
|
/// Returns the first [n] characters of this string.
|
|
///
|
|
/// Returns [this] if [n] is greater than or equal to [length].
|
|
@AlsoKnownAs { names { "limit" } }
|
|
external function take(n: Int): String
|
|
|
|
/// Returns the longest prefix of this string that satisfies [predicate].
|
|
external function takeWhile(predicate: (String) -> Boolean): String
|
|
|
|
/// Returns the last [n] characters of this string.
|
|
///
|
|
/// Returns [this] if [n] is greater than or equal to [length].
|
|
external function takeLast(n: Int): String
|
|
|
|
/// Returns the longest suffix of this string that satisfies [predicate].
|
|
external function takeLastWhile(predicate: (String) -> Boolean): String
|
|
|
|
/// Removes the first [n] characters of this string.
|
|
///
|
|
/// Returns the empty string if [n] is greater than or equal to [length].
|
|
@AlsoKnownAs { names { "skip" } }
|
|
external function drop(n: Int): String
|
|
|
|
/// Removes the longest prefix of this string that satisfies [predicate].
|
|
@AlsoKnownAs { names { "skipWhile" } }
|
|
external function dropWhile(predicate: (String) -> Boolean): String
|
|
|
|
/// Removes the last [n] characters of this string.
|
|
///
|
|
/// Returns the empty string if [n] is greater than or equal to [length].
|
|
@AlsoKnownAs { names { "skipLast" } }
|
|
external function dropLast(n: Int): String
|
|
|
|
/// Removes the longest suffix of this string that satisfies [predicate].
|
|
@AlsoKnownAs { names { "skipLastWhile" } }
|
|
external function dropLastWhile(predicate: (String) -> Boolean): String
|
|
|
|
/// Replaces the first occurrence of [pattern] in this string with [replacement].
|
|
///
|
|
/// Returns this string unchanged if [pattern] does not occur in this string.
|
|
external function replaceFirst(pattern: String | Regex, replacement: String): String
|
|
|
|
/// Replaces the last occurrence of [pattern] in this string with [replacement].
|
|
///
|
|
/// Returns this string unchanged if [pattern] does not occur in this string.
|
|
external function replaceLast(pattern: String | Regex, replacement: String): String
|
|
|
|
/// Replaces all occurrences of [pattern] in this string with [replacement].
|
|
///
|
|
/// Returns this string unchanged if [pattern] does not occur in this string.
|
|
external function replaceAll(pattern: String | Regex, replacement: String): String
|
|
|
|
/// Replaces the first occurrence of [pattern] in this string with the return value of [mapper].
|
|
///
|
|
/// Returns this string unchanged if [pattern] does not occur in this string.
|
|
external function replaceFirstMapped(
|
|
pattern: String | Regex,
|
|
mapper: (RegexMatch) -> String,
|
|
): String
|
|
|
|
/// Replaces the last occurrence of [pattern] in this string with the return value of [mapper].
|
|
///
|
|
/// Returns this string unchanged if [pattern] does not occur in this string.
|
|
external function replaceLastMapped(
|
|
pattern: String | Regex,
|
|
mapper: (RegexMatch) -> String,
|
|
): String
|
|
|
|
/// Replaces all occurrences of [pattern] in this string with the return value of [mapper].
|
|
///
|
|
/// Returns this string unchanged if [pattern] does not occur in this string.
|
|
external function replaceAllMapped(
|
|
pattern: String | Regex,
|
|
mapper: (RegexMatch) -> String,
|
|
): String
|
|
|
|
/// Replaces the characters between [start] and [exclusiveEnd] with [replacement].
|
|
///
|
|
/// Inserts [replacement] at index [start] if `start == exclusiveEnd`.
|
|
external function replaceRange(start: Int, exclusiveEnd: Int, replacement: String): String
|
|
|
|
/// Performs a locale-independent character-by-character conversion of this string to uppercase.
|
|
external function toUpperCase(): String
|
|
|
|
/// Performs a locale-independent character-by-character conversion of this string to lowercase.
|
|
external function toLowerCase(): String
|
|
|
|
/// Reverses the order of characters in this string.
|
|
external function reverse(): String
|
|
|
|
/// Removes any leading and trailing characters with Unicode property "White_Space" from this
|
|
/// string.
|
|
@AlsoKnownAs { names { "strip" } }
|
|
external function trim(): String
|
|
|
|
/// Removes any leading characters with Unicode property "White_Space" from this string.
|
|
@AlsoKnownAs { names { "stripLeft"; "stripStart"; "stripLeading"; "trimLeft"; "trimLeading" } }
|
|
external function trimStart(): String
|
|
|
|
/// Removes any trailing characters with Unicode property "White_Space" from this string.
|
|
@AlsoKnownAs { names { "stripRight"; "stripEnd"; "stripTrailing"; "trimRight"; "trimTrailin" } }
|
|
external function trimEnd(): String
|
|
|
|
/// Increases the length of this string to [width] by adding leading [char]s.
|
|
///
|
|
/// Returns this string unchanged if its length is already equal to or greater than [width].
|
|
@AlsoKnownAs { names { "padLeft" } }
|
|
external function padStart(width: Int, char: Char)
|
|
|
|
/// Increases the length of this string to [width] by adding trailing [char]s.
|
|
///
|
|
/// Returns this string unchanged if its length is already equal to or greater than [width].
|
|
@AlsoKnownAs { names { "padRight" } }
|
|
external function padEnd(width: Int, char: Char)
|
|
|
|
/// Splits this string around matches of [pattern].
|
|
external function split(pattern: String | Regex): List<String>
|
|
|
|
/// Splits this string matches of [pattern], up to [limit] substrings.
|
|
///
|
|
/// Returns a [List] with at most [limit] elements.
|
|
/// If the limit has been reached, the last entry will contain the un-split remainder of this
|
|
/// string.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "a.b.c".splitLimit(".", 2) == List("a", "b.c")
|
|
/// "a.b.c".splitLimit(".", 1) == List("a.b.c")
|
|
/// "a.b.c".splitLimit(".", 50) == List("a", "b", "c")
|
|
/// "a.b:c".splitLimit(Regex("[.:]"), 3) == List("a", "b", "c")
|
|
/// ```
|
|
@Since { version = "0.27.0" }
|
|
external function splitLimit(pattern: String | Regex, limit: Int(this > 0)): List<String>
|
|
|
|
/// Converts the first character of this string to title case.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "pigeon".capitalize() == "Pigeon"
|
|
/// "pigeon bird".capitalize() == "Pigeon bird"
|
|
/// "".capitalize() == ""
|
|
/// ```
|
|
external function capitalize(): String
|
|
|
|
/// Converts the first character of this string to lower case.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "Pigeon".decapitalize() == "pigeon"
|
|
/// "Pigeon Bird".decapitalize() == "pigeon Bird"
|
|
/// "".decapitalize() == ""
|
|
/// ```
|
|
external function decapitalize(): String
|
|
|
|
/// Parses this string as a signed decimal (base 10) integer.
|
|
///
|
|
/// Throws if this string cannot be parsed as a signed decimal integer,
|
|
/// or if the integer is too large to fit into [Int].
|
|
external function toInt(): Int
|
|
|
|
/// Parses this string as a signed decimal (base 10) integer.
|
|
///
|
|
/// Returns [null] if this string cannot be parsed as a signed decimal integer,
|
|
/// or if the integer is too large to fit into [Int].
|
|
external function toIntOrNull(): Int?
|
|
|
|
/// Parses this string as a floating point number.
|
|
///
|
|
/// Throws if this string cannot be parsed as a floating point number.
|
|
external function toFloat(): Float
|
|
|
|
/// Parses this string as a floating point number.
|
|
///
|
|
/// Returns [null] if this string cannot be parsed as a floating point number.
|
|
external function toFloatOrNull(): Float?
|
|
|
|
/// Parses `"true"` to [true] and `"false"` to [false] (case-insensitive).
|
|
///
|
|
/// Throws if this string is neither `"true"` nor `"false"` (case-insensitive).
|
|
external function toBoolean(): Boolean
|
|
|
|
/// Parses `"true"` to [true] and `"false"` to [false] (case-insensitive).
|
|
///
|
|
/// Returns [null] if this string is neither `"true"` nor `"false"` (case-insensitive).
|
|
external function toBooleanOrNull(): Boolean?
|
|
|
|
/// Returns the bytes of this string, encoded using [charset].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// "Parrot".encodeToBytes("UTF-8") == Bytes(80, 97, 114, 114, 111, 116)
|
|
/// ```
|
|
@Since { version = "0.29.0" }
|
|
external function encodeToBytes(charset: Charset): Bytes
|
|
}
|
|
|
|
/// An identifier for a [character encoding](https://en.wikipedia.org/wiki/Character_encoding).
|
|
///
|
|
/// * `"UTF-8"`: <https://en.wikipedia.org/wiki/UTF-8>
|
|
/// * `"UTF-16"`: <https://en.wikipedia.org/wiki/UTF-16>
|
|
/// * `"ISO-8859-1"` (also known as latin1): <https://en.wikipedia.org/wiki/ISO/IEC_8859-1>
|
|
@Since { version = "0.29.0" }
|
|
typealias Charset = "UTF-8" | "UTF-16" | "ISO-8859-1"
|
|
|
|
/// A string representing a [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier).
|
|
typealias Uri = String
|
|
|
|
/// Constructs a regular expression described by [pattern].
|
|
///
|
|
/// Throws if [pattern] is not a valid regular expression.
|
|
///
|
|
/// To test if [pattern] is a valid regular expression, use [String.isRegex].
|
|
external const function Regex(pattern: String): Regex
|
|
|
|
/// A regular expression to match strings against.
|
|
external class Regex {
|
|
/// The pattern string of this regular expression.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// Regex("some pattern string").pattern == "some pattern string"
|
|
/// ```
|
|
external pattern: String
|
|
|
|
/// The number of capturing groups in this regular expression.
|
|
///
|
|
/// Returns zero if this regular expression does not have any capturing groups.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// Regex(#"abc"#).groupCount == 0
|
|
/// Regex(#"a(\s*)b(\s*)c"#).groupCount == 2 // `()` denotes a capturing group
|
|
/// Regex(#"a(?:\s*)bc"#).groupCount == 0 // `(?:)` denotes a non-capturing group
|
|
/// ```
|
|
external groupCount: Int
|
|
|
|
/// Finds all matches of this regular expression in [input].
|
|
@AlsoKnownAs { names { "match" } }
|
|
external function findMatchesIn(input: String): List<RegexMatch>
|
|
|
|
/// Matches this regular expression against the entire [input].
|
|
external function matchEntire(input: String): RegexMatch?
|
|
}
|
|
|
|
/// A match of a regular expression in a string.
|
|
class RegexMatch {
|
|
/// The string value of this match.
|
|
value: String
|
|
|
|
/// The start index of this match.
|
|
start: Int
|
|
|
|
/// The exclusive end index of this match.
|
|
end: Int
|
|
|
|
/// The capturing group matches within this match.
|
|
///
|
|
/// If [this] is already a capturing group match, returns the empty list.
|
|
/// Otherwise, returns a list of length `regex.groupCount + 1`,
|
|
/// where `groups[0]` contains the entire match (for consistency with other regex APIs),
|
|
/// and `groups[1]` to `groups[regex.groupCount]` contain capturing group matches.
|
|
/// If a capturing group did not produce a match, the corresponding [RegexMatch] element is [null].
|
|
groups: List<RegexMatch?>
|
|
|
|
/// Returns [value].
|
|
function toString(): String = value
|
|
}
|
|
|
|
/// The unit of a [Duration].
|
|
typealias DurationUnit = "ns" | "us" | "ms" | "s" | "min" | "h" | "d"
|
|
|
|
/// A quantity of elapsed time, represented as a [value] (e.g. `30.5`) and [unit] (e.g. `min`).
|
|
external class Duration extends Any {
|
|
/// The value of this duration.
|
|
///
|
|
/// Returns [Int] if possible and [Float] otherwise.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.min.value == 1
|
|
/// 2.2.h.value == 2.2
|
|
/// ```
|
|
external value: Number
|
|
|
|
/// An [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Durations) representation of this
|
|
/// duration.
|
|
///
|
|
/// The ISO representation has the format `[-]PT{hours}H{minutes}M{seconds}S`, where
|
|
///
|
|
/// - negative durations have a leading minus sign,
|
|
/// - `{hours}` and `{minutes}` are positive integers,
|
|
/// - `{seconds}` is a positive integer or a positive decimal with decimal point (`.`),
|
|
/// - zero-valued components are omitted, and
|
|
/// - durations with length zero are represented as `PT0S`.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.5.h.isoString == "PT1H30M"
|
|
/// -1.5.h.isoString == "-PT1H30M"
|
|
/// 1.23.s.isoString == "PT1.23S"
|
|
/// 0.ms.isoString == "PT0S"
|
|
/// ```
|
|
external isoString: String(matches(Regex(#"-?PT(\d+H)?(\d+M)?(\d+([.]\d+)?S)?"#)))
|
|
|
|
/// The unit of this duration.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.min.unit == "min"
|
|
/// 2.2.h.unit == "h"
|
|
/// ```
|
|
external unit: DurationUnit
|
|
|
|
/// Tells if this duration has a value of zero or greater.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 2.min.isPositive
|
|
/// !(-2.min.isPositive)
|
|
/// ```
|
|
external isPositive: Boolean
|
|
|
|
/// Tells if this duration is greater than or equal to [start] and less than or equal to
|
|
/// [inclusiveEnd].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 3.min.isBetween(120.s, 4.min)
|
|
/// 3.min.isBetween(180.s, 4.min)
|
|
/// 3.min.isBetween(120.s, 3.min)
|
|
/// !3.min.isBetween(1.min, 2.min)
|
|
/// ```
|
|
external function isBetween(start: Duration, inclusiveEnd: Duration): Boolean
|
|
|
|
/// Returns the equivalent duration with the given unit.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 60.min.toUnit("h") == 1.h
|
|
/// 1.h.toUnit("min") == 60.min
|
|
/// ```
|
|
external function toUnit(unit: DurationUnit): Duration
|
|
}
|
|
|
|
/// The unit of a [DataSize].
|
|
typealias DataSizeUnit =
|
|
"b" | "kb" | "kib" | "mb" | "mib" | "gb" | "gib" | "tb" | "tib" | "pb" | "pib"
|
|
|
|
/// A quantity of binary data, represented as a [value] (e.g. `30.5`) and [unit] (e.g. `mb`).
|
|
external class DataSize extends Any {
|
|
/// The value of this data size.
|
|
///
|
|
/// Returns [Int] if possible and [Float] otherwise.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.mb.value == 1
|
|
/// 2.2.mib.value == 2.2
|
|
/// ```
|
|
external value: Number
|
|
|
|
/// The unit of this data size.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1.mb.unit == "mb"
|
|
/// 2.2.mib.unit == "mib"
|
|
/// ```
|
|
external unit: DataSizeUnit
|
|
|
|
/// Tells if this data size has a value of zero or greater.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 2.mb.isPositive
|
|
/// !(-2.mb.isPositive)
|
|
/// ```
|
|
external isPositive: Boolean
|
|
|
|
/// Tells if this data size is greater than or equal to [start] and less than or equal to
|
|
/// [inclusiveEnd].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 3.kb.isBetween(2000.b, 4.kb)
|
|
/// 3.kb.isBetween(3000.b, 4.kb)
|
|
/// 3.kb.isBetween(2000.b, 3.kb)
|
|
/// !3.kb.isBetween(1.kb, 2.kb)
|
|
/// ```
|
|
external function isBetween(start: DataSize, inclusiveEnd: DataSize)
|
|
|
|
/// Returns the equivalent data size with the given unit.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1000.kb.toUnit("mb") == 1.mb
|
|
/// 1.mb.toUnit("kb") == 1000.kb
|
|
/// ```
|
|
external function toUnit(unit: DataSizeUnit): DataSize
|
|
|
|
/// Tells if this data size has a binary unit, for example `mib`.
|
|
///
|
|
/// Returns [true] for unit `b` (bytes).
|
|
external isBinaryUnit: Boolean
|
|
|
|
/// Tells if this data size has a decimal unit, for example `mb`.
|
|
///
|
|
/// Returns [true] for unit `b` (bytes).
|
|
external isDecimalUnit: Boolean
|
|
|
|
/// Returns the equivalent data size with a binary unit.
|
|
///
|
|
/// Returns this data size unchanged if it already has a binary unit.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1024.kb.toBinaryUnit() == 1000.kib
|
|
/// 1024.mb.toBinaryUnit() == 1000.mib
|
|
///
|
|
/// 1000.kib.toBinaryUnit() == 1000.kib
|
|
/// 1000.b.toBinaryUnit() == 1000.b
|
|
/// ```
|
|
external function toBinaryUnit(): DataSize
|
|
|
|
/// Returns the equivalent data size with a decimal unit.
|
|
///
|
|
/// Returns this data size unchanged if it already has a decimal unit.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 1000.kib.toDecimalUnit() == 1024.kb
|
|
/// 1000.mib.toDecimalUnit() == 1024.mb
|
|
///
|
|
/// 1000.kb.toDecimalUnit() == 1000.kb
|
|
/// 1000.b.toDecimalUnit() == 1000.b
|
|
/// ```
|
|
external function toDecimalUnit(): DataSize
|
|
}
|
|
|
|
/// A composite value containing members (properties, elements, entries).
|
|
///
|
|
/// ```
|
|
/// obj = new {
|
|
/// name = "Pigeon" // property
|
|
/// "Hello" // element
|
|
/// ["two"] = 2 // entry
|
|
/// }
|
|
///
|
|
/// obj.name // "Pigeon"
|
|
/// obj[0] // "Hello"
|
|
/// obj["two"] // 2
|
|
/// ```
|
|
///
|
|
/// An object can be *amended* to create variants of itself.
|
|
/// This is similar to inheritance in prototype-oriented programming.
|
|
///
|
|
/// ```
|
|
/// pigeon = new { name = "Pigeon"; age = 42 }
|
|
/// barnOwl = (pigeon) { name = "Barn Owl" } // override property `name`
|
|
/// oldPigeon = (pigeon) { age = 84 } // override property `age`
|
|
/// ```
|
|
///
|
|
/// Object members may reference other members:
|
|
///
|
|
/// ```
|
|
/// thresholds = new { lower = 10; upper = lower + 5 }
|
|
/// ```
|
|
///
|
|
/// Object members are dynamically bound.
|
|
/// This is similar to how computed cells in a spreadsheet work.
|
|
///
|
|
/// ```
|
|
/// thresholds = new { lower = 10; upper = lower + 5 }
|
|
/// thresholds2 = new { lower = 7 } // thresholds2.upper == 12
|
|
/// ```
|
|
///
|
|
/// Objects have memberwise equality and hash code.
|
|
///
|
|
/// To arbitrarily manipulate an object, convert it to a [Collection].
|
|
/// If necessary, the manipulated [Collection] can be converted back to an [Object].
|
|
///
|
|
/// ```
|
|
/// pigeon = new { name = "Pigeon"; age = 42 }
|
|
/// manipulated = pigeon.toMap().mapKeys((key, value) -> key.reverse())
|
|
/// manipulated.toDynamic() // new { eman = "Pigeon"; ega = 42 }
|
|
/// ```
|
|
abstract external class Object extends Any
|
|
|
|
/// Base class for objects whose members are described by a class definition.
|
|
///
|
|
/// User-defined classes (that is, classes without `external` modifier) implicitly extend this
|
|
/// class.
|
|
abstract class Typed extends Object {
|
|
/// Tells if this object has a property with the given [name].
|
|
external function hasProperty(name: String): Boolean
|
|
|
|
/// Returns the value of the property with the given [name].
|
|
///
|
|
/// Throws if a property with this name does not exist.
|
|
external function getProperty(name: String): unknown
|
|
|
|
/// Returns the value of the property with the given [name].
|
|
///
|
|
/// Returns [null] if a property with this name does not exist.
|
|
external function getPropertyOrNull(name: String): unknown?
|
|
|
|
/// Converts this object to a [Dynamic] object.
|
|
external function toDynamic(): Dynamic
|
|
|
|
/// Converts this object to a [Map].
|
|
external function toMap(): Map<String, unknown>
|
|
}
|
|
|
|
/// An object that can contain arbitrary properties, elements, and entries.
|
|
///
|
|
/// Example:
|
|
/// ```
|
|
/// obj = new Dynamic {
|
|
/// propertyName = "propertyValue"
|
|
/// "element"
|
|
/// ["entryKey"] = "entryValue"
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// Unlike a [Typed] object, a dynamic object does not have an associated class describing its
|
|
/// shape.
|
|
class Dynamic extends Object {
|
|
/// The function used to compute the default value for an object element or entry given its key.
|
|
hidden default: (unknown) -> Any = (_) -> new Dynamic {}
|
|
|
|
/// Returns the number of elements in this object.
|
|
external function length(): Int
|
|
|
|
/// Tells if this object has a property with the given [name].
|
|
external function hasProperty(name: String): Boolean
|
|
|
|
/// Returns the value of the property with the given [name].
|
|
///
|
|
/// Throws if a property with this name does not exist.
|
|
external function getProperty(name: String): unknown
|
|
|
|
/// Returns the value of the property with the given [name].
|
|
///
|
|
/// Returns [null] if a property with this name does not exist.
|
|
external function getPropertyOrNull(name: String): unknown
|
|
|
|
/// Converts the properties and/or entries of this dynamic object to a [Map].
|
|
external function toMap(): Map<unknown, unknown>
|
|
|
|
/// Converts the elements of this dynamic object to a [List].
|
|
external function toList(): List<unknown>
|
|
|
|
/// Converts this object to a typed object of class [clazz].
|
|
///
|
|
/// Conforms to the semantics of the following manual conversion:
|
|
/// ```
|
|
/// class Person { name: String; age: Int }
|
|
/// dynamic = new Dynamic { name = "Pigeon"; age = 42 }
|
|
/// function toTyped(dynamic: Dynamic): Person = new {
|
|
/// name = dynamic.getPropertyOrNull("name") ?? super.name
|
|
/// age = dynamic.getPropertyOrNull("age") ?? super.age
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// Notable behavior:
|
|
/// - Elements and entries of [this] are ignored.
|
|
/// - Properties of [this] that have no corresponding property in [clazz] are ignored.
|
|
/// - [clazz] properties that have no corresponding property in [this] have their defaults
|
|
/// preserved.
|
|
/// - [clazz] properties that have neither a default nor a corresponding property in [this]
|
|
/// throw an "undefined property" error (only) when accessed.
|
|
///
|
|
/// Throws if [clazz] is abstract or not a subclass of [Typed].
|
|
external function toTyped<Type>(clazz: Class<Type>): Type(this is Typed)
|
|
}
|
|
|
|
/// An object containing an ordered sequence of elements.
|
|
///
|
|
/// This class is the object equivalent of [List].
|
|
class Listing<out Element> extends Object {
|
|
/// The function used to compute the default value for a listing element given its index.
|
|
hidden default: (Int) -> Element = (_) -> new Dynamic {}
|
|
|
|
/// The number of elements in this listing.
|
|
external length: Int
|
|
|
|
/// Tells if this listing is empty, that is, has zero elements.
|
|
external isEmpty: Boolean
|
|
|
|
/// Tells if this listing is not empty, that is, it has at least one element.
|
|
@Since { version = "0.31.0" }
|
|
external isNotEmpty: 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?
|
|
|
|
/// Returns the element at [index].
|
|
///
|
|
/// Returns [default] applied to [index] if [index] is outside the bounds of this listing.
|
|
///
|
|
/// This is equivalent to `getOrNull(index) ?? default.apply(index)`.
|
|
@Since { version = "0.29.0" }
|
|
external function getOrDefault(index: Int): Element
|
|
|
|
/// Tells if this listing has no duplicate elements.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// new Listing { 1; 2; 3 }.isDistinct
|
|
/// !new Listing { 1; 2; 1 }.isDistinct
|
|
/// ```
|
|
@AlsoKnownAs { names { "isUnique" } }
|
|
external isDistinct: Boolean
|
|
|
|
/// Tells if this listing has no elements that are duplicates after applying [selector].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// new Listing { "a"; "ab"; "abc" }.isDistinctBy((it) -> it.length)
|
|
/// !new Listing { "a"; "ab"; "c" }.isDistinctBy((it) -> it.length)
|
|
/// ```
|
|
@AlsoKnownAs { names { "isUniqueBy" } }
|
|
external function isDistinctBy(selector: (Element) -> Any): Boolean
|
|
|
|
/// Removes duplicate elements from this listing, preserving the first occurrence.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// new Listing { 1; 2; 3 }.distinct == new Listing { 1; 2; 3 }
|
|
/// new Listing { 1; 2; 1 }.distinct == new Listing { 1; 2 }
|
|
/// ```
|
|
@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:
|
|
/// ```
|
|
/// new Listing { "a"; "ab"; "abc" }.distinctBy((it) -> it.length) == new Listing { "a"; "ab"; "abc" }
|
|
/// new Listing { "a"; "ab"; "c" }.distinctBy((it) -> it.length) == new Listing { "a"; "ab" }
|
|
/// ```
|
|
@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
|
|
|
|
/// Folds this listing in iteration order using [operator], starting with [initial].
|
|
///
|
|
/// The first parameter of [operator] is the zero-based index of the current element.
|
|
external function foldIndexed<Result>(
|
|
initial: Result,
|
|
operator: (Int, Result, Element) -> Result,
|
|
): Result
|
|
|
|
/// Converts the elements of this listing to strings and concatenates them inserting [separator]
|
|
/// between elements.
|
|
external function join(separator: String): String
|
|
|
|
/// Converts this listing to a [List].
|
|
external function toList(): List<Element>
|
|
|
|
/// Converts this listing to a [Set].
|
|
external function toSet(): Set<Element>
|
|
}
|
|
|
|
/// An object containing an ordered sequence of key-value pairs.
|
|
///
|
|
/// This class is the object equivalent of [Map].
|
|
///
|
|
/// To retrieve a value given its key, use subscript notation (`object[key]`),
|
|
/// which throws an error if no value is associated with the given key, or the `getOrNull` method.
|
|
/* Note: [Key] can be co-variant as long as [getOrNull], [containsKey], and similar methods admit keys of type [Any]. */
|
|
class Mapping<out Key, out Value> extends Object {
|
|
/// The function used to compute the default value for a mapping entry given its key.
|
|
hidden default: (Key) -> Value = (_) -> new Dynamic {}
|
|
|
|
/// Tells if this mapping is empty, that is, has zero entries.
|
|
external isEmpty: Boolean
|
|
|
|
/// Tells whether this mapping is not empty, that is, it has at least one entry.
|
|
@Since { version = "0.31.0" }
|
|
external isNotEmpty: Boolean
|
|
|
|
/// The number of entries in this mapping.
|
|
external length: Int
|
|
|
|
/// The keys contained in this mapping.
|
|
external keys: Set<Key>
|
|
|
|
/// 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].
|
|
///
|
|
/// This is the nullable equivalent of the subscript operator (`object[key]`).
|
|
external function getOrNull(key: Any): Value?
|
|
|
|
/// Returns the value associated with [key] or [default] applied to [key] if this mapping does
|
|
/// not contain [key].
|
|
///
|
|
/// This is equivalent to `getOrNull(key) ?? default.apply(key)`.
|
|
@Since { version = "0.29.0" }
|
|
external function getOrDefault(key: Any): Value
|
|
|
|
/// 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>
|
|
}
|
|
|
|
/// Base class for function literals (also known as *lambda expressions*).
|
|
abstract external class Function<out Result> extends Any {
|
|
@AlsoKnownAs { names { "call"; "invoke" } }
|
|
external function applyToList(argumentList: List<Any>): Result
|
|
}
|
|
|
|
/// A function literal with zero parameters.
|
|
external class Function0<out Result> extends Function<Result> {
|
|
@AlsoKnownAs { names { "call"; "invoke" } }
|
|
external function apply(): Result
|
|
}
|
|
|
|
/// A function literal with one parameter.
|
|
external class Function1<in Param1, out Result> extends Function<Result> {
|
|
@AlsoKnownAs { names { "call"; "invoke" } }
|
|
external function apply(p1: Param1): Result
|
|
}
|
|
|
|
/// A function literal with two parameters.
|
|
external class Function2<in Param1, in Param2, out Result> extends Function<Result> {
|
|
@AlsoKnownAs { names { "call"; "invoke" } }
|
|
external function apply(p1: Param1, p2: Param2): Result
|
|
}
|
|
|
|
/// A function literal with three parameters.
|
|
external class Function3<in Param1, in Param2, in Param3, out Result> extends Function<Result> {
|
|
@AlsoKnownAs { names { "call"; "invoke" } }
|
|
external function apply(p1: Param1, p2: Param2, p3: Param3): Result
|
|
}
|
|
|
|
/// A function literal with four parameters.
|
|
external class Function4<in Param1, in Param2, in Param3, in Param4, out Result>
|
|
extends Function<Result> {
|
|
@AlsoKnownAs { names { "call"; "invoke" } }
|
|
external function apply(p1: Param1, p2: Param2, p3: Param3, p4: Param4): Result
|
|
}
|
|
|
|
/// A function literal with five parameters.
|
|
external class Function5<in Param1, in Param2, in Param3, in Param4, in Param5, out Result>
|
|
extends Function<Result> {
|
|
@AlsoKnownAs { names { "call"; "invoke" } }
|
|
external function apply(p1: Param1, p2: Param2, p3: Param3, p4: Param4, p5: Param5): Result
|
|
}
|
|
|
|
/// An anonymous function used to apply the same modification to different objects.
|
|
///
|
|
/// Even though mixins are regular [Function]s, they are best created with object syntax:
|
|
/// ```
|
|
/// withNamePigeon = new Mixin<Person> { name = "Pigeon" } // explicit type
|
|
/// withNamePigeon: Mixin<Person> = new { name = "Pigeon" } // inferred type
|
|
/// ```
|
|
///
|
|
/// To apply a mixin to an object, use the `|>` (pipe) operator:
|
|
/// ```
|
|
/// pigeon = person |> withNamePigeon
|
|
/// ```
|
|
///
|
|
/// Like all object-returning functions, mixins can be amended:
|
|
/// ```
|
|
/// withNamePigeonAndAge42 = (withNamePigeon) { age = 42 }
|
|
/// pigeon42 = person |> withNamePigeonAndAge42
|
|
/// ```
|
|
typealias Mixin<Type> = (Type) -> Type
|
|
|
|
/// Throws an error indicating that the requested value is undefined.
|
|
external const function Undefined(): nothing
|
|
|
|
/// Throws an error indicating that the requested functionality has not yet been implemented.
|
|
const function TODO(): nothing = throw("TODO")
|
|
|
|
/// Creates a null value that turns into [defaultValue] when amended.
|
|
external const function Null(defaultValue: Object | Function<Object>): Null
|
|
|
|
/// Constructs a [Pair].
|
|
external const function Pair<First, Second>(first: First, second: Second): Pair<First, Second>
|
|
|
|
/// An ordered pair of elements.
|
|
///
|
|
/// To construct a [Pair], use method [Pair()].
|
|
external class Pair<out First, out Second> extends Any {
|
|
/// The first element of this pair.
|
|
external first: First
|
|
|
|
/// The second element of this pair.
|
|
external second: Second
|
|
|
|
/// Alias for [first].
|
|
external key: First
|
|
|
|
/// Alias for [second].
|
|
external value: Second
|
|
}
|
|
|
|
/// Common base class for [List] and [Set].
|
|
///
|
|
/// The following operators are supported for all collections:
|
|
/// ```
|
|
/// coll1 + coll2 // concatenation; result type is `Set` if `coll1` is a set and `List` otherwise
|
|
/// ```
|
|
///
|
|
/// Additionally, the following operators are supported for [List]s:
|
|
/// ```
|
|
/// coll[3] // subscript
|
|
/// ```
|
|
abstract external class Collection<out Element> extends Any {
|
|
/// The number of elements in this collection.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).length == 3
|
|
/// List().length == 0
|
|
/// ```
|
|
@AlsoKnownAs { names { "size"; "count" } }
|
|
abstract length: Int
|
|
|
|
/// Tells whether this collection is empty.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// !List(1, 2, 3).isEmpty
|
|
/// List().isEmpty
|
|
/// ```
|
|
abstract isEmpty: Boolean
|
|
|
|
/// Tells whether this collection is not empty.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).isNotEmpty
|
|
/// !List().isNotEmpty
|
|
/// ```
|
|
@Since { version = "0.31.0" }
|
|
abstract isNotEmpty: Boolean
|
|
|
|
/// The first element in this collection.
|
|
///
|
|
/// Throws if this collection is empty.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).first == 1
|
|
/// import("pkl:test").catch(() -> List().first)
|
|
/// ```
|
|
@AlsoKnownAs { names { "head" } }
|
|
abstract first: Element
|
|
|
|
/// Same as [first] but returns [null] if this collection is empty.
|
|
@AlsoKnownAs { names { "head" } }
|
|
abstract firstOrNull: Element?
|
|
|
|
/// The tail of this collection.
|
|
///
|
|
/// Throws if this collection is empty.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).rest == List(2, 3)
|
|
/// import("pkl:test").catch(() -> List().rest)
|
|
/// ```
|
|
@AlsoKnownAs { names { "tail" } }
|
|
abstract rest: Collection<Element>
|
|
|
|
/// Same as [rest] but returns [null] if this collection is empty.
|
|
@AlsoKnownAs { names { "tail" } }
|
|
abstract restOrNull: Collection<Element>?
|
|
|
|
/// The last element in this collection.
|
|
///
|
|
/// Throws if this collection is empty.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).last == 3
|
|
/// import("pkl:test").catch(() -> List().last)
|
|
/// ```
|
|
abstract last: Element
|
|
|
|
/// Same as [last] but returns [null] if this collection is empty.
|
|
abstract lastOrNull: Element?
|
|
|
|
/// The single element in this collection.
|
|
///
|
|
/// Throws if this collection has zero or more than one element.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1).single == 1
|
|
/// throws(() -> List().single)
|
|
/// throws(() -> List(1, 2, 3).single)
|
|
/// ```
|
|
abstract single: Element
|
|
|
|
/// Same as [single] but returns [null] if this collection is empty or has more than one element.
|
|
abstract singleOrNull: Element?
|
|
|
|
/// Tests if [element] is contained in this collection.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).contains(1)
|
|
/// List(1, 2, 3).contains(2)
|
|
/// List(1, 2, 3).contains(3)
|
|
/// !List(1, 2, 3).contains(4)
|
|
/// ```
|
|
// TODO: add containsAll
|
|
abstract function contains(element: Element): Boolean
|
|
|
|
/// Tests if this collection starts with the elements in [coll].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).startsWith(List(1, 2))
|
|
/// List(1, 2, 3).startsWith(List())
|
|
/// !List(1, 2, 3).startsWith(List(2, 3))
|
|
/// ```
|
|
abstract function startsWith(coll: Collection<Any>): Boolean
|
|
|
|
/// Tests if this collection ends with the elements in [coll].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).endsWith(List(2, 3))
|
|
/// List(1, 2, 3).endsWith(List())
|
|
/// !List(1, 2, 3).endsWith(List(1, 2))
|
|
/// ```
|
|
abstract function endsWith(coll: Collection<Any>): Boolean
|
|
|
|
/// Splits this collection into two at split point [index].
|
|
///
|
|
/// If [index] is zero or [length], one of the two collections is empty.
|
|
/// Throws if [index] is outside range `0`..[length].
|
|
abstract function split(index: Int): Pair<Collection<Element>, Collection<Element>>
|
|
|
|
/// Same as [split()] but returns [null] if [index] is outside range `0`..[length].
|
|
abstract function splitOrNull(index: Int): Pair<Collection<Element>, Collection<Element>>?
|
|
|
|
abstract function partition(
|
|
predicate: (Element) -> Boolean,
|
|
): Pair<Collection<Element>, Collection<Element>>
|
|
|
|
/// The zero-based index of the first occurrence of [element] in this collection.
|
|
///
|
|
/// Throws if this collection does not contains [element].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).indexOf(2) == 1
|
|
/// List(1, 2, 2).indexOf(2) == 1
|
|
/// import("pkl:test").catch(() -> List(1, 2, 3).indexOf(4))
|
|
/// ```
|
|
abstract function indexOf(element: Any): Int
|
|
|
|
/// Same as [indexOf()] but returns [null] if this collection does not contain [element].
|
|
abstract function indexOfOrNull(element: Any): Int?
|
|
|
|
/// The zero-based index of the last occurrence of [element] in this collection.
|
|
///
|
|
/// Throws if this collection does not contain [element].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).lastIndexOf(2) == 1
|
|
/// List(1, 2, 2).lastIndexOf(2) == 2
|
|
/// import("pkl:test").catch(() -> List(1, 2, 3).lastIndexOf(4))
|
|
/// ```
|
|
abstract function lastIndexOf(element: Any): Int
|
|
|
|
/// Same as [lastIndexOf()] but returns [null] if this collection does not contain [element].
|
|
abstract function lastIndexOfOrNull(element: Any): Int?
|
|
|
|
/// The first element for which [predicate] returns [true].
|
|
///
|
|
/// Throws if [predicate] does not hold for any element in this collection.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 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))
|
|
/// ```
|
|
abstract function find(predicate: (Element) -> Boolean): Element
|
|
|
|
/// Same as [find()] but returns [null] if [predicate] does not hold for any element in this
|
|
/// collection.
|
|
abstract function findOrNull(predicate: (Element) -> Boolean): Element?
|
|
|
|
/// The last element for which [predicate] returns [true].
|
|
///
|
|
/// Throws if [predicate] does not hold for any element in this collection.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(5, 6, 7).findLast((n) -> n.isEven) == 6
|
|
/// List(4, 6, 8).findLast((n) -> n.isEven) == 8
|
|
/// List(5, 7, 9).findLast((n) -> n.isEven) == null
|
|
/// ```
|
|
abstract function findLast(predicate: (Element) -> Boolean): Any
|
|
|
|
/// Same as [findLast()] but returns [null] if [predicate] does not hold for any element in this
|
|
/// collection.
|
|
abstract function findLastOrNull(predicate: (Element) -> Boolean): Element?
|
|
|
|
/// The index of the first element for which [predicate] returns [true].
|
|
///
|
|
/// Throws if [predicate] does not hold for any element in this collection.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 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))
|
|
/// ```
|
|
@AlsoKnownAs { names { "indexWhere" } }
|
|
abstract function findIndex(predicate: (Element) -> Boolean): Int
|
|
|
|
/// Same as [findIndex()] but returns [null] if [predicate] does not hold for any element in this
|
|
/// collection.
|
|
@AlsoKnownAs { names { "indexWhere" } }
|
|
abstract function findIndexOrNull(predicate: (Element) -> Boolean): Int?
|
|
|
|
/// The index of the last element for which [predicate] returns [true].
|
|
///
|
|
/// Throws if [predicate] does not hold for any element in this collection.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// 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))
|
|
/// ```
|
|
@AlsoKnownAs { names { "lastIndexWhere" } }
|
|
abstract function findLastIndex(predicate: (Element) -> Boolean): Int
|
|
|
|
/// Same as [findLastIndex()] but returns [null] if [predicate] does not hold for any element in
|
|
/// this collection.
|
|
@AlsoKnownAs { names { "lastIndexWhere" } }
|
|
abstract function findLastIndexOrNull(predicate: (Element) -> Boolean): Int?
|
|
|
|
/// The number of elements for which [predicate] returns [true].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).count((n) -> n.isEven) == 1
|
|
/// List(1, 2, 3).count((n) -> n.isOdd) == 2
|
|
/// List(1, 2, 3).count((n) -> n > 9) == 0
|
|
/// ```
|
|
abstract function count(predicate: (Element) -> Boolean): Int
|
|
|
|
/// Tests whether [predicate] holds for every element in this collection.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 3, 3).every((n) -> n.isOdd)
|
|
/// List().every((n) -> n.isOdd)
|
|
/// !List(1, 2, 3).every((n) -> n.isOdd)
|
|
/// ```
|
|
@AlsoKnownAs { names { "all"; "forall" } }
|
|
abstract function every(predicate: (Element) -> Boolean): Boolean
|
|
|
|
/// Tests whether [predicate] holds for at least one element in this collection.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).any((n) -> n.isEven)
|
|
/// !List(1, 2, 3).any((n) -> n.isEven)
|
|
/// !List().any((n) -> n.isEven)
|
|
/// ```
|
|
@AlsoKnownAs { names { "exists" } }
|
|
abstract function any(predicate: (Element) -> Boolean): Boolean
|
|
|
|
/// Retains elements for which [predicate] holds.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).filter((n) -> n.isOdd) == List(1, 3)
|
|
/// List(1, 2, 3).filter((n) -> n.isEven) == List(2)
|
|
/// List(1, 2, 3).filter((n) -> n > 9) == List()
|
|
/// ```
|
|
@AlsoKnownAs { names { "findAll"; "where" } }
|
|
abstract function filter(predicate: (Element) -> Boolean): Collection<Element>
|
|
|
|
/// Retains non-null elements.
|
|
///
|
|
/// Shorthand for `filter((it) -> it != null)`.
|
|
abstract function filterNonNull(): Collection<Element(this != null)>
|
|
|
|
/// Retains elements for which [predicate] holds.
|
|
///
|
|
/// [predicate] takes two arguments: the index of the element, and the element itself.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).filterIndexed((i, n) -> i.isOdd) == List(2)
|
|
/// List(1, 2, 3).filterIndexed((i, n) -> i.isEven) == List(1, 3)
|
|
/// List(1, 2, 3).filterIndexed((i, n) -> i.isOdd && n > 2) == List()
|
|
/// List(1, 2, 3).filterIndexed((i, n) -> i.isEven && n > 2) == List(3)
|
|
/// ```
|
|
@AlsoKnownAs { names { "findAll"; "where" } }
|
|
abstract function filterIndexed(predicate: (Int, Element) -> Boolean): Collection<Element>
|
|
|
|
/// Retains elements whose class is a subclass of [clazz].
|
|
///
|
|
/// Shorthand for `filter((it) -> it is X)`.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(42, "Pigeon", true, "Parrot").filterIsInstance(String) == List("Pigeon", "Parrot")
|
|
/// ```
|
|
@AlsoKnownAs { names { "whereType" } }
|
|
abstract function filterIsInstance<Type>(clazz: Class<Type>): Collection<Type>
|
|
|
|
/// Transforms this collection by applying [transform] to each element.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).map((n) -> n * 2) == List(2, 4, 6)
|
|
/// List(1, 2, 3).map((n) -> n.isEven) == List(false, true, false)
|
|
/// ```
|
|
abstract function map<Result>(transform: (Element) -> Result): Collection<Result>
|
|
|
|
/// Transforms this collection by applying [transform] to each element.
|
|
///
|
|
/// [transform] takes two arguments: the index of the element, and the element itself.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).mapIndexed((i, n) -> n * i) == List(0, 2, 6)
|
|
/// List(1, 2, 3).mapIndexed((i, n) -> i.isOdd && n.isEven) == List(false, true, false)
|
|
/// ```
|
|
abstract function mapIndexed<Result>(transform: (Int, Element) -> Result): Collection<Result>
|
|
|
|
/// Transforms this collection by applying [transform] to each element and removing resulting
|
|
/// [null] elements.
|
|
///
|
|
/// Equivalent to `map(transform).filterNonNull()`.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).mapNonNull((n) -> if (n.isOdd) null else n + 2) == List(4)
|
|
/// ```
|
|
@AlsoKnownAs { names { "filterMap" } }
|
|
abstract function mapNonNull<Result>(
|
|
transform: (Element) -> Result,
|
|
): Collection<Result(this != null)>
|
|
|
|
/// Transforms this collection by applying [transform] to each element and removing resulting
|
|
/// [null] elements.
|
|
///
|
|
/// [transform] takes two arguments: the index of the element, and the element itself.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3, 4).mapNonNullIndexed((i, n) -> if (n.isOdd) null else n * i) == List(2, 12)
|
|
/// List(1, 2, 3, 4, null).mapNonNullIndexed((i, n) -> if (n?.isOdd ?? true) null else n * i) == List(2, 12)
|
|
/// ```
|
|
@Since { version = "0.29.0" }
|
|
abstract function mapNonNullIndexed<Result>(
|
|
transform: (Int, Element) -> Result,
|
|
): Collection<Result(this != null)>
|
|
|
|
/// Applies a collection-generating [transform] to each element in this collection
|
|
/// and concatenates the resulting collections.
|
|
///
|
|
/// Throws if [transform] produces a non-collection value.
|
|
abstract function flatMap<Result>(transform: (Element) -> Collection<Result>): Collection<Result>
|
|
|
|
/// Applies a collection-generating [transform] to each element in this collection
|
|
/// and concatenates the resulting collections.
|
|
///
|
|
/// [transform] takes two arguments: the index of the element, and the element itself.
|
|
///
|
|
/// Throws if [transform] produces a non-collection value.
|
|
abstract function flatMapIndexed<Result>(
|
|
transform: (Int, Element) -> Collection<Result>,
|
|
): Collection<Result>
|
|
|
|
/// Concatenates the elements in this collection, each of which must itself be a collection.
|
|
///
|
|
/// Throws if any element is not a collection.
|
|
/* Note: Can't specify return type precisely. */
|
|
abstract function flatten(): Collection
|
|
|
|
/// Adds [element] to this collection.
|
|
///
|
|
/// For [List], [element] is appended.
|
|
abstract function add<Other>(element: Other): Collection<Element | Other>
|
|
|
|
/// Returns the first [n] elements in this collection.
|
|
@AlsoKnownAs { names { "limit" } }
|
|
abstract function take(n: Int): Collection<Element>
|
|
|
|
/// Returns the last [n] elements in this collection.
|
|
abstract function takeLast(n: Int): Collection<Element>
|
|
|
|
/// Returns the longest prefix of this collection that satisfies [predicate].
|
|
abstract function takeWhile(predicate: (Element) -> Boolean): Collection<Element>
|
|
|
|
/// Returns the longest suffix of this collection that satisfies [predicate].
|
|
abstract function takeLastWhile(predicate: (Element) -> Boolean): Collection<Element>
|
|
|
|
/// Removes the first [n] elements in this collection.
|
|
@AlsoKnownAs { names { "skip" } }
|
|
abstract function drop(n: Int): Collection<Element>
|
|
|
|
/// Removes the last [n] elements in this collection.
|
|
@AlsoKnownAs { names { "skipLast" } }
|
|
abstract function dropLast(n: Int): Collection<Element>
|
|
|
|
/// Removes the longest prefix of this collection that satisfies [predicate].
|
|
@AlsoKnownAs { names { "skipWhile" } }
|
|
abstract function dropWhile(predicate: (Element) -> Boolean): Collection<Element>
|
|
|
|
/// Removes the longest suffix of this collection that satisfies [predicate].
|
|
@AlsoKnownAs { names { "skipLastWhile" } }
|
|
abstract function dropLastWhile(predicate: (Element) -> Boolean): Collection<Element>
|
|
|
|
/// Folds this collection in iteration order using [operator], starting with [initial].
|
|
abstract function fold<Result>(initial: Result, operator: (Result, Element) -> Result): Result
|
|
|
|
/// Folds this collection in reverse iteration order using [operator], starting with [initial].
|
|
@AlsoKnownAs { names { "foldRight" } }
|
|
abstract function foldBack<Result>(initial: Result, operator: (Element, Result) -> Result): Result
|
|
|
|
/// Folds this collection in iteration order using [operator], starting with [initial].
|
|
///
|
|
/// The first parameter of [operator] is the zero-based index of the current element.
|
|
abstract function foldIndexed<Result>(
|
|
initial: Result,
|
|
operator: (Int, Result, Element) -> Result,
|
|
): Result
|
|
|
|
/// Folds this collection in iteration order using [operator], starting with the first element.
|
|
///
|
|
/// Throws if this collection is empty.
|
|
abstract function reduce<Result>(operator: (Element | Result, Element) -> Result): Result
|
|
|
|
/// Same as [reduce()] but returns [null] if this collection is empty.
|
|
abstract function reduceOrNull<Result>(operator: (Element | Result, Element) -> Result): Result?
|
|
|
|
/// Groups the elements in this collection according to keys returned by [selector].
|
|
abstract function groupBy<Key>(selector: (Element) -> Key): Map<Key, Collection<Element>>
|
|
|
|
/// Concatenates this collection [n] times.
|
|
abstract function repeat(n: UInt): Collection<Element>
|
|
|
|
/// Returns the first element in this collection that is less than or equal to any other element.
|
|
///
|
|
/// Shorthand for `minWith((a, b) -> a < b)`.
|
|
///
|
|
/// Throws if this collection is empty, or if any two elements cannot be compared with `<`.
|
|
abstract min: Element
|
|
|
|
/// Same as [min] but returns [null] if this collection is empty.
|
|
abstract minOrNull: Element?
|
|
|
|
/// Returns the first element in this collection that is less than or equal to any other element
|
|
/// after applying [selector].
|
|
///
|
|
/// Shorthand for `minWith((a, b) -> selector.apply(a) < selector.apply(b))`.
|
|
///
|
|
/// Throws if this collection is empty or if any two elements cannot be compared with `<`.
|
|
abstract function minBy(selector: (Element) -> Comparable): Element
|
|
|
|
/// Same as [minBy()] but returns [null] if this collection is empty.
|
|
abstract function minByOrNull(selector: (Element) -> Comparable): Element?
|
|
|
|
/// Returns the first element in this collection that is less than or equal to any other element
|
|
/// according to [comparator].
|
|
///
|
|
/// [comparator] should return [true] if its first argument is less than its second argument, and
|
|
/// [false] otherwise.
|
|
///
|
|
/// Throws if this collection is empty.
|
|
abstract function minWith(comparator: (Element, Element) -> Boolean): Element
|
|
|
|
/// Same as [minWith()] but returns [null] if this collection is empty.
|
|
abstract function minWithOrNull(comparator: (Element, Element) -> Boolean): Element?
|
|
|
|
/// Returns the first element in this collection that is greater than or equal to any other
|
|
/// element.
|
|
///
|
|
/// Shorthand for `maxWith((a, b) -> a < b)`.
|
|
///
|
|
/// Throws if this collection is empty, or if any two elements cannot be compared with `<`.
|
|
abstract max: Element
|
|
|
|
/// Same as [max] but returns [null] if this collection empty.
|
|
abstract maxOrNull: Element
|
|
|
|
/// Returns the first element in this collection that is greater than or equal to any other
|
|
/// element after applying [selector].
|
|
///
|
|
/// Shorthand for `maxWith((a, b) -> selector.apply(a) < selector.apply(b))`.
|
|
///
|
|
/// Throws if this collection is empty, or if any two elements cannot be compared with `<` after
|
|
/// applying [selector].
|
|
abstract function maxBy(selector: (Element) -> Comparable): Element
|
|
|
|
/// Same as [maxBy()] but returns [null] if this collection is empty.
|
|
abstract function maxByOrNull(selector: (Element) -> Comparable): Element?
|
|
|
|
/// Returns the first element in this collection that is greater than or equal to any other
|
|
/// element according to [comparator].
|
|
///
|
|
/// [comparator] should return [true] if its first argument is less than its second argument, and
|
|
/// [false] otherwise.
|
|
///
|
|
/// Throws if this collection is empty.
|
|
abstract function maxWith(comparator: (Element, Element) -> Boolean | /*Deprecated*/ Int): Element
|
|
|
|
/// Same as [maxWith()] but returns [null] if this collection is empty.
|
|
abstract function maxWithOrNull(
|
|
comparator: (Element, Element) -> Boolean | /*Deprecated*/ Int,
|
|
): Element?
|
|
|
|
/// Sorts this collection of [Comparable] elements in ascending order.
|
|
///
|
|
/// Shorthand for `sortWith((a, b) -> a < b)`.
|
|
///
|
|
/// Throws if any two elements in this collection cannot be compared with `<`.
|
|
abstract function sort(): List<Element>
|
|
|
|
/// Sorts this collection in ascending order after applying [selector].
|
|
///
|
|
/// Shorthand for `sortWith((a, b) -> selector.apply(a) < selector.apply(b))`.
|
|
///
|
|
/// Throws if any two elements in this collection cannot be compared with `<` after applying
|
|
/// [selector].
|
|
abstract function sortBy(selector: (Element) -> Comparable): Collection<Element>
|
|
|
|
/// Sorts this collection according to [comparator].
|
|
///
|
|
/// [comparator] should return [true] if its first argument
|
|
/// comes before its second argument in the sort order, and [false] otherwise.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).sortWith((a, b) -> a > b)) == List(3, 2, 1)
|
|
/// ```
|
|
abstract function sortWith(
|
|
comparator: (Element, Element) -> Boolean | /*Deprecated*/ Int,
|
|
): Collection<Element>
|
|
|
|
/// Reverses the order of elements in this collection.
|
|
abstract function reverse(): Collection<Element>
|
|
|
|
/// Returns a collection that combines corresponding elements of [this] and [coll] in pairs.
|
|
///
|
|
/// The returned collection's length is the minimum of `this.length` and `coll.length`.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).zip(List(4, 5, 6)) == List(Pair(1, 4), Pair(2, 5), Pair(3, 6))
|
|
/// List(1, 2, 3).zip(List(4, 5, 6, 7, 8)) == List(Pair(1, 4), Pair(2, 5), Pair(3, 6))
|
|
/// ```
|
|
abstract function zip<Other>(coll: Collection<Other>): Collection<Pair<Element, Other>>
|
|
|
|
/// Transposes this two-dimensional collection of collections.
|
|
///
|
|
/// The *n*th row of the resulting collection corresponds to the
|
|
/// *n*th column of this collection.
|
|
/// Throws if an element of this collection is not itself a collection.
|
|
/* Note: Can't specify return type precisely. */
|
|
abstract function transpose(): Collection
|
|
|
|
/// Converts the elements of this collection to strings and concatenates them inserting
|
|
/// [separator] between elements.
|
|
abstract function join(separator: String): String
|
|
|
|
/// Converts this collection to a list.
|
|
///
|
|
/// Returns this collection if it already is a list.
|
|
abstract function toList(): List<Element>
|
|
|
|
/// Converts this collection to a set.
|
|
///
|
|
/// Returns this collection if it already is a set.
|
|
abstract function toSet(): Set<Element>
|
|
|
|
/// Converts this collection to a map by extracting a key and value from each element using the
|
|
/// given functions.
|
|
abstract function toMap<Key, Value>(
|
|
keyExtractor: (Element) -> Key,
|
|
valueExtractor: (Element) -> Value,
|
|
): Map<Key, Value>
|
|
|
|
/// Converts this collection to a [Listing].
|
|
abstract function toListing(): Listing<Element>
|
|
|
|
/// Converts this collection to a [Dynamic] object.
|
|
abstract function toDynamic(): Dynamic
|
|
}
|
|
|
|
/// Constructs an [IntSeq] with the given [start], [end], and step 1.
|
|
///
|
|
/// To set a step other than 1, use method [IntSeq.step()].
|
|
external const function IntSeq(start: Int, end: Int): IntSeq
|
|
|
|
/// A finite arithmetic sequence of integers.
|
|
///
|
|
/// A sequence has a [start], [end], and [step].
|
|
/// It is either ascending ([step] > 0) or descending ([step] < 0).
|
|
/// The default [step] is 1.
|
|
///
|
|
/// The members of a sequence are defined as:
|
|
///
|
|
/// - seq(0) = [start] + 0 * [step]
|
|
/// - seq(1) = [start] + 1 * [step]
|
|
/// - seq(2) = [start] + 2 * [step]
|
|
/// - etc. where seq(n) <= [end] if [step] > 0, and seq(n) >= [end] if [step] < 0
|
|
///
|
|
/// ## Construction
|
|
///
|
|
/// To construct a sequence, use method [IntSeq()]:
|
|
/// ```
|
|
/// ascending = IntSeq(2, 5)
|
|
/// empty = IntSeq(5, 2)
|
|
/// ```
|
|
///
|
|
/// To set a step other than 1, use method [step()]:
|
|
/// ```
|
|
/// descending = IntSeq(5, 2).step(-2)
|
|
/// ```
|
|
///
|
|
/// ## Iteration
|
|
///
|
|
/// To iterate over a sequence, use method [map()]:
|
|
/// ```
|
|
/// numbers = IntSeq(2, 5).map((n) -> n * 2)
|
|
/// ```
|
|
///
|
|
/// A sequence can also be iterated over in a *for-generator*:
|
|
/// ```
|
|
/// numbers {
|
|
/// for (n in IntSeq(2, 5)) {
|
|
/// n * 2
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// ## Equality
|
|
///
|
|
/// Two sequences are equal if and only if they contain the same members in the same order.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// IntSeq(2, 5) == IntSeq(2, 5)
|
|
/// IntSeq(2, -3) == IntSeq(2, -2) // both empty
|
|
/// IntSeq(2, 5).step(2) == IntSeq(2, 4).step(2)
|
|
/// ```
|
|
external class IntSeq extends Any {
|
|
/// The start of this sequence.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// IntSeq(2, 5).start == 2
|
|
/// ```
|
|
external start: Int
|
|
|
|
/// The inclusive end of this sequence.
|
|
///
|
|
/// Note that [end] may or may not be a member of this sequence.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// IntSeq(2, 5).start == 5
|
|
/// ```
|
|
external end: Int
|
|
|
|
/// The common difference of successive members of this sequence.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// IntSeq(5, 2).step == 1
|
|
/// IntSeq(5, 2).step(-2).step == -2
|
|
/// ```
|
|
external step: Int(isNonZero)
|
|
|
|
/// Changes [step] to [newValue].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// IntSeq(5, 2).step == 1
|
|
/// IntSeq(5, 2).step(-2).step == -2
|
|
/// ```
|
|
external function step(newValue: Int(isNonZero)): IntSeq
|
|
|
|
/// Folds this sequence in iteration order using [operator], starting with [initial].
|
|
external function fold<Result>(initial: Result, operator: (Result, Int) -> Result): Result
|
|
|
|
/// Applies [mapper] to each member of this sequence and returns the resulting values as a list.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// IntSeq(2, 5).map((it) -> it) == List(2, 3, 4, 5)
|
|
/// IntSeq(5, 2).map((it) -> it) == List()
|
|
/// IntSeq(5, 2).step(-1).map((it) -> it * 2) == List(10, 8, 6, 4)
|
|
/// ```
|
|
external function map<Result>(mapper: (Int) -> Result): List<Result>
|
|
|
|
/// Converts the elements of this sequence to a [List].
|
|
external function toList(): List<Int>
|
|
|
|
/// Converts the elements of this sequence to a [Listing].
|
|
external function toListing(): Listing<Int>
|
|
}
|
|
|
|
/// A variable number of method arguments of type [Type].
|
|
///
|
|
/// The purpose of this class is to document methods that accept a variable number of arguments.
|
|
/// Only standard library methods can accept a variable number of arguments.
|
|
external class VarArgs<Type>
|
|
|
|
/// Creates a list containing the given [elements].
|
|
///
|
|
/// This method accepts any number of arguments.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List().isEmpty
|
|
/// List("one", "two", "three").contains("two")
|
|
/// ```
|
|
external const function List<Element>(elements: VarArgs<Element>): List<Element>
|
|
|
|
/// An indexed sequence of elements.
|
|
///
|
|
/// The following operators are supported for lists:
|
|
/// ```
|
|
/// list[3] // subscript
|
|
/// list1 + list2 // concatenation
|
|
/// ```
|
|
external class List<out Element> extends Collection<Element> {
|
|
external length: Int
|
|
|
|
external isEmpty: Boolean
|
|
|
|
@Since { version = "0.31.0" }
|
|
external isNotEmpty: Boolean
|
|
|
|
/// The index of the last element in this list (same as `length - 1`).
|
|
///
|
|
/// Returns `-1` for an empty list.
|
|
external lastIndex: Int
|
|
|
|
/// Returns the element at [index].
|
|
///
|
|
/// Returns [null] if [index] is outside the bounds of this list.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(3, 9, 6).getOrNull(0) == 3
|
|
/// List(3, 9, 6).getOrNull(1) == 9
|
|
/// List(3, 9, 6).getOrNull(2) == 6
|
|
/// List(3, 9, 6).getOrNull(-1) == null
|
|
/// List(3, 9, 6).getOrNull(3) == null
|
|
/// List(3, 9, 6).getOrNull(99) == null
|
|
/// ```
|
|
external function getOrNull(index: Int): Element?
|
|
|
|
/// Returns the sublist from [start] until [exclusiveEnd].
|
|
///
|
|
/// Throws if [start] is outside range `0`..[length] or [exclusiveEnd] is outside range
|
|
/// [start]..[length].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(3, 9, 6).sublist(0, 1) == List(3)
|
|
/// List(3, 9, 6).sublist(0, 2) == List(3, 9)
|
|
/// List(3, 9, 6).sublist(1, 3) == List(9, 6)
|
|
/// List(3, 9, 6).sublist(0, 3) == List(3, 9, 6)
|
|
/// List(3, 9, 6).sublist(-1, 2) // error
|
|
/// List(3, 9, 6).sublist(1, 4) // error
|
|
/// List(3, 9, 6).sublist(9, 99) // error
|
|
/// ```
|
|
external function sublist(start: Int, exclusiveEnd: Int): List<Element>
|
|
|
|
/// Returns the sublist from [start] until [exclusiveEnd].
|
|
///
|
|
/// Returns [null] if [start] is outside range `0`..[length] or [exclusiveEnd] is outside range
|
|
/// [start]..[length].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(3, 9, 6).sublistOrNull(0, 1) == List(3)
|
|
/// List(3, 9, 6).sublistOrNull(0, 2) == List(3, 9)
|
|
/// List(3, 9, 6).sublistOrNull(1, 3) == List(9, 6)
|
|
/// List(3, 9, 6).sublistOrNull(0, 3) == List(3, 9, 6)
|
|
/// List(3, 9, 6).sublistOrNull(-1, 2) == null
|
|
/// List(3, 9, 6).sublistOrNull(1, 4) == null
|
|
/// List(3, 9, 6).sublistOrNull(9, 99) == null
|
|
/// ```
|
|
external function sublistOrNull(start: Int, exclusiveEnd: Int): List<Element>?
|
|
|
|
external first: Element
|
|
external firstOrNull: Element?
|
|
|
|
external rest: List<Element>
|
|
external restOrNull: List<Element>?
|
|
|
|
external last: Element
|
|
external lastOrNull: Element?
|
|
|
|
external single: Element
|
|
external singleOrNull: Element?
|
|
|
|
external function contains(element: Any): Boolean
|
|
external function startsWith(coll: Collection<Any>): Boolean
|
|
external function endsWith(coll: Collection<Any>): Boolean
|
|
|
|
external function split(index: Int): Pair<List<Element>, List<Element>>
|
|
external function splitOrNull(index: Int): Pair<List<Element>, List<Element>>?
|
|
external function partition(predicate: (Element) -> Boolean): Pair<List<Element>, List<Element>>
|
|
|
|
external function filter(predicate: (Element) -> Boolean): List<Element>
|
|
external function filterNonNull(): List<Element(this != null)>
|
|
external function map<Result>(transform: (Element) -> Result): List<Result>
|
|
external function mapNonNull<Result>(transform: (Element) -> Result): List<Result(this != null)>
|
|
external function flatMap<Result>(transform: (Element) -> Collection<Result>): List<Result>
|
|
|
|
external function filterIndexed(predicate: (Int, Element) -> Boolean): List<Element>
|
|
external function mapIndexed<Result>(transform: (Int, Element) -> Result): List<Result>
|
|
|
|
@Since { version = "0.29.0" }
|
|
external function mapNonNullIndexed<Result>(
|
|
transform: (Int, Element) -> Result,
|
|
): List<Result(this != null)>
|
|
external function flatMapIndexed<Result>(
|
|
transform: (Int, Element) -> Collection<Result>,
|
|
): List<Result>
|
|
|
|
external function filterIsInstance<Type>(clazz: Class<Type>): List<Type>
|
|
|
|
/// Tells whether this list contains no duplicate elements.
|
|
///
|
|
/// Equivalent to `length == toSet().length`.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).isDistinct
|
|
/// !List(1, 2, 1).isDistinct
|
|
/// ```
|
|
@AlsoKnownAs { names { "isUnique" } }
|
|
external isDistinct: Boolean
|
|
|
|
/// Tells whether this list contains no duplicate elements after applying [selector].
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List("a", "b", "abc").isDistinctBy((it) -> it.length)
|
|
/// !List("a", "ab", "c").isDistinctBy((it) -> it.length)
|
|
/// ```
|
|
@AlsoKnownAs { names { "isUniqueBy" } }
|
|
external function isDistinctBy(selector: (Element) -> Any): Boolean
|
|
|
|
/// Removes duplicate elements from this list, preserving the first occurrence of each element.
|
|
///
|
|
/// Equivalent to `toSet().toList()`.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List(1, 2, 3).distinct == List(1, 2, 3)
|
|
/// List(1, 2, 1).distinct == List(1, 2)
|
|
/// ```
|
|
@AlsoKnownAs { names { "unique" } }
|
|
external distinct: List<Element>
|
|
|
|
/// Removes elements that are duplicates after applying [selector] from this list, preserving the
|
|
/// first occurrence.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// List("a", "b", "abc").distinctBy((it) -> it.length) == List("a", "b", "abc")
|
|
/// List("a", "ab", "c").distinctBy((it) -> it.length) == List("a", "ab")
|
|
/// ```
|
|
@AlsoKnownAs { names { "uniqueBy" } }
|
|
external function distinctBy(selector: (Element) -> Any): List<Element>
|
|
|
|
external function flatten(): List
|
|
|
|
external function every(predicate: (Element) -> Boolean): Boolean
|
|
external function any(predicate: (Element) -> Boolean): Boolean
|
|
|
|
external function add<Other>(element: Other): List<Element | Other>
|
|
|
|
/// Replaces the element at [index] with [replacement].
|
|
///
|
|
/// Throws if [index] is outside the bounds of this list.
|
|
external function replace<Other>(index: Int, replacement: Other): List<Element | Other>
|
|
|
|
/// Replaces the element at [index] with [replacement].
|
|
///
|
|
/// Returns [null] if [index] is outside the bounds of this list.
|
|
external function replaceOrNull<Other>(index: Int, replacement: Other): List<Element | Other>?
|
|
|
|
/// Replaces the elements between indices [range] and [exclusiveEnd] with [replacement].
|
|
///
|
|
/// Throws if [range] or [exclusiveEnd] is outside the bounds of this list.
|
|
external function replaceRange<Other>(
|
|
start: Int,
|
|
exclusiveEnd: Int,
|
|
replacement: Collection<Other>,
|
|
): List<Element | Other>
|
|
|
|
/// Replaces the elements between indices [range] and [exclusiveEnd] with [replacement].
|
|
///
|
|
/// Returns [null] if [range] or [exclusiveEnd] is outside the bounds of this list.
|
|
external function replaceRangeOrNull<Other>(
|
|
start: Int,
|
|
exclusiveEnd: Int,
|
|
replacement: Collection<Other>,
|
|
): List<Element | Other>?
|
|
|
|
external function find(predicate: (Element) -> Boolean): Element
|
|
external function findOrNull(predicate: (Element) -> Boolean): Element?
|
|
|
|
external function findLast(predicate: (Element) -> Boolean): Element
|
|
external function findLastOrNull(predicate: (Element) -> Boolean): Element?
|
|
|
|
external function findIndex(predicate: (Element) -> Boolean): Int
|
|
external function findIndexOrNull(predicate: (Element) -> Boolean): Int?
|
|
|
|
external function findLastIndex(predicate: (Element) -> Boolean): Int
|
|
external function findLastIndexOrNull(predicate: (Element) -> Boolean): Int?
|
|
|
|
external function indexOf(element: Any): Int
|
|
external function indexOfOrNull(element: Any): Int?
|
|
|
|
external function lastIndexOf(element: Any): Int
|
|
external function lastIndexOfOrNull(element: Any): Int?
|
|
|
|
external function count(predicate: (Element) -> Boolean): Int
|
|
|
|
external function take(n: Int): List<Element>
|
|
external function takeWhile(predicate: (Element) -> Boolean): List<Element>
|
|
external function takeLast(n: Int): List<Element>
|
|
external function takeLastWhile(predicate: (Element) -> Boolean): List<Element>
|
|
|
|
external function drop(n: Int): List<Element>
|
|
external function dropWhile(predicate: (Element) -> Boolean): List<Element>
|
|
external function dropLast(n: Int): List<Element>
|
|
external function dropLastWhile(predicate: (Element) -> Boolean): List<Element>
|
|
|
|
external function fold<Result>(initial: Result, operator: (Result, Element) -> Result): Result
|
|
external function foldBack<Result>(initial: Result, operator: (Element, Result) -> Result): Result
|
|
external function foldIndexed<Result>(
|
|
initial: Result,
|
|
operator: (Int, Result, Element) -> Result,
|
|
): Result
|
|
|
|
external function reduce<Result>(operator: (Element | Result, Element) -> Result): Result
|
|
external function reduceOrNull<Result>(operator: (Element | Result, Element) -> Result): Result?
|
|
|
|
external function groupBy<Key>(selector: (Element) -> Key): Map<Key, List<Element>>
|
|
|
|
external function repeat(n: Int): List<Element>
|
|
|
|
external min: Element
|
|
external minOrNull: Element
|
|
|
|
external function minBy(selector: (Element) -> Comparable): Element
|
|
external function minByOrNull(selector: (Element) -> Comparable): Element?
|
|
|
|
external function minWith(comparator: (Element, Element) -> Boolean): Element
|
|
external function minWithOrNull(comparator: (Element, Element) -> Boolean): Element?
|
|
|
|
external max: Element
|
|
external maxOrNull: Element?
|
|
|
|
external function maxBy(selector: (Element) -> Comparable): Element
|
|
external function maxByOrNull(selector: (Element) -> Comparable): Element?
|
|
|
|
external function maxWith(comparator: (Element, Element) -> Boolean): Element
|
|
external function maxWithOrNull(comparator: (Element, Element) -> Boolean): Element?
|
|
|
|
external function sort(): List<Element>
|
|
external function sortBy(selector: (Element) -> Comparable): List<Element>
|
|
external function sortWith(comparator: (Element, Element) -> Boolean): List<Element>
|
|
|
|
external function reverse(): List<Element>
|
|
|
|
external function zip<Other>(coll: Collection<Other>): List<Pair<Element, Other>>
|
|
|
|
external function join(separator: String): String
|
|
|
|
external function toList(): List<Element>
|
|
|
|
external function toSet(): Set<Element>
|
|
|
|
external function toMap<Key, Value>(
|
|
keyExtractor: (Element) -> Key,
|
|
valueExtractor: (Element) -> Value,
|
|
): Map<Key, Value>
|
|
|
|
external function toListing(): Listing<Element>
|
|
|
|
external function toDynamic(): Dynamic
|
|
|
|
/// Converts this list to [Bytes].
|
|
///
|
|
/// Throws a type error if any of its elements are not [UInt8].
|
|
@Since { version = "0.29.0" }
|
|
external function toBytes(): Bytes
|
|
}
|
|
|
|
/// Creates a set containing the given [elements].
|
|
///
|
|
/// This method accepts any number of arguments.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// Set().isEmpty
|
|
/// Set("one", "two", "three").contains("two")
|
|
/// ```
|
|
external const function Set<Element>(elements: VarArgs<Element>): Set<Element>
|
|
|
|
/// A collection of unique elements.
|
|
///
|
|
/// Sets retain the order of elements when constructed, which affects the how they are iterated
|
|
/// over.
|
|
/// However, ordering does not affect equality between two sets.
|
|
///
|
|
/// The following operators are supported for sets:
|
|
/// ```
|
|
/// set1 + set2 // union
|
|
/// ```
|
|
external class Set<out Element> extends Collection<Element> {
|
|
external length: Int
|
|
|
|
external isEmpty: Boolean
|
|
|
|
@Since { version = "0.31.0" }
|
|
external isNotEmpty: Boolean
|
|
|
|
external first: Element
|
|
external firstOrNull: Element?
|
|
|
|
external rest: Set<Element>
|
|
external restOrNull: Set<Element>?
|
|
|
|
external last: Element
|
|
external lastOrNull: Element?
|
|
|
|
external single: Element
|
|
external singleOrNull: Element?
|
|
|
|
external function contains(element: Any): Boolean
|
|
external function startsWith(coll: Collection<Any>): Boolean
|
|
external function endsWith(coll: Collection<Any>): Boolean
|
|
|
|
external function split(index: Int): Pair<Set<Element>, Set<Element>>
|
|
external function splitOrNull(index: Int): Pair<Set<Element>, Set<Element>>?
|
|
external function partition(predicate: (Element) -> Boolean): Pair<Set<Element>, Set<Element>>
|
|
|
|
external function filter(predicate: (Element) -> Boolean): Set<Element>
|
|
external function filterNonNull(): Set<Element(this != null)>
|
|
external function map<Result>(transform: (Element) -> Result): Set<Result>
|
|
external function mapNonNull<Result>(transform: (Element) -> Result): Set<Result(this != null)>
|
|
external function flatMap<Result>(transform: (Element) -> Collection<Result>): Set<Result>
|
|
|
|
external function filterIndexed(predicate: (Int, Element) -> Boolean): Set<Element>
|
|
external function mapIndexed<Result>(transform: (Int, Element) -> Result): Set<Result>
|
|
|
|
@Since { version = "0.29.0" }
|
|
external function mapNonNullIndexed<Result>(
|
|
transform: (Int, Element) -> Result,
|
|
): Set<Result(this != null)>
|
|
external function flatMapIndexed<Result>(
|
|
transform: (Int, Element) -> Collection<Result>,
|
|
): Set<Result>
|
|
|
|
external function filterIsInstance<Type>(clazz: Class<Type>): Set<Type>
|
|
|
|
external function flatten(): Set
|
|
|
|
external function every(predicate: (Element) -> Boolean): Boolean
|
|
external function any(predicate: (Element) -> Boolean): Boolean
|
|
|
|
external function add<Other>(element: Other): Set<Element | Other>
|
|
|
|
external function find(predicate: (Element) -> Boolean): Element
|
|
external function findOrNull(predicate: (Element) -> Boolean): Element?
|
|
|
|
external function findLast(predicate: (Element) -> Boolean): Element
|
|
external function findLastOrNull(predicate: (Element) -> Boolean): Element?
|
|
|
|
external function count(predicate: (Element) -> Boolean): Int
|
|
|
|
external function take(n: Int): Set<Element>
|
|
external function takeWhile(predicate: (Element) -> Boolean): Set<Element>
|
|
external function takeLast(n: Int): Set<Element>
|
|
external function takeLastWhile(predicate: (Element) -> Boolean): Set<Element>
|
|
|
|
external function drop(n: Int): Set<Element>
|
|
external function dropWhile(predicate: (Element) -> Boolean): Set<Element>
|
|
external function dropLast(n: Int): Set<Element>
|
|
external function dropLastWhile(predicate: (Element) -> Boolean): Set<Element>
|
|
|
|
external function fold<Result>(initial: Result, operator: (Result, Element) -> Result): Result
|
|
external function foldBack<Result>(initial: Result, operator: (Element, Result) -> Result): Result
|
|
external function foldIndexed<Result>(
|
|
initial: Result,
|
|
operator: (Int, Result, Element) -> Result,
|
|
): Result
|
|
|
|
external function reduce<Result>(operator: (Element | Result, Element) -> Result): Result
|
|
external function reduceOrNull<Result>(operator: (Element | Result, Element) -> Result): Result?
|
|
|
|
external function groupBy<Key>(selector: (Element) -> Key): Map<Key, Set<Element>>
|
|
|
|
external function repeat(n: Int): List<Element>
|
|
|
|
external min: Element
|
|
external minOrNull: Element
|
|
|
|
external function minBy(selector: (Element) -> Int): Element
|
|
external function minByOrNull(selector: (Element) -> Int): Element?
|
|
|
|
external function minWith(comparator: (Element, Element) -> Boolean | /*Deprecated*/ Int): Element
|
|
external function minWithOrNull(
|
|
comparator: (Element, Element) -> Boolean | /*Deprecated*/ Int,
|
|
): Element?
|
|
|
|
external max: Element
|
|
external maxOrNull: Element?
|
|
|
|
external function maxBy(selector: (Element) -> Int): Element
|
|
external function maxByOrNull(selector: (Element) -> Int): Element?
|
|
|
|
external function maxWith(comparator: (Element, Element) -> Boolean | /*Deprecated*/ Int): Element
|
|
external function maxWithOrNull(
|
|
comparator: (Element, Element) -> Boolean | /*Deprecated*/ Int,
|
|
): Element?
|
|
|
|
external function sort(): List<Element>
|
|
external function sortBy(selector: (Element) -> Comparable): List<Element>
|
|
external function sortWith(
|
|
comparator: (Element, Element) -> Boolean | /*Deprecated*/ Int,
|
|
): List<Element>
|
|
|
|
external function reverse(): List<Element>
|
|
|
|
external function zip<Other>(coll: Collection<Other>): Set<Pair<Element, Other>>
|
|
|
|
external function join(separator: String): String
|
|
|
|
external function toList(): List<Element>
|
|
|
|
external function toSet(): Set<Element>
|
|
|
|
external function toMap<Key, Value>(
|
|
keyExtractor: (Element) -> Key,
|
|
valueExtractor: (Element) -> Value,
|
|
): Map<Key, Value>
|
|
|
|
external function toListing(): Listing<Element>
|
|
|
|
external function toDynamic(): Dynamic
|
|
|
|
/// The intersection of this set and [other].
|
|
external function intersect(other: Set): Set<Element>
|
|
|
|
/// The difference of this set and [other].
|
|
external function difference(other: Set): Set<Element>
|
|
}
|
|
|
|
/// Creates a map containing the given alternating [keysAndValues].
|
|
///
|
|
/// This method accepts any even number of arguments.
|
|
/// Facts:
|
|
/// ```
|
|
/// Map().isEmpty
|
|
/// Map("name", "Pigeon", "age", 42).keys == Set("name", "age")
|
|
/// Map("name", "Pigeon", "age", 42).values == Set("Pigeon", 42)
|
|
/// ```
|
|
external const function Map<Key, Value>(keysAndValues: VarArgs<Key | Value>): Map<Key, Value>
|
|
|
|
/// A mapping from keys to values.
|
|
///
|
|
/// Maps retain the order of entries when constructed, which affects the how they are iterated
|
|
/// over.
|
|
/// However, ordering of entries does not affect equality between two maps.
|
|
///
|
|
/// The following operators are supported for maps:
|
|
/// ```
|
|
/// map[key] // subscript; similar to `getOrNull` but throws if key not found
|
|
/// map1 + map2 // merge; if both maps have an entry with the same key, the entry in map2 wins
|
|
/// ```
|
|
/* Note: [Key] can be co-variant as long as [getOrNull], [containsKey], and similar methods admit keys of type [Any]. */
|
|
external class Map<out Key, out Value> extends Any {
|
|
/// The number of entries in this map.
|
|
external length: Int
|
|
|
|
/// Tells whether this map is empty.
|
|
external isEmpty: Boolean
|
|
|
|
/// Tells whether this map not empty.
|
|
@Since { version = "0.31.0" }
|
|
external isNotEmpty: Boolean
|
|
|
|
/// Returns the value for [key].
|
|
///
|
|
/// Returns [null] if this map does not contain [key].
|
|
external function getOrNull(key: Any): Value?
|
|
|
|
/// The keys contained in this map.
|
|
external keys: Set<Key>
|
|
|
|
/// The values contained in this map.
|
|
external values: List<Value>
|
|
|
|
/// The entries contained in this map.
|
|
external entries: List<Pair<Key, Value>>
|
|
|
|
/// Tells if this map contains an entry with the given key.
|
|
external function containsKey(key: Any): Boolean
|
|
|
|
/// Tells if this map contains an entry with the given value.
|
|
external function containsValue(value: Any): Boolean
|
|
|
|
/// Adds or updates [key] to [value].
|
|
external function put<NewKey, NewValue>(
|
|
key: NewKey,
|
|
value: NewValue,
|
|
): Map<NewKey | Key, NewValue | Value>
|
|
|
|
/// Removes the map entry with the given key.
|
|
///
|
|
/// Returns this map unchanged if it does not contain an entry with the given key.
|
|
external function remove(key: Any): Map<Key, Value>
|
|
|
|
/// Removes all entries for which [predicate] does not hold.
|
|
external function filter(predicate: (Key, Value) -> Boolean): Map<Key, Value>
|
|
|
|
/// Folds the entries of this map in iteration order using [operator], starting with [initial].
|
|
external function fold<Result>(initial: Result, operator: (Result, Key, Value) -> Result): Result
|
|
|
|
/// Transforms the entries of this map using [transform].
|
|
external function map<NewKey, NewValue>(
|
|
transform: (Key, Value) -> Pair<NewKey, NewValue>,
|
|
): Map<NewKey, NewValue>
|
|
|
|
/// Transforms the keys of this map using [transform].
|
|
external function mapKeys<NewKey>(transform: (Key, Value) -> NewKey): Map<NewKey, Value>
|
|
|
|
/// Transforms the values of this map using [transform].
|
|
external function mapValues<NewValue>(transform: (Key, Value) -> NewValue): Map<Key, NewValue>
|
|
|
|
/// Applies a map-generating [transform] to each map entry and concatenates the resulting maps.
|
|
external function flatMap<NewKey, NewValue>(
|
|
transform: (Key, Value) -> Map<NewKey, NewValue>,
|
|
): Map<NewKey, NewValue>
|
|
|
|
/// Tells if [predicate] holds for every entry of this map.
|
|
///
|
|
/// Returns [true] for an empty map.
|
|
external function every(predicate: (Key, Value) -> Boolean): Boolean
|
|
|
|
/// Tells if [predicate] holds for at least one entry of this map.
|
|
///
|
|
/// Returns [false] for an empty map.
|
|
external function any(predicate: (Key, Value) -> Boolean): Boolean
|
|
|
|
/// Returns this map.
|
|
external function toMap(): Map
|
|
|
|
/// Converts this map to a [Dynamic] object.
|
|
external function toDynamic(): Dynamic
|
|
|
|
/// Converts this map to a typed object of class [clazz].
|
|
///
|
|
/// Conforms to the semantics of the following manual conversion:
|
|
/// ```
|
|
/// class Person { name: String; age: Int }
|
|
/// map = Map(name, "Pigeon", age, 42)
|
|
/// function toTyped(map: Map): Person = new {
|
|
/// name = map.getOrNull("name") ?? super.name
|
|
/// age = map.getOrNull("age") ?? super.age
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// Notable behavior:
|
|
/// - Entries of [this] that have no corresponding property in [clazz] are ignored.
|
|
/// - [clazz] properties that have no corresponding entry in [this] have their defaults preserved.
|
|
/// - [clazz] properties that have neither a default nor a corresponding entry in [this]
|
|
/// throw an "undefined property" error (only) when accessed.
|
|
///
|
|
/// Throws if [clazz] is abstract or not a subclass of [Typed].
|
|
external function toTyped<Type>(clazz: Class<Type>): Type(this is Typed)
|
|
|
|
/// Converts this map to a [Mapping].
|
|
external function toMapping(): Mapping<Key, Value>
|
|
}
|
|
|
|
/// Creates [Bytes] from the given numbers.
|
|
///
|
|
/// Examples:
|
|
/// ```
|
|
/// bytes = Bytes(0x1, 0x2, 0x3, 0x4)
|
|
/// ```
|
|
@Since { version = "0.29.0" }
|
|
external const function Bytes(values: VarArgs<UInt8>): Bytes
|
|
|
|
/// A sequence of [UInt8] values.
|
|
///
|
|
/// Bytes can hold up to [math.maxInt] amount of bytes.
|
|
///
|
|
/// The following operators are supported for [Bytes]:
|
|
/// ```
|
|
/// bytes1 + bytes2 // concatenation
|
|
/// bytes[3] // subscript
|
|
/// ```
|
|
///
|
|
/// For other list-like procedures, convert this into a [List] using [toList()].
|
|
@Since { version = "0.29.0" }
|
|
external class Bytes extends Any {
|
|
/// The length of these bytes.
|
|
external length: Int
|
|
|
|
/// The number of bytes as [DataSize].
|
|
external size: DataSize
|
|
|
|
/// The bytes in base64 encoding.
|
|
external base64: String(isBase64)
|
|
|
|
/// The bytes in hexadecimal encoding.
|
|
external hex: String
|
|
|
|
/// The [MD5](https://en.wikipedia.org/wiki/MD5) hash of these bytes as hexadecimal string.
|
|
///
|
|
/// MD5 is cryptographically broken and should not be used for secure applications.
|
|
external md5: String
|
|
|
|
/// The [SHA-1](https://en.wikipedia.org/wiki/SHA-1) hash of these bytes as hexadecimal string.
|
|
///
|
|
/// SHA-1 is cryptographically broken and should not be used for secure applications.
|
|
external sha1: String
|
|
|
|
/// The [SHA-256](https://en.wikipedia.org/wiki/SHA-2) cryptographic hash of these bytes as
|
|
/// hexadecimal string.
|
|
external sha256: String
|
|
|
|
/// The first 64 bits of the [SHA-256](https://en.wikipedia.org/wiki/SHA-2) cryptographic hash of
|
|
/// these bytes.
|
|
external sha256Int: Int
|
|
|
|
/// Returns the element at [index].
|
|
///
|
|
/// Returns [null] if [index] is outside the bounds of these Bytes.
|
|
///
|
|
/// Facts:
|
|
/// ```
|
|
/// Bytes(3, 9, 6).getOrNull(0) == 3
|
|
/// Bytes(3, 9, 6).getOrNull(1) == 9
|
|
/// Bytes(3, 9, 6).getOrNull(2) == 6
|
|
/// Bytes(3, 9, 6).getOrNull(-1) == null
|
|
/// Bytes(3, 9, 6).getOrNull(3) == null
|
|
/// Bytes(3, 9, 6).getOrNull(99) == null
|
|
/// ```
|
|
external function getOrNull(index: Int): UInt8?
|
|
|
|
/// Converts these bytes into a string using the given [charset].
|
|
///
|
|
/// Throws if these bytes are invalid according to the given [charset].
|
|
external function decodeToString(charset: Charset): String
|
|
|
|
/// Converts these bytes into a [List].
|
|
external function toList(): List<UInt8>
|
|
}
|