Convert Vector.new_builder to Vector.build in Standard.Base (#9754)

* Vector.build

* new_builder deprecated

* convert one

* convert vector_spec

* limit param

* convert vector

* docs

* changelog

* wip

* rename limit to capacity

* wip

* review

* append comments

* review

* wip

* wip

* fix tests

* docs

* wip

* wip

* fix filter warning propagation

* doc weird dependencies

* fix tests

* cleanup

* check builder result
This commit is contained in:
GregoryTravis 2024-04-25 10:38:29 -04:00 committed by GitHub
parent 12cbd900b4
commit b150b091b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 313 additions and 291 deletions

View File

@ -228,36 +228,36 @@ type Filter_Condition
Creates a Single_Choice Widget for delimiters.
default_widget : Boolean -> Boolean -> Boolean -> Boolean -> Boolean -> Widget
default_widget include_comparable=True include_text=True include_boolean=True include_nullable=True include_numeric=True =
options_builder = Vector.new_builder
if include_comparable then
options_builder.append "Less"
options_builder.append "Equal_Or_Less"
options_builder.append "Equal"
options_builder.append "Equal_Or_Greater"
options_builder.append "Greater"
options_builder.append "Not_Equal"
options_builder.append "Between"
if include_numeric then
options_builder.append "Is_Nan"
options_builder.append "Is_Infinite"
options_builder.append "Is_Finite"
if include_boolean then
options_builder.append "Is_True"
options_builder.append "Is_False"
if include_nullable then
options_builder.append "Is_Nothing"
options_builder.append "Not_Nothing"
if include_text then
options_builder.append "Is_Empty"
options_builder.append "Not_Empty"
options_builder.append "Equal_Ignore_Case"
options_builder.append "Starts_With"
options_builder.append "Ends_With"
options_builder.append "Contains"
options_builder.append "Like"
options_builder.append "Is_In"
options_before = Vector.build options_builder->
if include_comparable then
options_builder.append "Less"
options_builder.append "Equal_Or_Less"
options_builder.append "Equal"
options_builder.append "Equal_Or_Greater"
options_builder.append "Greater"
options_builder.append "Not_Equal"
options_builder.append "Between"
if include_numeric then
options_builder.append "Is_Nan"
options_builder.append "Is_Infinite"
options_builder.append "Is_Finite"
if include_boolean then
options_builder.append "Is_True"
options_builder.append "Is_False"
if include_nullable then
options_builder.append "Is_Nothing"
options_builder.append "Not_Nothing"
if include_text then
options_builder.append "Is_Empty"
options_builder.append "Not_Empty"
options_builder.append "Equal_Ignore_Case"
options_builder.append "Starts_With"
options_builder.append "Ends_With"
options_builder.append "Contains"
options_builder.append "Like"
options_builder.append "Is_In"
options = options_builder.to_vector.map constructor_name->
options = options_before.map constructor_name->
name = constructor_name.replace "_" " "
code = "(Filter_Condition." + constructor_name + ")"
[name, code]

View File

@ -159,16 +159,15 @@ sort_and_merge_ranges ranges =
sorted = ranges.filter (range-> range.is_empty.not) . sort on=(_.start)
if sorted.is_empty then [] else
current_ref = Ref.new sorted.first
builder = Vector.new_builder
sorted.drop 1 . each range->
current = current_ref.get
case range.start <= current.end of
True -> current_ref.put (current.start.up_to (current.end.max range.end))
False ->
builder.append current
current_ref.put range
builder.append current_ref.get
builder.to_vector
Vector.build builder->
sorted.drop 1 . each range->
current = current_ref.get
case range.start <= current.end of
True -> current_ref.put (current.start.up_to (current.end.max range.end))
False ->
builder.append current
current_ref.put range
builder.append current_ref.get
## PRIVATE
A helper that implements taking from an arbitrary collection using a set of

View File

@ -148,12 +148,12 @@ type JS_Object
new object_node =
make_field_names object =
name_iterator = object.fieldNames
builder = Vector.new_builder object.size
loop iterator builder =
if iterator.hasNext.not then builder.to_vector else
builder.append iterator.next
@Tail_Call loop iterator builder
loop name_iterator builder
Vector.build initial_capacity=object.size builder->
loop iterator builder =
if iterator.hasNext then
builder.append iterator.next
@Tail_Call loop iterator builder
loop name_iterator builder
JS_Object.Value object_node (make_field_names object_node)
## PRIVATE
@ -164,14 +164,15 @@ type JS_Object
from_pairs pairs =
mapper = ObjectMapper.new
new_object = mapper.createObjectNode
keys = pairs.fold Vector.new_builder current->pair->
case pair.first of
text : Text ->
jackson_value_node = to_json_node pair.second.to_js_object
new_object.set text jackson_value_node
current.append text
_ -> Error.throw (Illegal_Argument.Error "JS_Object.from_pairs: key must be a Text value")
JS_Object.Value new_object keys.to_vector
keys = Vector.build builder->
pairs.map pair->
case pair.first of
text : Text ->
jackson_value_node = to_json_node pair.second.to_js_object
new_object.set text jackson_value_node
builder.append text
_ -> Error.throw (Illegal_Argument.Error "JS_Object.from_pairs: key must be a Text value")
JS_Object.Value new_object keys
## PRIVATE
Value object_node ~field_array

View File

@ -116,11 +116,11 @@ Any.to_js_object self =
fs = m.fields
field_names = cons.fields
builder = Vector.new_builder field_names.length+2
builder.append type_pair
builder.append ["constructor", cons.name]
0.up_to field_names.length . map i-> builder.append [field_names.at i, fs.at i . to_js_object]
JS_Object.from_pairs builder.to_vector
pairs = Vector.build initial_capacity=field_names.length+2 builder->
builder.append type_pair
builder.append ["constructor", cons.name]
0.up_to field_names.length . map i-> builder.append [field_names.at i, fs.at i . to_js_object]
JS_Object.from_pairs pairs
_ : Meta.Constructor ->
type_name = Meta.get_qualified_type_name self . split '.' . at -2
JS_Object.from_pairs [["type", type_name], ["constructor", m.name]]
@ -144,13 +144,13 @@ Error.to_js_object self =
Custom serialization for Locale, serializes the language, country and variant.
Locale.to_js_object : JS_Object
Locale.to_js_object self =
b = Vector.new_builder 5
b.append ["type", "Locale"]
b.append ["constructor", "new"]
b.append ["language", self.language]
b.append ["country", self.country]
b.append ["variant", self.variant]
JS_Object.from_pairs b.to_vector
pairs = Vector.build initial_capacity=5 b->
b.append ["type", "Locale"]
b.append ["constructor", "new"]
b.append ["language", self.language]
b.append ["country", self.country]
b.append ["variant", self.variant]
JS_Object.from_pairs pairs
## PRIVATE
Converts the given value to a JSON serializable object.

View File

@ -542,9 +542,9 @@ type List
Convert this list to a vector with the same elements.
to_vector : Vector
to_vector self =
builder = self.fold (Vector.new_builder self.length) builder-> elem->
builder.append elem
builder.to_vector
Vector.build initial_capacity=self.length builder->
self.map elem->
builder.append elem
## PRIVATE
Generates a human-readable text representation of the list.

View File

@ -198,9 +198,9 @@ type Range
filter : (Filter_Condition | (Integer -> Boolean)) -> Vector Integer
filter self filter =
predicate = unify_condition_or_predicate filter
builder = self.fold Vector.new_builder builder-> elem->
if predicate elem then builder.append elem else builder
builder.to_vector
Vector.build builder->
self.map elem->
if predicate elem then builder.append elem
## GROUP Selections
ICON preparation
@ -344,11 +344,11 @@ type Range
(0.up_to 4).running_fold 0 (+)
running_fold : Any -> (Any -> Any -> Any) -> Vector Any
running_fold self init function =
wrapped builder value =
current = if builder.length == 0 then init else builder.last
builder.append (function current value)
built = self.fold (Vector.new_builder self.length) wrapped
built.to_vector
Vector.build builder->
process value =
current = if builder.length == 0 then init else builder.last
builder.append (function current value)
self.map process
## GROUP Logical
ICON preparation

View File

@ -214,21 +214,19 @@ type Statistic
max_moment_order = moment_order.filter (v-> v != Nothing) . fold 0 .max
Panic.handle_wrapped_dataflow_error <|
output = Vector.new_builder data.length
Vector.build initial_capacity=data.length builder->
counter = Accumulator.new has_min_max max_moment_order
data.fold counter current->value->
result = compute_fold current value
counter = Accumulator.new has_min_max max_moment_order
data.fold counter current->value->
result = compute_fold current value
row = Panic.throw_wrapped_if_error <| statistics.map on_problems=No_Wrap s-> case s of
Statistic.Maximum -> if result.count == 0 then Nothing else result.maximum
Statistic.Minimum -> if result.count == 0 then Nothing else result.minimum
_ -> result.compute s
output.append row
row = Panic.throw_wrapped_if_error <| statistics.map on_problems=No_Wrap s-> case s of
Statistic.Maximum -> if result.count == 0 then Nothing else result.maximum
Statistic.Minimum -> if result.count == 0 then Nothing else result.minimum
_ -> result.compute s
builder.append row
result
output.to_vector
result
## ICON math
Calculate a variance-covariance matrix between the input series.
@ -258,17 +256,14 @@ type Statistic
spearman_correlation : Vector Vector -> Vector Vector
spearman_correlation data =
Panic.handle_wrapped_dataflow_error <|
output = Vector.new_builder data.length
0.up_to data.length . each i->
output.append <|
Vector.new data.length j->
if j == i then 1 else
if j < i then (output.at j . at i) else
Panic.throw_wrapped_if_error <|
calculate_spearman_rank (data.at i) (data.at j)
output.to_vector
Vector.build initial_capacity=data.length builder->
0.up_to data.length . each i->
builder.append <|
Vector.new data.length j->
if j == i then 1 else
if j < i then (builder.at j . at i) else
Panic.throw_wrapped_if_error <|
calculate_spearman_rank (data.at i) (data.at j)
## PRIVATE
Assigns a rank to each value of data, dealing with equal values according to the method.

View File

@ -227,9 +227,8 @@ Text.last self = self.at -1
"건반(Korean)".characters
Text.characters : Vector Text
Text.characters self =
bldr = Vector.new_builder
self.each bldr.append
bldr.to_vector
Vector.build builder->
self.each builder.append
## GROUP Selections
ICON find
@ -561,21 +560,19 @@ Text.words : Boolean -> Vector Text
Text.words self keep_whitespace=False =
iterator = BreakIterator.getWordInstance
iterator.setText self
bldr = Vector.new_builder
fst = iterator.first
nxt = iterator.next
Vector.build builder->
fst = iterator.first
nxt = iterator.next
build prev nxt = if nxt == -1 then Nothing else
word = Text_Utils.substring self prev nxt
word_not_whitespace = (Text_Utils.is_all_whitespace word).not
if word_not_whitespace || keep_whitespace then bldr.append word
build prev nxt = if nxt == -1 then Nothing else
word = Text_Utils.substring self prev nxt
word_not_whitespace = (Text_Utils.is_all_whitespace word).not
if word_not_whitespace || keep_whitespace then builder.append word
next_nxt = iterator.next
@Tail_Call build nxt next_nxt
next_nxt = iterator.next
@Tail_Call build nxt next_nxt
build fst nxt
bldr.to_vector
build fst nxt
## ALIAS get lines
GROUP Text

View File

@ -120,15 +120,14 @@ type Regex
match_all self (input : Text) =
pattern_is_empty = self.pattern == ''
if pattern_is_empty then Error.throw (Illegal_Argument.Error "Cannot run match_all with an empty pattern") else
builder = Vector.new_builder
it = Match_Iterator.new self input
go it = case it.next of
Match_Iterator_Value.Next _ match next_it ->
builder.append match
@Tail_Call go next_it
Match_Iterator_Value.Last _ -> Nothing
go it
builder.to_vector
Vector.build builder->
it = Match_Iterator.new self input
go it = case it.next of
Match_Iterator_Value.Next _ match next_it ->
builder.append match
@Tail_Call go next_it
Match_Iterator_Value.Last _ -> Nothing
go it
## GROUP Selections
ICON find
@ -189,17 +188,16 @@ type Regex
texts . should_equal ["abcdefghij"]
split : Text -> Boolean -> Vector Text | Type_Error
split self (input : Text) (only_first : Boolean = False) =
builder = Vector.new_builder
it = Match_Iterator.new self input
go next = case next of
Match_Iterator_Value.Next filler _ next_it ->
builder.append filler.text
next = if only_first then next_it.early_exit else next_it.next
@Tail_Call go next
Match_Iterator_Value.Last filler ->
builder.append filler.text
go it.next
builder.to_vector
Vector.build builder->
it = Match_Iterator.new self input
go next = case next of
Match_Iterator_Value.Next filler _ next_it ->
builder.append filler.text
next = if only_first then next_it.early_exit else next_it.next
@Tail_Call go next
Match_Iterator_Value.Last filler ->
builder.append filler.text
go it.next
## GROUP Conversions
ICON split_text

View File

@ -206,19 +206,19 @@ resolve_index_or_range text descriptor = Panic.recover [Index_Out_Of_Bounds, Ill
case true_range.step == 1 of
True -> Span_Module.range_to_char_indices text true_range
False ->
ranges = Vector.new_builder
if true_range.step <= 0 then panic_on_non_positive_step
go start_index current_grapheme =
end_index = iterator.next
if (start_index == -1) || (end_index == -1) || (current_grapheme >= true_range.end) then Nothing else
ranges.append (start_index.up_to end_index)
## We advance by step-1, because we already advanced by
one grapheme when looking for the end of the previous
one.
@Tail_Call go (iterator.next true_range.step-1) current_grapheme+true_range.step
ranges = Vector.build builder->
if true_range.step <= 0 then panic_on_non_positive_step
go start_index current_grapheme =
end_index = iterator.next
if (start_index == -1) || (end_index == -1) || (current_grapheme >= true_range.end) then Nothing else
builder.append (start_index.up_to end_index)
## We advance by step-1, because we already advanced by
one grapheme when looking for the end of the previous
one.
@Tail_Call go (iterator.next true_range.step-1) current_grapheme+true_range.step
go (iterator.next true_range.start) true_range.start
Codepoint_Ranges.Value ranges.to_vector is_sorted_and_distinct=True
go (iterator.next true_range.start) true_range.start
Codepoint_Ranges.Value ranges is_sorted_and_distinct=True
## PRIVATE
Returns an array of UTF-16 code-unit indices corresponding to the beginning
@ -228,12 +228,11 @@ resolve_index_or_range text descriptor = Panic.recover [Index_Out_Of_Bounds, Ill
character_ranges text =
iterator = BreakIterator.getCharacterInstance
iterator.setText text
ranges = Vector.new_builder
go prev nxt = if nxt == -1 then Nothing else
ranges.append (prev.up_to nxt)
@Tail_Call go nxt iterator.next
go iterator.first iterator.next
ranges.to_vector
Vector.build builder->
go prev nxt = if nxt == -1 then Nothing else
builder.append (prev.up_to nxt)
@Tail_Call go nxt iterator.next
go iterator.first iterator.next
## PRIVATE
batch_resolve_indices_or_ranges text descriptors = Panic.recover [Index_Out_Of_Bounds, Illegal_Argument] <|
@ -244,25 +243,25 @@ batch_resolve_indices_or_ranges text descriptors = Panic.recover [Index_Out_Of_B
demand, using a Vector.Builder to cache any prior ranges for random
access.
characters = character_ranges text
ranges = Vector.new_builder
descriptors.each descriptor->
case descriptor of
_ : Integer ->
ranges.append (Panic.rethrow <| characters.at descriptor)
_ : Range ->
if descriptor.is_empty then 0.up_to 0 else
true_range = normalize_range descriptor characters.length
case true_range.step == 1 of
True ->
first_grapheme = Panic.rethrow <| characters.at true_range.start
last_grapheme = Panic.rethrow <| characters.at true_range.end-1
ranges.append (first_grapheme.start.up_to last_grapheme.end)
False ->
if true_range.start >= characters.length then
Panic.throw (Index_Out_Of_Bounds.Error true_range.start characters.length)
true_range.to_vector.each ix->
ranges.append (Panic.rethrow <| characters.at ix)
Codepoint_Ranges.Value ranges.to_vector is_sorted_and_distinct=False
ranges = Vector.build builder->
descriptors.each descriptor->
case descriptor of
_ : Integer ->
builder.append (Panic.rethrow <| characters.at descriptor)
_ : Range ->
if descriptor.is_empty then 0.up_to 0 else
true_range = normalize_range descriptor characters.length
case true_range.step == 1 of
True ->
first_grapheme = Panic.rethrow <| characters.at true_range.start
last_grapheme = Panic.rethrow <| characters.at true_range.end-1
builder.append (first_grapheme.start.up_to last_grapheme.end)
False ->
if true_range.start >= characters.length then
Panic.throw (Index_Out_Of_Bounds.Error true_range.start characters.length)
true_range.to_vector.each ix->
builder.append (Panic.rethrow <| characters.at ix)
Codepoint_Ranges.Value ranges is_sorted_and_distinct=False
## PRIVATE
panic_on_non_positive_step =

View File

@ -257,9 +257,9 @@ type Date_Range
filter : (Filter_Condition | (Date -> Boolean)) -> Vector Date
filter self filter =
predicate = unify_condition_or_predicate filter
builder = self.fold Vector.new_builder builder-> elem->
if predicate elem then builder.append elem else builder
builder.to_vector
Vector.build builder->
self.map elem->
if predicate elem then builder.append elem else builder
## GROUP Selections
ICON preparation

View File

@ -280,15 +280,15 @@ type Duration
example_to_json = (Duration.new seconds=10).to_js_object
to_js_object : JS_Object
to_js_object self =
b = Vector.new_builder 7
b.append ["type", "Duration"]
b.append ["constructor", "new"]
if self.hours==0 . not then b.append ["hours", self.hours]
if self.minutes==0 . not then b.append ["minutes", self.minutes]
if self.seconds==0 . not then b.append ["seconds", self.seconds]
if self.milliseconds==0 . not then b.append ["milliseconds", self.milliseconds]
if self.nanoseconds==0 . not then b.append ["nanoseconds", self.nanoseconds]
JS_Object.from_pairs b.to_vector
v = Vector.build initial_capacity=7 builder->
builder.append ["type", "Duration"]
builder.append ["constructor", "new"]
if self.hours==0 . not then builder.append ["hours", self.hours]
if self.minutes==0 . not then builder.append ["minutes", self.minutes]
if self.seconds==0 . not then builder.append ["seconds", self.seconds]
if self.milliseconds==0 . not then builder.append ["milliseconds", self.milliseconds]
if self.nanoseconds==0 . not then builder.append ["nanoseconds", self.nanoseconds]
JS_Object.from_pairs v
## PRIVATE
Convert Duration to a friendly string.

View File

@ -201,13 +201,13 @@ type Period
example_to_json = (Period.new months=10).to_js_object
to_js_object : JS_Object
to_js_object self =
b = Vector.new_builder 7
b.append ["type", "Period"]
b.append ["constructor", "new"]
if self.years==0 . not then b.append ["years", self.years]
if self.months==0 . not then b.append ["months", self.months]
if self.days==0 . not then b.append ["days", self.days]
JS_Object.from_pairs b.to_vector
v = Vector.build initial_capacity=7 builder->
builder.append ["type", "Period"]
builder.append ["constructor", "new"]
if self.years==0 . not then builder.append ["years", self.years]
if self.months==0 . not then builder.append ["months", self.months]
if self.days==0 . not then builder.append ["days", self.days]
JS_Object.from_pairs v
## PRIVATE
catch_java_exceptions operation ~action =

View File

@ -147,7 +147,7 @@ type Vector a
## PRIVATE
ADVANCED
DEPRECATED
DEPRECATED `Vector.build` is the preferred way to build `Vector`s.
Creates a new vector builder instance.
A vector `Builder` is a mutable data structure, that allows for gathering
@ -157,6 +157,9 @@ type Vector a
A vector allows to store an arbitrary number of elements in linear
memory. It is the recommended data structure for most applications.
The `Vector.build` method is preferred over `.new_builder`, since it
automatically closes and returns the finished `Vector`.
Arguments:
- capacity: Initial capacity of the Vector.Builder
@ -216,8 +219,11 @@ type Vector a
build : (Builder -> Any) -> Integer -> Vector
build (function : Builder -> Any) (initial_capacity : Integer = 10) -> Vector =
builder = Builder.new initial_capacity
result = function builder
result.if_not_error builder.to_vector
## TODO: This extra `case` is necessary to propagate warnings attached to
values that are added to the builder. Will be fixed in
https://github.com/enso-org/enso/issues/9733.
case function builder of
result -> result.if_not_error builder.to_vector
## PRIVATE
ADVANCED
@ -1200,12 +1206,17 @@ type Builder
number of elements and then convert them to a vector. This is
particularly useful when the number of elements is not known upfront.
> Example
In the following example we'll read items from the standard input,
until the string "end" is entered by the user and then return a vector
containing all items.
There are two common ways to create and use a `Builder`:
`Vector.new_builder` and `Vector.build`. `.build` is the preferred
approach.
- `Vector.new_builder`: creates a new `Builder`, which you have to
"close" at the end to get your newly-created `Vector`.
- `Vector.build`: takes a function which uses the `Builder`, and
automatically "closes" and returns the newly-created `Vector`.
Construct a vector using a builder that contains the items 1 to 10.
> Example
Construct a vector using a builder that contains the items 1 to 5,
using `.new_builder`.
example_new_builder =
do_build builder start stop =
@ -1215,6 +1226,18 @@ type Builder
builder = do_build Vector.new_builder 1 10
builder.to_vector
> Example
Construct a vector using a builder that contains the items 1 to 5,
using `.build`.
Vector.build initial_capacity=5 builder->
do_build start stop =
builder.append start
if start >= stop then Nothing else
@Tail_Call do_build start+1 stop
do_build 1 5
# => [1, 2, 3, 4, 5]
! TODO
We may want to revisit the fold pattern - it is required for correct
propagation of dataflow errors, but it is very easy to forget about it

View File

@ -666,12 +666,12 @@ type XML_Element
Convert to a JavaScript Object representing this XML_Element.
to_js_object : JS_Object ! XML_Error
to_js_object self =
builder = Vector.new_builder 4
builder.append ["type", "XML_Element"]
builder.append ["tag", self.name]
builder.append ["attributes", self.attributes.to_js_object]
builder.append ["children", self.children_cache.to_js_object]
JS_Object.from_pairs builder.to_vector
vec = Vector.build initial_capacity=4 builder->
builder.append ["type", "XML_Element"]
builder.append ["tag", self.name]
builder.append ["attributes", self.attributes.to_js_object]
builder.append ["children", self.children_cache.to_js_object]
JS_Object.from_pairs vec
## PRIVATE

View File

@ -132,17 +132,16 @@ slice_many_ranges vector ranges =
new_length = ranges.fold 0 acc-> descriptor-> case descriptor of
_ : Integer -> acc+1
_ : Range -> acc+descriptor.length
builder = Vector.new_builder new_length
ranges.each descriptor-> case descriptor of
_ : Integer ->
builder.append (vector.at descriptor)
Range.Between start end step -> case step == 1 of
True ->
builder.append_vector_range vector start end
False ->
descriptor.each ix->
builder.append (vector.at ix)
builder.to_vector
Vector.build initial_capacity=new_length builder->
ranges.each descriptor-> case descriptor of
_ : Integer ->
builder.append (vector.at descriptor)
Range.Between start end step -> case step == 1 of
True ->
builder.append_vector_range vector start end
False ->
descriptor.each ix->
builder.append (vector.at ix)
check_start_valid start length function =
used_start = if start < 0 then start + length else start
@ -269,11 +268,11 @@ reduce vector function ~if_empty =
fold_function (vector.at 0) 1
running_fold vector init function =
wrapped builder value =
current = if builder.length == 0 then init else builder.last
builder.append (function current value)
built = vector.fold (Vector.new_builder vector.length) wrapped
built.to_vector
Vector.build initial_capacity=vector.length builder->
wrapped value =
current = if builder.length == 0 then init else builder.last
builder.append (function current value)
vector.map wrapped
pad vector n elem =
if vector.length >= n then vector else
@ -325,14 +324,22 @@ partition_with_index vector predicate =
filter vector filter =
predicate = unify_condition_or_predicate filter
builder = vector.fold Vector.new_builder builder-> elem->
if predicate elem then builder.append elem else builder
builder.to_vector
## TODO: Correct propagation of warnings attached to vector elements
requires that this method return the list of `Builder`s that are returned
by `builder.append`. Will be fixed in
https://github.com/enso-org/enso/issues/9733.
Vector.build builder->
vector.map elem->
if predicate elem then builder.append elem
filter_with_index vector predicate =
builder = vector.fold_with_index Vector.new_builder builder-> ix-> elem->
if predicate ix elem then builder.append elem else builder
builder.to_vector
## TODO: Correct propagation of warnings attached to vector elements
requires that this method return the list of `Builder`s that are returned
by `builder.append`. Will be fixed in
https://github.com/enso-org/enso/issues/9733.
Vector.build builder->
vector.map_with_index ix-> elem->
if predicate ix elem then builder.append elem
## PRIVATE
Check that all vectors have the same length and return an informative message

View File

@ -47,21 +47,20 @@ type Analyzer
## PRIVATE
Runs basic validations that can happen on construction of the formatter, regardless of the context.
validate_after_parsing self ~continuation =
problem_builder = Vector.new_builder
self.check_possible_m_mismatches problem_builder
self.check_possible_seconds_aliasing problem_builder
self.check_24h_and_am_pm_collision problem_builder
Problem_Behavior.Report_Warning.attach_problems_after continuation problem_builder.to_vector
problems = Vector.build problem_builder->
self.check_possible_m_mismatches problem_builder
self.check_possible_seconds_aliasing problem_builder
self.check_24h_and_am_pm_collision problem_builder
Problem_Behavior.Report_Warning.attach_problems_after continuation problems
## PRIVATE
Prepares a list of warnings that are only reported when parsing using the
formatter.
get_parsing_only_warnings : Vector
get_parsing_only_warnings self =
problem_builder = Vector.new_builder
self.check_missing_am_pm_in_hour_parse problem_builder
self.check_missing_year_in_date_parse problem_builder
problem_builder.to_vector
Vector.build problem_builder->
self.check_missing_am_pm_in_hour_parse problem_builder
self.check_missing_year_in_date_parse problem_builder
## PRIVATE
check_possible_m_mismatches self problem_builder =

View File

@ -128,9 +128,9 @@ type Parser
if optional_nesting_level > 0 then
Panic.throw (Illegal_State.Error "Unterminated optional section. This should have been caught by the tokenizer.")
Format_Token.Optional_Section_Start ->
inner_builder = Vector.new_builder
go inner_builder (optional_nesting_level+1)
current_builder.append (Common_Nodes.Optional_Section inner_builder.to_vector)
results = Vector.build inner_builder->
go inner_builder (optional_nesting_level+1)
current_builder.append (Common_Nodes.Optional_Section results)
@Tail_Call go current_builder optional_nesting_level
Format_Token.Optional_Section_End ->
if optional_nesting_level <= 0 then
@ -139,9 +139,8 @@ type Parser
parsed_node = self.parse_common_token other_token
current_builder.append parsed_node
@Tail_Call go current_builder optional_nesting_level
root_builder = Vector.new_builder
go root_builder 0
root_builder.to_vector
Vector.build root_builder->
go root_builder 0
## PRIVATE
parse_common_token self token = case token of

View File

@ -826,16 +826,15 @@ type File
itself is returned.
list_descendants : File -> Vector File
list_descendants file =
builder = Vector.new_builder
go file =
builder.append file
case file.is_directory of
True ->
children = file.list_immediate_children
children.each go
False -> Nothing
go file
builder.to_vector
Vector.build builder->
go file =
builder.append file
case file.is_directory of
True ->
children = file.list_immediate_children
children.each go
False -> Nothing
go file
## PRIVATE

View File

@ -24,26 +24,25 @@ type File_Permissions
Converts the Enso atom to its Java enum counterpart.
to_java : Vector PosixFilePermission
to_java self =
result = Vector.new_builder
if self.owner.contains Permission.Read then
result.append PosixFilePermission.OWNER_READ
if self.owner.contains Permission.Write then
result.append PosixFilePermission.OWNER_WRITE
if self.owner.contains Permission.Execute then
result.append PosixFilePermission.OWNER_EXECUTE
if self.group.contains Permission.Read then
result.append PosixFilePermission.GROUP_READ
if self.group.contains Permission.Write then
result.append PosixFilePermission.GROUP_WRITE
if self.group.contains Permission.Execute then
result.append PosixFilePermission.GROUP_EXECUTE
if self.others.contains Permission.Read then
result.append PosixFilePermission.OTHERS_READ
if self.others.contains Permission.Write then
result.append PosixFilePermission.OTHERS_WRITE
if self.others.contains Permission.Execute then
result.append PosixFilePermission.OTHERS_EXECUTE
result.to_vector
Vector.new_builder result->
if self.owner.contains Permission.Read then
result.append PosixFilePermission.OWNER_READ
if self.owner.contains Permission.Write then
result.append PosixFilePermission.OWNER_WRITE
if self.owner.contains Permission.Execute then
result.append PosixFilePermission.OWNER_EXECUTE
if self.group.contains Permission.Read then
result.append PosixFilePermission.GROUP_READ
if self.group.contains Permission.Write then
result.append PosixFilePermission.GROUP_WRITE
if self.group.contains Permission.Execute then
result.append PosixFilePermission.GROUP_EXECUTE
if self.others.contains Permission.Read then
result.append PosixFilePermission.OTHERS_READ
if self.others.contains Permission.Write then
result.append PosixFilePermission.OTHERS_WRITE
if self.others.contains Permission.Execute then
result.append PosixFilePermission.OTHERS_EXECUTE
## GROUP Metadata
ICON metadata

View File

@ -120,10 +120,9 @@ type File_By_Line
- action: The action to perform on each line.
map : (Text -> Any) -> Vector Any
map self action =
builder = Vector.new_builder
wrapped_action _ t = builder.append (action t)
self.each_with_index wrapped_action
builder.to_vector
Vector.build builder->
wrapped_action _ t = builder.append (action t)
self.each_with_index wrapped_action
## ICON dataframe_map_column
Transforms each line in the file and returns the result as a vector.
@ -132,10 +131,9 @@ type File_By_Line
- action: The action to perform on each line.
map_with_index : (Integer -> Text -> Any) -> Vector Any
map_with_index self action =
builder = Vector.new_builder
wrapped_action i t = builder.append (action i t)
self.each_with_index wrapped_action
builder.to_vector
Vector.build builder->
wrapped_action i t = builder.append (action i t)
self.each_with_index wrapped_action
## GROUP Selections
ICON select_row

View File

@ -54,17 +54,17 @@ type File_Format_Metadata
## PRIVATE
to_display_text self -> Text =
entries = Vector.new_builder
self.path.if_not_nothing <|
entries.append "path="+self.path
self.name.if_not_nothing <|
entries.append "name="+self.name
self.extension.if_not_nothing <|
entries.append "extension="+self.extension
self.content_type.if_not_nothing <|
entries.append "content_type="+self.content_type
entries = Vector.build builder->
self.path.if_not_nothing <|
builder.append "path="+self.path
self.name.if_not_nothing <|
builder.append "name="+self.name
self.extension.if_not_nothing <|
builder.append "extension="+self.extension
self.content_type.if_not_nothing <|
builder.append "content_type="+self.content_type
description = if entries.is_empty then "No information" else entries.to_vector.join ", "
description = if entries.is_empty then "No information" else entries.join ", "
"(File_Format_Metadata: "+description+")"
## PRIVATE

View File

@ -1060,6 +1060,15 @@ add_specs suite_builder =
Error.throw (Illegal_Argument.Error "asdf")
v . should_fail_with (Illegal_Argument.Error "asdf")
group_builder.specify "example" <|
vec = Vector.build initial_capacity=5 builder->
do_build start stop =
builder.append start
if start >= stop then Nothing else
@Tail_Call do_build start+1 stop
do_build 1 5
vec . should_equal [1, 2, 3, 4, 5]
suite_builder.group "Vector/Array equality" group_builder->
v1 = [1, 2, 3]
a1 = v1.to_array

View File

@ -537,7 +537,7 @@ add_specs suite_builder setup =
map2 = Map.from_vector [[1, "FirstColumn"], [-3, "DifferentName!"]]
t2 = data.table.rename_columns map2 on_problems=Problem_Behavior.Report_Error
t2.should_fail_with Ambiguous_Column_Rename
err = t2.catch
err = t2.catch . inner_error
err.column_name . should_equal "beta"
err.new_names.sort . should_equal ["DifferentName!", "FirstColumn"]
@ -551,7 +551,7 @@ add_specs suite_builder setup =
map2 = Map.from_vector [["a.*".to_regex, "StartsWithA"], [".*a".to_regex, "EndsWithA"]]
t2 = t.rename_columns map2 on_problems=Problem_Behavior.Report_Error
t2.should_fail_with Ambiguous_Column_Rename
err = t2.catch
err = t2.catch . inner_error
err.column_name . should_equal "alpha"
err.new_names . sort . should_equal ["EndsWithA", "StartsWithA"]