Java Code Examples for com.google.auto.common.MoreElements#asExecutable()

The following examples show how to use com.google.auto.common.MoreElements#asExecutable() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: StringReducerElement.java    From reductor with Apache License 2.0 6 votes vote down vote up
private static List<AutoReducerConstructor> parseConstructors(TypeElement typeElement) throws ValidationException {
    List<AutoReducerConstructor> constructors = new ArrayList<>();
    boolean hasNonDefaultConstructors = false;
    for (Element element : typeElement.getEnclosedElements()) {
        if (element.getKind() == ElementKind.CONSTRUCTOR) {
            ExecutableElement executableElement = MoreElements.asExecutable(element);

            if (executableElement.getModifiers().contains(Modifier.PRIVATE)) continue;

            List<? extends VariableElement> parameters = executableElement.getParameters();

            hasNonDefaultConstructors |= parameters.size() != 0;
            constructors.add(new AutoReducerConstructor(executableElement));
        }
    }

    //if we only have one default constructor, it can be omitted
    if (!hasNonDefaultConstructors && constructors.size() == 1) return Collections.emptyList();

    //this is the case when all constructors are private
    if (constructors.size() == 0)
        throw new ValidationException(typeElement, "No accessible constructors available for class %s", typeElement);

    return constructors;
}
 
Example 2
Source File: AdditionProcessing.java    From Auto-Dagger2 with MIT License 5 votes vote down vote up
@Override
public boolean processElement(Element element, Errors.ElementErrors elementErrors) {
    // @AutoX applied on annotation
    if (element.getKind() == ElementKind.ANNOTATION_TYPE) {
        // @AutoX is applied on another annotation, find out the targets of that annotation
        Set<? extends Element> targetElements = roundEnvironment.getElementsAnnotatedWith(MoreElements.asType(element));
        for (Element targetElement : targetElements) {
            if (!process(targetElement, element)) {
                return false;
            }
        }
        return true;
    }

    // @AutoX applied on method
    // only valid for @AutoExpose with @Provides
    if (element.getKind() == ElementKind.METHOD) {
        if (processedAnnotation.equals(AutoInjector.class)) {
            errors.addInvalid(element, "@AutoInjector cannot be applied on the method %s", element.getSimpleName());
            return false;
        }

        if (!MoreElements.isAnnotationPresent(element, Provides.class)) {
            errors.addInvalid(element, "@AutoExpose can be applied on @Provides method only, %s is missing it", element.getSimpleName());
            return false;
        }

        ExecutableElement executableElement = MoreElements.asExecutable(element);
        Element returnElement = MoreTypes.asElement(executableElement.getReturnType());

        return process(returnElement, element);
    }

    process(element, element);
    return !errors.hasErrors();
}
 
Example 3
Source File: StringReducerElement.java    From reductor with Apache License 2.0 4 votes vote down vote up
public static StringReducerElement parseStringReducerElement(Element element, Map<String, ActionCreatorElement> knownActionCreators, Env env) throws ValidationException {
    if (element.getKind() != ElementKind.CLASS) {
        throw new ValidationException(element, "You can apply %s only to classes", AutoReducer.class.getSimpleName());
    }

    TypeElement typeElement = (TypeElement) element;
    if (MoreTypes.asDeclared(typeElement.asType()).getEnclosingType().getKind() != TypeKind.NONE) {
        throw new ValidationException(element, "%s annotated reducers should not be inner classes. Probably 'static' modifier missing", AutoReducer.class.getSimpleName());
    }

    DeclaredType declaredType = (DeclaredType) typeElement.asType();
    DeclaredType reducerSuperInterface = Utils.getReducerSuperInterface(declaredType);
    if (reducerSuperInterface == null) {
        throw new ValidationException(typeElement, "%s should implement %s interface", typeElement, Reducer.class.getSimpleName());
    }

    TypeMirror stateType = reducerSuperInterface.getTypeArguments().get(0);

    List<ReduceAction> actions = new ArrayList<>();
    AutoReducerInit initMethod = null;
    for (Element enclosedElement : typeElement.getEnclosedElements()) {
        if(enclosedElement.getKind() != ElementKind.METHOD) continue;
        ExecutableElement executableElement = MoreElements.asExecutable(enclosedElement);

        if (enclosedElement.getAnnotation(AutoReducer.InitialState.class) != null) {
            if(initMethod != null) {
                throw new ValidationException(enclosedElement, "Methods %s and %s are both annotated with @AutoReducer.InitialState. Only one @AutoReducer.InitialState method is allowed", initMethod.executableElement, executableElement);
            }
            initMethod = AutoReducerInit.parse(env, executableElement, stateType);
        } else {
            ReduceAction reduceAction = ReduceAction.parseReduceAction(env, stateType, executableElement, knownActionCreators);
            if (reduceAction != null) {
                actions.add(reduceAction);
            }
        }
    }

    List<AutoReducerConstructor> constructors = parseConstructors(typeElement);

    final DeclaredType stateDeclaredType = (DeclaredType) stateType;
    return new StringReducerElement(stateDeclaredType, actions, initMethod, typeElement, constructors);
}
 
