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);
       }
     }
   }
 }
 private void processSimpleTypes(
     String prefix,
     TypeElement element,
     ExecutableElement source,
     TypeElementMembers members,
     Map<String, Object> fieldValues) {
   for (Map.Entry<String, ExecutableElement> entry : members.getPublicGetters().entrySet()) {
     String name = entry.getKey();
     ExecutableElement getter = entry.getValue();
     TypeMirror returnType = getter.getReturnType();
     ExecutableElement setter = members.getPublicSetter(name, returnType);
     VariableElement field = members.getFields().get(name);
     Element returnTypeElement = this.processingEnv.getTypeUtils().asElement(returnType);
     boolean isExcluded = this.typeExcludeFilter.isExcluded(returnType);
     boolean isNested = isNested(returnTypeElement, field, element);
     boolean isCollection = this.typeUtils.isCollectionOrMap(returnType);
     if (!isExcluded && !isNested && (setter != null || isCollection)) {
       String dataType = this.typeUtils.getType(returnType);
       String sourceType = this.typeUtils.getType(element);
       String description = this.typeUtils.getJavaDoc(field);
       Object defaultValue = fieldValues.get(name);
       boolean deprecated = isDeprecated(getter) || isDeprecated(setter) || isDeprecated(source);
       this.metadataCollector.add(
           ItemMetadata.newProperty(
               prefix,
               name,
               dataType,
               sourceType,
               null,
               description,
               defaultValue,
               (deprecated ? getItemDeprecation(getter) : null)));
     }
   }
 }
 /**
  * Tests whether a method invocation is an invocation of {@link Comparable#compareTo}.
  *
  * <p>
  *
  * @param node a method invocation node
  * @return true iff {@code node} is a invocation of {@code compareTo()}
  */
 private boolean isInvocationOfCompareTo(MethodInvocationTree node) {
   ExecutableElement method = TreeUtils.elementFromUse(node);
   return (method.getParameters().size() == 1
       && method.getReturnType().getKind() == TypeKind.INT
       // method symbols only have simple names
       && method.getSimpleName().contentEquals("compareTo"));
 }
Ejemplo n.º 4
0
 @Override
 public void printErrorCheckMethod(
     final PrintWriter writer, final ExecutableElement method, final String tabs) {
   final Check check = method.getAnnotation(Check.class);
   if (check != null) // Get the error code from an IntBuffer output parameter
   writer.println(
         tabs + "Util.checkCLError(" + check.value() + ".get(" + check.value() + ".position()));");
   else {
     final Class return_type = Utils.getJavaType(method.getReturnType());
     if (return_type == int.class) writer.println(tabs + "Util.checkCLError(__result);");
     else {
       boolean hasErrCodeParam = false;
       for (final VariableElement param : method.getParameters()) {
         if ("errcode_ret".equals(param.getSimpleName().toString())
             && Utils.getJavaType(param.asType()) == IntBuffer.class) {
           hasErrCodeParam = true;
           break;
         }
       }
       if (hasErrCodeParam)
         throw new RuntimeException(
             "A method is missing the @Check annotation: " + method.toString());
     }
   }
 }
  private void processFromProperties(TypeElement type, Set<TypeElement> types) {
    List<? extends Element> children = type.getEnclosedElements();
    VisitorConfig config = conf.getConfig(type, children);

    // fields
    if (config.visitFieldProperties()) {
      for (VariableElement field : ElementFilter.fieldsIn(children)) {
        TypeElement typeElement = typeExtractor.visit(field.asType());
        if (typeElement != null) {
          types.add(typeElement);
        }
      }
    }

    // getters
    if (config.visitMethodProperties()) {
      for (ExecutableElement method : ElementFilter.methodsIn(children)) {
        String name = method.getSimpleName().toString();
        if ((name.startsWith("get") || name.startsWith("is")) && method.getParameters().isEmpty()) {
          TypeElement typeElement = typeExtractor.visit(method.getReturnType());
          if (typeElement != null) {
            types.add(typeElement);
          }
        }
      }
    }
  }
Ejemplo n.º 6
0
 private MethodSpec generateMethod(ExecutableElement method) {
   MethodSpec.Builder builder = overriding(method);
   TypeKind returnType = method.getReturnType().getKind();
   if (returnType != VOID) {
     builder.addStatement("return " + defaultValue(returnType));
   }
   return builder.build();
 }
