/**
   * 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();
  }
Exemple #2
0
  public List<Parameter> getParameters(ExecutableType methodType, ExecutableElement method) {
    List<? extends TypeMirror> parameterTypes = methodType.getParameterTypes();
    List<? extends VariableElement> parameters = method.getParameters();
    List<Parameter> result = new ArrayList<Parameter>(parameters.size());

    Iterator<? extends VariableElement> varIt = parameters.iterator();
    Iterator<? extends TypeMirror> typesIt = parameterTypes.iterator();

    for (; varIt.hasNext(); ) {
      VariableElement parameter = varIt.next();
      TypeMirror parameterType = typesIt.next();

      result.add(
          new Parameter(
              parameter.getSimpleName().toString(),
              getType(parameterType),
              MappingTargetPrism.getInstanceOn(parameter) != null,
              TargetTypePrism.getInstanceOn(parameter) != null));
    }

    return result;
  }
  private void doProcess(RoundEnvironment roundEnv) {
    for (Element element : roundEnv.getElementsAnnotatedWith(Provided.class)) {
      providedChecker.checkProvidedParameter(element);
    }

    ImmutableListMultimap.Builder<String, FactoryMethodDescriptor> indexedMethods =
        ImmutableListMultimap.builder();
    ImmutableSet.Builder<ImplementationMethodDescriptor> implementationMethodDescriptors =
        ImmutableSet.builder();
    for (Element element : roundEnv.getElementsAnnotatedWith(AutoFactory.class)) {
      Optional<AutoFactoryDeclaration> declaration = declarationFactory.createIfValid(element);
      if (declaration.isPresent()) {
        TypeElement extendingType = declaration.get().extendingType();
        List<ExecutableElement> supertypeMethods =
            ElementFilter.methodsIn(elements.getAllMembers(extendingType));
        for (ExecutableElement supertypeMethod : supertypeMethods) {
          if (supertypeMethod.getModifiers().contains(Modifier.ABSTRACT)) {
            ExecutableType methodType =
                Elements2.getExecutableElementAsMemberOf(types, supertypeMethod, extendingType);
            implementationMethodDescriptors.add(
                new ImplementationMethodDescriptor.Builder()
                    .name(supertypeMethod.getSimpleName().toString())
                    .returnType(getAnnotatedType(element).getQualifiedName().toString())
                    .publicMethod()
                    .passedParameters(
                        Parameter.forParameterList(
                            supertypeMethod.getParameters(), methodType.getParameterTypes()))
                    .build());
          }
        }
        for (TypeElement implementingType : declaration.get().implementingTypes()) {
          List<ExecutableElement> interfaceMethods =
              ElementFilter.methodsIn(elements.getAllMembers(implementingType));
          for (ExecutableElement interfaceMethod : interfaceMethods) {
            if (interfaceMethod.getModifiers().contains(Modifier.ABSTRACT)) {
              ExecutableType methodType =
                  Elements2.getExecutableElementAsMemberOf(
                      types, interfaceMethod, implementingType);
              implementationMethodDescriptors.add(
                  new ImplementationMethodDescriptor.Builder()
                      .name(interfaceMethod.getSimpleName().toString())
                      .returnType(getAnnotatedType(element).getQualifiedName().toString())
                      .publicMethod()
                      .passedParameters(
                          Parameter.forParameterList(
                              interfaceMethod.getParameters(), methodType.getParameterTypes()))
                      .build());
            }
          }
        }
      }

      ImmutableSet<FactoryMethodDescriptor> descriptors =
          factoryDescriptorGenerator.generateDescriptor(element);
      indexedMethods.putAll(
          Multimaps.index(
              descriptors,
              new Function<FactoryMethodDescriptor, String>() {
                @Override
                public String apply(FactoryMethodDescriptor descriptor) {
                  return descriptor.factoryName();
                }
              }));
    }

    for (Entry<String, Collection<FactoryMethodDescriptor>> entry :
        indexedMethods.build().asMap().entrySet()) {
      ImmutableSet.Builder<String> extending = ImmutableSet.builder();
      ImmutableSortedSet.Builder<String> implementing = ImmutableSortedSet.naturalOrder();
      boolean publicType = false;
      Boolean allowSubclasses = null;
      boolean skipCreation = false;
      for (FactoryMethodDescriptor methodDescriptor : entry.getValue()) {
        extending.add(methodDescriptor.declaration().extendingType().getQualifiedName().toString());
        for (TypeElement implementingType : methodDescriptor.declaration().implementingTypes()) {
          implementing.add(implementingType.getQualifiedName().toString());
        }
        publicType |= methodDescriptor.publicMethod();
        if (allowSubclasses == null) {
          allowSubclasses = methodDescriptor.declaration().allowSubclasses();
        } else if (!allowSubclasses.equals(methodDescriptor.declaration().allowSubclasses())) {
          skipCreation = true;
          messager.printMessage(
              Kind.ERROR,
              "Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.",
              methodDescriptor.declaration().target(),
              methodDescriptor.declaration().mirror(),
              methodDescriptor.declaration().valuesMap().get("allowSubclasses"));
        }
      }
      if (!skipCreation) {
        try {
          factoryWriter.writeFactory(
              new FactoryDescriptor(
                  entry.getKey(),
                  Iterables.getOnlyElement(extending.build()),
                  implementing.build(),
                  publicType,
                  ImmutableSet.copyOf(entry.getValue()),
                  // TODO(gak): this needs to be indexed too
                  implementationMethodDescriptors.build(),
                  allowSubclasses));
        } catch (IOException e) {
          messager.printMessage(Kind.ERROR, "failed");
        }
      }
    }
  }
 public Boolean visitExecutable(ExecutableType t, Void v) {
   return t.getParameterTypes().isEmpty();
 }