1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2015 The Dagger Authors. 3*f585d8a3SJacky Wang * 4*f585d8a3SJacky Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5*f585d8a3SJacky Wang * you may not use this file except in compliance with the License. 6*f585d8a3SJacky Wang * You may obtain a copy of the License at 7*f585d8a3SJacky Wang * 8*f585d8a3SJacky Wang * http://www.apache.org/licenses/LICENSE-2.0 9*f585d8a3SJacky Wang * 10*f585d8a3SJacky Wang * Unless required by applicable law or agreed to in writing, software 11*f585d8a3SJacky Wang * distributed under the License is distributed on an "AS IS" BASIS, 12*f585d8a3SJacky Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*f585d8a3SJacky Wang * See the License for the specific language governing permissions and 14*f585d8a3SJacky Wang * limitations under the License. 15*f585d8a3SJacky Wang */ 16*f585d8a3SJacky Wang 17*f585d8a3SJacky Wang package dagger.functional.cycle; 18*f585d8a3SJacky Wang 19*f585d8a3SJacky Wang import dagger.Binds; 20*f585d8a3SJacky Wang import dagger.Component; 21*f585d8a3SJacky Wang import dagger.Lazy; 22*f585d8a3SJacky Wang import dagger.Module; 23*f585d8a3SJacky Wang import dagger.Provides; 24*f585d8a3SJacky Wang import dagger.Subcomponent; 25*f585d8a3SJacky Wang import dagger.multibindings.IntoMap; 26*f585d8a3SJacky Wang import dagger.multibindings.StringKey; 27*f585d8a3SJacky Wang import java.util.Map; 28*f585d8a3SJacky Wang import javax.inject.Inject; 29*f585d8a3SJacky Wang import javax.inject.Provider; 30*f585d8a3SJacky Wang 31*f585d8a3SJacky Wang /** 32*f585d8a3SJacky Wang * Cycle classes used for testing cyclic dependencies. 33*f585d8a3SJacky Wang * 34*f585d8a3SJacky Wang * <pre> 35*f585d8a3SJacky Wang * {@literal A ← (E ← D ← B ← C ← Provider<A>, Lazy<A>), (B ← C ← Provider<A>, Lazy<A>)} 36*f585d8a3SJacky Wang * {@literal S ← Provider<S>, Lazy<S>} 37*f585d8a3SJacky Wang * </pre> 38*f585d8a3SJacky Wang */ 39*f585d8a3SJacky Wang final class Cycles { Cycles()40*f585d8a3SJacky Wang private Cycles() {} 41*f585d8a3SJacky Wang 42*f585d8a3SJacky Wang static class A { 43*f585d8a3SJacky Wang public final B b; 44*f585d8a3SJacky Wang public final E e; 45*f585d8a3SJacky Wang 46*f585d8a3SJacky Wang @Inject A(E e, B b)47*f585d8a3SJacky Wang A(E e, B b) { 48*f585d8a3SJacky Wang this.e = e; 49*f585d8a3SJacky Wang this.b = b; 50*f585d8a3SJacky Wang } 51*f585d8a3SJacky Wang } 52*f585d8a3SJacky Wang 53*f585d8a3SJacky Wang static class B { 54*f585d8a3SJacky Wang public final C c; 55*f585d8a3SJacky Wang 56*f585d8a3SJacky Wang @Inject B(C c)57*f585d8a3SJacky Wang B(C c) { 58*f585d8a3SJacky Wang this.c = c; 59*f585d8a3SJacky Wang } 60*f585d8a3SJacky Wang } 61*f585d8a3SJacky Wang 62*f585d8a3SJacky Wang static class C { 63*f585d8a3SJacky Wang public final Provider<A> aProvider; 64*f585d8a3SJacky Wang @Inject public Lazy<A> aLazy; 65*f585d8a3SJacky Wang @Inject public Provider<Lazy<A>> aLazyProvider; 66*f585d8a3SJacky Wang 67*f585d8a3SJacky Wang @Inject C(Provider<A> aProvider)68*f585d8a3SJacky Wang C(Provider<A> aProvider) { 69*f585d8a3SJacky Wang this.aProvider = aProvider; 70*f585d8a3SJacky Wang } 71*f585d8a3SJacky Wang } 72*f585d8a3SJacky Wang 73*f585d8a3SJacky Wang static class D { 74*f585d8a3SJacky Wang public final B b; 75*f585d8a3SJacky Wang 76*f585d8a3SJacky Wang @Inject D(B b)77*f585d8a3SJacky Wang D(B b) { 78*f585d8a3SJacky Wang this.b = b; 79*f585d8a3SJacky Wang } 80*f585d8a3SJacky Wang } 81*f585d8a3SJacky Wang 82*f585d8a3SJacky Wang static class E { 83*f585d8a3SJacky Wang public final D d; 84*f585d8a3SJacky Wang 85*f585d8a3SJacky Wang @Inject E(D d)86*f585d8a3SJacky Wang E(D d) { 87*f585d8a3SJacky Wang this.d = d; 88*f585d8a3SJacky Wang } 89*f585d8a3SJacky Wang } 90*f585d8a3SJacky Wang 91*f585d8a3SJacky Wang static class S { 92*f585d8a3SJacky Wang public final Provider<S> sProvider; 93*f585d8a3SJacky Wang @Inject public Lazy<S> sLazy; 94*f585d8a3SJacky Wang 95*f585d8a3SJacky Wang @Inject S(Provider<S> sProvider)96*f585d8a3SJacky Wang S(Provider<S> sProvider) { 97*f585d8a3SJacky Wang this.sProvider = sProvider; 98*f585d8a3SJacky Wang } 99*f585d8a3SJacky Wang } 100*f585d8a3SJacky Wang 101*f585d8a3SJacky Wang static class X { 102*f585d8a3SJacky Wang public final Y y; 103*f585d8a3SJacky Wang 104*f585d8a3SJacky Wang @Inject X(Y y)105*f585d8a3SJacky Wang X(Y y) { 106*f585d8a3SJacky Wang this.y = y; 107*f585d8a3SJacky Wang } 108*f585d8a3SJacky Wang } 109*f585d8a3SJacky Wang 110*f585d8a3SJacky Wang static class Y { 111*f585d8a3SJacky Wang public final Map<String, Provider<X>> mapOfProvidersOfX; 112*f585d8a3SJacky Wang public final Map<String, Provider<Y>> mapOfProvidersOfY; 113*f585d8a3SJacky Wang 114*f585d8a3SJacky Wang @Inject Y(Map<String, Provider<X>> mapOfProvidersOfX, Map<String, Provider<Y>> mapOfProvidersOfY)115*f585d8a3SJacky Wang Y(Map<String, Provider<X>> mapOfProvidersOfX, Map<String, Provider<Y>> mapOfProvidersOfY) { 116*f585d8a3SJacky Wang this.mapOfProvidersOfX = mapOfProvidersOfX; 117*f585d8a3SJacky Wang this.mapOfProvidersOfY = mapOfProvidersOfY; 118*f585d8a3SJacky Wang } 119*f585d8a3SJacky Wang } 120*f585d8a3SJacky Wang 121*f585d8a3SJacky Wang @Module 122*f585d8a3SJacky Wang abstract static class CycleMapModule { 123*f585d8a3SJacky Wang @Binds 124*f585d8a3SJacky Wang @IntoMap 125*f585d8a3SJacky Wang @StringKey("X") x(X x)126*f585d8a3SJacky Wang abstract X x(X x); 127*f585d8a3SJacky Wang 128*f585d8a3SJacky Wang @Binds 129*f585d8a3SJacky Wang @IntoMap 130*f585d8a3SJacky Wang @StringKey("Y") y(Y y)131*f585d8a3SJacky Wang abstract Y y(Y y); 132*f585d8a3SJacky Wang } 133*f585d8a3SJacky Wang 134*f585d8a3SJacky Wang @SuppressWarnings("dependency-cycle") 135*f585d8a3SJacky Wang @Component(modules = CycleMapModule.class) 136*f585d8a3SJacky Wang interface CycleMapComponent { y()137*f585d8a3SJacky Wang Y y(); 138*f585d8a3SJacky Wang } 139*f585d8a3SJacky Wang 140*f585d8a3SJacky Wang @SuppressWarnings("dependency-cycle") 141*f585d8a3SJacky Wang @Component(modules = CycleModule.class) 142*f585d8a3SJacky Wang interface CycleComponent { a()143*f585d8a3SJacky Wang A a(); 144*f585d8a3SJacky Wang c()145*f585d8a3SJacky Wang C c(); 146*f585d8a3SJacky Wang child()147*f585d8a3SJacky Wang ChildCycleComponent child(); 148*f585d8a3SJacky Wang } 149*f585d8a3SJacky Wang 150*f585d8a3SJacky Wang @Module 151*f585d8a3SJacky Wang static class CycleModule { 152*f585d8a3SJacky Wang @Provides provideObjectWithCycle(@uppressWarnings"unused") Provider<Object> object)153*f585d8a3SJacky Wang static Object provideObjectWithCycle(@SuppressWarnings("unused") Provider<Object> object) { 154*f585d8a3SJacky Wang return "object"; 155*f585d8a3SJacky Wang } 156*f585d8a3SJacky Wang } 157*f585d8a3SJacky Wang 158*f585d8a3SJacky Wang @SuppressWarnings("dependency-cycle") 159*f585d8a3SJacky Wang @Component 160*f585d8a3SJacky Wang interface SelfCycleComponent { s()161*f585d8a3SJacky Wang S s(); 162*f585d8a3SJacky Wang } 163*f585d8a3SJacky Wang 164*f585d8a3SJacky Wang @Subcomponent 165*f585d8a3SJacky Wang interface ChildCycleComponent { 166*f585d8a3SJacky Wang @SuppressWarnings("dependency-cycle") a()167*f585d8a3SJacky Wang A a(); 168*f585d8a3SJacky Wang 169*f585d8a3SJacky Wang @SuppressWarnings("dependency-cycle") object()170*f585d8a3SJacky Wang Object object(); 171*f585d8a3SJacky Wang } 172*f585d8a3SJacky Wang 173*f585d8a3SJacky Wang interface Foo {} 174*f585d8a3SJacky Wang 175*f585d8a3SJacky Wang static class Bar implements Foo { 176*f585d8a3SJacky Wang @Inject Bar(Provider<Foo> fooProvider)177*f585d8a3SJacky Wang Bar(Provider<Foo> fooProvider) {} 178*f585d8a3SJacky Wang } 179*f585d8a3SJacky Wang 180*f585d8a3SJacky Wang /** 181*f585d8a3SJacky Wang * A component with a cycle in which a {@code @Binds} binding depends on the binding that has to 182*f585d8a3SJacky Wang * be deferred. 183*f585d8a3SJacky Wang */ 184*f585d8a3SJacky Wang @Component(modules = BindsCycleModule.class) 185*f585d8a3SJacky Wang interface BindsCycleComponent { bar()186*f585d8a3SJacky Wang Bar bar(); 187*f585d8a3SJacky Wang } 188*f585d8a3SJacky Wang 189*f585d8a3SJacky Wang @Module 190*f585d8a3SJacky Wang abstract static class BindsCycleModule { 191*f585d8a3SJacky Wang @Binds foo(Bar bar)192*f585d8a3SJacky Wang abstract Foo foo(Bar bar); 193*f585d8a3SJacky Wang } 194*f585d8a3SJacky Wang } 195