Ejemplo n.º 7
0
 private MethodSpec.Builder createOverridingMethod(ExecutableElement element) {
   // TODO fix the cast
   MethodSpec.Builder result =
       MethodSpec.overriding(element, (DeclaredType) getSourceType().asType(), types);
   String literal = ClassGenerationUtil.defaultReturnLiteral(element.getReturnType());
   if (literal != null) result.addStatement("return $L", literal);
   return result;
 }
Ejemplo n.º 8
0
 private static Set<TypeElement> nestedAnnotationElements(
     TypeElement annotationElement, Set<TypeElement> annotationElements) {
   if (annotationElements.add(annotationElement)) {
     for (ExecutableElement method : methodsIn(annotationElement.getEnclosedElements())) {
       TRAVERSE_NESTED_ANNOTATIONS.visit(method.getReturnType(), annotationElements);
     }
   }
   return annotationElements;
 }
 private void processNestedTypes(
     String prefix, TypeElement element, ExecutableElement source, TypeElementMembers members) {
   for (Map.Entry<String, ExecutableElement> entry : members.getPublicGetters().entrySet()) {
     String name = entry.getKey();
     ExecutableElement getter = entry.getValue();
     VariableElement field = members.getFields().get(name);
     processNestedType(prefix, element, source, name, getter, field, getter.getReturnType());
   }
 }
Ejemplo n.º 10
0
  private void printMethod(ExecutableElement executableElement) {
    StringBuilder s = new StringBuilder(256);
    s.append("method: " + executableElement).append("\n\t");
    s.append("annotations: " + executableElement.getAnnotationMirrors()).append("\n\t");
    s.append("return: " + executableElement.getReturnType()).append("\n\t");
    for (VariableElement var : executableElement.getParameters()) {
      s.append("parameter: " + var + ", " + var.getAnnotation(ApiParameterDoc.class))
          .append("\n\t");
    }

    generator.log(s.toString());
  }
 private ProcessorMetaModelMethod toMethodModel(ExecutableElement e, AnnotationMirror am) {
   //  TypeMirror declaringType =  e.getReceiverType();
   final String declaringClassName =
       ((TypeElement) e.getEnclosingElement()).getQualifiedName().toString();
   final String metamodelAnnotationName = getAnnotationClassName(am);
   final Map<String, String> metamodelAttributes = getAnnotationAttributes(am);
   return new ProcessorMetaModelMethod(
       e.getSimpleName().toString(),
       declaringClassName,
       getParamTypes(e),
       e.getReturnType().toString(),
       metamodelAnnotationName,
       metamodelAttributes);
 }
  private Set<TypeElement> processDelegateMethods() {
    Set<Element> delegateMethods = (Set) getElements(QueryDelegate.class);
    Set<TypeElement> typeElements = new HashSet<TypeElement>();

    for (Element delegateMethod : delegateMethods) {
      ExecutableElement method = (ExecutableElement) delegateMethod;
      Element element = delegateMethod.getEnclosingElement();
      String name = method.getSimpleName().toString();
      Type delegateType = typeFactory.getType(element.asType(), true);
      Type returnType = typeFactory.getType(method.getReturnType(), true);
      List<Parameter> parameters = elementHandler.transformParams(method.getParameters());
      // remove first element
      parameters = parameters.subList(1, parameters.size());

      EntityType entityType = null;
      for (AnnotationMirror annotation : delegateMethod.getAnnotationMirrors()) {
        if (TypeUtils.isAnnotationMirrorOfType(annotation, QueryDelegate.class)) {
          TypeMirror type = TypeUtils.getAnnotationValueAsTypeMirror(annotation, "value");
          if (type != null) {
            entityType = typeFactory.getEntityType(type, true);
          }
        }
      }

      if (entityType != null) {
        registerTypeElement(entityType.getFullName(), (TypeElement) element);
        entityType.addDelegate(
            new Delegate(entityType, delegateType, name, parameters, returnType));
        TypeElement typeElement =
            processingEnv.getElementUtils().getTypeElement(entityType.getFullName());
        boolean isAnnotated = false;
        for (Class<? extends Annotation> ann : conf.getEntityAnnotations()) {
          if (typeElement.getAnnotation(ann) != null) {
            isAnnotated = true;
          }
        }
        if (isAnnotated) {
          // handle also properties of entity type
          typeElements.add(
              processingEnv.getElementUtils().getTypeElement(entityType.getFullName()));
        } else {
          // skip handling properties
          context.extensionTypes.put(entityType.getFullName(), entityType);
          context.allTypes.put(entityType.getFullName(), entityType);
        }
      }
    }

    return typeElements;
  }
