• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Dagger Authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package dagger.internal.codegen.writing;
18 
19 import static dagger.internal.codegen.base.Util.reentrantComputeIfAbsent;
20 import static dagger.internal.codegen.model.BindingKind.MULTIBOUND_MAP;
21 import static dagger.internal.codegen.model.BindingKind.MULTIBOUND_SET;
22 
23 import dagger.assisted.Assisted;
24 import dagger.assisted.AssistedFactory;
25 import dagger.assisted.AssistedInject;
26 import dagger.internal.codegen.binding.BindingRequest;
27 import dagger.internal.codegen.binding.FrameworkType;
28 import dagger.internal.codegen.binding.ProductionBinding;
29 import java.util.HashMap;
30 import java.util.Map;
31 import java.util.Optional;
32 
33 /**
34  * A binding representation that wraps code generation methods that satisfy all kinds of request for
35  * that binding.
36  */
37 final class ProductionBindingRepresentation implements BindingRepresentation {
38   private final ProductionBinding binding;
39   private final DerivedFromFrameworkInstanceRequestRepresentation.Factory
40       derivedFromFrameworkInstanceRequestRepresentationFactory;
41   private final RequestRepresentation frameworkInstanceRequestRepresentation;
42   private final Map<BindingRequest, RequestRepresentation> requestRepresentations = new HashMap<>();
43 
44   @AssistedInject
ProductionBindingRepresentation( @ssisted ProductionBinding binding, ComponentImplementation componentImplementation, DerivedFromFrameworkInstanceRequestRepresentation.Factory derivedFromFrameworkInstanceRequestRepresentationFactory, ProducerNodeInstanceRequestRepresentation.Factory producerNodeInstanceRequestRepresentationFactory, UnscopedFrameworkInstanceCreationExpressionFactory unscopedFrameworkInstanceCreationExpressionFactory, BindingRepresentations bindingRepresentations)45   ProductionBindingRepresentation(
46       @Assisted ProductionBinding binding,
47       ComponentImplementation componentImplementation,
48       DerivedFromFrameworkInstanceRequestRepresentation.Factory
49           derivedFromFrameworkInstanceRequestRepresentationFactory,
50       ProducerNodeInstanceRequestRepresentation.Factory
51           producerNodeInstanceRequestRepresentationFactory,
52       UnscopedFrameworkInstanceCreationExpressionFactory
53           unscopedFrameworkInstanceCreationExpressionFactory,
54       BindingRepresentations bindingRepresentations) {
55     this.binding = binding;
56     this.derivedFromFrameworkInstanceRequestRepresentationFactory =
57         derivedFromFrameworkInstanceRequestRepresentationFactory;
58     Optional<MemberSelect> staticMethod = staticFactoryCreation();
59     FrameworkInstanceSupplier frameworkInstanceSupplier =
60         staticMethod.isPresent()
61             ? staticMethod::get
62             : new FrameworkFieldInitializer(
63                 componentImplementation,
64                 binding,
65                 binding.scope().isPresent()
66                     ? bindingRepresentations.scope(
67                         binding, unscopedFrameworkInstanceCreationExpressionFactory.create(binding))
68                     : unscopedFrameworkInstanceCreationExpressionFactory.create(binding));
69     this.frameworkInstanceRequestRepresentation =
70         producerNodeInstanceRequestRepresentationFactory.create(binding, frameworkInstanceSupplier);
71   }
72 
73   @Override
getRequestRepresentation(BindingRequest request)74   public RequestRepresentation getRequestRepresentation(BindingRequest request) {
75     return reentrantComputeIfAbsent(
76         requestRepresentations, request, this::getRequestRepresentationUncached);
77   }
78 
getRequestRepresentationUncached(BindingRequest request)79   private RequestRepresentation getRequestRepresentationUncached(BindingRequest request) {
80     return request.frameworkType().isPresent()
81         ? frameworkInstanceRequestRepresentation
82         : derivedFromFrameworkInstanceRequestRepresentationFactory.create(
83             binding,
84             frameworkInstanceRequestRepresentation,
85             request.requestKind(),
86             FrameworkType.PRODUCER_NODE);
87   }
88   /**
89    * If {@code resolvedBindings} is an unscoped provision binding with no factory arguments, then we
90    * don't need a field to hold its factory. In that case, this method returns the static member
91    * select that returns the factory.
92    */
staticFactoryCreation()93   private Optional<MemberSelect> staticFactoryCreation() {
94     if (binding.dependencies().isEmpty()) {
95       if (binding.kind().equals(MULTIBOUND_MAP)) {
96         return Optional.of(StaticMemberSelects.emptyMapFactory(binding));
97       }
98       if (binding.kind().equals(MULTIBOUND_SET)) {
99         return Optional.of(StaticMemberSelects.emptySetFactory(binding));
100       }
101     }
102     return Optional.empty();
103   }
104 
105   @AssistedFactory
106   static interface Factory {
create(ProductionBinding binding)107     ProductionBindingRepresentation create(ProductionBinding binding);
108   }
109 }
110