/**
  * 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;
 }
  private void visitConstructorOrMethod(MethodNode node, int methodTarget) {
    visitAnnotations(node, methodTarget);
    for (int i = 0; i < node.getParameters().length; i++) {
      Parameter parameter = node.getParameters()[i];
      visitAnnotations(parameter, AnnotationNode.PARAMETER_TARGET);
    }

    if (this.currentClass.isAnnotationDefinition() && !node.isStaticConstructor()) {
      ErrorCollector errorCollector = new ErrorCollector(this.source.getConfiguration());
      AnnotationVisitor visitor = new AnnotationVisitor(this.source, errorCollector);
      visitor.setReportClass(currentClass);
      visitor.checkReturnType(node.getReturnType(), node);
      if (node.getParameters().length > 0) {
        addError("Annotation members may not have parameters.", node.getParameters()[0]);
      }
      if (node.getExceptions().length > 0) {
        addError("Annotation members may not have a throws clause.", node.getExceptions()[0]);
      }
      ReturnStatement code = (ReturnStatement) node.getCode();
      if (code != null) {
        visitor.visitExpression(node.getName(), code.getExpression(), node.getReturnType());
        visitor.checkCircularReference(currentClass, node.getReturnType(), code.getExpression());
      }
      this.source.getErrorCollector().addCollectorContents(errorCollector);
    }
  }
 private void memorizeInitialExpressions(final MethodNode node) {
   // add node metadata for default parameters because they are erased by the Verifier
   if (node.getParameters() != null) {
     for (Parameter parameter : node.getParameters()) {
       parameter.putNodeMetaData(
           StaticTypesMarker.INITIAL_EXPRESSION, parameter.getInitialExpression());
     }
   }
 }
Esempio n. 4
0
 public static boolean isConstructorMethod(MethodNode declaredMethod) {
   return declaredMethod.isStatic()
       && declaredMethod.isPublic()
       && declaredMethod.getName().equals("initialize")
       && declaredMethod.getParameters().length >= 1
       && declaredMethod
           .getParameters()[0]
           .getType()
           .equals(AbstractGrailsArtefactTransformer.OBJECT_CLASS);
 }
 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);
   }
 }
  /**
   * This method is used to add "bridge" methods for private methods of an inner/outer class, so
   * that the outer class is capable of calling them. It does basically the same job as access$000
   * like methods in Java.
   *
   * @param node an inner/outer class node for which to generate bridge methods
   */
  @SuppressWarnings("unchecked")
  private void addPrivateBridgeMethods(final ClassNode node) {
    Set<ASTNode> accessedMethods =
        (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_METHODS_ACCESS);
    if (accessedMethods == null) return;
    List<MethodNode> methods = new ArrayList<MethodNode>(node.getAllDeclaredMethods());
    Map<MethodNode, MethodNode> privateBridgeMethods =
        (Map<MethodNode, MethodNode>) node.getNodeMetaData(PRIVATE_BRIDGE_METHODS);
    if (privateBridgeMethods != null) {
      // private bridge methods already added
      return;
    }
    privateBridgeMethods = new HashMap<MethodNode, MethodNode>();
    int i = -1;
    final int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;
    for (MethodNode method : methods) {
      if (accessedMethods.contains(method)) {
        i++;
        Parameter[] methodParameters = method.getParameters();
        Parameter[] newParams = new Parameter[methodParameters.length + 1];
        System.arraycopy(methodParameters, 0, newParams, 1, methodParameters.length);
        newParams[0] = new Parameter(node.getPlainNodeReference(), "$that");
        Expression arguments;
        if (method.getParameters() == null || method.getParameters().length == 0) {
          arguments = ArgumentListExpression.EMPTY_ARGUMENTS;
        } else {
          List<Expression> args = new LinkedList<Expression>();
          for (Parameter parameter : methodParameters) {
            args.add(new VariableExpression(parameter));
          }
          arguments = new ArgumentListExpression(args);
        }
        Expression receiver =
            method.isStatic() ? new ClassExpression(node) : new VariableExpression(newParams[0]);
        MethodCallExpression mce = new MethodCallExpression(receiver, method.getName(), arguments);
        mce.setMethodTarget(method);

        ExpressionStatement returnStatement = new ExpressionStatement(mce);
        MethodNode bridge =
            node.addMethod(
                "access$" + i,
                access,
                method.getReturnType(),
                newParams,
                method.getExceptions(),
                returnStatement);
        privateBridgeMethods.put(method, bridge);
        bridge.addAnnotation(new AnnotationNode(COMPILESTATIC_CLASSNODE));
      }
    }
    if (!privateBridgeMethods.isEmpty()) {
      node.setNodeMetaData(PRIVATE_BRIDGE_METHODS, privateBridgeMethods);
    }
  }
 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;
     }
   }
 }
 private void checkMethodForWeakerAccessPrivileges(MethodNode mn, ClassNode cn) {
   Parameter[] params = mn.getParameters();
   for (MethodNode superMethod : cn.getSuperClass().getMethods(mn.getName())) {
     Parameter[] superParams = superMethod.getParameters();
     if (!hasEqualParameterTypes(params, superParams)) continue;
     if ((mn.isPrivate() && !superMethod.isPrivate())
         || (mn.isProtected() && superMethod.isPublic())) {
       addWeakerAccessError(cn, mn, params, superMethod);
       return;
     }
   }
 }