Ejemplo n.º 13
0
  public TargetMethodInjector(ExecutableElement executableElement) {
    this.executableElement = executableElement;
    this.methodName = executableElement.getSimpleName().toString();
    this.returnType = executableElement.getReturnType();
    this.arguments = executableElement.getParameters();

    if (executableElement.getAnnotation(POST.class) != null) {
      httpMethod = _POST;
      url = executableElement.getAnnotation(POST.class).value();
    } else if (executableElement.getAnnotation(GET.class) != null) {
      httpMethod = _GET;
      url = executableElement.getAnnotation(GET.class).value();
    }
  }
 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();
 }
Ejemplo n.º 15
0
  private void parseGetter(ExecutableElement methodElement) {
    assert methodElement.getSimpleName().toString().startsWith("get");
    assert methodElement.getParameters().size() == 1;

    final boolean isFactoryGetter =
        methodElement
            .getParameters()
            .get(0)
            .asType()
            .toString()
            .equals(DynamicObjectFactory.class.getName());
    final boolean isObjectTypeGetter =
        methodElement.getParameters().get(0).asType().toString().equals(ObjectType.class.getName());

    assert !(isFactoryGetter & isObjectTypeGetter);

    if (isFactoryGetter) {
      assert methodElement.getParameters().get(0).getSimpleName().toString().equals("factory");
    } else if (isObjectTypeGetter) {
      assert methodElement.getParameters().get(0).getSimpleName().toString().equals("objectType");
    } else {
      assert methodElement
          .getParameters()
          .get(0)
          .asType()
          .toString()
          .equals(DynamicObject.class.getName());
      assert methodElement.getParameters().get(0).getSimpleName().toString().equals("object");
    }

    final String name =
        titleToCamel(methodElement.getSimpleName().toString().substring("get".length()));
    final PropertyBuilder property = getProperty(name);

    if (isFactoryGetter) {
      property.setHasFactoryGetter(true);
    } else if (isObjectTypeGetter) {
      property.setHasObjectTypeGetter(true);
    } else {
      property.setHasGetter(true);
    }

    setPropertyType(property, methodElement.getReturnType());
  }
Ejemplo n.º 16
0
  /**
   * Value is the canonical outside look of the value type. It should be either {@link
   * #typeAbstract()} or {@link #typeImmutable()}. For factory it is a special surrogate.
   *
   * @return canonical value type name forms
   */
  @Value.Lazy
  public NameForms typeValue() {
    if (protoclass().kind().isValue()) {
      return returnsAbstractValueType() ? typeAbstract() : typeImmutable();
    }
    if (isFactory()) {
      ExecutableElement method = (ExecutableElement) protoclass().sourceElement();
      String type = method.getReturnType().toString();

      return ImmutableConstitution.NameForms.builder()
          .simple(NA_ERROR)
          .relativeRaw(type)
          .packageOf(NA_ERROR)
          .relativeAlreadyQualified(true)
          .visibility(protoclass().visibility())
          .build();
    }
    return typeEnclosing();
  }
Ejemplo n.º 17
0
  private void processRequestMappingMethod(ExecutableElement executableElement) {
    TypeElement cls = (TypeElement) executableElement.getEnclosingElement();
    String path = getClassLevelUrlPath(cls);

    RequestMapping anno = executableElement.getAnnotation(RequestMapping.class);
    path = addMethodPathComponent(executableElement, cls, path, anno);
    RequestMethod meth = getRequestMethod(executableElement, cls, anno);

    RestDocumentation.Resource.Method doc =
        _docs.getResourceDocumentation(path).newMethodDocumentation(meth);
    String docComment = processingEnv.getElementUtils().getDocComment(executableElement);
    if (StringUtils.isNotBlank(docComment)) {
      MethodStructure methodStructure = generateMethodStructure(docComment);
      doc.setCommentText(generateJavaDocHTML(methodStructure));
      doc.setCommentSummary(methodStructure.getDescription());
    }
    buildParameterData(executableElement, doc);
    buildResponseFormat(executableElement.getReturnType(), doc);
  }
