Skip to content

Commit a3ccbf9

Browse files
ZacSweersakarnokd
authored andcommitted
Improve compose() generics (ReactiveX#4972)
Resolves ReactiveX#4950
1 parent 2e0d3b9 commit a3ccbf9

File tree

5 files changed

+84
-12
lines changed

5 files changed

+84
-12
lines changed

src/main/java/io/reactivex/Flowable.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6483,11 +6483,12 @@ public final <U> Single<U> collectInto(final U initialItem, BiConsumer<? super U
64836483
* @return the source Publisher, transformed by the transformer function
64846484
* @see <a href="https://github.com/ReactiveX/RxJava/wiki/Implementing-Your-Own-Operators">RxJava wiki: Implementing Your Own Operators</a>
64856485
*/
6486+
@SuppressWarnings("unchecked")
64866487
@CheckReturnValue
64876488
@BackpressureSupport(BackpressureKind.PASS_THROUGH)
64886489
@SchedulerSupport(SchedulerSupport.NONE)
6489-
public final <R> Flowable<R> compose(FlowableTransformer<T, R> composer) {
6490-
return fromPublisher(composer.apply(this));
6490+
public final <R> Flowable<R> compose(FlowableTransformer<? super T, ? extends R> composer) {
6491+
return fromPublisher(((FlowableTransformer<T, R>) composer).apply(this));
64916492
}
64926493

64936494
/**

src/main/java/io/reactivex/Maybe.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,10 +2074,11 @@ public final <U> Maybe<U> cast(final Class<? extends U> clazz) {
20742074
* @return a Maybe, transformed by the transformer function
20752075
* @see <a href="https://github.com/ReactiveX/RxJava/wiki/Implementing-Your-Own-Operators">RxJava wiki: Implementing Your Own Operators</a>
20762076
*/
2077+
@SuppressWarnings("unchecked")
20772078
@CheckReturnValue
20782079
@SchedulerSupport(SchedulerSupport.NONE)
2079-
public final <R> Maybe<R> compose(MaybeTransformer<T, R> transformer) {
2080-
return wrap(transformer.apply(this));
2080+
public final <R> Maybe<R> compose(MaybeTransformer<? super T, ? extends R> transformer) {
2081+
return wrap(((MaybeTransformer<T, R>) transformer).apply(this));
20812082
}
20822083

20832084
/**

src/main/java/io/reactivex/Observable.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5722,10 +5722,11 @@ public final <U> Single<U> collectInto(final U initialValue, BiConsumer<? super
57225722
* @return the source ObservableSource, transformed by the transformer function
57235723
* @see <a href="https://github.com/ReactiveX/RxJava/wiki/Implementing-Your-Own-Operators">RxJava wiki: Implementing Your Own Operators</a>
57245724
*/
5725+
@SuppressWarnings("unchecked")
57255726
@CheckReturnValue
57265727
@SchedulerSupport(SchedulerSupport.NONE)
5727-
public final <R> Observable<R> compose(ObservableTransformer<T, R> composer) {
5728-
return wrap(composer.apply(this));
5728+
public final <R> Observable<R> compose(ObservableTransformer<? super T, ? extends R> composer) {
5729+
return wrap(((ObservableTransformer<T, R>) composer).apply(this));
57295730
}
57305731

57315732
/**

src/main/java/io/reactivex/Single.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,10 +1540,11 @@ public final Single<T> hide() {
15401540
* @return the source Single, transformed by the transformer function
15411541
* @see <a href="https://github.com/ReactiveX/RxJava/wiki/Implementing-Your-Own-Operators">RxJava wiki: Implementing Your Own Operators</a>
15421542
*/
1543+
@SuppressWarnings("unchecked")
15431544
@CheckReturnValue
15441545
@SchedulerSupport(SchedulerSupport.NONE)
1545-
public final <R> Single<R> compose(SingleTransformer<T, R> transformer) {
1546-
return wrap(transformer.apply(this));
1546+
public final <R> Single<R> compose(SingleTransformer<? super T, ? extends R> transformer) {
1547+
return wrap(((SingleTransformer<T, R>) transformer).apply(this));
15471548
}
15481549

15491550
/**

src/test/java/io/reactivex/TransformerTest.java

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@
1313

1414
package io.reactivex;
1515

16-
import static org.junit.Assert.*;
17-
16+
import io.reactivex.exceptions.TestException;
1817
import org.junit.Test;
1918
import org.reactivestreams.Publisher;
2019

21-
import io.reactivex.exceptions.TestException;
20+
import static org.junit.Assert.*;
2221

2322
public class TransformerTest {
2423

@@ -83,7 +82,7 @@ public Maybe<Integer> apply(Maybe<Integer> v) {
8382
}
8483

8584
@Test
86-
public void completabeTransformerThrows() {
85+
public void completableTransformerThrows() {
8786
try {
8887
Completable.complete().compose(new CompletableTransformer() {
8988
@Override
@@ -96,4 +95,73 @@ public Completable apply(Completable v) {
9695
assertEquals("Forced failure", ex.getMessage());
9796
}
9897
}
98+
99+
// Test demos for signature generics in compose() methods. Just needs to compile.
100+
101+
@Test
102+
public void observableGenericsSignatureTest() {
103+
A<String, Integer> a = new A<String, Integer>() { };
104+
105+
Observable.just(a).compose(TransformerTest.<String>testObservableTransformerCreator());
106+
}
107+
108+
@Test
109+
public void singleGenericsSignatureTest() {
110+
A<String, Integer> a = new A<String, Integer>() { };
111+
112+
Single.just(a).compose(TransformerTest.<String>testSingleTransformerCreator());
113+
}
114+
115+
@Test
116+
public void maybeGenericsSignatureTest() {
117+
A<String, Integer> a = new A<String, Integer>() { };
118+
119+
Maybe.just(a).compose(TransformerTest.<String>testMaybeTransformerCreator());
120+
}
121+
122+
@Test
123+
public void flowableGenericsSignatureTest() {
124+
A<String, Integer> a = new A<String, Integer>() { };
125+
126+
Flowable.just(a).compose(TransformerTest.<String>testFlowableTransformerCreator());
127+
}
128+
129+
interface A<T, R> {}
130+
interface B<T> {}
131+
132+
private static <T> ObservableTransformer<A<T, ?>, B<T>> testObservableTransformerCreator() {
133+
return new ObservableTransformer<A<T, ?>, B<T>>() {
134+
@Override
135+
public ObservableSource<B<T>> apply(Observable<A<T, ?>> a) {
136+
return Observable.empty();
137+
}
138+
};
139+
}
140+
141+
private static <T> SingleTransformer<A<T, ?>, B<T>> testSingleTransformerCreator() {
142+
return new SingleTransformer<A<T, ?>, B<T>>() {
143+
@Override
144+
public SingleSource<B<T>> apply(Single<A<T, ?>> a) {
145+
return Single.never();
146+
}
147+
};
148+
}
149+
150+
private static <T> MaybeTransformer<A<T, ?>, B<T>> testMaybeTransformerCreator() {
151+
return new MaybeTransformer<A<T, ?>, B<T>>() {
152+
@Override
153+
public MaybeSource<B<T>> apply(Maybe<A<T, ?>> a) {
154+
return Maybe.empty();
155+
}
156+
};
157+
}
158+
159+
private static <T> FlowableTransformer<A<T, ?>, B<T>> testFlowableTransformerCreator() {
160+
return new FlowableTransformer<A<T, ?>, B<T>>() {
161+
@Override
162+
public Publisher<B<T>> apply(Flowable<A<T, ?>> a) {
163+
return Flowable.empty();
164+
}
165+
};
166+
}
99167
}

0 commit comments

Comments
 (0)