private AutoValueExtension.Context createContext(TypeElement type) { String packageName = MoreElements.getPackage(type).getQualifiedName().toString(); Set<ExecutableElement> allMethods = MoreElements.getLocalAndInheritedMethods(type, elements); Set<ExecutableElement> methods = methodsToImplement(type, allMethods); Map<String, ExecutableElement> properties = new LinkedHashMap<String, ExecutableElement>(); for (ExecutableElement e : methods) { properties.put(e.getSimpleName().toString(), e); } return new TestContext(processingEnvironment, packageName, type, properties); }
/** * Formats an ExecutableElement as if it were contained within the container, if the container is * present. */ public String format(ExecutableElement method, Optional<DeclaredType> container) { StringBuilder builder = new StringBuilder(); TypeElement type = MoreElements.asType(method.getEnclosingElement()); ExecutableType executableType = MoreTypes.asExecutable(method.asType()); if (container.isPresent()) { executableType = MoreTypes.asExecutable(types.asMemberOf(container.get(), method)); type = MoreElements.asType(container.get().asElement()); } // TODO(cgruber): AnnotationMirror formatter. List<? extends AnnotationMirror> annotations = method.getAnnotationMirrors(); if (!annotations.isEmpty()) { Iterator<? extends AnnotationMirror> annotationIterator = annotations.iterator(); for (int i = 0; annotationIterator.hasNext(); i++) { if (i > 0) { builder.append(' '); } builder.append(ErrorMessages.format(annotationIterator.next())); } builder.append(' '); } builder.append(nameOfType(executableType.getReturnType())); builder.append(' '); builder.append(type.getQualifiedName()); builder.append('.'); builder.append(method.getSimpleName()); builder.append('('); checkState(method.getParameters().size() == executableType.getParameterTypes().size()); Iterator<? extends VariableElement> parameters = method.getParameters().iterator(); Iterator<? extends TypeMirror> parameterTypes = executableType.getParameterTypes().iterator(); for (int i = 0; parameters.hasNext(); i++) { if (i > 0) { builder.append(", "); } appendParameter(builder, parameters.next(), parameterTypes.next()); } builder.append(')'); return builder.toString(); }
/** * Returns a code block that injects the instance's field or method by calling a static method on * the parent MembersInjector class. */ private CodeBlock delegateInjectMemberCodeBlock( ImmutableMap<BindingKey, FieldSpec> dependencyFields, InjectionSite injectionSite) { return CodeBlocks.format( "$L.$L($L);", javapoetMembersInjectorNameForType( MoreElements.asType(injectionSite.element().getEnclosingElement())), injectionSiteDelegateMethodName(injectionSite.element()), makeParametersCodeBlock( new ImmutableList.Builder<CodeBlock>() .add(CodeBlocks.format("instance")) .addAll(parameterCodeBlocks(dependencyFields, injectionSite.dependencies(), false)) .build())); }
@Override public String format(BindingDeclaration bindingDeclaration) { if (bindingDeclaration instanceof SubcomponentDeclaration) { return formatSubcomponentDeclaration((SubcomponentDeclaration) bindingDeclaration); } if (bindingDeclaration instanceof ContributionBinding) { ContributionBinding binding = (ContributionBinding) bindingDeclaration; switch (binding.bindingKind()) { case SYNTHETIC_RELEASABLE_REFERENCE_MANAGER: return String.format( "binding for %s from the scope declaration", stripCommonTypePrefixes(keyFormatter.format(binding.key()))); case SYNTHETIC_RELEASABLE_REFERENCE_MANAGERS: return String.format( "Dagger-generated binding for %s", stripCommonTypePrefixes(keyFormatter.format(binding.key()))); default: break; } } checkArgument( bindingDeclaration.bindingElement().isPresent(), "Cannot format bindings without source elements: %s", bindingDeclaration); Element bindingElement = bindingDeclaration.bindingElement().get(); switch (bindingElement.asType().getKind()) { case EXECUTABLE: return methodSignatureFormatter.format( MoreElements.asExecutable(bindingElement), bindingDeclaration .contributingModule() .map(module -> MoreTypes.asDeclared(module.asType()))); case DECLARED: return stripCommonTypePrefixes(bindingElement.asType().toString()); default: throw new IllegalArgumentException("Formatting unsupported for element: " + bindingElement); } }
/** * Returns true if the passed {@link TypeElement} requires a passed instance in order to be used * within a component. */ static boolean requiresAPassedInstance(Elements elements, TypeElement typeElement) { ImmutableSet<ExecutableElement> methods = MoreElements.getLocalAndInheritedMethods(typeElement, elements); boolean foundInstanceMethod = false; for (ExecutableElement method : methods) { if (method.getModifiers().contains(ABSTRACT) && !isAnnotationPresent(method, Binds.class)) { /* We found an abstract method that isn't a @Binds method. That automatically means that * a user will have to provide an instance because we don't know which subclass to use. */ return true; } else if (!method.getModifiers().contains(STATIC) && (isAnnotationPresent(method, Provides.class) || isAnnotationPresent(method, Produces.class))) { foundInstanceMethod = true; } } if (foundInstanceMethod) { return !componentCanMakeNewInstances(typeElement); } return false; }
@Override protected boolean onProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { for (Element e : roundEnv.getElementsAnnotatedWith(BeanFactoryExtension.class)) { TypeElement factoryElement = (TypeElement) e; factories.add(factoryElement.getQualifiedName().toString()); } for (Element e : roundEnv.getElementsAnnotatedWith(AutoBeanFactory.Category.class)) { AnnotationMirror categoryAnnotation = MoreElements.getAnnotationMirror(e, AutoBeanFactory.Category.class).get(); AnnotationValue value = AnnotationMirrors.getAnnotationValue(categoryAnnotation, "value"); Collection<String> categories = extractValue(value); this.categories.addAll(categories); } if (!factories.isEmpty()) { debug("Generating composite bean factory"); code( BEAN_FACTORY_TEMPLATE, BEAN_FACTORY_PACKAGE, BEAN_FACTORY_CLASS, () -> { Map<String, Object> context = new HashMap<>(); context.put("packageName", BEAN_FACTORY_PACKAGE); context.put("className", BEAN_FACTORY_CLASS); context.put("factories", factories); context.put("categories", categories); return context; }); info("Successfully generated composite bean factory [%s].", BEAN_FACTORY_CLASS); factories.clear(); categories.clear(); } return false; }
String format(BindingMethodIdentifier bindingMethodIdentifier) { return format( MoreElements.asExecutable(bindingMethodIdentifier.bindingMethod()), Optional.of(MoreTypes.asDeclared(bindingMethodIdentifier.contributingModule().asType()))); }