Ejemplo n.º 18
0
    public SectorMethod build() {
      SectorMethod method = new SectorMethod();
      String methodName = methodElement.getSimpleName().toString();
      SectorOperation operationAnnotation = methodElement.getAnnotation(SectorOperation.class);
      if (operationAnnotation == null) {
        return null;
      }

      int argCount = methodElement.getParameters().size();

      method.cellbased = operationAnnotation.cellbased();
      method.name = "hz_" + methodName;

      method.returnType = methodElement.getReturnType().toString();
      method.invocationClassName =
          CodeGenerationUtils.capitalizeFirstLetter(methodName) + argCount + "Invocation";
      method.targetMethod = methodName;
      method.readonly = operationAnnotation.readonly();
      method.functionId = sectorClassModel.getMethods().size();

      List<FormalArgument> args = new LinkedList<>();

      for (VariableElement variableElement : methodElement.getParameters()) {
        FormalArgument formalArgument = new FormalArgument();
        if (method.cellbased && args.isEmpty()) {
          formalArgument.name = "id";
          formalArgument.type = "long";
        } else {
          formalArgument.name = "arg" + (args.size() + 1);
          formalArgument.type = variableElement.asType().toString();
        }
        args.add(formalArgument);
      }

      method.formalArguments = args;

      buildOriginalMethos(method);

      buildAsyncMethod(method);

      return method;
    }
Ejemplo n.º 19
0
    private boolean isJsonBeanGetter(ExecutableElement executableElement) {
      if (executableElement.getKind() != ElementKind.METHOD) {
        return false;
      }

      if (executableElement.getReturnType().getKind() == TypeKind.NULL) {
        return false;
      }

      if (!(executableElement.getSimpleName().toString().startsWith("get")
          || executableElement.getSimpleName().toString().startsWith("is"))) {
        return false;
      }

      if (executableElement.getParameters().size() > 0) {
        return false;
      }

      return executableElement.getAnnotation(JsonIgnore.class) == null;
    }
Ejemplo n.º 20
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);
    }
  }
Ejemplo n.º 21
0
    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;
    }
Ejemplo n.º 22
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;
  }
Ejemplo n.º 23
0
    private void addFieldFromBeanMethod(JsonObject o, ExecutableElement executableElement) {
      if (!isJsonBeanGetter(executableElement)) {
        return;
      }

      TypeMirror type = executableElement.getReturnType();
      String methodName = executableElement.getSimpleName().toString();
      int trimLength = methodName.startsWith("is") ? 2 : 3;
      String beanName = methodName.substring(trimLength + 1, methodName.length());
      beanName = methodName.substring(trimLength, trimLength + 1).toLowerCase() + beanName;

      // loop over the element's generic types, and build a concrete list from the owning context
      List<DeclaredType> concreteTypes = new ArrayList();

      // replace variables with the current concrete manifestation
      if (type instanceof TypeVariable) {
        type = getDeclaredTypeForTypeVariable((TypeVariable) type);
        if (type == null) {
          return; // couldn't find a replacement -- must be a generics-capable type with no generics
                  // info
        }
      }

      String docComment = processingEnv.getElementUtils().getDocComment(executableElement);
      if (type instanceof DeclaredType) {
        TypeElement element = (TypeElement) ((DeclaredType) type).asElement();
        for (TypeParameterElement generic : element.getTypeParameters()) {
          concreteTypes.add(_typeArguments.get(generic.getSimpleName()));
        }
        Collection<DeclaredType> types = new HashSet<DeclaredType>(_typeRecursionGuard);
        types.add(_type);
        o.addField(beanName, newJsonType((DeclaredType) type, concreteTypes, types))
            .setCommentText(docComment);
      } else {
        o.addField(beanName, newJsonType(type)).setCommentText(docComment);
      }
    }
