/**
  * Snoops through the declaring class and all parents looking for methods
  *
  * <ul>
  *   <li><code>public String getMessage(java.lang.String)</code>
  *   <li><code>public String getMessage(java.lang.String, java.util.Locale)</code>
  *   <li><code>public String getMessage(java.lang.String, java.lang.Object[])</code>
  *   <li><code>public String getMessage(java.lang.String, java.lang.Object[], java.util.Locale)
  *       </code>
  *   <li><code>public String getMessage(java.lang.String, java.util.List)</code>
  *   <li><code>public String getMessage(java.lang.String, java.util.List, java.util.Locale)</code>
  *   <li><code>public String getMessage(java.lang.String, java.util.Map)</code>
  *   <li><code>public String getMessage(java.lang.String, java.util.Map, java.util.Locale)</code>
  *   <li><code>public String getMessage(java.lang.String, java.lang.String)</code>
  *   <li><code>public String getMessage(java.lang.String, java.lang.String, java.util.Locale)
  *       </code>
  *   <li><code>public String getMessage(java.lang.String, java.lang.Object[], java.lang.String)
  *       </code>
  *   <li><code>
  *       public String getMessage(java.lang.String, java.lang.Object[], java.lang.String, java.util.Locale)
  *       </code>
  *   <li><code>public String getMessage(java.lang.String, java.util.List, java.lang.String)</code>
  *   <li><code>
  *       public String getMessage(java.lang.String, java.util.List, java.lang.String, java.util.Locale)
  *       </code>
  *   <li><code>public String getMessage(java.lang.String, java.util.Map, java.lang.String)</code>
  *   <li><code>
  *       public String getMessage(java.lang.String, java.util.Map, java.lang.String, java.util.Locale)
  *       </code>
  * </ul>
  *
  * If any are defined all must be defined or a compilation error results.
  *
  * @param declaringClass the class to search
  * @param sourceUnit the source unit, for error reporting. {@code @NotNull}.
  * @return true if property change support should be added
  */
 protected static boolean needsMessageSource(ClassNode declaringClass, SourceUnit sourceUnit) {
   boolean found = false;
   ClassNode consideredClass = declaringClass;
   while (consideredClass != null) {
     for (MethodNode method : consideredClass.getMethods()) {
       // just check length, MOP will match it up
       found = method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 1;
       found |= method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 2;
       found |= method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 3;
       found |= method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 4;
       if (found) return false;
     }
     consideredClass = consideredClass.getSuperClass();
   }
   if (found) {
     sourceUnit
         .getErrorCollector()
         .addErrorAndContinue(
             new SimpleMessage(
                 "@MessageSourceAware cannot be processed on "
                     + declaringClass.getName()
                     + " because some but not all of variants of getMessage() were declared in the current class or super classes.",
                 sourceUnit));
     return false;
   }
   return true;
 }
 @Override
 protected ClassNode createClosureClass(final ClosureExpression expression, final int mods) {
   ClassNode closureClass = super.createClosureClass(expression, mods);
   List<MethodNode> methods = closureClass.getDeclaredMethods("call");
   List<MethodNode> doCall = closureClass.getMethods("doCall");
   if (doCall.size() != 1) {
     throw new GroovyBugError(
         "Expected to find one (1) doCall method on generated closure, but found "
             + doCall.size());
   }
   MethodNode doCallMethod = doCall.get(0);
   if (methods.isEmpty() && doCallMethod.getParameters().length == 1) {
     createDirectCallMethod(closureClass, doCallMethod);
   }
   MethodTargetCompletionVisitor visitor = new MethodTargetCompletionVisitor(doCallMethod);
   Object dynamic = expression.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION);
   if (dynamic != null) {
     doCallMethod.putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, dynamic);
   }
   for (MethodNode method : methods) {
     visitor.visitMethod(method);
   }
   closureClass.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE, Boolean.TRUE);
   return closureClass;
 }
 public static List<MethodNode> getAllMethods(ClassNode type) {
   ClassNode node = type;
   List<MethodNode> result = new ArrayList<MethodNode>();
   while (node != null) {
     result.addAll(node.getMethods());
     node = node.getSuperClass();
   }
   return result;
 }
 private void checkRepetitiveMethod(MethodNode node) {
   if (isConstructor(node)) return;
   for (MethodNode method : currentClass.getMethods(node.getName())) {
     if (method == node) continue;
     if (!method.getDeclaringClass().equals(node.getDeclaringClass())) continue;
     Parameter[] p1 = node.getParameters();
     Parameter[] p2 = method.getParameters();
     if (p1.length != p2.length) continue;
     addErrorIfParamsAndReturnTypeEqual(p2, p1, node, method);
   }
 }
 private void checkMethodsForOverridingFinal(ClassNode cn) {
   for (MethodNode method : cn.getMethods()) {
     Parameter[] params = method.getParameters();
     for (MethodNode superMethod : cn.getSuperClass().getMethods(method.getName())) {
       Parameter[] superParams = superMethod.getParameters();
       if (!hasEqualParameterTypes(params, superParams)) continue;
       if (!superMethod.isFinal()) break;
       addInvalidUseOfFinalError(method, params, superMethod.getDeclaringClass());
       return;
     }
   }
 }
 /**
  * Tests whether the ClassNode implements the specified method name
  *
  * @param classNode The ClassNode
  * @param methodName The method name
  * @param argTypes
  * @return True if it implements the method
  */
 private static boolean implementsMethod(
     ClassNode classNode, String methodName, Class[] argTypes) {
   List methods = classNode.getMethods();
   for (Iterator i = methods.iterator(); i.hasNext(); ) {
     MethodNode mn = (MethodNode) i.next();
     final boolean isZeroArg = (argTypes == null || argTypes.length == 0);
     boolean methodMatch = mn.getName().equals(methodName) && isZeroArg;
     if (methodMatch) return true;
     // TODO Implement further parameter analysis
   }
   return false;
 }
 private void visitClassNode(ClassNode cNode, List<PackageScopeTarget> value) {
   String cName = cNode.getName();
   if (cNode.isInterface() && value.size() != 1 && value.get(0) != PackageScopeTarget.CLASS) {
     throw new RuntimeException(
         "Error processing interface '"
             + cName
             + "'. "
             + MY_TYPE_NAME
             + " not allowed for interfaces except when targeting Class level.");
   }
   if (value.contains(groovy.transform.PackageScopeTarget.CLASS)) {
     if (cNode.isSyntheticPublic()) revertVisibility(cNode);
     else
       throw new RuntimeException(
           "Can't use "
               + MY_TYPE_NAME
               + " for class '"
               + cNode.getName()
               + "' which has explicit visibility.");
   }
   if (value.contains(groovy.transform.PackageScopeTarget.METHODS)) {
     final List<MethodNode> mList = cNode.getMethods();
     for (MethodNode mNode : mList) {
       if (mNode.isSyntheticPublic()) revertVisibility(mNode);
     }
   }
   if (value.contains(PackageScopeTarget.FIELDS)) {
     final List<PropertyNode> pList = cNode.getProperties();
     List<PropertyNode> foundProps = new ArrayList<PropertyNode>();
     List<String> foundNames = new ArrayList<String>();
     for (PropertyNode pNode : pList) {
       foundProps.add(pNode);
       foundNames.add(pNode.getName());
     }
     for (PropertyNode pNode : foundProps) {
       pList.remove(pNode);
     }
     final List<FieldNode> fList = cNode.getFields();
     for (FieldNode fNode : fList) {
       if (foundNames.contains(fNode.getName())) {
         revertVisibility(fNode);
       }
     }
   }
 }
  public MethodNode tryFindPossibleMethod(String name, Expression arguments) {
    int count = 0;

    if (arguments instanceof TupleExpression) {
      TupleExpression tuple = (TupleExpression) arguments;
      // TODO this won't strictly be true when using list expansion in argument calls
      count = tuple.getExpressions().size();
    } else return null;

    MethodNode res = null;
    ClassNode node = this;
    TupleExpression args = (TupleExpression) arguments;
    do {
      for (MethodNode method : node.getMethods(name)) {
        if (method.getParameters().length == count) {
          boolean match = true;
          for (int i = 0; i != count; ++i)
            if (!args.getType().isDerivedFrom(method.getParameters()[i].getType())) {
              match = false;
              break;
            }

          if (match) {
            if (res == null) res = method;
            else {
              if (res.getParameters().length != count) return null;
              if (node.equals(this)) return null;

              match = true;
              for (int i = 0; i != count; ++i)
                if (!res.getParameters()[i].getType().equals(method.getParameters()[i].getType())) {
                  match = false;
                  break;
                }
              if (!match) return null;
            }
          }
        }
      }
      node = node.getSuperClass();
    } while (node != null);

    return res;
  }
