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);
       }
     }
   }
 }
Example #2
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);
 }
 /**
  * Build the comments for the method. Do nothing if {@link Configuration#nocomment} is set to
  * true.
  *
  * @param node the XML element that specifies which components to document
  * @param methodDocTree the content tree to which the documentation will be added
  */
 public void buildMethodComments(XMLNode node, Content methodDocTree) {
   if (!configuration.nocomment) {
     ExecutableElement method = currentMethod;
     if (utils.getBody(currentMethod).isEmpty()) {
       DocFinder.Output docs =
           DocFinder.search(configuration, new DocFinder.Input(utils, currentMethod));
       if (docs.inlineTags != null && !docs.inlineTags.isEmpty())
         method = (ExecutableElement) docs.holder;
     }
     TypeMirror containingType = method.getEnclosingElement().asType();
     writer.addComments(containingType, method, methodDocTree);
   }
 }
 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);
 }
Example #5
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);
  }
Example #6
0
  private void buildRequestBodies(
      ExecutableElement executableElement, RestDocumentation.Resource.Method doc) {
    List<VariableElement> requestBodies = new ArrayList<VariableElement>();
    for (VariableElement var : executableElement.getParameters()) {
      if (var.getAnnotation(org.springframework.web.bind.annotation.RequestBody.class) != null) {
        requestBodies.add(var);
      }
    }

    if (requestBodies.size() > 1) {
      throw new IllegalStateException(
          String.format(
              "Method %s in class %s has multiple @RequestBody params",
              executableElement.getSimpleName(), executableElement.getEnclosingElement()));
    }

    if (requestBodies.size() == 1) {
      buildRequestBody(requestBodies.get(0), doc);
    }
  }
  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;
  }
 @Override
 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
   for (Element annotatedElt : roundEnv.getElementsAnnotatedWith(CodeTranslate.class)) {
     ExecutableElement methodElt = (ExecutableElement) annotatedElt;
     TypeElement typeElt = (TypeElement) methodElt.getEnclosingElement();
     if (typeElt.getQualifiedName().toString().equals(fqn)
         && methodElt.getSimpleName().toString().equals(method)) {
       for (Lang lang : langs) {
         Result result;
         try {
           String translation = translator.translate(methodElt, lang);
           result = new Result.Source(translation);
         } catch (Exception e) {
           result = new Result.Failure(e);
         }
         results.put(lang, result);
       }
     }
   }
   return false;
 }
  /**
   * 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();
  }
Example #10
0
 /** Returns a user-presentable string like {@code coffee.CoffeeModule}. */
 public static String className(ExecutableElement method) {
   return ((TypeElement) method.getEnclosingElement()).getQualifiedName().toString();
 }
