private static boolean isAsyncDependency(DependencyRequest dependency) { switch (dependency.kind()) { case INSTANCE: case PRODUCED: return true; default: return false; } }
/** * Returns the verb for a component method dependency request. Returns "produced", "provided", or * "injected", depending on the kind of request. */ private String componentMethodRequestVerb(DependencyRequest request) { switch (request.kind()) { case FUTURE: case PRODUCER: return "produced"; case INSTANCE: case LAZY: case PROVIDER: case PROVIDER_OF_LAZY: return "provided"; case MEMBERS_INJECTION: return "injected"; case PRODUCED: default: throw new AssertionError("illegal request kind for method: " + request); } } }
/** * Returns the {@link FrameworkType} to use for a collection of requests of the same {@link Key}. * This allows factories to only take a single argument for multiple requests of the same key. */ FrameworkType getFrameworkType(Set<DependencyRequest> requests) { Set<FrameworkType> frameworkTypes = requests.stream().map(request -> getFrameworkType(request.kind())).collect(toSet()); return frameworkTypes.size() == 1 ? getOnlyElement(frameworkTypes) : FrameworkType.PROVIDER; } }
@Override ImmutableList<CodeBlock> parameterCodeBlocks() { ImmutableList.Builder<CodeBlock> parameterCodeBlocks = ImmutableList.builder(); for (DependencyRequest dependency : binding.explicitDependencies()) { parameterCodeBlocks.add( frameworkTypeUsageStatement( CodeBlock.of("$N", fields.get(dependency.key())), dependency.kind())); } return parameterCodeBlocks.build(); } }
private static TypeName asyncDependencyType(DependencyRequest dependency) { TypeName keyName = TypeName.get(dependency.key().type()); switch (dependency.kind()) { case INSTANCE: return keyName; case PRODUCED: return producedOf(keyName); default: throw new AssertionError(); } }
@Override public String toString() { String string = dependencyRequest .requestElement() .map(DaggerElements::elementToString) .orElseGet( () -> "synthetic request for " + dependencyRequest.kind().format(dependencyRequest.key())); return entryPoint ? string + " (entry point)" : string; } }
/** * Returns the parameter type for {@code dependency}. If the raw type is not accessible, returns * {@link Object}. */ private static TypeName accessibleType(DependencyRequest dependency) { TypeName typeName = requestTypeName(dependency.kind(), accessibleType(dependency.key().type())); return dependency .requestElement() .map(element -> element.asType().getKind().isPrimitive()) .orElse(false) ? typeName.unbox() : typeName; }
/** * Returns a mapping of {@link DependencyRequest}s to {@link CodeBlock}s that {@linkplain * #frameworkTypeUsageStatement(CodeBlock, RequestKind) use them}. */ static ImmutableMap<DependencyRequest, CodeBlock> frameworkFieldUsages( ImmutableSet<DependencyRequest> dependencies, ImmutableMap<Key, FieldSpec> fields) { return Maps.toMap( dependencies, dep -> frameworkTypeUsageStatement(CodeBlock.of("$N", fields.get(dep.key())), dep.kind())); }
@Override ImmutableList<CodeBlock> parameterCodeBlocks() { ImmutableList.Builder<CodeBlock> parameterCodeBlocks = ImmutableList.builder(); for (DependencyRequest dependency : binding.explicitDependencies()) { // We really want to compare instances here, because asyncDependency is an element in the // set binding.dependencies(). if (dependency == asyncDependency) { parameterCodeBlocks.add(CodeBlock.of("$L", applyArgName())); } else { parameterCodeBlocks.add( // TODO(ronshapiro) extract this into a method shared by FutureTransform subclasses frameworkTypeUsageStatement( CodeBlock.of("$N", fields.get(dependency.key())), dependency.kind())); } } return parameterCodeBlocks.build(); } }
private static ImmutableList<CodeBlock> getParameterCodeBlocks( ProductionBinding binding, ImmutableMap<Key, FieldSpec> fields, String listArgName) { int argIndex = 0; ImmutableList.Builder<CodeBlock> codeBlocks = ImmutableList.builder(); for (DependencyRequest dependency : binding.explicitDependencies()) { if (isAsyncDependency(dependency)) { codeBlocks.add( CodeBlock.of( "($T) $L.get($L)", asyncDependencyType(dependency), listArgName, argIndex)); argIndex++; } else { codeBlocks.add( frameworkTypeUsageStatement( CodeBlock.of("$N", fields.get(dependency.key())), dependency.kind())); } } return codeBlocks.build(); }
variableName = toLowerCamel(variableName); switch (dependency.kind()) { case INSTANCE: return variableName;
/** * Creates a {@link BindingRequest} for a normal dependency request for the given {@link Key} and * {@link RequestKind}. */ static BindingRequest bindingRequest(Key key, RequestKind requestKind) { // When there's a request that has a 1:1 mapping to a FrameworkType, the request should be // associated with that FrameworkType as well, because we want to ensure that if a request // comes in for that as a dependency first and as a framework instance later, they resolve to // the same binding expression. // TODO(cgdecker): Instead of doing this, make ComponentBindingExpressions create a // BindingExpression for the RequestKind that simply delegates to the BindingExpression for the // FrameworkType. Then there are separate BindingExpressions, but we don't end up doing weird // things like creating two fields when there should only be one. return new AutoValue_BindingRequest( key, Optional.of(requestKind), FrameworkType.forRequestKind(requestKind)); }
private boolean dependencyCanBeProduction(DependencyEdge edge, BindingGraph graph) { Node source = graph.network().incidentNodes(edge).source(); if (source instanceof ComponentNode) { return entryPointCanUseProduction(edge.dependencyRequest().kind()); } if (source instanceof dagger.model.Binding) { return ((dagger.model.Binding) source).isProduction(); } throw new IllegalArgumentException( "expected a dagger.model.Binding or ComponentNode: " + source); }
private static PresentFactorySpec of(ContributionBinding binding) { return new AutoValue_OptionalFactories_PresentFactorySpec( FrameworkType.forBindingType(binding.bindingType()), OptionalType.from(binding.key()).kind(), getOnlyElement(binding.dependencies()).kind()); } }
private boolean dependencyCanUseProduction(DependencyEdge edge, BindingGraph bindingGraph) { return edge.isEntryPoint() ? entryPointCanUseProduction(edge.dependencyRequest().kind()) : bindingRequestingDependency(edge, bindingGraph).isProduction(); }
@Override public String visitVariable(VariableElement variable, DependencyRequest request) { TypeMirror requestedType = requestType(request.kind(), request.key().type(), types); return INDENT + formatQualifier(request.key().qualifier()) + requestedType + " is injected at\n" + DOUBLE_INDENT + elementToString(variable); }
private static CodeBlock injectionMethodArgument( DependencyRequest dependency, CodeBlock argument, ClassName generatedTypeName) { TypeMirror keyType = dependency.key().type(); CodeBlock.Builder codeBlock = CodeBlock.builder(); if (!isRawTypeAccessible(keyType, generatedTypeName.packageName()) && isTypeAccessibleFrom(keyType, generatedTypeName.packageName())) { if (!dependency.kind().equals(RequestKind.INSTANCE)) { TypeName usageTypeName = accessibleType(dependency); codeBlock.add("($T) ($T)", usageTypeName, rawTypeName(usageTypeName)); } else if (dependency.requestElement().get().asType().getKind().equals(TypeKind.TYPEVAR)) { codeBlock.add("($T)", keyType); } } return codeBlock.add(argument).build(); }
private boolean breaksCycle(DependencyEdge edge, BindingGraph graph) { if (edge.dependencyRequest().key().multibindingContributionIdentifier().isPresent()) { return false; } if (breaksCycle(edge.dependencyRequest().key().type(), edge.dependencyRequest().kind())) { return true; } Node target = graph.network().incidentNodes(edge).target(); if (target instanceof dagger.model.Binding && ((dagger.model.Binding) target).kind().equals(BindingKind.OPTIONAL)) { /* For @BindsOptionalOf bindings, unwrap the type inside the Optional. If the unwrapped type * breaks the cycle, so does the optional binding. */ TypeMirror optionalValueType = OptionalType.from(edge.dependencyRequest().key()).valueType(); RequestKind requestKind = getRequestKind(optionalValueType); return breaksCycle(extractKeyType(requestKind, optionalValueType), requestKind); } return false; }
if (dependencyRequest.kind().equals(RequestKind.INSTANCE) && !isTypeAccessibleFrom(dependencyType, requestingClass.packageName()) && isRawTypeAccessible(dependencyType, requestingClass.packageName())) {