diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Internal/Array_Like_Helpers.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Internal/Array_Like_Helpers.enso index a5172a6bad57..c63ad1013fea 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Internal/Array_Like_Helpers.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Internal/Array_Like_Helpers.enso @@ -36,6 +36,7 @@ new_vector_builder capacity = @Builtin_Method "Array_Like_Helpers.new_vector_bui length : (Array | Vector) -> Integer length array_like = @Builtin_Method "Array_Like_Helpers.length" +raw_length array_like = @Builtin_Method "Array_Like_Helpers.raw_length" at : (Array | Vector) -> Integer -> Any at array_like index = @Builtin_Method "Array_Like_Helpers.at" @@ -82,8 +83,8 @@ vector_from_function length constructor on_problems = @Builtin_Method "Array_Lik `self` and `that`. See `Vector.zip` for full documentation. zip this that (function : Any -> Any -> Any = [_,_]) (skip_nothing : Boolean = False) (keep_unmatched : Boolean | Report_Unmatched = False) on_problems:(Problem_Behavior | No_Wrap)=..Report_Error = - left_len = this.length - right_len = that.length + left_len = this.raw_size + right_len = that.raw_size keep_unmatched_bool = case keep_unmatched of Report_Unmatched -> True @@ -131,8 +132,8 @@ zip this that (function : Any -> Any -> Any = [_,_]) (skip_nothing : Boolean = F Assumes that the ranges have been already bounds-checked (for example by passing them through `resolve_ranges`). slice_ranges vector ranges = - if ranges.length == 0 then [] else - if ranges.length != 1 then slice_many_ranges vector ranges else + if ranges.raw_size == 0 then [] else + if ranges.raw_size != 1 then slice_many_ranges vector ranges else case ranges.first of _ : Integer -> [vector.at ranges.first] Range.Between start end step -> case step == 1 of @@ -146,7 +147,7 @@ slice_ranges vector ranges = slice_many_ranges vector ranges = new_length = ranges.fold 0 acc-> descriptor-> case descriptor of _ : Integer -> acc+1 - _ : Range -> acc+descriptor.length + _ : Range -> acc+descriptor.raw_size Vector.build initial_capacity=new_length builder-> ranges.each descriptor-> case descriptor of _ : Integer -> @@ -208,18 +209,18 @@ take vector range = case range of rng = Random.new_generator seed rng.items vector count _ -> - take_helper vector.length (vector.at _) vector.slice (slice_ranges vector) range + take_helper vector.raw_size (vector.at _) vector.slice (slice_ranges vector) range drop vector range = - drop_helper vector.length (vector.at _) vector.slice (slice_ranges vector) range + drop_helper vector.raw_size (vector.at _) vector.slice (slice_ranges vector) range get vector index ~if_missing = - len = vector.length + len = vector.raw_size if index < -len || index >= len then if_missing else vector.at index insert vector at item = - self_len = vector.length + self_len = vector.raw_size used_index = if at < 0 then self_len + at else at if used_index < 0 || used_index > self_len then Error.throw (Index_Out_Of_Bounds.Error at self_len+1) else if used_index == self_len then vector + [item] else @@ -227,19 +228,19 @@ insert vector at item = insert_builtin vector used_index [item] remove vector at = - self_len = vector.length + self_len = vector.raw_size used_index = if at < 0 then self_len + at else at if used_index >= self_len || used_index < 0 then Error.throw (Index_Out_Of_Bounds.Error at self_len) else remove_builtin vector used_index index_of vector condition start = - self_len = vector.length + self_len = vector.raw_size check_start_valid start self_len used_start-> predicate = unify_condition_predicate_or_element condition - used_start.up_to vector.length . find if_missing=Nothing (i-> predicate (vector.at i)) + used_start.up_to vector.raw_size . find if_missing=Nothing (i-> predicate (vector.at i)) last_index_of vector condition start = - self_len = vector.length + self_len = vector.raw_size if self_len == 0 && (start==0 || start==-1) then Nothing else check_start_valid start self_len used_start-> predicate = unify_condition_predicate_or_element condition @@ -247,51 +248,51 @@ last_index_of vector condition start = any vector condition = predicate = unify_condition_or_predicate condition - 0.up_to vector.length . any (idx -> (predicate (vector.at idx))) + 0.up_to vector.raw_size . any (idx -> (predicate (vector.at idx))) all vector condition = predicate = unify_condition_or_predicate condition vector.any (predicate >> .not) . not plus vector that:(Vector | Array) = case that of - _ : Vector -> insert_builtin vector vector.length that + _ : Vector -> insert_builtin vector vector.raw_size that _ : Array -> plus vector (Vector.from_polyglot_array that) find vector condition start ~if_missing = predicate = unify_condition_or_predicate condition - self_len = vector.length + self_len = vector.raw_size check_start_valid start self_len used_start-> found = used_start.up_to self_len . find (idx -> (predicate (vector.at idx))) if_missing=Nothing if found.is_nothing then if_missing else vector.at found transpose vec_of_vecs = if vec_of_vecs.is_empty then [] else - length = vec_of_vecs.length - first_subvector_length = vec_of_vecs.at 0 . length + length = vec_of_vecs.raw_size + first_subvector_length = vec_of_vecs.at 0 . raw_size check_same_length vec_of_vecs <| inner i = Vector.from_polyglot_array (Array_Proxy.new length j-> ((vec_of_vecs.at j).at i)) proxy = Array_Proxy.new first_subvector_length inner Vector.from_polyglot_array proxy map vector function on_problems = - @Tail_Call vector_from_function vector.length (i-> function (vector.at i)) on_problems + @Tail_Call vector_from_function vector.raw_size (i-> function (vector.at i)) on_problems map_with_index vector function on_problems = - vector_from_function vector.length (i-> function i (vector.at i)) on_problems + @Tail_Call vector_from_function vector.raw_size (i-> function i (vector.at i)) on_problems flat_map vector function on_problems = vector.map function on_problems . flatten fold vector init function = f = acc -> ix -> function acc (vector.at ix) - 0.up_to vector.length . fold init f + 0.up_to vector.raw_size . fold init f fold_with_index vector init function = f = acc -> ix -> function acc ix (vector.at ix) - 0.up_to vector.length . fold init f + 0.up_to vector.raw_size . fold init f reduce vector function ~if_empty = - len = vector.length + len = vector.raw_size case len of 0 -> if_empty 1 -> vector.at 0 @@ -302,25 +303,25 @@ reduce vector function ~if_empty = fold_function (vector.at 0) 1 running_fold vector init function = - Vector.build initial_capacity=vector.length builder-> + Vector.build initial_capacity=vector.raw_size 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 - vector + (Vector.fill n-vector.length elem) + if vector.raw_size >= n then vector else + vector + (Vector.fill n-vector.raw_size elem) each vector f = - 0.up_to vector.length . each ix-> + 0.up_to vector.raw_size . each ix-> f (vector.at ix) each_with_index vector f = - 0.up_to vector.length . each ix-> + 0.up_to vector.raw_size . each ix-> f ix (vector.at ix) -reverse vector = Vector.new vector.length (i -> vector.at (vector.length - (1 + i))) +reverse vector = Vector.new vector.raw_size (i -> vector.at (vector.raw_size - (1 + i))) to_list vector = vector.reverse.fold List.Nil acc-> elem-> List.Cons elem acc @@ -328,20 +329,20 @@ to_list vector = short_display_text vector max_entries = if max_entries < 1 then Error.throw <| Illegal_Argument.Error "The `max_entries` parameter must be positive." else prefix = vector.take (..First max_entries) - if prefix.length == vector.length then vector.to_text else - remaining_count = vector.length - prefix.length + if prefix.raw_size == vector.raw_size then vector.to_text else + remaining_count = vector.raw_size - prefix.raw_size remaining_text = if remaining_count == 1 then "and 1 more element" else "and " + remaining_count.to_text + " more elements" prefix.map .to_text . join ", " "[" " "+remaining_text+"]" join vector separator prefix suffix = if vector.is_empty then prefix+suffix else - if vector.length == 1 then prefix + vector.at 0 + suffix else - prefix + vector.at 0 + (1.up_to vector.length . fold "" acc-> i-> acc + separator + vector.at i) + suffix + if vector.raw_size == 1 then prefix + vector.at 0 + suffix else + prefix + vector.at 0 + (1.up_to vector.raw_size . fold "" acc-> i-> acc + separator + vector.at i) + suffix partition vector condition = predicate = unify_condition_or_predicate condition - vecs = Vector.build_multiple 2 initial_capacity=(vector.length.div 2) function=builders-> + vecs = Vector.build_multiple 2 initial_capacity=(vector.raw_size.div 2) function=builders-> vector.map elem-> case predicate elem of True -> builders.at 0 . append elem @@ -376,9 +377,16 @@ filter_with_index vector predicate = check_same_length : Vector (Vector Any) -> Any -> Any ! Illegal_Argument check_same_length vecs ~action = if vecs.is_empty then action else - num_vecs = vecs.length - len = vecs.at 0 . length + num_vecs = vecs.raw_size + len = vecs.at 0 . raw_size go i = if i >= num_vecs then action else - if vecs.at i . length == len then @Tail_Call go (i+1) else - Error.throw (Illegal_Argument.Error "Transpose requires that all vectors be the same length, but rows 0 and "+i.to_text+" had different lengths ("+len.to_text+" and "+(vecs.at i . length).to_text+")") + if vecs.at i . raw_size == len then @Tail_Call go (i+1) else + Error.throw (Illegal_Argument.Error "Transpose requires that all vectors be the same length, but rows 0 and "+i.to_text+" had different lengths ("+len.to_text+" and "+(vecs.at i . raw_size).to_text+")") go 0 + +Vector.raw_size self = + raw_length self +Array.raw_size self = + raw_length self +Any.raw_size self = + self.length diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Warning.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Warning.enso index d22292d8ded6..f977a8a3582e 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Warning.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Warning.enso @@ -42,7 +42,8 @@ type Warning Are any warnings attached to the value? has_warnings : Any -> Any -> Boolean has_warnings value warning_type=Any = - Warning.get_all value . any (w-> w.value.is_a warning_type) + Warning.get_all value . any w-> + w.value.is_a warning_type ## --- private: true diff --git a/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/VectorTest.java b/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/VectorTest.java index 7d339121cff3..4bd979ab3d55 100644 --- a/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/VectorTest.java +++ b/engine/runtime-integration-tests/src/test/java/org/enso/interpreter/test/VectorTest.java @@ -15,11 +15,11 @@ import org.graalvm.polyglot.proxy.ProxyArray; import org.graalvm.polyglot.proxy.ProxyExecutable; import org.junit.ClassRule; -import org.junit.Ignore; import org.junit.Test; public class VectorTest { - @ClassRule public static final ContextUtils ctxRule = ContextUtils.createDefault(); + @ClassRule + public static final ContextUtils ctxRule = ContextUtils.newBuilder().assertGC(false).build(); @Test public void evaluation() throws Exception { @@ -164,13 +164,19 @@ public void vectorToArrayToVectorWithWarningViaForEach() throws Exception { warningsInContainer(3, 1); } + @Test + public void insertSelfWithWarningCheck() throws Exception { + var ww = warningsInContainer(4, 0); + assertTrue("Array: " + ww, ww.hasArrayElements()); + assertHasWarning("Has warnings", ww); + } + @Test public void insertSelfWithWarningViaForEach() throws Exception { warningsInContainer(4, 1); } @Test - @Ignore // calling vector.slice drops warnings from element values public void insertArgWithWarningViaForEach() throws Exception { warningsInContainer(5, 1); } @@ -190,7 +196,17 @@ public void vectorToArrayToVectorWithWarningViaMap() throws Exception { warningsInContainer(3, 2); } - private void warningsInContainer(int type, int callType) throws Exception { + @Test + public void insertSelfWithWarningViaMap() throws Exception { + warningsInContainer(4, 2); + } + + @Test + public void insertArgWithWarningViaMap() throws Exception { + warningsInContainer(5, 2); + } + + private Value warningsInContainer(int type, int callType) throws Exception { final URI srcUri = new URI("memory://warning.enso"); final Source src = Source.newBuilder( @@ -208,6 +224,7 @@ private void warningsInContainer(int type, int callType) throws Exception { 5 -> ([42]+v).slice 1 2 case call_type of + 0 -> container 1 -> container.each f 2 -> container.map f """, @@ -221,16 +238,23 @@ private void warningsInContainer(int type, int callType) throws Exception { var cnt = new int[1]; ProxyExecutable callback = (arg) -> { - if (ctxRule.unwrapValue(arg[0]) instanceof WithWarnings) { + if (arg[0].isNull()) { + fail("Expecting non-null value: " + arg[0]); + } + var raw = ctxRule.unwrapValue(arg[0]); + if (raw instanceof WithWarnings) { cnt[0]++; return null; } - fail("Unexpected value " + arg[0]); + fail("Unexpected value without warning " + raw + " type: " + raw.getClass().getName()); return null; }; - cb.execute(callback, type, callType); - assertEquals("One callback", 1, cnt[0]); + var res = cb.execute(callback, type, callType); + if (callType != 0) { + assertEquals("One callback", 1, cnt[0]); + } + return res; } private static final BitSet QUERIED = new BitSet(); @@ -340,4 +364,18 @@ private void noCopyTest(String factoryName) throws Exception { assertEquals("Two queries", 2, QUERIED.cardinality()); } } + + private static void assertHasWarning(String msg, Value v) { + var hasWarnings = + ctxRule.evalModule( + """ + from Standard.Base import Warning + main = Warning.has_warnings + """); + + var ok = hasWarnings.execute(v).asBoolean(); + if (!ok) { + fail("Value should have warnings: " + v); + } + } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/AtVectorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/AtVectorNode.java index bf73f6072c2c..006c4be60cd7 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/AtVectorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/AtVectorNode.java @@ -15,7 +15,7 @@ type = "Array_Like_Helpers", name = "at", description = "Returns an element of Vector at the specified index.") -public class AtVectorNode extends Node { +final class AtVectorNode extends Node { private @Child ArrayLikeAtNode at = ArrayLikeAtNode.create(); private @Child ArrayLikeLengthNode length; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FlattenVectorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FlattenVectorNode.java index e9714d6c523c..eeabd80d8957 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FlattenVectorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FlattenVectorNode.java @@ -20,7 +20,7 @@ name = "flatten", description = "Flattens a vector of vectors into a single vector.", autoRegister = false) -public abstract class FlattenVectorNode extends Node { +abstract class FlattenVectorNode extends Node { static FlattenVectorNode build() { return FlattenVectorNodeGen.create(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FromArrayBuiltinVectorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FromArrayBuiltinVectorNode.java index 34fef9fbc447..4fc875b792c9 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FromArrayBuiltinVectorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FromArrayBuiltinVectorNode.java @@ -14,7 +14,7 @@ name = "from_array", description = "Creates a Vector by copying Array content.", autoRegister = false) -public abstract class FromArrayBuiltinVectorNode extends Node { +abstract class FromArrayBuiltinVectorNode extends Node { static FromArrayBuiltinVectorNode build() { return FromArrayBuiltinVectorNodeGen.create(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FromPolyglotArrayBuiltinVectorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FromPolyglotArrayBuiltinVectorNode.java index 7048bf07880f..a5d3076d18dc 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FromPolyglotArrayBuiltinVectorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/FromPolyglotArrayBuiltinVectorNode.java @@ -1,6 +1,7 @@ package org.enso.interpreter.node.expression.builtin.immutable; -import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; @@ -18,7 +19,7 @@ "Creates a Vector by providing its underlying storage as a polyglot array. The underlying" + " array should be guaranteed to never be mutated.", autoRegister = false) -public abstract class FromPolyglotArrayBuiltinVectorNode extends Node { +abstract class FromPolyglotArrayBuiltinVectorNode extends Node { static FromPolyglotArrayBuiltinVectorNode build() { return FromPolyglotArrayBuiltinVectorNodeGen.create(); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/InsertBuiltinVectorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/InsertBuiltinVectorNode.java index dd0ec10ee156..5afefcf8b5e7 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/InsertBuiltinVectorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/InsertBuiltinVectorNode.java @@ -15,7 +15,7 @@ name = "insert_builtin", description = "Inserts a set of values into the Vector at the specified index.", autoRegister = false) -public abstract class InsertBuiltinVectorNode extends Node { +abstract class InsertBuiltinVectorNode extends Node { static InsertBuiltinVectorNode build() { return InsertBuiltinVectorNodeGen.create(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/LengthVectorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/LengthVectorNode.java index 839dbf277f1f..98b9ccb9fc0e 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/LengthVectorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/LengthVectorNode.java @@ -1,7 +1,6 @@ package org.enso.interpreter.node.expression.builtin.immutable; import com.oracle.truffle.api.nodes.Node; -import org.enso.interpreter.dsl.AcceptsWarning; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode; @@ -9,10 +8,10 @@ type = "Array_Like_Helpers", name = "length", description = "Returns the length of this Vector.") -public class LengthVectorNode extends Node { +final class LengthVectorNode extends Node { @Child ArrayLikeLengthNode length = ArrayLikeLengthNode.create(); - long execute(@AcceptsWarning Object arrayLike) { + final Object execute(Object arrayLike) { return length.executeLength(arrayLike); } } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/RawLengthVectorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/RawLengthVectorNode.java new file mode 100644 index 000000000000..99449c024fba --- /dev/null +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/RawLengthVectorNode.java @@ -0,0 +1,18 @@ +package org.enso.interpreter.node.expression.builtin.immutable; + +import com.oracle.truffle.api.nodes.Node; +import org.enso.interpreter.dsl.AcceptsWarning; +import org.enso.interpreter.dsl.BuiltinMethod; +import org.enso.interpreter.runtime.data.vector.ArrayLikeLengthNode; + +@BuiltinMethod( + type = "Array_Like_Helpers", + name = "raw_length", + description = "Returns the length of this Vector.") +final class RawLengthVectorNode extends Node { + @Child ArrayLikeLengthNode length = ArrayLikeLengthNode.create(); + + final Object execute(@AcceptsWarning Object arrayLike) { + return length.executeLength(arrayLike); + } +} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/RemoveAtVectorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/RemoveAtVectorNode.java index ff05b8a1ab59..bbf95814b690 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/RemoveAtVectorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/RemoveAtVectorNode.java @@ -14,7 +14,7 @@ name = "remove_builtin", description = "Removes a value for the vector at the specified index.", autoRegister = false) -public abstract class RemoveAtVectorNode extends Node { +abstract class RemoveAtVectorNode extends Node { static RemoveAtVectorNode build() { return RemoveAtVectorNodeGen.create(); } diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java index f1247ae066c5..56babfd5a02b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/immutable/SliceArrayVectorNode.java @@ -10,7 +10,7 @@ type = "Array_Like_Helpers", name = "slice", description = "Returns a slice of this Vector.") -public final class SliceArrayVectorNode extends Node { +final class SliceArrayVectorNode extends Node { private @Child ArrayLikeLengthNode lengthNode = ArrayLikeLengthNode.create(); private SliceArrayVectorNode() {} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Vector.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Vector.java index 2fad7a282ae8..58a2ff85edd2 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Vector.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/data/vector/Vector.java @@ -89,7 +89,7 @@ public String toString() { } static Vector fromInteropArray(Object arr) { - return new Generic(arr); + return new Generic(arr, null); } static Vector fromLongArray(long[] arr) { @@ -174,8 +174,9 @@ boolean isLimitReached() { @ExportLibrary(WarningsLibrary.class) static final class Generic extends Vector { private final Object storage; + private Boolean withWarnings; - private Generic(Object storage) { + private Generic(Object storage, Boolean withWarnings) { if (CompilerDirectives.inInterpreter()) { if (!InteropLibrary.getUncached().hasArrayElements(storage)) { throw EnsoContext.get(null) @@ -184,6 +185,7 @@ private Generic(Object storage) { } } this.storage = storage; + this.withWarnings = withWarnings; } final Object toArray() { @@ -261,7 +263,10 @@ boolean isArrayElementReadable( @ExportMessage boolean hasWarnings( @Cached.Shared(value = "warnsLib") @CachedLibrary(limit = "3") WarningsLibrary warnings) { - return warnings.hasWarnings(this.storage); + if (withWarnings == null) { + withWarnings = warnings.hasWarnings(this.storage); + } + return withWarnings; } @ExportMessage @@ -269,14 +274,22 @@ EnsoHashMap getWarnings( boolean shouldWrap, @Cached.Shared(value = "warnsLib") @CachedLibrary(limit = "3") WarningsLibrary warnings) throws UnsupportedMessageException { - return warnings.getWarnings(this.storage, shouldWrap); + if (withWarnings != null && !withWarnings) { + return EnsoHashMap.empty(); + } else { + return warnings.getWarnings(this.storage, shouldWrap); + } } @ExportMessage Generic removeWarnings( @Cached.Shared(value = "warnsLib") @CachedLibrary(limit = "3") WarningsLibrary warnings) throws UnsupportedMessageException { - return new Generic(warnings.removeWarnings(this.storage)); + if (withWarnings != null && !withWarnings) { + return this; + } else { + return new Generic(storage, false); + } } @ExportMessage diff --git a/test/Base_Tests/src/Data/Vector_Spec.enso b/test/Base_Tests/src/Data/Vector_Spec.enso index 544626bcfec5..99c4ed1f6459 100644 --- a/test/Base_Tests/src/Data/Vector_Spec.enso +++ b/test/Base_Tests/src/Data/Vector_Spec.enso @@ -1012,9 +1012,37 @@ type_spec suite_builder name alter = suite_builder.group name group_builder-> expected_warnings = expected_warnings_regular + [(Additional_Warnings.Error 2)] Warning.get_all result wrap_errors=True . map .value . should_equal expected_warnings + group_builder.specify "Warnings and length" <| + result = alter [Warning.attach "OKeyish" 20] + len = result.length + len . should_equal 1 + + has_warning = Warning.has_warnings len + if Java.is_instance result ArrayList then has_warning . should_be_false else + has_warning . should_be_true + + group_builder.specify "Warnings and length if check" <| + result = alter [Warning.attach "OKeyish" 20] + empty = if result.length == 0 then "empty" else "some" + empty . should_equal "some" + + has_warning = Warning.has_warnings empty + if Java.is_instance result ArrayList then has_warning . should_be_false else + has_warning . should_be_true + + group_builder.specify "Warnings and is_empty check" <| + result = alter [Warning.attach "OKeyish" 20] + empty = if result.is_empty then "empty" else "some" + empty . should_equal "some" + + has_warning = Warning.has_warnings empty + if Java.is_instance result ArrayList then has_warning . should_be_false else + has_warning . should_be_true + group_builder.specify "Warnings and each" <| result = alter [Warning.attach "OKeyish" 20] - has_at = Warning.has_warnings (result.at 0) + elem = result.at 0 + has_at = Warning.has_warnings elem # when calling ArrayList.new we strip all the warnings (currently) # as such the result object backed by ArrayList has no warnings