Skip to content

Commit

Permalink
Merge d6ad23a into 6c90914
Browse files Browse the repository at this point in the history
  • Loading branch information
nicovio committed Sep 20, 2019
2 parents 6c90914 + d6ad23a commit 09a92fb
Show file tree
Hide file tree
Showing 10 changed files with 684 additions and 35 deletions.
50 changes: 37 additions & 13 deletions org.uqbar.project.wollok.lib/src/wollok/lang.wlk
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,17 @@ class Pair {
method key() = x
method value() = y

/**
* Two pairs are equal if they have the same values
*
* Example:
* new Pair(1, 2).equals(new Pair(1, 2)) ==> Answers true
*/
override method equals(other) {
self.checkNotNull(other, "equals")
return x == other.x() && y == other.y()
}

/** String representation of a Pair */
override method toString() = x.toString() + " -> " + y.toString()
}
Expand Down Expand Up @@ -912,6 +923,7 @@ class Collection {
* with default element separator (",")
*/
method join()

}

/**
Expand Down Expand Up @@ -950,13 +962,13 @@ class Set inherits Collection {
}

/**
* Returns a new copy of current Set.
* Converts an object to a Set. No effect on Sets.
*
* Examples
* #{1, 2, 3}.asSet() => Answers #{1, 2, 3}, which is a copy of original set
* #{}.asSet() => Answers #{}, also a copy of original #{}
* #{1, 2, 3}.asSet() => Answers #{1, 2, 3}
* #{}.asSet() => Answers #{}
*/
override method asSet() native
override method asSet() = self

/**
* Answers any element of a non-empty collection
Expand Down Expand Up @@ -1221,7 +1233,11 @@ class List inherits Collection {
*
* @see Set
*/
override method asSet() native
override method asSet() {
const result = #{}
result.addAll(self)
return result
}

/**
* Answers a view of the portion of this list between the specified fromIndex
Expand Down Expand Up @@ -1416,19 +1432,19 @@ class List inherits Collection {
*
*
* Examples:
* [].equals([]) => Answers true
* [1, 2].equals([2, 1]) => Answers false
* [1, 2].equals([1, 2]) => Answers true
* [] == [] => Answers true
* [1, 2] == [2, 1] => Answers false
* [1, 2] == [1, 2] => Answers true
*/
override method ==(other) native

/**
* Answers the list without duplicate elements
* Answers the list without duplicate elements. Preserves order of elements.
*
* [1, 3, 1, 5, 1, 3, 2, 5].withoutDuplicates() => Answers [1, 2, 3, 5]
* [1, 3, 1, 5, 1, 3, 2, 5].withoutDuplicates() => Answers [1, 3, 5, 2]
* [].withoutDuplicates() => Answers []
*/
method withoutDuplicates() = self.asSet().asList()
method withoutDuplicates() native

}

Expand Down Expand Up @@ -1604,7 +1620,15 @@ class Dictionary {
if (self.size() > 0) result = result.substring(0, result.length() - 2)
return result + "]"
}


/**
* Two dictionaries are equal if they have the same keys and values
*/
override method equals(other) {
self.checkNotNull(other, "equals")
return self.keys() == other.keys() && self.values() == other.values()
}

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,10 @@ class WCollection<T extends Collection<WollokObject>> {
wrapped.map[ if (it instanceof WCallable) call("toString") else toString ].join(separator)
}

def asSet(){
wrapped.toSet
}

@NativeMessage("==")
def wollokEqualsEquals(WollokObject other) { wollokEquals(other) }
def wollokEqualsEquals(WollokObject other) {
wollokEquals(other)
}

@NativeMessage("equals")
def wollokEquals(WollokObject other) {
Expand All @@ -115,7 +113,6 @@ class WCollection<T extends Collection<WollokObject>> {
verifyWollokElementsContained(other.getNativeCollection, wrapped)
}


protected def hasNativeType(WollokObject it) {
hasNativeType(this.class.name)
}
Expand Down
10 changes: 10 additions & 0 deletions org.uqbar.project.wollok.lib/src/wollok/lang/WList.xtend
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ class WList extends WCollection<List<WollokObject>> implements JavaWrapper<List<
}
wrapped = wrapped.sortWith(comparator)
}