Esempio n. 9
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;
  }
 @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 void visitConstructorCallExpression(ConstructorCallExpression call) {
    isSpecialConstructorCall = call.isSpecialCall();
    super.visitConstructorCallExpression(call);
    isSpecialConstructorCall = false;
    if (!call.isUsingAnonymousInnerClass()) return;

    pushState();
    InnerClassNode innerClass = (InnerClassNode) call.getType();
    innerClass.setVariableScope(currentScope);
    for (MethodNode method : innerClass.getMethods()) {
      Parameter[] parameters = method.getParameters();
      if (parameters.length == 0) parameters = null; // null means no implicit "it"
      ClosureExpression cl = new ClosureExpression(parameters, method.getCode());
      visitClosureExpression(cl);
    }

    for (FieldNode field : innerClass.getFields()) {
      final Expression expression = field.getInitialExpression();
      if (expression != null) {
        expression.visit(this);
      }
    }

    for (Statement statement : innerClass.getObjectInitializerStatements()) {
      statement.visit(this);
    }
    markClosureSharedVariables();
    popState();
  }
  private void createBuilderForAnnotatedMethod(
      BuilderASTTransformation transform, MethodNode mNode, AnnotationNode anno) {
    if (transform.getMemberValue(anno, "includes") != null
        || transform.getMemberValue(anno, "includes") != null) {
      transform.addError(
          "Error during "
              + BuilderASTTransformation.MY_TYPE_NAME
              + " processing: includes/excludes only allowed on classes",
          anno);
    }
    if (mNode instanceof ConstructorNode) {
      mNode.setModifiers(ACC_PRIVATE | ACC_SYNTHETIC);
    } else {
      if ((mNode.getModifiers() & ACC_STATIC) == 0) {
        transform.addError(
            "Error during "
                + BuilderASTTransformation.MY_TYPE_NAME
                + " processing: method builders only allowed on static methods",
            anno);
      }
      mNode.setModifiers(ACC_PRIVATE | ACC_SYNTHETIC | ACC_STATIC);
    }
    ClassNode buildee = mNode.getDeclaringClass();
    Parameter[] parameters = mNode.getParameters();
    ClassNode builder =
        createInnerHelperClass(buildee, getBuilderClassName(buildee, anno), parameters.length);
    List<FieldNode> convertedFields = convertParamsToFields(builder, parameters);

    buildCommon(buildee, anno, convertedFields, builder);
    if (mNode instanceof ConstructorNode) {
      createBuildeeConstructors(transform, buildee, builder, convertedFields, false);
    } else {
      createBuildeeMethods(buildee, mNode, builder, convertedFields);
    }
  }
  private String getPropertyName(MethodNode m) {
    String name = m.getName();
    if (!(name.startsWith("set") || name.startsWith("get"))) return null;
    String pname = name.substring(3);
    if (pname.length() == 0) return null;
    pname = java.beans.Introspector.decapitalize(pname);

    if (name.startsWith("get")
        && (m.getReturnType() == ClassHelper.VOID_TYPE || m.getParameters().length != 0)) {
      return null;
    }
    if (name.startsWith("set") && m.getParameters().length != 1) {
      return null;
    }
    return pname;
  }
Esempio n. 14
0
 public static boolean isCandidateInstanceMethod(ClassNode classNode, MethodNode declaredMethod) {
   Parameter[] parameterTypes = declaredMethod.getParameters();
   return isCandidateMethod(declaredMethod)
       && parameterTypes != null
       && parameterTypes.length > 0
       && isAssignableFrom(parameterTypes[0].getType(), classNode);
 }