Example 4
Source File: ComponentGenerator.java    From dagger2-sample with Apache License 2.0 4 votes vote down vote up
private void writeInterfaceMethods(BindingGraph input, ClassWriter componentWriter,
    ImmutableMap<BindingKey, MemberSelect> memberSelectSnippets,
    ImmutableSet<BindingKey> enumBindingKeys) throws AssertionError {
  Set<MethodSignature> interfaceMethods = Sets.newHashSet();

  for (ComponentMethodDescriptor componentMethod :
      input.componentDescriptor().componentMethods()) {
    if (componentMethod.dependencyRequest().isPresent()) {
      DependencyRequest interfaceRequest = componentMethod.dependencyRequest().get();
      ExecutableElement requestElement =
          MoreElements.asExecutable(interfaceRequest.requestElement());
      ExecutableType requestType = MoreTypes.asExecutable(types.asMemberOf(
          MoreTypes.asDeclared(input.componentDescriptor().componentDefinitionType().asType()),
          requestElement));
      MethodSignature signature = MethodSignature.fromExecutableType(
          requestElement.getSimpleName().toString(),
          requestType);
      if (!interfaceMethods.contains(signature)) {
        interfaceMethods.add(signature);
        MethodWriter interfaceMethod = requestType.getReturnType().getKind().equals(VOID)
            ? componentWriter.addMethod(VoidName.VOID, requestElement.getSimpleName().toString())
                : componentWriter.addMethod(requestType.getReturnType(),
                    requestElement.getSimpleName().toString());
        interfaceMethod.annotate(Override.class);
        interfaceMethod.addModifiers(PUBLIC);
        BindingKey bindingKey = interfaceRequest.bindingKey();
        switch(interfaceRequest.kind()) {
          case MEMBERS_INJECTOR:
            MemberSelect membersInjectorSelect = memberSelectSnippets.get(bindingKey);
            List<? extends VariableElement> parameters = requestElement.getParameters();
            if (parameters.isEmpty()) {
              // we're returning the framework type
              interfaceMethod.body().addSnippet("return %s;",
                  membersInjectorSelect.getSnippetFor(componentWriter.name()));
            } else {
              VariableElement parameter = Iterables.getOnlyElement(parameters);
              Name parameterName = parameter.getSimpleName();
              interfaceMethod.addParameter(
                  TypeNames.forTypeMirror(
                      Iterables.getOnlyElement(requestType.getParameterTypes())),
                  parameterName.toString());
              interfaceMethod.body().addSnippet("%s.injectMembers(%s);",
                  // in this case we know we won't need the cast because we're never going to pass
                  // the reference to anything
                  membersInjectorSelect.getSnippetFor(componentWriter.name()),
                  parameterName);
              if (!requestType.getReturnType().getKind().equals(VOID)) {
                interfaceMethod.body().addSnippet("return %s;", parameterName);
              }
            }
            break;
          case INSTANCE:
            if (enumBindingKeys.contains(bindingKey)
                && !MoreTypes.asDeclared(bindingKey.key().type())
                        .getTypeArguments().isEmpty()) {
              // If using a parameterized enum type, then we need to store the factory
              // in a temporary variable, in order to help javac be able to infer
              // the generics of the Factory.create methods.
              TypeName factoryType = ParameterizedTypeName.create(Provider.class,
                  TypeNames.forTypeMirror(requestType.getReturnType()));
              interfaceMethod.body().addSnippet("%s factory = %s;", factoryType,
                  memberSelectSnippets.get(bindingKey).getSnippetFor(componentWriter.name()));
              interfaceMethod.body().addSnippet("return factory.get();");
              break;
            }
            // fall through in the else case.
          case LAZY:
          case PRODUCED:
          case PRODUCER:
          case PROVIDER:
          case FUTURE:
            interfaceMethod.body().addSnippet("return %s;",
                frameworkTypeUsageStatement(
                    memberSelectSnippets.get(bindingKey).getSnippetFor(componentWriter.name()),
                    interfaceRequest.kind()));
            break;
          default:
            throw new AssertionError();
        }
      }
    }
  }
}
 