def withoutDuplicates() {
val result = newArrayList
val comparator = new WollokObjectComparator
for (var i = 0; i < wrapped.size; i++) {
val element = wrapped.get(i)
if (result.forall [ newElement | comparator.compare(newElement, element) !== 0 ]) result.add(element)
}
result
}

def max() {
if (wrapped.isEmpty) throw new RuntimeException(NLS.bind(Messages.WollokRuntime_WrongMessage_EMPTY_LIST, "max"))
Expand Down
2 changes: 1 addition & 1 deletion org.uqbar.project.wollok.lib/src/wollok/lang/WSet.xtend
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class WSet extends WCollection<Set<WollokObject>> implements JavaWrapper<Set<Wol

override protected def verifyWollokElementsContained(Collection<WollokObject> set, Collection<WollokObject> set2) {
set2.forall [ elem |
set.exists[ it.wollokEquals(elem) ]
set.exists[ it.wollokEqualsMethod(elem) ]
]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class WollokObjectComparator implements Comparator<WollokObject> {
val comparator = comparisonsStrategy.get(o1.kind.fqn) ?: new WollokObjectEqualsComparator
return comparator.compare(o1, o2)
} catch (RuntimeException e) {
return o1.hashCode.compareTo(o2.hashCode)
return (o1.kind.hashCode).compareTo(o2.kind.hashCode)
}
}

Expand All @@ -48,7 +48,7 @@ class WollokObjectEqualsComparator implements Comparator<WollokObject> {

override compare(WollokObject o1, WollokObject o2) {
if (o1.hasEqualsMethod) {
return if (o1.wollokEquals(o2)) 0 else 1 // o1.compareGreaterThan(o2)
return if (o1.wollokEqualsMethod(o2)) 0 else o1.compareGreaterThan(o2)
}
// default case
return o1.hashCode.compareTo(o2.hashCode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,82 @@ import org.junit.Test

/**
* @author matifreyre
* @author nicoviotti
* @author fdodino
*
*/
class SetTestCase extends CollectionTestCase {

@Test
def void aSetWithObjectsOfSameClassAreNotAddedIfEqualEqualSetToTrue() {
'''
class C {
override method ==(other) = true
}
test "issue 1771" {
const aSet = #{new C(), new C()}
assert.equals(1, aSet.size())
}
'''.interpretPropagatingErrors
}

@Test
def void aSetWithObjectsOfSameClassAreNotAddedIfEqualsSetToTrue() {
'''
class C {
override method equals(other) = true
}
test "issue 1771" {
const aSet = #{new C(), new C()}
assert.equals(1, aSet.size())
}
'''.interpretPropagatingErrors
}

@Test
def void aSetWithObjectsInDifferentHierarchyAreNotAddedIfEqualsSetToTrue() {
'''
class Animal {
override method equals(other) = true
}
class Perro inherits Animal {
}
class Gato inherits Animal {
}
test "issue 1771" {
const aSet = #{new Perro(), new Perro(), new Gato()}
assert.equals(1, aSet.size())
}
'''.interpretPropagatingErrors
}

@Test
def void aSetWithObjectsInDifferentHierarchyAreNotAddedIfEqualEqualSetToTrue() {
'''
class Animal {
override method ==(other) = true
}
class Perro inherits Animal {
}
class Gato inherits Animal {
}
test "issue 1771" {
const aSet = #{new Perro(), new Perro(), new Gato()}
assert.equals(1, aSet.size())
}
'''.interpretPropagatingErrors
}

@Test
def void unionWithEmptySet() {
'''
Expand Down
Loading

0 comments on commit 09a92fb

Please sign in to comment.