Esempio n. 15
0
 public static void addMethodIfNotPresent(ClassNode controllerClassNode, MethodNode methodNode) {
   MethodNode existing =
       controllerClassNode.getMethod(methodNode.getName(), methodNode.getParameters());
   if (existing == null) {
     controllerClassNode.addMethod(methodNode);
   }
 }
 public static String makeDescriptorWithoutReturnType(MethodNode mn) {
   StringBuilder sb = new StringBuilder();
   sb.append(mn.getName()).append(':');
   for (Parameter p : mn.getParameters()) {
     sb.append(p.getType()).append(',');
   }
   return sb.toString();
 }
  public void visitMethod(MethodNode node) {

    visitParameters(node, node.getParameters());

    String methodType =
        BytecodeHelper.getMethodDescriptor(node.getReturnType(), node.getParameters());
    mv = cv.visitMethod(node.getModifiers(), node.getName(), methodType, null, null);

    mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
    mv.visitInsn(DUP);
    mv.visitLdcInsn("not intended for execution");
    mv.visitMethodInsn(
        INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false);
    mv.visitInsn(ATHROW);

    mv.visitMaxs(0, 0);
  }
  protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {
    pushState(node.isStatic());
    inConstructor = isConstructor;
    node.setVariableScope(currentScope);
    visitAnnotations(node);

    // GROOVY-2156
    Parameter[] parameters = node.getParameters();
    for (Parameter parameter : parameters) {
      visitAnnotations(parameter);
    }

    declare(node.getParameters(), node);
    visitClassCodeContainer(node.getCode());

    popState();
  }
 public static boolean hasDeclaredMethod(ClassNode cNode, String name, int argsCount) {
   List<MethodNode> ms = cNode.getDeclaredMethods(name);
   for (MethodNode m : ms) {
     Parameter[] paras = m.getParameters();
     if (paras != null && paras.length == argsCount) {
       return true;
     }
   }
   return false;
 }
 // no rename so delete and add
 private static void renameMethod(ClassNode buildee, MethodNode mNode, String newName) {
   buildee.addMethod(
       newName,
       mNode.getModifiers(),
       mNode.getReturnType(),
       mNode.getParameters(),
       mNode.getExceptions(),
       mNode.getCode());
   buildee.removeMethod(mNode);
 }
 public void visitMethod(MethodNode node) {
   inConstructor = false;
   inStaticConstructor = node.isStaticConstructor();
   checkAbstractDeclaration(node);
   checkRepetitiveMethod(node);
   checkOverloadingPrivateAndPublic(node);
   checkMethodModifiers(node);
   checkGenericsUsage(node, node.getParameters());
   checkGenericsUsage(node, node.getReturnType());
   super.visitMethod(node);
 }
 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 changeBaseScriptType(
      final AnnotatedNode parent, final ClassNode cNode, final ClassNode baseScriptType) {
    if (!cNode.isScriptBody()) {
      addError("Annotation " + MY_TYPE_NAME + " can only be used within a Script.", parent);
      return;
    }

    if (!baseScriptType.isScript()) {
      addError(
          "Declared type " + baseScriptType + " does not extend groovy.lang.Script class!", parent);
      return;
    }

    cNode.setSuperClass(baseScriptType);

    // Method in base script that will contain the script body code.
    MethodNode runScriptMethod = ClassHelper.findSAM(baseScriptType);

    // If they want to use a name other than than "run", then make the change.
    if (isCustomScriptBodyMethod(runScriptMethod)) {
      MethodNode defaultMethod = cNode.getDeclaredMethod("run", Parameter.EMPTY_ARRAY);
      // GROOVY-6706: Sometimes an NPE is thrown here.
      // The reason is that our transform is getting called more than once sometimes.
      if (defaultMethod != null) {
        cNode.removeMethod(defaultMethod);
        MethodNode methodNode =
            new MethodNode(
                runScriptMethod.getName(),
                runScriptMethod.getModifiers() & ~ACC_ABSTRACT,
                runScriptMethod.getReturnType(),
                runScriptMethod.getParameters(),
                runScriptMethod.getExceptions(),
                defaultMethod.getCode());
        // The AST node metadata has the flag that indicates that this method is a script body.
        // It may also be carrying data for other AST transforms.
        methodNode.copyNodeMetaData(defaultMethod);
        cNode.addMethod(methodNode);
      }
    }

    // If the new script base class does not have a contextual constructor (g.l.Binding), then we
    // won't either.
    // We have to do things this way (and rely on just default constructors) because the logic that
    // generates
    // the constructors for our script class have already run.
    if (cNode.getSuperClass().getDeclaredConstructor(CONTEXT_CTOR_PARAMETERS) == null) {
      ConstructorNode orphanedConstructor = cNode.getDeclaredConstructor(CONTEXT_CTOR_PARAMETERS);
      cNode.removeConstructor(orphanedConstructor);
    }
  }
