private FieldSpec supertypeBindingField(TypeMirror supertype) { return FieldSpec.builder(bindingOf(supertype), "supertype", PRIVATE).build(); }
@Override public TypeName visitPrimitive(PrimitiveType primitiveType, Void v) { return box(primitiveType); }
protected ProviderMethodBinding(String provideKey, ExecutableElement method, boolean library) { super(provideKey, method.getAnnotation(Singleton.class) != null, className(method), method.getSimpleName().toString()); this.method = method; this.parameters = new Binding[method.getParameters().size()]; setLibrary(library); }
private void validateProvides(Element element) { if (element.getAnnotation(Provides.class) != null && Util.getAnnotation(Module.class, element.getEnclosingElement()) == null) { error("@Provides methods must be declared in modules: " + elementToString(element), element); } }
String packageName = getPackage(type).getQualifiedName().toString(); TypeMirror supertype = getApplicationSupertype(type); if (supertype != null) { supertype = processingEnv.getTypeUtils().erasure(supertype); ClassName adapterClassName = adapterName(injectedClassName, INJECT_ADAPTER_SUFFIX); .addModifiers(PUBLIC, FINAL) .superclass(ParameterizedTypeName.get(ClassName.get(Binding.class), injectedClassName)) .addJavadoc("$L", bindingTypeDocs(injectableType(type.asType()), isAbstract, injectMembers, dependent).toString());
default: error("Cannot inject " + elementToString(member), member); break; constructor = getNoArgsConstructor(type); if (constructor != null && !isCallableConstructor(constructor)) { constructor = null;
ClassName className = bindingClassName( adapterName, providerMethod, methodToClassName, methodNameToNextId); TypeName returnType = Util.injectableType(providerMethod.getReturnType()); List<? extends VariableElement> parameters = providerMethod.getParameters(); boolean dependent = !parameters.isEmpty(); result.addField(bindingOf(parameter.asType()), parameterName(parameter), PRIVATE); key, (singleton ? "IS_SINGLETON" : "NOT_SINGLETON"), typeToString(moduleType), methodName) .addStatement("this.module = module") "$N = ($T) linker.requestBinding($S, $T.class, getClass().getClassLoader())", parameterName(parameter), bindingOf(parameter.asType()), parameterKey, moduleClassName);
ClassName adapterClassName = Util.adapterName(moduleClassName, MODULE_ADAPTER_SUFFIX); .build()); ExecutableElement noArgsConstructor = getNoArgsConstructor(type); if (noArgsConstructor != null && isCallableConstructor(noArgsConstructor)) { adapterBuilder.addMethod(MethodSpec.methodBuilder("newModule") .addAnnotation(Override.class)
/** * Write a companion class for {@code type} that extends {@link StaticInjection}. */ private void generateStaticInjection(TypeElement type, List<Element> fields) throws IOException { ClassName typeName = ClassName.get(type); ClassName adapterClassName = adapterName(ClassName.get(type), STATIC_INJECTION_SUFFIX); TypeSpec.Builder result = TypeSpec.classBuilder(adapterClassName.simpleName()) .addOriginatingElement(type) .addJavadoc(AdapterJavadocs.STATIC_INJECTION_TYPE, type) .addModifiers(PUBLIC, FINAL) .superclass(StaticInjection.class); for (Element field : fields) { result.addField(memberBindingField(false, field)); } result.addMethod(attachMethod(null, fields, false, typeName, null, true)); result.addMethod(staticInjectMethod(fields, typeName)); String packageName = getPackage(type).getQualifiedName().toString(); JavaFile javaFile = JavaFile.builder(packageName, result.build()) .addFileComment(AdapterJavadocs.GENERATED_BY_DAGGER) .build(); javaFile.writeTo(processingEnv.getFiler()); }
Map<String, Object> annotation = getAnnotation(Module.class, module); boolean overrides = (Boolean) annotation.get("overrides"); boolean library = (Boolean) annotation.get("library"); String providerKey = GeneratorKeys.get(injectableType); injectsProvisionKeys.add(providerKey); String key = isInterface(injectableType) ? providerKey : GeneratorKeys.rawMembersKey(injectableType);
error("@Inject is not valid on a class: " + elementToString(injectable), injectable); return false; error("Method injection is not supported: " + elementToString(injectable), injectable); return false; error("Can't inject a final field: " + elementToString(injectable), injectable); return false; error("Can't inject a private field: " + elementToString(injectable), injectable); return false; error("Can't inject a private constructor: " + elementToString(injectable), injectable); return false; error("Can't inject a non-static inner class: " + elementToString(injectable), injectableType); return false;
@Override public boolean process(Set<? extends TypeElement> types, RoundEnvironment env) { remainingTypes.putAll(providerMethodsByClass(env)); for (Iterator<String> i = remainingTypes.keySet().iterator(); i.hasNext();) { String typeName = i.next(); TypeElement type = processingEnv.getElementUtils().getTypeElement(typeName); List<ExecutableElement> providesTypes = remainingTypes.get(typeName); try { // Attempt to get the annotation. If types are missing, this will throw // CodeGenerationIncompleteException. Map<String, Object> parsedAnnotation = getAnnotation(Module.class, type); if (parsedAnnotation == null) { error(type + " has @Provides methods but no @Module annotation", type); continue; } JavaFile javaFile = generateModuleAdapter(type, parsedAnnotation, providesTypes); javaFile.writeTo(processingEnv.getFiler()); } catch (CodeGenerationIncompleteException e) { continue; // A dependent type was not defined, we'll try to catch it on another pass. } catch (IOException e) { error("Code gen failed: " + e, type); } i.remove(); } if (env.processingOver() && remainingTypes.size() > 0) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not find types required by provides methods for " + remainingTypes.keySet()); } return false; // FullGraphProcessor needs an opportunity to process. }
/** The requirement's null policy. */ NullPolicy nullPolicy(DaggerElements elements, DaggerTypes types) { if (overrideNullPolicy().isPresent()) { return overrideNullPolicy().get(); } switch (kind()) { case MODULE: return componentCanMakeNewInstances(typeElement()) ? NullPolicy.NEW : requiresAPassedInstance(elements, types) ? NullPolicy.THROW : NullPolicy.ALLOW; case DEPENDENCY: case BOUND_INSTANCE: return NullPolicy.THROW; } throw new AssertionError(); }
static void rawTypeToString(StringBuilder result, TypeElement type, char innerClassSeparator) { String packageName = getPackage(type).getQualifiedName().toString(); String qualifiedName = type.getQualifiedName().toString(); if (packageName.isEmpty()) { result.append(qualifiedName.replace('.', innerClassSeparator)); } else { result.append(packageName); result.append('.'); result.append( qualifiedName.substring(packageName.length() + 1).replace('.', innerClassSeparator)); } }
TypeMirror supertype = getApplicationSupertype(type); String supertypeKey = supertype != null ? GeneratorKeys.rawMembersKey(supertype)
if (!isProvidesMethod(element) && !suppressWarnings) { warning("Dagger will ignore scoping annotations on methods that are not " + "@Provides methods: " + elementToString(element), element); + elementToString(element), element); error("Only one scoping annotation is allowed per element: " + elementToString(element), element);
void collectIncludesRecursively( TypeElement module, Map<String, TypeElement> result, Deque<String> path) { Map<String, Object> annotation = getAnnotation(Module.class, module); if (annotation == null) {
private ImmutableSet<TypeElement> findMissingModules( ChildFactoryMethodEdge edge, BindingGraph graph) { ImmutableSet<TypeElement> factoryMethodParameters = subgraphFactoryMethodParameters(edge, graph); ComponentNode child = (ComponentNode) graph.network().incidentNodes(edge).target(); SetView<TypeElement> modulesOwnedByChild = ownedModules(child, graph); return graph.bindings().stream() // bindings owned by child .filter(binding -> binding.componentPath().equals(child.componentPath())) // that require a module instance .filter(binding -> binding.requiresModuleInstance()) .map(binding -> binding.contributingModule().get()) .distinct() // module owned by child .filter(module -> modulesOwnedByChild.contains(module)) // module not in the method parameters .filter(module -> !factoryMethodParameters.contains(module)) // module doesn't have an accessible no-arg constructor .filter(moduleType -> !componentCanMakeNewInstances(moduleType)) .collect(toImmutableSet()); }
void writeDotFile(TypeElement module, Map<String, Binding<?>> bindings) throws IOException { JavaFileManager.Location location = StandardLocation.SOURCE_OUTPUT; String path = getPackage(module).getQualifiedName().toString(); String file = module.getQualifiedName().toString().substring(path.length() + 1) + ".dot"; FileObject resource = processingEnv.getFiler().createResource(location, path, file, module); Writer writer = resource.openWriter(); GraphVizWriter dotWriter = new GraphVizWriter(writer); new GraphVisualizer().write(bindings, dotWriter); dotWriter.close(); }
private FieldSpec memberBindingField(boolean disambiguateFields, Element field) { return FieldSpec.builder(bindingOf(field.asType()), fieldName(disambiguateFields, field), PRIVATE).build(); }