Skip to content

Commit ea0173c

Browse files
Merge pull request #1701 from zsxwing/compose-generics
Fix the compose generics
2 parents 023555c + df18366 commit ea0173c

File tree

3 files changed

+48
-12
lines changed

3 files changed

+48
-12
lines changed

language-adaptors/rxjava-scala/src/main/scala/rx/lang/scala/JavaConversions.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ object JavaConversions {
6565

6666
implicit def toJavaTransformer[T, R](transformer: Observable[T] => Observable[R]): rx.Observable.Transformer[T, R] = {
6767
new rx.Observable.Transformer[T, R] {
68-
override def call(o: rx.Observable[_ <: T]): rx.Observable[R] = {
69-
transformer(toScalaObservable(o)).asJavaObservable.asInstanceOf[rx.Observable[R]]
68+
override def call(o: rx.Observable[_ <: T]): rx.Observable[_ <: R] = {
69+
transformer(toScalaObservable(o)).asJavaObservable
7070
}
7171
}
7272
}

rxjava-core/src/main/java/rx/Observable.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,16 +204,18 @@ public void call(Subscriber<? super R> o) {
204204
* @see <a href="https://github.com/Netflix/RxJava/wiki/Implementing-Your-Own-Operators">RxJava wiki: Implementing Your Own Operators</a>
205205
* @since 0.20
206206
*/
207-
public <R> Observable<R> compose(Transformer<? super T, R> transformer) {
208-
return transformer.call(this);
207+
@SuppressWarnings("unchecked")
208+
public <R> Observable<R> compose(Transformer<? super T, ? extends R> transformer) {
209+
// Casting to Observable<R> is type-safe because we know Observable is covariant.
210+
return (Observable<R>) transformer.call(this);
209211
}
210212

211213
/**
212214
* Transformer function used by {@link #compose}.
213215
* @warn more complete description needed
214216
* @since 0.20
215217
*/
216-
public static interface Transformer<T, R> extends Func1<Observable<? extends T>, Observable<R>> {
218+
public static interface Transformer<T, R> extends Func1<Observable<? extends T>, Observable<? extends R>> {
217219
// cover for generics insanity
218220
}
219221

rxjava-core/src/test/java/rx/CovarianceTest.java

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.junit.Test;
2121

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

2526
/**
@@ -61,28 +62,61 @@ public Integer call(Media t1, Media t2) {
6162

6263
@Test
6364
public void testCovarianceOfCompose() {
64-
Observable<HorrorMovie> movie = Observable.<HorrorMovie> from(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-
return Observable.from(new Movie());
69+
public Observable<? extends Movie> call(Observable<? extends Movie> t1) {
70+
return Observable.just(new Movie());
7071
}
7172

7273
});
7374
}
7475

7576
@Test
7677
public void testCovarianceOfCompose2() {
77-
Observable<Movie> movie = Observable.<Movie> from(new HorrorMovie());
78+
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-
return Observable.from(new HorrorMovie());
81+
public Observable<? extends HorrorMovie> call(Observable<? extends Movie> t1) {
82+
return Observable.just(new HorrorMovie());
83+
}
84+
});
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+
});
82117
}
83118
});
84119
}
85-
86120

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

0 commit comments

Comments
 (0)