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 addErrorIfParamsAndReturnTypeEqual(
     Parameter[] p2, Parameter[] p1, MethodNode node, MethodNode element) {
   boolean isEqual = true;
   for (int i = 0; i < p2.length; i++) {
     isEqual &= p1[i].getType().equals(p2[i].getType());
   }
   isEqual &= node.getReturnType().equals(element.getReturnType());
   if (isEqual) {
     addError(
         "Repetitive method name/signature for "
             + getDescription(node)
             + " in "
             + getDescription(currentClass)
             + ".",
         node);
   }
 }
  /**
   * 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);
    }
  }
 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);
 }
Example #5
0
 public MethodNode getSetterMethod(String setterName, boolean voidOnly) {
   for (MethodNode method : getDeclaredMethods(setterName)) {
     if (setterName.equals(method.getName())
         && (!voidOnly || ClassHelper.VOID_TYPE == method.getReturnType())
         && method.getParameters().length == 1) {
       return method;
     }
   }
   ClassNode parent = getSuperClass();
   if (parent != null) return parent.getSetterMethod(setterName, voidOnly);
   return null;
 }
Example #6
0
 public MethodNode getGetterMethod(String getterName) {
   for (MethodNode method : getDeclaredMethods(getterName)) {
     if (getterName.equals(method.getName())
         && ClassHelper.VOID_TYPE != method.getReturnType()
         && method.getParameters().length == 0) {
       return method;
     }
   }
   ClassNode parent = getSuperClass();
   if (parent != null) return parent.getGetterMethod(getterName);
   return null;
 }
  private void printMethod(PrintWriter out, ClassNode clazz, MethodNode methodNode) {
    if (methodNode.getName().equals("<clinit>")) return;
    if (methodNode.isPrivate() || !Utilities.isJavaIdentifier(methodNode.getName())) return;
    if (methodNode.isSynthetic() && methodNode.getName().equals("$getStaticMetaClass")) return;

    printAnnotations(out, methodNode);
    if (!clazz.isInterface()) printModifiers(out, methodNode.getModifiers());

    printGenericsBounds(out, methodNode.getGenericsTypes());
    out.print(" ");
    printType(out, methodNode.getReturnType());
    out.print(" ");
    out.print(methodNode.getName());

    printParams(out, methodNode);

    ClassNode[] exceptions = methodNode.getExceptions();
    for (int i = 0; i < exceptions.length; i++) {
      ClassNode exception = exceptions[i];
      if (i == 0) {
        out.print("throws ");
      } else {
        out.print(", ");
      }
      printType(out, exception);
    }

    if ((methodNode.getModifiers() & Opcodes.ACC_ABSTRACT) != 0) {
      out.println(";");
    } else {
      out.print(" { ");
      ClassNode retType = methodNode.getReturnType();
      printReturn(out, retType);
      out.println("}");
    }
  }
  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;
  }
  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);
  }
  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();
  }
 /**
  * Returns a method descriptor for the given {@link org.codehaus.groovy.ast.MethodNode}.
  *
  * @param methodNode the method node for which to create the descriptor
  * @return a method descriptor as defined in section JVMS section 4.3.3
  */
 public static String getMethodDescriptor(MethodNode methodNode) {
   return getMethodDescriptor(methodNode.getReturnType(), methodNode.getParameters());
 }
 private ClassNode getPropertyType(MethodNode m) {
   if (m.getReturnType() != ClassHelper.VOID_TYPE) {
     return m.getReturnType();
   }
   return m.getParameters()[0].getType();
 }
  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);
    }
  }