/** INTERNAL: Visit an executable and create a MetadataMethod object. */
  @Override
  public MetadataMethod visitExecutable(
      ExecutableElement executableElement, MetadataClass metadataClass) {
    MetadataMethod method = new MetadataMethod(metadataClass.getMetadataFactory(), metadataClass);

    // Set the name.
    method.setName(executableElement.getSimpleName().toString());

    // Set the attribute name.
    method.setAttributeName(Helper.getAttributeNameFromMethodName(method.getName()));

    // Set the modifiers.
    method.setModifiers(getModifiers(executableElement.getModifiers()));

    // Visit executable element for the parameters, return type and generic type.
    executableElement.asType().accept(typeVisitor, method);

    // Set the annotations.
    buildMetadataAnnotations(method, executableElement.getAnnotationMirrors());

    // Handle multiple methods with the same name.
    MetadataMethod existing = metadataClass.getMethods().get(method.getName());
    if (existing == null) {
      metadataClass.addMethod(method);
    } else {
      while (existing.getNext() != null) {
        existing = existing.getNext();
      }
      existing.setNext(method);
    }

    return method;
  }
예제 #2
0
  @SuppressWarnings("checkstyle:parameternumber")
  private SourceMethod(
      Type declaringMapper,
      ExecutableElement executable,
      List<Parameter> parameters,
      Type returnType,
      List<Type> exceptionTypes,
      MappingOptions mappingOptions,
      Types typeUtils,
      TypeFactory typeFactory,
      MapperConfiguration config,
      List<SourceMethod> prototypeMethods,
      Type mapperToImplement) {
    this.declaringMapper = declaringMapper;
    this.executable = executable;
    this.parameters = parameters;
    this.returnType = returnType;
    this.exceptionTypes = exceptionTypes;
    this.accessibility = Accessibility.fromModifiers(executable.getModifiers());

    this.mappingOptions = mappingOptions;

    this.mappingTargetParameter = determineMappingTargetParameter(parameters);
    this.targetTypeParameter = determineTargetTypeParameter(parameters);

    this.typeUtils = typeUtils;
    this.typeFactory = typeFactory;
    this.config = config;
    this.prototypeMethods = prototypeMethods;
    this.mapperToImplement = mapperToImplement;
  }
 private void processExecutableElement(String prefix, ExecutableElement element) {
   if (element.getModifiers().contains(Modifier.PUBLIC)
       && (TypeKind.VOID != element.getReturnType().getKind())) {
     Element returns = this.processingEnv.getTypeUtils().asElement(element.getReturnType());
     if (returns instanceof TypeElement) {
       ItemMetadata group =
           ItemMetadata.newGroup(
               prefix,
               this.typeUtils.getType(returns),
               this.typeUtils.getType(element.getEnclosingElement()),
               element.toString());
       if (this.metadataCollector.hasSimilarGroup(group)) {
         this.processingEnv
             .getMessager()
             .printMessage(
                 Kind.ERROR,
                 "Duplicate `@ConfigurationProperties` definition for prefix '" + prefix + "'",
                 element);
       } else {
         this.metadataCollector.add(group);
         processTypeElement(prefix, (TypeElement) returns, element);
       }
     }
   }
 }
예제 #4
0
 /**
  * Returns true if generated code can invoke {@code constructor}. That is, if the constructor is
  * non-private and its enclosing class is either a top-level class or a static nested class.
  */
 public static boolean isCallableConstructor(ExecutableElement constructor) {
   if (constructor.getModifiers().contains(Modifier.PRIVATE)) {
     return false;
   }
   TypeElement type = (TypeElement) constructor.getEnclosingElement();
   return type.getEnclosingElement().getKind() == ElementKind.PACKAGE
       || type.getModifiers().contains(Modifier.STATIC);
 }
예제 #5
0
파일: Proto.java 프로젝트: akune/immutables
    boolean verifiedFactory(ExecutableElement element) {
      if (!FactoryMirror.isPresent(element)) {
        return false;
      }
      if (!isTopLevel()
          || element.getReturnType().getKind() == TypeKind.VOID
          || element.getModifiers().contains(Modifier.PRIVATE)
          || !element.getModifiers().contains(Modifier.STATIC)
          || !element.getTypeParameters().isEmpty()) {
        report()
            .withElement(element)
            .annotationNamed(FactoryMirror.simpleName())
            .error(
                "@%s method '%s' should be static, non-private, non-void"
                    + " with no type parameters and enclosed in top level type",
                FactoryMirror.simpleName(), element.getSimpleName());
        return false;
      }

      return true;
    }