Ejemplo n.º 24
0
  private void processLabels(TypeElement resourcesType, List<LabelTemplateMethod> methods) {
    for (Element element : resourcesType.getEnclosedElements()) {
      if (element.getKind() != ElementKind.METHOD) {
        continue;
      }
      final ExecutableElement method = (ExecutableElement) element;
      Message labelAnnotation = element.getAnnotation(Message.class);
      final TemplateParam returnType = new TemplateParam(method.getReturnType().toString());
      final boolean deprecated = method.getAnnotation(Deprecated.class) != null;
      final LabelTemplateMethod labelMethod;
      try {
        labelMethod =
            new LabelTemplateMethod(
                method.getSimpleName().toString(),
                deprecated,
                returnType,
                labelAnnotation.value(),
                labelAnnotation.mobile());
      } catch (Throwable t) {
        processingEnv.getMessager().printMessage(Kind.WARNING, t.getMessage(), resourcesType);
        continue;
      }

      for (VariableElement variable : method.getParameters()) {
        final String paramName = variable.getSimpleName().toString();
        final String paramType = variable.asType().toString();

        List<TemplateAnnotation> annotations = new ArrayList<TemplateAnnotation>();
        for (AnnotationMirror annotationMirrors : variable.getAnnotationMirrors()) {
          annotations.add(new TemplateAnnotation(annotationMirrors.getAnnotationType().toString()));
        }

        labelMethod.getParams().add(new TemplateParam(paramType, paramName, annotations));
      }
      methods.add(labelMethod);
    }
  }
Ejemplo n.º 25
0
  private MethodSpec buildCreateMethod(
      ClassName mapKeyGeneratedTypeName, TypeElement annotationElement) {
    String createMethodName = "create" + annotationElement.getSimpleName();
    MethodSpec.Builder createMethod =
        methodBuilder(createMethodName)
            .addAnnotation(AutoAnnotation.class)
            .addModifiers(PUBLIC, STATIC)
            .returns(TypeName.get(annotationElement.asType()));

    ImmutableList.Builder<CodeBlock> parameters = ImmutableList.builder();
    for (ExecutableElement annotationMember : methodsIn(annotationElement.getEnclosedElements())) {
      String parameterName = annotationMember.getSimpleName().toString();
      TypeName parameterType = TypeName.get(annotationMember.getReturnType());
      createMethod.addParameter(parameterType, parameterName);
      parameters.add(CodeBlocks.format("$L", parameterName));
    }

    ClassName autoAnnotationClass =
        mapKeyGeneratedTypeName.peerClass(
            "AutoAnnotation_" + mapKeyGeneratedTypeName.simpleName() + "_" + createMethodName);
    createMethod.addStatement(
        "return new $T($L)", autoAnnotationClass, makeParametersCodeBlock(parameters.build()));
    return createMethod.build();
  }