Example #11
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();
  }
  private void processMethod(
      String name,
      ExecutableElement getterElt,
      ExecutableElement setterElt,
      ExecutableElement adderElt) {

    PropertyKind propKind = null;
    TypeInfo propType = null;
    TypeMirror propTypeMirror = null;

    //
    if (setterElt != null) {
      VariableElement paramElt = setterElt.getParameters().get(0);
      propTypeMirror = paramElt.asType();
      propType = typeFactory.create(propTypeMirror);
      propKind = PropertyKind.forType(propType.getKind());
      switch (propKind) {
        case LIST:
        case SET:
          propType = ((ParameterizedTypeInfo) propType).getArgs().get(0);
          propTypeMirror = ((DeclaredType) propTypeMirror).getTypeArguments().get(0);
          break;
        case MAP:
          propType = ((ParameterizedTypeInfo) propType).getArgs().get(1);
          propTypeMirror = ((DeclaredType) propTypeMirror).getTypeArguments().get(1);
          break;
      }
    }

    //
    if (getterElt != null) {
      TypeMirror getterTypeMirror = getterElt.getReturnType();
      TypeInfo getterType = typeFactory.create(getterTypeMirror);
      PropertyKind getterKind = PropertyKind.forType(getterType.getKind());
      switch (getterKind) {
        case LIST:
        case SET:
          getterType = ((ParameterizedTypeInfo) getterType).getArgs().get(0);
          getterTypeMirror = ((DeclaredType) getterTypeMirror).getTypeArguments().get(0);
          break;
        case MAP:
          getterType = ((ParameterizedTypeInfo) getterType).getArgs().get(1);
          getterTypeMirror = ((DeclaredType) getterTypeMirror).getTypeArguments().get(1);
          break;
      }
      if (propType != null) {
        if (propKind != getterKind) {
          throw new GenException(
              getterElt, name + " getter " + getterKind + " does not match the setter " + propKind);
        }
        if (!getterType.equals(propType)) {
          throw new GenException(
              getterElt,
              name + " getter type " + getterType + " does not match the setter type " + propType);
        }
      } else {
        propTypeMirror = getterTypeMirror;
        propType = getterType;
        propKind = getterKind;
      }
    }

    //
    if (adderElt != null) {
      switch (adderElt.getParameters().size()) {
        case 1:
          {
            VariableElement paramElt = adderElt.getParameters().get(0);
            TypeMirror adderTypeMirror = paramElt.asType();
            TypeInfo adderType = typeFactory.create(adderTypeMirror);
            if (propTypeMirror != null) {
              if (propKind != PropertyKind.LIST && propKind != PropertyKind.SET) {
                throw new GenException(
                    adderElt, name + "adder does not correspond to non list/set");
              }
              if (!adderType.equals(propType)) {
                throw new GenException(
                    adderElt,
                    name
                        + " adder type "
                        + adderType
                        + "  does not match the property type "
                        + propType);
              }
            } else {
              propTypeMirror = adderTypeMirror;
              propType = adderType;
              propKind = PropertyKind.LIST;
            }
            break;
          }
        case 2:
          {
            VariableElement paramElt = adderElt.getParameters().get(1);
            TypeMirror adderTypeMirror = paramElt.asType();
            TypeInfo adderType = typeFactory.create(adderTypeMirror);
            if (propTypeMirror != null) {
              if (propKind != PropertyKind.MAP) {
                throw new GenException(adderElt, name + "adder does not correspond to non map");
              }
              if (!adderType.equals(propType)) {
                throw new GenException(
                    adderElt,
                    name
                        + " adder type "
                        + adderType
                        + "  does not match the property type "
                        + propType);
              }
            } else {
              propTypeMirror = adderTypeMirror;
              propType = adderType;
              propKind = PropertyKind.MAP;
            }
            break;
          }
      }
    }

    //
    boolean jsonifiable;
    switch (propType.getKind()) {
      case OBJECT:
        if (propKind == PropertyKind.VALUE) {
          return;
        }
      case PRIMITIVE:
      case BOXED_PRIMITIVE:
      case STRING:
      case API:
      case JSON_OBJECT:
      case JSON_ARRAY:
      case ENUM:
        jsonifiable = true;
        break;
      case DATA_OBJECT:
        Element propTypeElt = typeUtils.asElement(propTypeMirror);
        jsonifiable =
            propTypeElt.getAnnotation(DataObject.class) == null
                || Helper.isJsonifiable(elementUtils, typeUtils, (TypeElement) propTypeElt);
        break;
      default:
        return;
    }

    boolean declared = false;
    Doc doc = null;
    for (ExecutableElement methodElt : Arrays.asList(setterElt, adderElt, getterElt)) {
      if (methodElt != null) {

        // A stream that list all overriden methods from super types
        // the boolean control whether or not we want to filter only annotated
        // data objects
        Function<Boolean, Stream<ExecutableElement>> overridenMeths =
            (annotated) -> {
              Set<DeclaredType> ancestorTypes = Helper.resolveAncestorTypes(modelElt, true, true);
              return ancestorTypes
                  .stream()
                  .map(DeclaredType::asElement)
                  .filter(elt -> !annotated || elt.getAnnotation(DataObject.class) != null)
                  .flatMap(Helper.cast(TypeElement.class))
                  .flatMap(elt -> elementUtils.getAllMembers(elt).stream())
                  .flatMap(Helper.instanceOf(ExecutableElement.class))
                  .filter(
                      executableElt ->
                          executableElt.getKind() == ElementKind.METHOD
                              && elementUtils.overrides(methodElt, executableElt, modelElt));
            };

        //
        if (doc == null) {
          doc = docFactory.createDoc(methodElt);
          if (doc == null) {
            Optional<Doc> first =
                overridenMeths
                    .apply(false)
                    .map(docFactory::createDoc)
                    .filter(d -> d != null)
                    .findFirst();
            doc = first.orElse(null);
          }
        }

        //
        if (!declared) {
          Element ownerElt = methodElt.getEnclosingElement();
          if (ownerElt.equals(modelElt)) {
            Object[] arr =
                overridenMeths
                    .apply(true)
                    .limit(1)
                    .filter(elt -> !elt.getModifiers().contains(Modifier.ABSTRACT))
                    .toArray();
            // Handle the case where this methods overrides from another data object
            declared = arr.length == 0;
          } else {
            declared = ownerElt.getAnnotation(DataObject.class) == null;
          }
        }
      }
    }

    PropertyInfo property =
        new PropertyInfo(
            declared,
            name,
            doc,
            propType,
            setterElt != null ? setterElt.getSimpleName().toString() : null,
            adderElt != null ? adderElt.getSimpleName().toString() : null,
            getterElt != null ? getterElt.getSimpleName().toString() : null,
            propKind,
            jsonifiable);
    propertyMap.put(property.name, property);
  }
  private void processMethods(List<ExecutableElement> methodsElt) {

    Map<String, ExecutableElement> getters = new HashMap<>();
    Map<String, ExecutableElement> setters = new HashMap<>();
    Map<String, ExecutableElement> adders = new HashMap<>();

    while (methodsElt.size() > 0) {
      ExecutableElement methodElt = methodsElt.remove(0);
      if (((TypeElement) methodElt.getEnclosingElement())
          .getQualifiedName()
          .toString()
          .equals("java.lang.Object")) {
        continue;
      }
      String methodName = methodElt.getSimpleName().toString();
      if (methodName.startsWith("get")
          && methodName.length() > 3
          && Character.isUpperCase(methodName.charAt(3))
          && methodElt.getParameters().isEmpty()
          && methodElt.getReturnType().getKind() != TypeKind.VOID) {
        String name = Helper.normalizePropertyName(methodName.substring(3));
        getters.put(name, methodElt);
      } else if (methodName.startsWith("is")
          && methodName.length() > 2
          && Character.isUpperCase(methodName.charAt(2))
          && methodElt.getParameters().isEmpty()
          && methodElt.getReturnType().getKind() != TypeKind.VOID) {
        String name = Helper.normalizePropertyName(methodName.substring(2));
        getters.put(name, methodElt);
      } else if ((methodName.startsWith("set") || methodName.startsWith("add"))
          && methodName.length() > 3
          && Character.isUpperCase(methodName.charAt(3))) {
        String prefix = methodName.substring(0, 3);
        String name = Helper.normalizePropertyName(methodName.substring(3));
        int numParams = methodElt.getParameters().size();
        if ("add".equals(prefix)) {
          if (name.endsWith("s")) {
            throw new GenException(methodElt, "Option adder name must not terminate with 's' char");
          } else {
            name += "s";
          }
          TypeMirror t = methodElt.getParameters().get(0).asType();
          if (numParams == 1
              || (numParams == 2
                  && t.getKind() == TypeKind.DECLARED
                  && ((TypeElement) ((DeclaredType) t).asElement())
                      .getQualifiedName()
                      .toString()
                      .equals("java.lang.String"))) {
            adders.put(name, methodElt);
          }
        } else {
          if (numParams == 1) {
            setters.put(name, methodElt);
          }
        }
      }
    }

    Set<String> names = new HashSet<>();
    names.addAll(getters.keySet());
    names.addAll(setters.keySet());
    names.addAll(adders.keySet());

    for (String name : names) {
      processMethod(name, getters.get(name), setters.get(name), adders.get(name));
    }
  }