예제 #6
0
파일: Util.java 프로젝트: yegeniy/dagger
  /**
   * 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;
  }
 private ImmutableSet<ExecutableElement> methodsToImplement(
     TypeElement autoValueClass, Set<ExecutableElement> methods) {
   ImmutableSet.Builder<ExecutableElement> toImplement = ImmutableSet.builder();
   for (ExecutableElement method : methods) {
     if (method.getModifiers().contains(Modifier.ABSTRACT)
         && !Arrays.asList("toString", "hashCode", "equals")
             .contains(method.getSimpleName().toString())) {
       if (method.getParameters().isEmpty() && method.getReturnType().getKind() != TypeKind.VOID) {
         toImplement.add(method);
       }
     }
   }
   return toImplement.build();
 }
예제 #8
0
  public TypeConstructorWrapper(MapperGeneratorContext context, TypeElement typeElement) {
    this.context = context;
    this.typeElement = typeElement;

    boolean defaultConstructor = false;
    boolean matchingSourcesConstructor = false;

    List<ExecutableElement> constructors =
        ElementFilter.constructorsIn(typeElement.getEnclosedElements());
    for (ExecutableElement constructor : constructors) {
      if (constructor.getModifiers().contains(Modifier.PUBLIC)
          && !constructor.getModifiers().contains(Modifier.ABSTRACT)) {
        int paramsCount = constructor.getParameters().size();
        if (paramsCount == 0) {
          defaultConstructor = true;
        }
        if (!matchingSourcesConstructor && paramsCount == context.getSourcesCount()) {
          matchingSourcesConstructor = validateParametersTypes(constructor);
        }
      }
    }
    hasMatchingSourcesConstructor = matchingSourcesConstructor;
    hasDefaultConstructor = defaultConstructor;
  }
예제 #9
0
  private int processConstructor(ExecutableElement constrElt) {
    if (constrElt.getModifiers().contains(Modifier.PUBLIC)) {
      Element ownerElt = constrElt.getEnclosingElement();
      if (ownerElt.equals(modelElt)) {
        List<? extends VariableElement> parameters = constrElt.getParameters();
        int size = parameters.size();
        if (size == 1) {
          TypeInfo ti = typeFactory.create(parameters.get(0).asType());
          if (ti instanceof ClassTypeInfo) {
            ClassTypeInfo cl = (ClassTypeInfo) ti;
            if (cl.getKind() == ClassKind.JSON_OBJECT) {
              return 2;
            }
          }
        }
      }
    }

    return 0;
  }
예제 #10
0
  /**
   * @param env the environment
   * @param annUtil utils
   * @param d the method
   */
  public MethodHandler(
      final ProcessingEnvironment env, final AnnUtil annUtil, final ExecutableElement d) {
    this.env = env;
    this.annUtil = annUtil;
    msg = env.getMessager();

    staticMethod = d.getModifiers().contains(Modifier.STATIC);
    methName = d.getSimpleName().toString();
    getter = methName.startsWith("get");
    setter = methName.startsWith("set");

    immutable = d.getAnnotation(Immutable.class) != null;

    CloneForOverride cfo = d.getAnnotation(CloneForOverride.class);
    cloneForOverride = cfo != null;
    if (cloneForOverride) {
      cloneCollectionType = cfo.cloneCollectionType();
      cloneElementType = cfo.cloneElementType();
    }

    returnType = d.getReturnType();
    returnsVoid = env.getTypeUtils().getNoType(TypeKind.VOID).equals(returnType);

    pars = d.getParameters();
    thrownTypes = d.getThrownTypes();

    if ((setter) && (pars != null) && (pars.size() == 1)) {
      fieldType = pars.iterator().next().asType();
      basicType = fieldType.getKind().isPrimitive();
    }

    if (getter) {
      fieldType = returnType;
      basicType = returnType.getKind().isPrimitive();
    }

    if (setter || getter) {
      ucFieldName = methName.substring(3);
      fieldName = ucFieldName.substring(0, 1).toLowerCase() + ucFieldName.substring(1);
    }
  }
예제 #11
0
  public static CodeExecutableElement clone(
      @SuppressWarnings("unused") ProcessingEnvironment env, ExecutableElement method) {
    CodeExecutableElement copy =
        new CodeExecutableElement(method.getReturnType(), method.getSimpleName().toString());
    for (TypeMirror thrownType : method.getThrownTypes()) {
      copy.addThrownType(thrownType);
    }
    copy.setDefaultValue(method.getDefaultValue());

    for (AnnotationMirror mirror : method.getAnnotationMirrors()) {
      copy.addAnnotationMirror(mirror);
    }
    for (VariableElement var : method.getParameters()) {
      copy.addParameter(CodeVariableElement.clone(var));
    }
    for (Element element : method.getEnclosedElements()) {
      copy.add(element);
    }
    copy.getModifiers().addAll(method.getModifiers());
    copy.setVarArgs(method.isVarArgs());
    return copy;
  }
 @Override
 public Void visitExecutable(ExecutableElement elem, TypeElement parent) {
   if (imp != null) {
     final Set<Modifier> modifiers = elem.getModifiers();
     boolean error = false;
     if (!modifiers.contains(Modifier.STATIC)) {
       error("@Resetter methods must be static");
       error = true;
     }
     if (!modifiers.contains(Modifier.PUBLIC)) {
       error("@Resetter methods must be public");
       error = true;
     }
     List<? extends VariableElement> params = elem.getParameters();
     if (params != null && !params.isEmpty()) {
       error("@Resetter methods must not have parameters");
       error = true;
     }
     if (!error) {
       model.addResetter(parent, elem);
     }
   }
   return null;
 }
예제 #13
0
 @Override
 public boolean isStatic() {
   return executable.getModifiers().contains(Modifier.STATIC);
 }
예제 #14
0
 /**
  * Whether an implementation of this method must be generated or not.
  *
  * @return true when an implementation is required
  */
 @Override
 public boolean overridesMethod() {
   return declaringMapper == null && executable.getModifiers().contains(Modifier.ABSTRACT);
 }
예제 #15
0
  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");
        }
      }
    }
  }
예제 #16
0
 private static boolean isPublic(ExecutableElement method) {
   return method.getModifiers().contains(Modifier.PUBLIC);
 }