Ejemplo n.º 26
0
  private void parseListenerAnnotation(
      Class<? extends Annotation> annotationClass,
      Element element,
      Map<TypeElement, BindingClass> targetClassMap,
      Set<String> erasedTargetNames)
      throws Exception {
    // This should be guarded by the annotation's @Target but it's worth a check for safe casting.
    if (!(element instanceof ExecutableElement) || element.getKind() != METHOD) {
      throw new IllegalStateException(
          String.format("@%s annotation must be on a method.", annotationClass.getSimpleName()));
    }

    ExecutableElement executableElement = (ExecutableElement) element;
    TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();

    // Assemble information on the method.
    Annotation annotation = element.getAnnotation(annotationClass);
    Method annotationValue = annotationClass.getDeclaredMethod("value");
    if (annotationValue.getReturnType() != int[].class) {
      throw new IllegalStateException(
          String.format("@%s annotation value() type not int[].", annotationClass));
    }

    int[] ids = (int[]) annotationValue.invoke(annotation);
    String name = executableElement.getSimpleName().toString();
    boolean required = isRequiredBinding(element);

    // Verify that the method and its containing class are accessible via generated code.
    boolean hasError = isInaccessibleViaGeneratedCode(annotationClass, "methods", element);
    hasError |= isBindingInWrongPackage(annotationClass, element);

    Integer duplicateId = findDuplicate(ids);
    if (duplicateId != null) {
      error(
          element,
          "@%s annotation for method contains duplicate ID %d. (%s.%s)",
          annotationClass.getSimpleName(),
          duplicateId,
          enclosingElement.getQualifiedName(),
          element.getSimpleName());
      hasError = true;
    }

    ListenerClass listener = annotationClass.getAnnotation(ListenerClass.class);
    if (listener == null) {
      throw new IllegalStateException(
          String.format(
              "No @%s defined on @%s.",
              ListenerClass.class.getSimpleName(), annotationClass.getSimpleName()));
    }

    for (int id : ids) {
      if (id == View.NO_ID) {
        if (ids.length == 1) {
          if (!required) {
            error(
                element,
                "ID-free binding must not be annotated with @Nullable. (%s.%s)",
                enclosingElement.getQualifiedName(),
                element.getSimpleName());
            hasError = true;
          }

          // Verify target type is valid for a binding without an id.
          String targetType = listener.targetType();
          if (!isSubtypeOfType(enclosingElement.asType(), targetType)
              && !isInterface(enclosingElement.asType())) {
            error(
                element,
                "@%s annotation without an ID may only be used with an object of type "
                    + "\"%s\" or an interface. (%s.%s)",
                annotationClass.getSimpleName(),
                targetType,
                enclosingElement.getQualifiedName(),
                element.getSimpleName());
            hasError = true;
          }
        } else {
          error(
              element,
              "@%s annotation contains invalid ID %d. (%s.%s)",
              annotationClass.getSimpleName(),
              id,
              enclosingElement.getQualifiedName(),
              element.getSimpleName());
          hasError = true;
        }
      }
    }

    ListenerMethod method;
    ListenerMethod[] methods = listener.method();
    if (methods.length > 1) {
      throw new IllegalStateException(
          String.format(
              "Multiple listener methods specified on @%s.", annotationClass.getSimpleName()));
    } else if (methods.length == 1) {
      if (listener.callbacks() != ListenerClass.NONE.class) {
        throw new IllegalStateException(
            String.format(
                "Both method() and callback() defined on @%s.", annotationClass.getSimpleName()));
      }
      method = methods[0];
    } else {
      Method annotationCallback = annotationClass.getDeclaredMethod("callback");
      Enum<?> callback = (Enum<?>) annotationCallback.invoke(annotation);
      Field callbackField = callback.getDeclaringClass().getField(callback.name());
      method = callbackField.getAnnotation(ListenerMethod.class);
      if (method == null) {
        throw new IllegalStateException(
            String.format(
                "No @%s defined on @%s's %s.%s.",
                ListenerMethod.class.getSimpleName(),
                annotationClass.getSimpleName(),
                callback.getDeclaringClass().getSimpleName(),
                callback.name()));
      }
    }

    // Verify that the method has equal to or less than the number of parameters as the listener.
    List<? extends VariableElement> methodParameters = executableElement.getParameters();
    if (methodParameters.size() > method.parameters().length) {
      error(
          element,
          "@%s methods can have at most %s parameter(s). (%s.%s)",
          annotationClass.getSimpleName(),
          method.parameters().length,
          enclosingElement.getQualifiedName(),
          element.getSimpleName());
      hasError = true;
    }

    // Verify method return type matches the listener.
    TypeMirror returnType = executableElement.getReturnType();
    if (returnType instanceof TypeVariable) {
      TypeVariable typeVariable = (TypeVariable) returnType;
      returnType = typeVariable.getUpperBound();
    }
    if (!returnType.toString().equals(method.returnType())) {
      error(
          element,
          "@%s methods must have a '%s' return type. (%s.%s)",
          annotationClass.getSimpleName(),
          method.returnType(),
          enclosingElement.getQualifiedName(),
          element.getSimpleName());
      hasError = true;
    }

    if (hasError) {
      return;
    }

    Parameter[] parameters = Parameter.NONE;
    if (!methodParameters.isEmpty()) {
      parameters = new Parameter[methodParameters.size()];
      BitSet methodParameterUsed = new BitSet(methodParameters.size());
      String[] parameterTypes = method.parameters();
      for (int i = 0; i < methodParameters.size(); i++) {
        VariableElement methodParameter = methodParameters.get(i);
        TypeMirror methodParameterType = methodParameter.asType();
        if (methodParameterType instanceof TypeVariable) {
          TypeVariable typeVariable = (TypeVariable) methodParameterType;
          methodParameterType = typeVariable.getUpperBound();
        }

        for (int j = 0; j < parameterTypes.length; j++) {
          if (methodParameterUsed.get(j)) {
            continue;
          }
          if (isSubtypeOfType(methodParameterType, parameterTypes[j])
              || isInterface(methodParameterType)) {
            parameters[i] = new Parameter(j, methodParameterType.toString());
            methodParameterUsed.set(j);
            break;
          }
        }
        if (parameters[i] == null) {
          StringBuilder builder = new StringBuilder();
          builder
              .append("Unable to match @")
              .append(annotationClass.getSimpleName())
              .append(" method arguments. (")
              .append(enclosingElement.getQualifiedName())
              .append('.')
              .append(element.getSimpleName())
              .append(')');
          for (int j = 0; j < parameters.length; j++) {
            Parameter parameter = parameters[j];
            builder
                .append("\n\n  Parameter #")
                .append(j + 1)
                .append(": ")
                .append(methodParameters.get(j).asType().toString())
                .append("\n    ");
            if (parameter == null) {
              builder.append("did not match any listener parameters");
            } else {
              builder
                  .append("matched listener parameter #")
                  .append(parameter.getListenerPosition() + 1)
                  .append(": ")
                  .append(parameter.getType());
            }
          }
          builder
              .append("\n\nMethods may have up to ")
              .append(method.parameters().length)
              .append(" parameter(s):\n");
          for (String parameterType : method.parameters()) {
            builder.append("\n  ").append(parameterType);
          }
          builder.append(
              "\n\nThese may be listed in any order but will be searched for from top to bottom.");
          error(executableElement, builder.toString());
          return;
        }
      }
    }

    MethodViewBinding binding = new MethodViewBinding(name, Arrays.asList(parameters), required);
    BindingClass bindingClass = getOrCreateTargetClass(targetClassMap, enclosingElement);
    for (int id : ids) {
      if (!bindingClass.addMethod(id, listener, method, binding)) {
        error(
            element,
            "Multiple listener methods with return value specified for ID %d. (%s.%s)",
            id,
            enclosingElement.getQualifiedName(),
            element.getSimpleName());
        return;
      }
    }

    // Add the type-erased version to the valid binding targets set.
    erasedTargetNames.add(enclosingElement.toString());
  }
