Skip to content

Commit 4a593af

Browse files
zsxwingbenjchristensen
authored andcommitted
Fix compose generics
1 parent f283fcf commit 4a593af

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

src/main/java/rx/Observable.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,17 @@ public void call(Subscriber<? super R> o) {
174174
* @return the source Observable, transformed by the transformer function
175175
* @see <a href="https://github.com/ReactiveX/RxJava/wiki/Implementing-Your-Own-Operators">RxJava wiki: Implementing Your Own Operators</a>
176176
*/
177-
public <R> Observable<R> compose(Transformer<? super T, R> transformer) {
178-
return transformer.call(this);
177+
@SuppressWarnings("unchecked")
178+
public <R> Observable<R> compose(Transformer<? super T, ? extends R> transformer) {
179+
// Casting to Observable<R> is type-safe because we know Observable is covariant.
180+
return (Observable<R>) transformer.call(this);
179181
}
180182

181183
/**
182184
* Transformer function used by {@link #compose}.
183185
* @warn more complete description needed
184186
*/
185-
public static interface Transformer<T, R> extends Func1<Observable<? extends T>, Observable<R>> {
187+
public static interface Transformer<T, R> extends Func1<Observable<? extends T>, Observable<? extends R>> {
186188
// cover for generics insanity
187189
}
188190

src/test/java/rx/CovarianceTest.java

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@
2020
import org.junit.Test;
2121

2222
import rx.Observable.Transformer;
23+
import rx.functions.Func1;
2324
import rx.functions.Func2;
2425

2526
/**
2627
* Test super/extends of generics.
2728
*
28-
* See https://github.com/ReactiveX/RxJava/pull/331
29+
* See https://github.com/Netflix/RxJava/pull/331
2930
*/
3031
public class CovarianceTest {
3132

@@ -61,11 +62,11 @@ public Integer call(Media t1, Media t2) {
6162

6263
@Test
6364
public void testCovarianceOfCompose() {
64-
Observable<HorrorMovie> movie = Observable.<HorrorMovie> just(new HorrorMovie());
65+
Observable<HorrorMovie> movie = Observable.just(new HorrorMovie());
6566
Observable<Movie> movie2 = movie.compose(new Transformer<Movie, Movie>() {
6667

6768
@Override
68-
public Observable<Movie> call(Observable<? extends Movie> t1) {
69+
public Observable<? extends Movie> call(Observable<? extends Movie> t1) {
6970
return Observable.just(new Movie());
7071
}
7172

@@ -77,12 +78,45 @@ public void testCovarianceOfCompose2() {
7778
Observable<Movie> movie = Observable.<Movie> just(new HorrorMovie());
7879
Observable<HorrorMovie> movie2 = movie.compose(new Transformer<Movie, HorrorMovie>() {
7980
@Override
80-
public Observable<HorrorMovie> call(Observable<? extends Movie> t1) {
81+
public Observable<? extends HorrorMovie> call(Observable<? extends Movie> t1) {
8182
return Observable.just(new HorrorMovie());
8283
}
8384
});
8485
}
85-
86+
87+
@Test
88+
public void testCovarianceOfCompose3() {
89+
Observable<Movie> movie = Observable.<Movie>just(new HorrorMovie());
90+
Observable<HorrorMovie> movie2 = movie.compose(new Transformer<Movie, HorrorMovie>() {
91+
@Override
92+
public Observable<? extends HorrorMovie> call(Observable<? extends Movie> t1) {
93+
return Observable.just(new HorrorMovie()).map(new Func1<HorrorMovie, HorrorMovie>() {
94+
95+
@Override
96+
public HorrorMovie call(HorrorMovie horrorMovie) {
97+
return horrorMovie;
98+
}
99+
});
100+
}
101+
});
102+
}
103+
104+
@Test
105+
public void testCovarianceOfCompose4() {
106+
Observable<HorrorMovie> movie = Observable.just(new HorrorMovie());
107+
Observable<HorrorMovie> movie2 = movie.compose(new Transformer<HorrorMovie, HorrorMovie>() {
108+
@Override
109+
public Observable<? extends HorrorMovie> call(Observable<? extends HorrorMovie> t1) {
110+
return t1.map(new Func1<HorrorMovie, HorrorMovie>() {
111+
112+
@Override
113+
public HorrorMovie call(HorrorMovie horrorMovie) {
114+
return horrorMovie;
115+
}
116+
});
117+
}
118+
});
119+
}
86120

87121
/*
88122
* Most tests are moved into their applicable classes such as [Operator]Tests.java

0 commit comments

Comments
 (0)