blob: 8ac498b34723c9e71a42889008e0d6a88d375cc8 [file] [log] [blame]
dpb02db2132018-01-08 07:20:23 -08001/*
2 * Copyright (C) 2017 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
17package dagger.internal.codegen;
18
19import static com.google.common.base.Preconditions.checkNotNull;
20import static dagger.internal.codegen.RequestKinds.requestType;
21
22import com.google.auto.common.MoreTypes;
23import com.squareup.javapoet.ClassName;
24import com.squareup.javapoet.CodeBlock;
25import dagger.model.Key;
26import dagger.model.RequestKind;
27import javax.lang.model.type.TypeKind;
28import javax.lang.model.type.TypeMirror;
29import javax.lang.model.util.Elements;
30
31/** Defines a method body and return type for a given {@link BindingExpression}. */
32class BindingMethodImplementation {
33 private final BindingExpression bindingExpression;
34 private final ClassName componentName;
35 private final ResolvedBindings resolvedBindings;
36 private final RequestKind requestKind;
37 private final DaggerTypes types;
38 private final Elements elements;
39
40 BindingMethodImplementation(
41 BindingExpression bindingExpression,
42 ClassName componentName,
43 DaggerTypes types,
44 Elements elements) {
45 this.bindingExpression = checkNotNull(bindingExpression);
46 this.componentName = checkNotNull(componentName);
47 this.types = checkNotNull(types);
48 this.elements = checkNotNull(elements);
49 this.resolvedBindings = bindingExpression.resolvedBindings();
50 this.requestKind = bindingExpression.requestKind();
51 }
52
53 /**
54 * Returns the method body, which contains zero or more statements (including semicolons).
55 *
56 * <p>If the implementation has a non-void return type, the body will also include the {@code
57 * return} statement.
58 */
dpb466064a2018-01-26 08:15:43 -080059 CodeBlock body() {
dpb02db2132018-01-08 07:20:23 -080060 return CodeBlock.of(
dpb466064a2018-01-26 08:15:43 -080061 "return $L;", bindingExpression.getDependencyExpression(componentName).codeBlock());
dpb02db2132018-01-08 07:20:23 -080062 }
63
64 /** Returns the return type for the dependency request. */
65 final TypeMirror returnType() {
66 ContributionBinding binding = resolvedBindings.contributionBinding();
67 if (requestKind.equals(RequestKind.INSTANCE)
68 && binding.contributedPrimitiveType().isPresent()) {
69 return binding.contributedPrimitiveType().get();
70 }
71 return accessibleType(requestType(requestKind, binding.contributedType(), types));
72 }
73
74 /** Returns the {@linkplain Key} for this expression. */
75 protected final Key key() {
76 return resolvedBindings.key();
77 }
78
79 /** Returns the {#linkplain RequestKind request kind} handled by this expression. */
80 protected final RequestKind requestKind() {
81 return requestKind;
82 }
83
84 /** The binding this instance uses to fulfill requests. */
85 protected final ResolvedBindings resolvedBindings() {
86 return resolvedBindings;
87 }
88
89 // TODO(user): Move this to Accessibility.java or DaggerTypes.java?
90 /** Returns a {@link TypeMirror} for the binding that is accessible to the component. */
91 protected final TypeMirror accessibleType(TypeMirror type) {
92 if (Accessibility.isTypeAccessibleFrom(type, componentName.packageName())) {
93 return type;
94 } else if (type.getKind().equals(TypeKind.DECLARED)
95 && Accessibility.isRawTypeAccessible(type, componentName.packageName())) {
96 return types.getDeclaredType(MoreTypes.asTypeElement(type));
97 } else {
98 return elements.getTypeElement(Object.class.getName()).asType();
99 }
100 }
101}