Example 5
Source File: BindingGraphValidator.java    From dagger2-sample with Apache License 2.0 4 votes vote down vote up
/**
 * Validates that the scope (if any) of this component are compatible with the scopes of the
 * bindings available in this component
 */
void validateComponentScope(final BindingGraph subject,
    final ValidationReport.Builder<BindingGraph> reportBuilder,
    ImmutableMap<BindingKey, ResolvedBindings> resolvedBindings) {
  Optional<Equivalence.Wrapper<AnnotationMirror>> componentScope =
      subject.componentDescriptor().wrappedScope();
  ImmutableSet.Builder<String> incompatiblyScopedMethodsBuilder = ImmutableSet.builder();
  for (ResolvedBindings bindings : resolvedBindings.values()) {
    if (bindings.bindingKey().kind().equals(BindingKey.Kind.CONTRIBUTION)) {
      for (ContributionBinding contributionBinding : bindings.ownedContributionBindings()) {
        if (contributionBinding instanceof ProvisionBinding) {
          ProvisionBinding provisionBinding = (ProvisionBinding) contributionBinding;
          if (provisionBinding.scope().isPresent()
              && !componentScope.equals(provisionBinding.wrappedScope())) {
            // Scoped components cannot reference bindings to @Provides methods or @Inject
            // types decorated by a different scope annotation. Unscoped components cannot
            // reference to scoped @Provides methods or @Inject types decorated by any
            // scope annotation.
            switch (provisionBinding.bindingKind()) {
              case PROVISION:
                ExecutableElement provisionMethod =
                    MoreElements.asExecutable(provisionBinding.bindingElement());
                incompatiblyScopedMethodsBuilder.add(
                    methodSignatureFormatter.format(provisionMethod));
                break;
              case INJECTION:
                incompatiblyScopedMethodsBuilder.add(stripCommonTypePrefixes(
                    provisionBinding.scope().get().toString()) + " class "
                        + provisionBinding.bindingTypeElement().getQualifiedName());
                break;
              default:
                throw new IllegalStateException();
            }
          }
        }
      }
    }
  }
  ImmutableSet<String> incompatiblyScopedMethods = incompatiblyScopedMethodsBuilder.build();
  if (!incompatiblyScopedMethods.isEmpty()) {
    TypeElement componentType = subject.componentDescriptor().componentDefinitionType();
    StringBuilder message = new StringBuilder(componentType.getQualifiedName());
    if (componentScope.isPresent()) {
      message.append(" scoped with ");
      message.append(stripCommonTypePrefixes(ErrorMessages.format(componentScope.get().get())));
      message.append(" may not reference bindings with different scopes:\n");
    } else {
      message.append(" (unscoped) may not reference scoped bindings:\n");
    }
    for (String method : incompatiblyScopedMethods) {
      message.append(ErrorMessages.INDENT).append(method).append("\n");
    }
    reportBuilder.addItem(message.toString(), componentType,
        subject.componentDescriptor().componentAnnotation());
  }
}