Esempio n. 24
0
 public void buildMethod(
     BuilderASTTransformation transform, MethodNode mNode, AnnotationNode anno) {
   if (transform.getMemberValue(anno, "includes") != null
       || transform.getMemberValue(anno, "includes") != null) {
     transform.addError(
         "Error during "
             + BuilderASTTransformation.MY_TYPE_NAME
             + " processing: includes/excludes only allowed on classes",
         anno);
   }
   ClassNode buildee = mNode.getDeclaringClass();
   ClassNode builder = createBuilder(anno, buildee);
   createBuilderFactoryMethod(anno, buildee, builder);
   for (Parameter parameter : mNode.getParameters()) {
     builder.addField(createFieldCopy(buildee, parameter));
     builder.addMethod(
         createBuilderMethodForProp(
             builder,
             new PropertyInfo(parameter.getName(), parameter.getType()),
             getPrefix(anno)));
   }
   builder.addMethod(createBuildMethodForMethod(anno, buildee, mNode, mNode.getParameters()));
 }
Esempio n. 25
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;
  }
  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 String createMethodLabel(MethodNode node) {
    StringBuilder sb = new StringBuilder();
    sb.append(createClassLabel(node.getReturnType()));
    sb.append(" ");
    sb.append(createClassLabel(node.getDeclaringClass()));
    sb.append(".");
    sb.append(node.getName());
    sb.append("(");
    Parameter[] params = node.getParameters();
    if (params != null) {
      for (int i = 0; i < params.length; i++) {
        sb.append(createClassLabel(params[i].getType()));
        sb.append(" " + params[i].getName());
        if (i < params.length - 1) {
          sb.append(", ");
        }
      }
    }
    sb.append(")");

    return sb.toString();
  }
 private void printParams(PrintWriter out, MethodNode methodNode) {
   out.print("(");
   Parameter[] parameters = methodNode.getParameters();
   if (parameters != null && parameters.length != 0) {
     int lastIndex = parameters.length - 1;
     boolean vararg = parameters[lastIndex].getType().isArray();
     for (int i = 0; i != parameters.length; ++i) {
       if (i == lastIndex && vararg) {
         printType(out, parameters[i].getType().getComponentType());
         out.print("...");
       } else {
         printType(out, parameters[i].getType());
       }
       out.print(" ");
       out.print(parameters[i].getName());
       if (i + 1 < parameters.length) {
         out.print(", ");
       }
     }
   }
   out.print(")");
 }
Esempio n. 29
0
  public static String getGenericsMethodSignature(MethodNode node) {
    GenericsType[] generics = node.getGenericsTypes();
    Parameter[] param = node.getParameters();
    ClassNode returnType = node.getReturnType();

    if (generics == null && !hasGenerics(param) && !hasGenerics(returnType)) return null;

    StringBuffer ret = new StringBuffer(100);
    getGenericsTypeSpec(ret, generics);

    GenericsType[] paramTypes = new GenericsType[param.length];
    for (int i = 0; i < param.length; i++) {
      ClassNode pType = param[i].getType();
      if (pType.getGenericsTypes() == null || !pType.isGenericsPlaceHolder()) {
        paramTypes[i] = new GenericsType(pType);
      } else {
        paramTypes[i] = pType.getGenericsTypes()[0];
      }
    }
    addSubTypes(ret, paramTypes, "(", ")");
    addSubTypes(ret, new GenericsType[] {new GenericsType(returnType)}, "", "");
    return ret.toString();
  }
 private boolean isCustomScriptBodyMethod(MethodNode node) {
   return node != null
       && !(node.getDeclaringClass().equals(ClassHelper.SCRIPT_TYPE)
           && "run".equals(node.getName())
           && node.getParameters().length == 0);
 }