Beispiel #9
0
  public static void addDelegateInstanceMethods(
      ClassNode supportedSuperType,
      ClassNode classNode,
      ClassNode delegateNode,
      Expression delegateInstance) {
    while (!delegateNode.equals(AbstractGrailsArtefactTransformer.OBJECT_CLASS)) {
      List<MethodNode> declaredMethods = delegateNode.getMethods();
      for (MethodNode declaredMethod : declaredMethods) {

        if (isConstructorMethod(declaredMethod)) {
          addDelegateConstructor(classNode, declaredMethod);

        } else if (isCandidateInstanceMethod(supportedSuperType, declaredMethod)) {
          addDelegateInstanceMethod(classNode, delegateInstance, declaredMethod);
        }
      }
      delegateNode = delegateNode.getSuperClass();
    }
  }
 private void checkOverloadingPrivateAndPublic(MethodNode node) {
   if (isConstructor(node)) return;
   boolean hasPrivate = false;
   boolean hasPublic = false;
   for (MethodNode method : currentClass.getMethods(node.getName())) {
     if (method == node) continue;
     if (!method.getDeclaringClass().equals(node.getDeclaringClass())) continue;
     if (method.isPublic() || method.isProtected()) {
       hasPublic = true;
     } else {
       hasPrivate = true;
     }
   }
   if (hasPrivate && hasPublic) {
     addError(
         "Mixing private and public/protected methods of the same name causes multimethods to be disabled and is forbidden to avoid surprising behaviour. Renaming the private methods will solve the problem.",
         node);
   }
 }
  private void printMethods(PrintWriter out, ClassNode classNode, boolean isEnum) {
    if (!isEnum) printConstructors(out, classNode);

    @SuppressWarnings("unchecked")
    List<MethodNode> methods = (List) propertyMethods.clone();
    methods.addAll(classNode.getMethods());
    for (MethodNode method : methods) {
      if (isEnum && method.isSynthetic()) {
        // skip values() method and valueOf(String)
        String name = method.getName();
        Parameter[] params = method.getParameters();
        if (name.equals("values") && params.length == 0) continue;
        if (name.equals("valueOf")
            && params.length == 1
            && params[0].getType().equals(ClassHelper.STRING_TYPE)) {
          continue;
        }
      }
      printMethod(out, classNode, method);
    }
  }
 private void checkInterfaceMethodVisibility(ClassNode node) {
   if (!node.isInterface()) return;
   for (MethodNode method : node.getMethods()) {
     if (method.isPrivate()) {
       addError(
           "Method '"
               + method.getName()
               + "' is private but should be public in "
               + getDescription(currentClass)
               + ".",
           method);
     } else if (method.isProtected()) {
       addError(
           "Method '"
               + method.getName()
               + "' is protected but should be public in "
               + getDescription(currentClass)
               + ".",
           method);
     }
   }
 }
 protected static boolean needsMybatisContribution(
     ClassNode declaringClass, SourceUnit sourceUnit) {
   boolean found1 = false, found2 = false, found3 = false, found4 = false;
   ClassNode consideredClass = declaringClass;
   while (consideredClass != null) {
     for (MethodNode method : consideredClass.getMethods()) {
       // just check length, MOP will match it up
       found1 =
           method.getName().equals(METHOD_WITH_SQL_SESSION) && method.getParameters().length == 1;
       found2 =
           method.getName().equals(METHOD_WITH_SQL_SESSION) && method.getParameters().length == 2;
       found3 =
           method.getName().equals(METHOD_SET_MYBATIS_PROVIDER)
               && method.getParameters().length == 1;
       found4 =
           method.getName().equals(METHOD_GET_MYBATIS_PROVIDER)
               && method.getParameters().length == 0;
       if (found1 && found2 && found3 && found4) {
         return false;
       }
     }
     consideredClass = consideredClass.getSuperClass();
   }
   if (found1 || found2 || found3 || found4) {
     sourceUnit
         .getErrorCollector()
         .addErrorAndContinue(
             new SimpleMessage(
                 "@MybatisAware cannot be processed on "
                     + declaringClass.getName()
                     + " because some but not all of methods from "
                     + MybatisContributionHandler.class.getName()
                     + " were declared in the current class or super classes.",
                 sourceUnit));
     return false;
   }
   return true;
 }
 private void checkMethodsForIncorrectModifiers(ClassNode cn) {
   if (!cn.isInterface()) return;
   for (MethodNode method : cn.getMethods()) {
     if (method.isFinal()) {
       addError(
           "The "
               + getDescription(method)
               + " from "
               + getDescription(cn)
               + " must not be final. It is by definition abstract.",
           method);
     }
     if (method.isStatic() && !isConstructor(method)) {
       addError(
           "The "
               + getDescription(method)
               + " from "
               + getDescription(cn)
               + " must not be static. Only fields may be static in an interface.",
           method);
     }
   }
 }
  private Variable findClassMember(ClassNode cn, String name) {
    if (cn == null) return null;
    if (cn.isScript()) {
      return new DynamicVariable(name, false);
    }

    for (FieldNode fn : cn.getFields()) {
      if (fn.getName().equals(name)) return fn;
    }

    for (MethodNode mn : cn.getMethods()) {
      String pName = getPropertyName(mn);
      // GRECLIPSE: start
      // must set the declaringClass
      /*old{
      if (pName != null && pName.equals(name))
          return new PropertyNode(pName, mn.getModifiers(), getPropertyType(mn), cn, null, null, null);
          */
      // newcode
      if (pName != null && pName.equals(name)) {
        PropertyNode property =
            new PropertyNode(pName, mn.getModifiers(), getPropertyType(mn), cn, null, null, null);
        property.setDeclaringClass(cn);
        property.getField().setDeclaringClass(cn);
        return property;
      }
      // GRECLIPSE: end
    }

    for (PropertyNode pn : cn.getProperties()) {
      if (pn.getName().equals(name)) return pn;
    }

    Variable ret = findClassMember(cn.getSuperClass(), name);
    if (ret != null) return ret;
    return findClassMember(cn.getOuterClass(), name);
  }
 private boolean anyMethodSkip(final ClassNode node) {
   for (MethodNode methodNode : node.getMethods()) {
     if (isSkipMode(methodNode)) return true;
   }
   return false;
 }
