private void completeEnum(ClassNode enumClass) {
    boolean isAic = isAnonymousInnerClass(enumClass);
    if (enumClass.getDeclaredConstructors().size() == 0) {
      addImplicitConstructors(enumClass, isAic);
    }

    for (ConstructorNode ctor : enumClass.getDeclaredConstructors()) {
      transformConstructor(ctor, isAic);
    }
  }
 private boolean validateConstructors(ClassNode cNode) {
   if (cNode.getDeclaredConstructors().size() != 0) {
     // TODO: allow constructors which only call provided constructor?
     addError(
         "Explicit constructors not allowed for "
             + ImmutableASTTransformation.MY_TYPE_NAME
             + " class: "
             + cNode.getNameWithoutPackage(),
         cNode.getDeclaredConstructors().get(0));
   }
   return true;
 }
Esempio n. 3
0
 /**
  * Obtains the default constructor for the given class node.
  *
  * @param classNode The class node
  * @return The default constructor or null if there isn't one
  */
 public static ConstructorNode getDefaultConstructor(ClassNode classNode) {
   for (ConstructorNode cons : classNode.getDeclaredConstructors()) {
     if (cons.getParameters().length == 0) {
       return cons;
     }
   }
   return null;
 }
Esempio n. 4
0
 /**
  * Finds a constructor for the given class node and parameter types
  *
  * @param classNode The class node
  * @param constructorParams The parameter types
  * @return The located constructor or null
  */
 public static ConstructorNode findConstructor(
     ClassNode classNode, Parameter[] constructorParams) {
   List<ConstructorNode> declaredConstructors = classNode.getDeclaredConstructors();
   for (ConstructorNode declaredConstructor : declaredConstructors) {
     if (parametersEqual(constructorParams, declaredConstructor.getParameters())) {
       return declaredConstructor;
     }
   }
   return null;
 }
 private void printConstructors(PrintWriter out, ClassNode classNode) {
   @SuppressWarnings("unchecked")
   List<ConstructorNode> constrs = (List<ConstructorNode>) constructors.clone();
   if (constrs != null) {
     constrs.addAll(classNode.getDeclaredConstructors());
     for (ConstructorNode constr : constrs) {
       printConstructor(out, classNode, constr);
     }
   }
 }
 static {
   final List<ConstructorNode> declaredConstructors = INTRANGE_TYPE.getDeclaredConstructors();
   ConstructorNode target = null;
   for (ConstructorNode constructor : declaredConstructors) {
     final Parameter[] parameters = constructor.getParameters();
     if (parameters.length == 3
         && ClassHelper.boolean_TYPE.equals(parameters[0].getOriginType())) {
       target = constructor;
       break;
     }
   }
   INTRANGE_CTOR = target;
 }
  public void writeClosure(ClosureExpression expression) {
    CompileStack compileStack = controller.getCompileStack();
    MethodVisitor mv = controller.getMethodVisitor();
    ClassNode classNode = controller.getClassNode();
    AsmClassGenerator acg = controller.getAcg();

    // generate closure as public class to make sure it can be properly invoked by classes of the
    // Groovy runtime without circumventing JVM access checks (see CachedMethod for example).
    ClassNode closureClass = getOrAddClosureClass(expression, ACC_PUBLIC);
    String closureClassinternalName = BytecodeHelper.getClassInternalName(closureClass);
    List constructors = closureClass.getDeclaredConstructors();
    ConstructorNode node = (ConstructorNode) constructors.get(0);

    Parameter[] localVariableParams = node.getParameters();

    mv.visitTypeInsn(NEW, closureClassinternalName);
    mv.visitInsn(DUP);
    if (controller.isStaticMethod() || compileStack.isInSpecialConstructorCall()) {
      (new ClassExpression(classNode)).visit(acg);
      (new ClassExpression(controller.getOutermostClass())).visit(acg);
    } else {
      mv.visitVarInsn(ALOAD, 0);
      controller.getOperandStack().push(ClassHelper.OBJECT_TYPE);
      loadThis();
    }

    // now let's load the various parameters we're passing
    // we start at index 2 because the first variable we pass
    // is the owner instance and at this point it is already
    // on the stack
    for (int i = 2; i < localVariableParams.length; i++) {
      Parameter param = localVariableParams[i];
      String name = param.getName();
      loadReference(name, controller);
      if (param.getNodeMetaData(ClosureWriter.UseExistingReference.class) == null) {
        param.setNodeMetaData(ClosureWriter.UseExistingReference.class, Boolean.TRUE);
      }
    }

    // we may need to pass in some other constructors
    // cv.visitMethodInsn(INVOKESPECIAL, innerClassinternalName, "<init>", prototype + ")V");
    mv.visitMethodInsn(
        INVOKESPECIAL,
        closureClassinternalName,
        "<init>",
        BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, localVariableParams),
        false);
    controller.getOperandStack().replace(ClassHelper.CLOSURE_TYPE, localVariableParams.length);
  }
  private Parameter[] selectAccessibleConstructorFromSuper(ConstructorNode node) {
    ClassNode type = node.getDeclaringClass();
    ClassNode superType = type.getSuperClass();

    for (ConstructorNode c : superType.getDeclaredConstructors()) {
      // Only look at things we can actually call
      if (c.isPublic() || c.isProtected()) {
        return c.getParameters();
      }
    }

    // fall back for parameterless constructor
    if (superType.isPrimaryClassNode()) {
      return Parameter.EMPTY_ARRAY;
    }

    return null;
  }
 /** Add map and no-arg constructor or mirror those of the superclass (i.e. base enum). */
 private void addImplicitConstructors(ClassNode enumClass, boolean aic) {
   if (aic) {
     ClassNode sn = enumClass.getSuperClass();
     List<ConstructorNode> sctors = new ArrayList<ConstructorNode>(sn.getDeclaredConstructors());
     if (sctors.size() == 0) {
       addMapConstructors(enumClass, false);
     } else {
       for (ConstructorNode constructorNode : sctors) {
         ConstructorNode init =
             new ConstructorNode(
                 Opcodes.ACC_PUBLIC,
                 constructorNode.getParameters(),
                 ClassNode.EMPTY_ARRAY,
                 new BlockStatement());
         enumClass.addConstructor(init);
       }
     }
   } else {
     addMapConstructors(enumClass, false);
   }
 }