From 04c966f5145560769b7227b03e8fc489408b2f1f Mon Sep 17 00:00:00 2001 From: Lars Hamann Date: Thu, 15 Sep 2022 20:09:46 +0200 Subject: [PATCH] Issue #43: Fix Sequence()->insertAt() - Fixed wrong check of precondition - Fixed position of insert (0-based behavior of Java was ignored) - Added documentation for Sequence()->insertAt() to the USE manual - Added JavaDoc for insertAt --- manual/main.md | 10 ++++++-- .../use/uml/ocl/value/CollectionValue.java | 19 ++++----------- .../tzi/use/uml/ocl/value/SequenceValue.java | 23 +++++++++++++------ .../src/it/resources/testfiles/shell/t001.in | 18 +++++++++++++++ 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/manual/main.md b/manual/main.md index bd78424e9..a1a7cdd56 100644 --- a/manual/main.md +++ b/manual/main.md @@ -3438,14 +3438,20 @@ If `self` is a sequence of collections, then this operation returns the sequence concatenation of all its elements. **Notation:** `self->flatten()` -#### Append elements +#### Adding elements `append(y:T):Sequence(T) := self->union(Sequence{y})` results -in the sequence which consists of all elements of `y` with `y` +in the sequence which consists of all elements of `self` with `y` appended. **Notation:** `self->append(y)` +`insertAt(index:Integer,y:T):Sequence(T)` results +in the sequence which consists of all elements of `self` with `y` +inserted at position `index`. All elements that were at a position `p` with `p >= index` +are afterwards at position `p + 1`, i.e., they moved right. +**Notation:** `self->insertAt(1, y)` + #### Prepend elements `prepend(y:T):Sequence(T) := diff --git a/use-core/src/main/java/org/tzi/use/uml/ocl/value/CollectionValue.java b/use-core/src/main/java/org/tzi/use/uml/ocl/value/CollectionValue.java index dfd663737..32da0ada3 100644 --- a/use-core/src/main/java/org/tzi/use/uml/ocl/value/CollectionValue.java +++ b/use-core/src/main/java/org/tzi/use/uml/ocl/value/CollectionValue.java @@ -21,23 +21,12 @@ package org.tzi.use.uml.ocl.value; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.tzi.use.uml.ocl.type.CollectionType; -import org.tzi.use.uml.ocl.type.TupleType; +import org.tzi.use.uml.ocl.type.*; import org.tzi.use.uml.ocl.type.TupleType.Part; -import org.tzi.use.uml.ocl.type.Type; -import org.tzi.use.uml.ocl.type.TypeFactory; -import org.tzi.use.uml.ocl.type.UniqueLeastCommonSupertypeDeterminator; import org.tzi.use.util.collections.CollectionComparator; +import java.util.*; + /** * Base class for collection values. * @@ -85,7 +74,7 @@ public Type getRuntimeType() { protected abstract CollectionType getRuntimeType(Type elementType); /** - * Returns the element type of the resultType if + * Returns the type of the elements of resultType, if * it is a collection type. * Otherwise, a runtime exception is thrown. * @param resultType diff --git a/use-core/src/main/java/org/tzi/use/uml/ocl/value/SequenceValue.java b/use-core/src/main/java/org/tzi/use/uml/ocl/value/SequenceValue.java index 718bc1690..7894aad69 100644 --- a/use-core/src/main/java/org/tzi/use/uml/ocl/value/SequenceValue.java +++ b/use-core/src/main/java/org/tzi/use/uml/ocl/value/SequenceValue.java @@ -21,17 +21,17 @@ package org.tzi.use.uml.ocl.value; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - import org.tzi.use.uml.ocl.type.CollectionType; import org.tzi.use.uml.ocl.type.Type; import org.tzi.use.uml.ocl.type.Type.VoidHandling; import org.tzi.use.uml.ocl.type.TypeFactory; import org.tzi.use.util.StringUtil; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + /** * Sequence values. * @@ -208,13 +208,22 @@ public SequenceValue prepend(Type resultType, Value v) { return res; } + /** + * Constructs a new {@link SequenceValue} with {@link Value} v inserted + * at the position index. + * @param resultType The {link Type} of the newly created {@link SequenceValue} + * @param index The position to insert the element at + * @param v The value that is inserted at position index + * @return A new {@link SequenceValue} with v inserted at position index or + * null if index is not a valid index. + */ public SequenceValue insertAt(Type resultType, IntegerValue index, Value v) { - if (index.value() < 1 || index.value() >= fElements.size()) + if (index.value() < 1 || index.value() > fElements.size() + 1) return null; SequenceValue res = new SequenceValue(getResultElementType(resultType)); res.addAll(fElements); - res.fElements.add(index.value(), v); + res.fElements.add(index.value() - 1, v); return res; } diff --git a/use-gui/src/it/resources/testfiles/shell/t001.in b/use-gui/src/it/resources/testfiles/shell/t001.in index bc1bd2774..aca80cc00 100644 --- a/use-gui/src/it/resources/testfiles/shell/t001.in +++ b/use-gui/src/it/resources/testfiles/shell/t001.in @@ -1039,6 +1039,24 @@ ? Sequence{1,2,2,3}->asSet *-> Set{1,2,3} : Set(Integer) +? Sequence{}->insertAt(1, 'Z') +*-> Sequence{'Z'} : Sequence(String) + +? Sequence{'A','B'}->insertAt(1, 'Z') +*-> Sequence{'Z','A','B'} : Sequence(String) + +? Sequence{'A','B'}->insertAt(2, 'Z') +*-> Sequence{'A','Z','B'} : Sequence(String) + +? Sequence{'A','B'}->insertAt(3, 'Z') +*-> Sequence{'A','B','Z'} : Sequence(String) + +? Sequence{'A','B'}->insertAt(4, 'Z') +*-> null : OclVoid + +? Sequence{'A','B'}->insertAt(0, 'Z') +*-> null : OclVoid + # ## Flattening #