Пример #1
0
  /**
   * Adds a delegate method to the target class node where the first argument is to the delegate
   * method is 'this'. In other words a method such as foo(Object instance, String bar) would be
   * added with a signature of foo(String) and 'this' is passed to the delegate instance
   *
   * @param classNode The class node
   * @param delegate The expression that looks up the delegate
   * @param declaredMethod The declared method
   * @param thisAsFirstArgument Whether 'this' should be passed as the first argument to the method
   * @return The added method node or null if it couldn't be added
   */
  public static MethodNode addDelegateInstanceMethod(
      ClassNode classNode,
      Expression delegate,
      MethodNode declaredMethod,
      boolean thisAsFirstArgument) {
    Parameter[] parameterTypes =
        thisAsFirstArgument
            ? getRemainingParameterTypes(declaredMethod.getParameters())
            : declaredMethod.getParameters();
    String methodName = declaredMethod.getName();
    if (classNode.hasDeclaredMethod(methodName, parameterTypes)) {
      return null;
    }
    String propertyName = GrailsClassUtils.getPropertyForGetter(methodName);
    if (propertyName != null && parameterTypes.length == 0 && classNode.hasProperty(propertyName)) {
      return null;
    }
    propertyName = GrailsClassUtils.getPropertyForSetter(methodName);
    if (propertyName != null && parameterTypes.length == 1 && classNode.hasProperty(propertyName)) {
      return null;
    }

    BlockStatement methodBody = new BlockStatement();
    ArgumentListExpression arguments =
        createArgumentListFromParameters(parameterTypes, thisAsFirstArgument);

    ClassNode returnType = nonGeneric(declaredMethod.getReturnType());

    MethodCallExpression methodCallExpression =
        new MethodCallExpression(delegate, methodName, arguments);
    methodCallExpression.setMethodTarget(declaredMethod);
    ThrowStatement missingMethodException = createMissingMethodThrowable(classNode, declaredMethod);
    VariableExpression apiVar = addApiVariableDeclaration(delegate, declaredMethod, methodBody);
    IfStatement ifStatement =
        createIfElseStatementForApiMethodCall(methodCallExpression, apiVar, missingMethodException);

    methodBody.addStatement(ifStatement);
    MethodNode methodNode =
        new MethodNode(
            methodName,
            Modifier.PUBLIC,
            returnType,
            copyParameters(parameterTypes),
            GrailsArtefactClassInjector.EMPTY_CLASS_ARRAY,
            methodBody);
    methodNode.addAnnotations(declaredMethod.getAnnotations());

    classNode.addMethod(methodNode);
    return methodNode;
  }
Пример #2
0
  /**
   * Adds a static method to the given class node that delegates to the given method and resolves
   * the object to invoke the method on from the given expression.
   *
   * @param expression The expression
   * @param classNode The class node
   * @param delegateMethod The delegate method
   * @return The added method node or null if it couldn't be added
   */
  public static MethodNode addDelegateStaticMethod(
      Expression expression, ClassNode classNode, MethodNode delegateMethod) {
    Parameter[] parameterTypes = delegateMethod.getParameters();
    String declaredMethodName = delegateMethod.getName();
    if (classNode.hasDeclaredMethod(declaredMethodName, parameterTypes)) {
      return null;
    }

    BlockStatement methodBody = new BlockStatement();
    ArgumentListExpression arguments = new ArgumentListExpression();

    for (Parameter parameterType : parameterTypes) {
      arguments.addExpression(new VariableExpression(parameterType.getName()));
    }
    MethodCallExpression methodCallExpression =
        new MethodCallExpression(expression, declaredMethodName, arguments);
    methodCallExpression.setMethodTarget(delegateMethod);

    ThrowStatement missingMethodException = createMissingMethodThrowable(classNode, delegateMethod);
    VariableExpression apiVar = addApiVariableDeclaration(expression, delegateMethod, methodBody);
    IfStatement ifStatement =
        createIfElseStatementForApiMethodCall(methodCallExpression, apiVar, missingMethodException);

    methodBody.addStatement(ifStatement);
    ClassNode returnType = nonGeneric(delegateMethod.getReturnType());
    if (METHOD_MISSING_METHOD_NAME.equals(declaredMethodName)) {
      declaredMethodName = STATIC_METHOD_MISSING_METHOD_NAME;
    }
    MethodNode methodNode = classNode.getDeclaredMethod(declaredMethodName, parameterTypes);
    if (methodNode == null) {
      methodNode =
          new MethodNode(
              declaredMethodName,
              Modifier.PUBLIC | Modifier.STATIC,
              returnType,
              copyParameters(parameterTypes),
              GrailsArtefactClassInjector.EMPTY_CLASS_ARRAY,
              methodBody);
      methodNode.addAnnotations(delegateMethod.getAnnotations());

      classNode.addMethod(methodNode);
    }
    return methodNode;
  }