Skip to content

Commit

Permalink
Merge pull request #510 from danieldietrich/master
Browse files Browse the repository at this point in the history
re-enabled type consistency checks
  • Loading branch information
danieldietrich committed Aug 24, 2015
2 parents 27e65ab + 4256474 commit c3c3e25
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 23 deletions.
10 changes: 10 additions & 0 deletions src/main/java/javaslang/collection/HashMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,16 @@ public HashMap<K, V> put(K key, V value) {
return new HashMap<>(tree.put(key, value));
}

@Override
public HashMap<K, V> put(Entry<? extends K, ? extends V> entry) {
return put(entry.key, entry.value);
}

@Override
public HashMap<K, V> put(Tuple2<? extends K, ? extends V> entry) {
return put(entry._1, entry._2);
}

@Override
public Entry<K, V> reduceRight(BiFunction<? super Entry<K, V>, ? super Entry<K, V>, ? extends Entry<K, V>> op) {
throw new UnsupportedOperationException("TODO");
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/javaslang/collection/Map.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,15 @@ default V apply(K key) {
* @param entry A Map.Entry
* @return A new Map containing these elements and that entry.
*/
default Map<K, V> put(Entry<? extends K, ? extends V> entry) {
return put(entry.key, entry.value);
}
Map<K, V> put(Entry<? extends K, ? extends V> entry);

/**
* Convenience method for {@code put(entry._1, entry._2)}.
*
* @param entry A Map.Entry
* @return A new Map containing these elements and that entry.
*/
default Map<K, V> put(Tuple2<? extends K, ? extends V> entry) {
return put(entry._1, entry._2);
}
Map<K, V> put(Tuple2<? extends K, ? extends V> entry);

Map<K, V> remove(K key);

Expand Down
6 changes: 6 additions & 0 deletions src/main/java/javaslang/collection/SortedMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ public interface SortedMap<K, V> extends Map<K, V> {
@Override
SortedMap<K, V> put(K key, V value);

@Override
SortedMap<K, V> put(Entry<? extends K, ? extends V> entry);

@Override
SortedMap<K, V> put(Tuple2<? extends K, ? extends V> entry);

@Override
SortedMap<K, V> remove(K key);

Expand Down
46 changes: 29 additions & 17 deletions src/test/java/javaslang/TypeConsistencyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import javaslang.collection.List;
import javaslang.collection.Stream;
import javaslang.control.Try;
import org.junit.Ignore;
import org.junit.Test;

import java.io.File;
Expand All @@ -32,18 +31,19 @@ public class TypeConsistencyTest {
// javaslang.collection.HashMap
"javaslang.collection.HashMap//public abstract javaslang.collection.Map javaslang.collection.Map.groupBy(java.util.function.Function)",

// javaslang.collection.SortedMap
"javaslang.collection.SortedMap//public abstract javaslang.collection.Map javaslang.collection.Map.groupBy(java.util.function.Function)",

// javaslang.control.Match
"javaslang.control.Match//public default java.util.function.Function java.util.function.Function.andThen(java.util.function.Function)",
"javaslang.control.Match//public default java.util.function.Function java.util.function.Function.compose(java.util.function.Function)",

// javaslang.control.Failure
"javaslang.control.Failure//public abstract javaslang.control.Try javaslang.control.Try.recover(java.util.function.Function)",
"javaslang.control.Failure//public abstract javaslang.control.Try javaslang.control.Try.recoverWith(java.util.function.Function)",
"javaslang.control.Failure//public abstract javaslang.control.Try javaslang.control.Try.failed()",
"javaslang.control.Failure//public default javaslang.control.Try javaslang.control.Try.andThen(javaslang.control.Try$CheckedRunnable)",

// javaslang.control.Success
"javaslang.control.Success//public abstract javaslang.control.Try javaslang.control.Try.failed()",
"javaslang.control.Success//public abstract javaslang.control.Try javaslang.control.Try.filter(java.util.function.Predicate)",
"javaslang.control.Success//public abstract javaslang.control.Try javaslang.control.Try.filterTry(javaslang.control.Try$CheckedPredicate)",
"javaslang.control.Success//public abstract javaslang.control.Try javaslang.control.Try.flatMap(java.util.function.Function)",
Expand All @@ -60,21 +60,14 @@ public class TypeConsistencyTest {
"javaslang.control.Some//public abstract javaslang.control.Option javaslang.control.Option.filter(java.util.function.Predicate)",
"javaslang.control.Some//public abstract javaslang.control.Option javaslang.control.Option.flatMap(java.util.function.Function)",
"javaslang.control.Some//public abstract javaslang.control.Option javaslang.control.Option.flatMapVal(java.util.function.Function)",
"javaslang.control.Some//public abstract javaslang.control.Option javaslang.control.Option.flatten()",

// javaslang.control.Left
"javaslang.control.Left//public abstract javaslang.control.Either javaslang.control.Either.swap()",

// javaslang.control.Right
"javaslang.control.Right//public abstract javaslang.control.Either javaslang.control.Either.swap()"
"javaslang.control.Some//public abstract javaslang.control.Option javaslang.control.Option.flatten()"
);

/**
* CAUTION: Non-reifiable types (like {@code Tuple2<? extends Traversable<T>, ? extends Traversable<T>>})
* are not recognized by this test because there is no runtime information available via reflection.
*/
@Test
@Ignore
public void shouldHaveAConsistentTypeSystem() {

final Stream<Class<?>> relevantClasses = loadClasses("src-gen/main/java")
Expand Down Expand Up @@ -134,10 +127,9 @@ Stream<Method> getUnoverriddenMethods(Class<?> clazz) {
comparableMethod.m.getDeclaringClass().equals(comparableMethod.m.getReturnType()));
final Stream<ComparableMethod> thisMethods = getOverridableMethods(Stream.of(clazz));
return superMethods.filter(superMethod -> thisMethods
.findFirst(thisMethod -> thisMethod.equals(superMethod))
// TODO: special case if visibility is package private and classes are in different package
.map(thisMethod -> !clazz.equals(thisMethod.m.getReturnType()))
.orElse(true))
.findFirst(thisMethod -> thisMethod.overrides(superMethod))
.map(thisMethod -> superMethod.m.getReturnType().equals(thisMethod.m.getReturnType())) // return type not changed at all
.orElse(true)) // method is not overridden at all and is therefor returned
.sort()
.map(comparableMethod -> comparableMethod.m);
}
Expand Down Expand Up @@ -191,6 +183,26 @@ static class ComparableMethod implements Comparable<ComparableMethod> {
this.m = m;
}

public boolean overrides(ComparableMethod that) {
if (that == null) {
return false;
}
if (!Objects.equals(this.m.getName(), that.m.getName())) {
return false;
}
final Class<?>[] thisParamTypes = this.m.getParameterTypes();
final Class<?>[] thatParamTypes = that.m.getParameterTypes();
if (thisParamTypes.length != thatParamTypes.length) {
return false;
}
for (int i = 0; i < thisParamTypes.length; i++) {
if (!thatParamTypes[i].isAssignableFrom(thisParamTypes[i])) {
return false;
}
}
return true;
}

@Override
public int compareTo(ComparableMethod that) {
return this.toString().compareTo(that.toString());
Expand All @@ -202,8 +214,8 @@ public boolean equals(Object o) {
return true;
} else if (o instanceof ComparableMethod) {
final ComparableMethod that = (ComparableMethod) o;
return Objects.equals(this.m.getName(), that.m.getName()) &&
Arrays.equals(this.m.getParameterTypes(), that.m.getParameterTypes());
return Objects.equals(this.m.getName(), that.m.getName())
&& Arrays.equals(this.m.getParameterTypes(), that.m.getParameterTypes());
} else {
return false;
}
Expand Down

0 comments on commit c3c3e25

Please sign in to comment.