Beispiel #17
0
 public static void removeMethod(ClassNode declaringClass, MethodNode methodNode) {
   declaringClass.getMethods().remove(methodNode);
   declaringClass.getDeclaredMethods(methodNode.getName()).clear();
 }
 private void checkMethodsForWeakerAccess(ClassNode cn) {
   for (MethodNode method : cn.getMethods()) {
     checkMethodForWeakerAccessPrivileges(method, cn);
   }
 }
  public static void apply(ClassNode declaringClass) {
    injectInterface(declaringClass, MYBATIS_CONTRIBUTION_HANDLER_CNODE);

    // add field:
    // protected MybatisProvider this$MybatisProvider = DefaultMybatisProvider.instance
    FieldNode providerField =
        declaringClass.addField(
            MYBATIS_PROVIDER_FIELD_NAME,
            ACC_PRIVATE | ACC_SYNTHETIC,
            MYBATIS_PROVIDER_CNODE,
            defaultMybatisProviderInstance());

    // add method:
    // MybatisProvider getMybatisProvider() {
    //     return this$MybatisProvider
    // }
    injectMethod(
        declaringClass,
        new MethodNode(
            METHOD_GET_MYBATIS_PROVIDER,
            ACC_PUBLIC,
            MYBATIS_PROVIDER_CNODE,
            Parameter.EMPTY_ARRAY,
            NO_EXCEPTIONS,
            returns(field(providerField))));

    // add method:
    // void setMybatisProvider(MybatisProvider provider) {
    //     this$MybatisProvider = provider ?: DefaultMybatisProvider.instance
    // }
    injectMethod(
        declaringClass,
        new MethodNode(
            METHOD_SET_MYBATIS_PROVIDER,
            ACC_PUBLIC,
            ClassHelper.VOID_TYPE,
            params(param(MYBATIS_PROVIDER_CNODE, PROVIDER)),
            NO_EXCEPTIONS,
            block(
                ifs_no_return(
                    cmp(var(PROVIDER), ConstantExpression.NULL),
                    assigns(field(providerField), defaultMybatisProviderInstance()),
                    assigns(field(providerField), var(PROVIDER))))));

    for (MethodNode method : MYBATIS_CONTRIBUTION_HANDLER_CNODE.getMethods()) {
      if (Arrays.binarySearch(DELEGATING_METHODS, method.getName()) < 0) continue;
      List<Expression> variables = new ArrayList<Expression>();
      Parameter[] parameters = new Parameter[method.getParameters().length];
      for (int i = 0; i < method.getParameters().length; i++) {
        Parameter p = method.getParameters()[i];
        parameters[i] = new Parameter(makeClassSafe(p.getType()), p.getName());
        parameters[i].getType().setGenericsTypes(p.getType().getGenericsTypes());
        variables.add(var(p.getName()));
      }
      ClassNode returnType = makeClassSafe(method.getReturnType());
      returnType.setGenericsTypes(method.getReturnType().getGenericsTypes());
      returnType.setGenericsPlaceHolder(method.getReturnType().isGenericsPlaceHolder());

      MethodNode newMethod =
          new MethodNode(
              method.getName(),
              ACC_PUBLIC,
              returnType,
              parameters,
              NO_EXCEPTIONS,
              returns(call(field(providerField), method.getName(), args(variables))));
      newMethod.setGenericsTypes(method.getGenericsTypes());
      injectMethod(declaringClass, newMethod);
    }
  }