/**
   * Visits a class declaration.
   *
   * @param d the declaration to visit
   */
  public void visitClassDeclaration(ClassDeclaration d) {
    d.accept(pre);

    SortedSet<Declaration> decls = new TreeSet<Declaration>(SourceOrderDeclScanner.comparator);

    for (TypeParameterDeclaration tpDecl : d.getFormalTypeParameters()) {
      decls.add(tpDecl);
    }

    for (FieldDeclaration fieldDecl : d.getFields()) {
      decls.add(fieldDecl);
    }

    for (MethodDeclaration methodDecl : d.getMethods()) {
      decls.add(methodDecl);
    }

    for (TypeDeclaration typeDecl : d.getNestedTypes()) {
      decls.add(typeDecl);
    }

    for (ConstructorDeclaration ctorDecl : d.getConstructors()) {
      decls.add(ctorDecl);
    }

    for (Declaration decl : decls) decl.accept(this);

    d.accept(post);
  }
 private boolean checkInheritedMethod(
     Thing data,
     String methodName,
     String returnType,
     ClassDeclaration superclass,
     boolean finalOk,
     InheritCheck inheritCheck) {
   if (inheritCheck != null) {
     if (inheritCheck.isInherited(data, superclass)) {
       return true;
     }
   }
   for (MethodDeclaration methodDeclaration : superclass.getMethods()) {
     if (methodName.equals(methodDeclaration.getSimpleName())
         && methodDeclaration.getParameters().isEmpty()
         && returnType.equals(methodDeclaration.getReturnType().toString())) {
       data.put(methodName + "Inherited", true);
       Collection<Modifier> modifiers = methodDeclaration.getModifiers();
       if ((modifiers.contains(Modifier.FINAL) || modifiers.contains(Modifier.PRIVATE))
           && !finalOk) {
         // TBD TBD TBD - ERROR!!! cannot extend class with superclass method like this - how to
         // report?
       } else if (modifiers.contains(Modifier.PROTECTED)) {
         data.put(methodName + "Modifiers", "protected");
       } else if (modifiers.contains(Modifier.PUBLIC)) {
         data.put(methodName + "Modifiers", "public");
       } else {
         data.put(methodName + "Modifiers", "");
       }
       return true;
     }
   }
   if (superclass.getSuperclass() != null) {
     if (superclass.getSuperclass().getDeclaration() != null) {
       if (checkInheritedMethod(
           data,
           methodName,
           returnType,
           superclass.getSuperclass().getDeclaration(),
           finalOk,
           inheritCheck)) {
         return true;
       }
     }
   }
   return false;
 }
예제 #3
0
 @Test(result = {"m1()", "m2()", "m2(int)"})
 Collection<MethodDeclaration> getMethods() {
   return nested.getMethods();
 }
  private void processDefaultMethods(Thing data, ClassDeclaration classDeclaration) {
    // find any methods that have default parameters
    boolean error = false;
    for (ConstructorDeclaration constructorDeclaration : classDeclaration.getConstructors()) {
      Collection<ParameterDeclaration> parameters = constructorDeclaration.getParameters();
      for (ParameterDeclaration parameterDeclaration : parameters) {
        Default annotation = parameterDeclaration.getAnnotation(Default.class);
        if (annotation != null) {
          error(parameterDeclaration, "@Default is not legal in constructor parameters");
          error = true;
        }
      }
    }
    if (error) {
      return;
    }

    boolean atLeastOneDefault = false;
    methods:
    for (MethodDeclaration methodDeclaration : classDeclaration.getMethods()) {
      Collection<ParameterDeclaration> parameters = methodDeclaration.getParameters();
      boolean seenDefault = false;
      String[] names = new String[parameters.size()];
      String[] types = new String[parameters.size()];
      String[] defaults = new String[parameters.size()];
      int n = 0;
      for (ParameterDeclaration parameterDeclaration : parameters) {
        Default annotation = parameterDeclaration.getAnnotation(Default.class);
        names[n] = parameterDeclaration.getSimpleName();
        types[n] = parameterDeclaration.getType().toString();
        if (annotation != null) {
          seenDefault = true;
          if ("java.lang.String".equals(types[n])) {
            defaults[n] = '"' + annotation.value() + '"';
          } else {
            defaults[n] = annotation.value();
          }
        } else if (seenDefault) {
          error(
              parameterDeclaration,
              "All parameters after a parameter annotated with @Default must be annotated with @Default");
          continue methods;
        }
        n++;
      }

      if (seenDefault) {
        atLeastOneDefault = true;
        if (methodDeclaration.getModifiers().contains(Modifier.PRIVATE)) {
          error(methodDeclaration, "Private methods cannot use @Default parameters");
        }
        if (methodDeclaration.getModifiers().contains(Modifier.STATIC)) {
          error(methodDeclaration, "Static methods cannot use @Default parameters");
        }
        String modifiers3 = "";
        if (methodDeclaration.getModifiers().contains(Modifier.PUBLIC)) {
          modifiers3 = "public ";
        } else if (methodDeclaration.getModifiers().contains(Modifier.PROTECTED)) {
          modifiers3 = "protected ";
        }
        String throwsClause = getThrowsClause(methodDeclaration);
        String returnType = methodDeclaration.getReturnType().toString();
        String methodName = methodDeclaration.getSimpleName();
        String argDecl = "";
        String callArgs = "";
        for (int i = 0; i < n; i++) {
          if (defaults[i] != null) {
            String callArgsWithDefaults = callArgs;
            for (int j = i; j < n; j++) {
              if (j > 0) {
                callArgsWithDefaults += ", ";
              }
              callArgsWithDefaults += defaults[j];
            }
            Thing method = new Thing("method");
            method.put("name", methodName);
            method.put("returnType", returnType);
            method.put("throwsClause", throwsClause);
            method.put("argDecls", argDecl);
            method.put("modifiers", modifiers3);
            method.put("args", callArgsWithDefaults);
            data.add("defaultMethods", method);
          }
          if (i > 0) {
            argDecl += ", ";
            callArgs += ", ";
          }
          argDecl += types[i] + ' ' + names[i];
          callArgs += names[i];
        }
        Thing method = new Thing("method");
        method.put("name", methodName);
        method.put("returnType", returnType);
        method.put("throwsClause", throwsClause);
        method.put("modifiers", modifiers3);
        method.put("abstract", true);
        method.put("argDecls", argDecl);
        data.add("defaultMethods", method);
      }
    }
    data.put("atLeastOneDefault", atLeastOneDefault);
    if (!atLeastOneDefault) {
      data.setEmpty("defaultMethods");
    }
  }