Ejemplo n.º 27
0
  private void writeProvidesAdapter(
      JavaWriter writer,
      ExecutableElement providerMethod,
      Map<ExecutableElement, String> methodToClassName,
      Map<String, AtomicInteger> methodNameToNextId)
      throws IOException {
    String methodName = providerMethod.getSimpleName().toString();
    String moduleType = CodeGen.typeToString(providerMethod.getEnclosingElement().asType());
    String className = bindingClassName(providerMethod, methodToClassName, methodNameToNextId);
    String returnType = CodeGen.typeToString(providerMethod.getReturnType());
    List<? extends VariableElement> parameters = providerMethod.getParameters();
    boolean dependent = !parameters.isEmpty();

    writer.emitEmptyLine();
    writer.emitJavadoc(binderTypeDocs(returnType, false, false, dependent));
    writer.beginType(
        className,
        "class",
        PUBLIC | FINAL | STATIC,
        JavaWriter.type(Binding.class, returnType),
        JavaWriter.type(Provider.class, returnType));
    writer.emitField(moduleType, "module", PRIVATE | FINAL);
    for (Element parameter : parameters) {
      TypeMirror parameterType = parameter.asType();
      writer.emitField(
          JavaWriter.type(Binding.class, CodeGen.typeToString(parameterType)),
          parameterName(parameter),
          PRIVATE);
    }

    writer.emitEmptyLine();
    writer.beginMethod(null, className, PUBLIC, moduleType, "module");
    boolean singleton = providerMethod.getAnnotation(Singleton.class) != null;
    String key = JavaWriter.stringLiteral(GeneratorKeys.get(providerMethod));
    String membersKey = null;
    writer.emitStatement(
        "super(%s, %s, %s, %s.class)",
        key, membersKey, (singleton ? "IS_SINGLETON" : "NOT_SINGLETON"), moduleType);
    writer.emitStatement("this.module = module");
    writer.endMethod();

    if (dependent) {
      writer.emitEmptyLine();
      writer.emitJavadoc(ProcessorJavadocs.ATTACH_METHOD);
      writer.emitAnnotation(Override.class);
      writer.emitAnnotation(SuppressWarnings.class, JavaWriter.stringLiteral("unchecked"));
      writer.beginMethod("void", "attach", PUBLIC, Linker.class.getCanonicalName(), "linker");
      for (VariableElement parameter : parameters) {
        String parameterKey = GeneratorKeys.get(parameter);
        writer.emitStatement(
            "%s = (%s) linker.requestBinding(%s, %s.class)",
            parameterName(parameter),
            writer.compressType(
                JavaWriter.type(Binding.class, CodeGen.typeToString(parameter.asType()))),
            JavaWriter.stringLiteral(parameterKey),
            writer.compressType(moduleType));
      }
      writer.endMethod();

      writer.emitEmptyLine();
      writer.emitJavadoc(ProcessorJavadocs.GET_DEPENDENCIES_METHOD);
      writer.emitAnnotation(Override.class);
      String setOfBindings = JavaWriter.type(Set.class, "Binding<?>");
      writer.beginMethod(
          "void",
          "getDependencies",
          PUBLIC,
          setOfBindings,
          "getBindings",
          setOfBindings,
          "injectMembersBindings");
      for (Element parameter : parameters) {
        writer.emitStatement("getBindings.add(%s)", parameter.getSimpleName().toString());
      }
      writer.endMethod();
    }

    writer.emitEmptyLine();
    writer.emitJavadoc(ProcessorJavadocs.GET_METHOD, returnType);
    writer.emitAnnotation(Override.class);
    writer.beginMethod(returnType, "get", PUBLIC);
    StringBuilder args = new StringBuilder();
    boolean first = true;
    for (Element parameter : parameters) {
      if (!first) args.append(", ");
      else first = false;
      args.append(String.format("%s.get()", parameter.getSimpleName().toString()));
    }
    writer.emitStatement("return module.%s(%s)", methodName, args.toString());
    writer.endMethod();

    writer.endType();
  }
Ejemplo n.º 28
0
  @Override
  public Set<ConstraintCheckError> checkMethod(
      ExecutableElement element, AnnotationMirror annotation) {

    return checkInternal(element, annotation, element.getReturnType(), "NOT_SUPPORTED_RETURN_TYPE");
  }
 public JavaType getReturnType() {
   return getTypeAdapter(executable.getReturnType());
 }
Ejemplo n.º 30
0
  @Override
  public boolean process(Set<? extends TypeElement> elements, RoundEnvironment env) {
    System.out.println("processing: " + env.toString());
    List<MethodToLog> methodToLogs = new ArrayList<>();
    List<String> classNames = new ArrayList<>();

    for (Element element : env.getElementsAnnotatedWith(XLog.class)) {
      if (element.getKind() != ElementKind.METHOD
          && element.getKind() != ElementKind.CONSTRUCTOR
          && element.getKind() != ElementKind.CLASS) {
        throw new IllegalStateException(
            String.format(
                "@%s annotation must be on as method, constructor or class.",
                element.getSimpleName()));
      }
      if (element instanceof TypeElement) {
        // class
        String pkgName = ((TypeElement) element).getQualifiedName().toString();
        if (!classNames.contains(pkgName)) {
          classNames.add(pkgName);
        }
      } else if (element instanceof ExecutableElement) {
        // method or constructor
        ExecutableElement e = (ExecutableElement) element;

        int type = XLogUtils.TYPE_METHOD;
        if (e.getKind() == ElementKind.METHOD) {
          type = XLogUtils.TYPE_METHOD;
        } else if (e.getKind() == ElementKind.CONSTRUCTOR) {
          type = XLogUtils.TYPE_CONSTRUCTOR;
        }

        TypeElement te = findEnclosingTypeElement(e);
        System.out.println(te.getQualifiedName().toString() + "." + e.getSimpleName());
        System.out.println(e.getReturnType());
        List<String> parameters = new ArrayList<>();
        List<String> parameterNames = new ArrayList<>();
        for (VariableElement ve : e.getParameters()) {
          System.out.println(ve.asType());
          System.out.println(ve.getSimpleName());
          parameters.add(ve.asType().toString());
          parameterNames.add(ve.getSimpleName().toString());
        }
        MethodToLog methodToLog =
            new MethodToLog(
                type,
                te.getQualifiedName().toString(),
                e.getSimpleName().toString(),
                parameters,
                parameterNames);
        methodToLogs.add(methodToLog);

        if (!classNames.contains(methodToLog.getClassName())) {
          classNames.add(methodToLog.getClassName());
        }
      }
    }

    if (methodToLogs.size() > 0) {
      generateXLogProcessor("_" + MD5(env.toString()), methodToLogs, classNames);
    }

    return true;
  }