private MethodNode createBuilderMethodForField(
     ClassNode builder, List<FieldNode> fields, String prefix, int fieldPos) {
   String fieldName = fields.get(fieldPos).getName();
   String setterName = getSetterName(prefix, fieldName);
   GenericsType[] gtypes = new GenericsType[fields.size()];
   List<Expression> argList = new ArrayList<Expression>();
   for (int i = 0; i < fields.size(); i++) {
     gtypes[i] =
         i == fieldPos ? new GenericsType(ClassHelper.make(SET.class)) : makePlaceholder(i);
     argList.add(
         i == fieldPos ? propX(varX("this"), constX(fieldName)) : varX(fields.get(i).getName()));
   }
   ClassNode returnType = makeClassSafeWithGenerics(builder, gtypes);
   FieldNode fNode = fields.get(fieldPos);
   Map<String, ClassNode> genericsSpec = createGenericsSpec(fNode.getDeclaringClass());
   extractSuperClassGenerics(fNode.getType(), builder, genericsSpec);
   ClassNode correctedType = correctToGenericsSpecRecurse(genericsSpec, fNode.getType());
   return new MethodNode(
       setterName,
       ACC_PUBLIC,
       returnType,
       params(param(correctedType, fieldName)),
       NO_EXCEPTIONS,
       block(
           stmt(assignX(propX(varX("this"), constX(fieldName)), varX(fieldName, correctedType))),
           returnS(ctorX(returnType, args(argList)))));
 }
 private Statement createConstructorStatementMapSpecial(FieldNode fNode) {
   final Expression fieldExpr = new VariableExpression(fNode);
   Expression initExpr = fNode.getInitialValueExpression();
   if (initExpr == null) initExpr = new ConstantExpression(null);
   Expression namedArgs = findArg(fNode.getName());
   Expression baseArgs = new VariableExpression("args");
   return new IfStatement(
       equalsNullExpr(baseArgs),
       new IfStatement(
           equalsNullExpr(initExpr),
           new EmptyStatement(),
           assignStatement(fieldExpr, cloneCollectionExpr(initExpr))),
       new IfStatement(
           equalsNullExpr(namedArgs),
           new IfStatement(
               isTrueExpr(
                   new MethodCallExpression(
                       baseArgs, "containsKey", new ConstantExpression(fNode.getName()))),
               assignStatement(fieldExpr, namedArgs),
               assignStatement(fieldExpr, cloneCollectionExpr(baseArgs))),
           new IfStatement(
               isOneExpr(
                   new MethodCallExpression(baseArgs, "size", MethodCallExpression.NO_ARGUMENTS)),
               assignStatement(fieldExpr, cloneCollectionExpr(namedArgs)),
               assignStatement(fieldExpr, cloneCollectionExpr(baseArgs)))));
 }
 private static FieldNode createFieldCopy(ClassNode buildee, FieldNode fNode) {
   Map<String, ClassNode> genericsSpec = createGenericsSpec(fNode.getDeclaringClass());
   extractSuperClassGenerics(fNode.getType(), buildee, genericsSpec);
   ClassNode correctedType = correctToGenericsSpecRecurse(genericsSpec, fNode.getType());
   return new FieldNode(
       fNode.getName(), fNode.getModifiers(), correctedType, buildee, DEFAULT_INITIAL_VALUE);
 }
 private Statement createConstructorStatement(
     ClassNode cNode,
     PropertyNode pNode,
     List<String> knownImmutableClasses,
     List<String> knownImmutables) {
   FieldNode fNode = pNode.getField();
   final ClassNode fieldType = fNode.getType();
   Statement statement = null;
   if (fieldType.isArray() || isOrImplements(fieldType, CLONEABLE_TYPE)) {
     statement = createConstructorStatementArrayOrCloneable(fNode);
   } else if (isKnownImmutableClass(fieldType, knownImmutableClasses)
       || isKnownImmutable(pNode.getName(), knownImmutables)) {
     statement = createConstructorStatementDefault(fNode);
   } else if (fieldType.isDerivedFrom(DATE_TYPE)) {
     statement = createConstructorStatementDate(fNode);
   } else if (isOrImplements(fieldType, COLLECTION_TYPE)
       || fieldType.isDerivedFrom(COLLECTION_TYPE)
       || isOrImplements(fieldType, MAP_TYPE)
       || fieldType.isDerivedFrom(MAP_TYPE)) {
     statement = createConstructorStatementCollection(fNode);
   } else if (fieldType.isResolved()) {
     addError(
         createErrorMessage(cNode.getName(), fNode.getName(), fieldType.getName(), "compiling"),
         fNode);
     statement = EmptyStatement.INSTANCE;
   } else {
     statement = createConstructorStatementGuarded(cNode, fNode);
   }
   return statement;
 }
 private String[] ensureInitialized(ClassNode domainClass) {
   FieldNode field = domainClass.getField("namedQueries");
   if (field != null && field.isStatic()) {
     Expression initialExpression = field.getInitialExpression();
     if (initialExpression instanceof ClosureExpression) {
       Statement code = ((ClosureExpression) initialExpression).getCode();
       if (code instanceof BlockStatement) {
         List<Statement> statements = ((BlockStatement) code).getStatements();
         if (statements != null) {
           List<String> namedQueries = new ArrayList<String>(statements.size());
           for (Statement s : statements) {
             if (s instanceof ExpressionStatement) {
               Expression expr = ((ExpressionStatement) s).getExpression();
               if (expr instanceof MethodCallExpression) {
                 MethodCallExpression call = (MethodCallExpression) expr;
                 namedQueries.add(call.getMethodAsString());
               }
             }
           }
           return namedQueries.toArray(NO_QUERIES);
         }
       }
     }
   }
   return NO_QUERIES;
 }
  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();
  }
  /**
   * Main entry point for the calling the TestForTransformation programmatically.
   *
   * @param classNode The class node that represents th test
   * @param ce The class expression that represents the class to test
   */
  public void testFor(ClassNode classNode, ClassExpression ce) {
    boolean junit3Test = isJunit3Test(classNode);

    // make sure the 'log' property is not the one from GroovyTestCase
    FieldNode log = classNode.getField("log");
    if (log == null || log.getDeclaringClass().equals(GROOVY_TEST_CASE_CLASS)) {
      LoggingTransformer.addLogField(classNode, classNode.getName());
    }
    boolean isSpockTest = isSpockTest(classNode);

    if (!isSpockTest && !junit3Test) {
      // assume JUnit 4
      Map<String, MethodNode> declaredMethodsMap = classNode.getDeclaredMethodsMap();
      for (String methodName : declaredMethodsMap.keySet()) {
        MethodNode methodNode = declaredMethodsMap.get(methodName);
        if (isCandidateMethod(methodNode) && methodNode.getName().startsWith("test")) {
          if (methodNode.getAnnotations().size() == 0) {
            methodNode.addAnnotation(TEST_ANNOTATION);
          }
        }
      }
    }

    final MethodNode methodToAdd = weaveMock(classNode, ce, true);
    if (methodToAdd != null && junit3Test) {
      addMethodCallsToMethod(classNode, SET_UP_METHOD, Arrays.asList(methodToAdd));
    }
  }
  public static void loadReference(String name, WriterController controller) {
    CompileStack compileStack = controller.getCompileStack();
    MethodVisitor mv = controller.getMethodVisitor();
    ClassNode classNode = controller.getClassNode();
    AsmClassGenerator acg = controller.getAcg();

    // compileStack.containsVariable(name) means to ask if the variable is already declared
    // compileStack.getScope().isReferencedClassVariable(name) means to ask if the variable is a
    // field
    // If it is no field and is not yet declared, then it is either a closure shared variable or
    // an already declared variable.
    if (!compileStack.containsVariable(name)
        && compileStack.getScope().isReferencedClassVariable(name)) {
      acg.visitFieldExpression(new FieldExpression(classNode.getDeclaredField(name)));
    } else {
      BytecodeVariable v =
          compileStack.getVariable(name, !classNodeUsesReferences(controller.getClassNode()));
      if (v == null) {
        // variable is not on stack because we are
        // inside a nested Closure and this variable
        // was not used before
        // then load it from the Closure field
        FieldNode field = classNode.getDeclaredField(name);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(
            GETFIELD,
            controller.getInternalClassName(),
            name,
            BytecodeHelper.getTypeDescription(field.getType()));
      } else {
        mv.visitVarInsn(ALOAD, v.getIndex());
      }
      controller.getOperandStack().push(ClassHelper.REFERENCE_TYPE);
    }
  }
    protected void addTimeStamp(ClassNode node) {
      if (node.getDeclaredField(Verifier.__TIMESTAMP)
          == null) { // in case if verifier visited the call already
        FieldNode timeTagField =
            new FieldNode(
                Verifier.__TIMESTAMP,
                ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC,
                ClassHelper.long_TYPE,
                // "",
                node,
                new ConstantExpression(System.currentTimeMillis()));
        // alternatively, FieldNode timeTagField = SourceUnit.createFieldNode("public static final
        // long __timeStamp = " + System.currentTimeMillis() + "L");
        timeTagField.setSynthetic(true);
        node.addField(timeTagField);

        timeTagField =
            new FieldNode(
                Verifier.__TIMESTAMP__ + String.valueOf(System.currentTimeMillis()),
                ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC,
                ClassHelper.long_TYPE,
                // "",
                node,
                new ConstantExpression((long) 0));
        // alternatively, FieldNode timeTagField = SourceUnit.createFieldNode("public static final
        // long __timeStamp = " + System.currentTimeMillis() + "L");
        timeTagField.setSynthetic(true);
        node.addField(timeTagField);
      }
    }
 public void visitField(FieldNode node) {
   if (currentClass.getDeclaredField(node.getName()) != node) {
     addError("The " + getDescription(node) + " is declared multiple times.", node);
   }
   checkInterfaceFieldModifiers(node);
   checkGenericsUsage(node, node.getType());
   super.visitField(node);
 }
 public static List<String> getInstanceNonPropertyFieldNames(ClassNode cNode) {
   List<FieldNode> fList = getInstanceNonPropertyFields(cNode);
   List<String> result = new ArrayList<String>(fList.size());
   for (FieldNode fNode : fList) {
     result.add(fNode.getName());
   }
   return result;
 }
  private List<FieldNode> getAnnotatedFieldOfClass(ClassNode target, ClassNode annotation) {
    List<FieldNode> result = new ArrayList<FieldNode>();

    for (FieldNode fieldNode : target.getFields())
      if (!fieldNode.getAnnotations(annotation).isEmpty()) result.add(fieldNode);

    return result;
  }
 private Expression findConstant(FieldNode fn) {
   if (fn != null && !fn.isEnum() && fn.isStatic() && fn.isFinal()) {
     if (fn.getInitialValueExpression() instanceof ConstantExpression) {
       return fn.getInitialValueExpression();
     }
   }
   return null;
 }
 private Expression findStaticField(ClassNode staticImportType, String fieldName) {
   if (staticImportType.isPrimaryClassNode() || staticImportType.isResolved()) {
     FieldNode field = staticImportType.getField(fieldName);
     if (field != null && field.isStatic())
       return new PropertyExpression(new ClassExpression(staticImportType), fieldName);
   }
   return null;
 }
 private static List<FieldNode> selectFieldsFromExistingClass(
     List<FieldNode> fieldNodes, List<String> includes, List<String> excludes) {
   List<FieldNode> fields = new ArrayList<FieldNode>();
   for (FieldNode fNode : fieldNodes) {
     if (shouldSkip(fNode.getName(), excludes, includes)) continue;
     fields.add(fNode);
   }
   return fields;
 }
 private static Expression initializeInstance(
     ClassNode buildee, List<FieldNode> fields, BlockStatement body) {
   Expression instance = varX("_the" + buildee.getNameWithoutPackage(), buildee);
   body.addStatement(declS(instance, ctorX(buildee)));
   for (FieldNode field : fields) {
     body.addStatement(stmt(assignX(propX(instance, field.getName()), varX(field))));
   }
   return instance;
 }
 private static void initializeFields(List<FieldNode> fields, BlockStatement body) {
   for (FieldNode field : fields) {
     body.addStatement(
         stmt(
             assignX(
                 propX(varX("this"), field.getName()),
                 varX(param(field.getType(), field.getName())))));
   }
 }
 private static List<FieldNode> filterFields(
     List<FieldNode> fieldNodes, List<String> includes, List<String> excludes) {
   List<FieldNode> fields = new ArrayList<FieldNode>();
   for (FieldNode fNode : fieldNodes) {
     if (AbstractASTTransformation.shouldSkip(fNode.getName(), excludes, includes)) continue;
     fields.add(fNode);
   }
   return fields;
 }
 public static List<FieldNode> getInstanceNonPropertyFields(ClassNode cNode) {
   final List<FieldNode> result = new ArrayList<FieldNode>();
   for (FieldNode fNode : cNode.getFields()) {
     if (!fNode.isStatic() && cNode.getProperty(fNode.getName()) == null) {
       result.add(fNode);
     }
   }
   return result;
 }
 private String createFieldLabel(FieldNode node) {
   StringBuilder sb = new StringBuilder();
   sb.append(createClassLabel(node.getType()));
   sb.append(" ");
   sb.append(createClassLabel(node.getDeclaringClass()));
   sb.append(".");
   sb.append(node.getName());
   return sb.toString();
 }
  public void visitField(FieldNode fieldNode) {

    cv.visitField(
        fieldNode.getModifiers(),
        fieldNode.getName(),
        BytecodeHelper.getTypeDescription(fieldNode.getType()),
        null, // fieldValue,  //br  all the sudden that one cannot init the field here. init is done
        // in static initializer and instance initializer.
        null);
  }
  private void createMethodsForSingleField(FieldNode fieldNode) {
    if (shouldFieldBeIgnored(fieldNode)) return;

    if (hasAnnotation(fieldNode.getType(), DSL_CONFIG_ANNOTATION)) {
      createSingleDSLObjectClosureMethod(fieldNode);
      createSingleFieldSetterMethod(fieldNode);
    } else if (ASTHelper.isMap(fieldNode.getType())) createMapMethod(fieldNode);
    else if (ASTHelper.isList(fieldNode.getType())) createListMethod(fieldNode);
    else createSingleFieldSetterMethod(fieldNode);
  }
 @SuppressWarnings("RedundantIfStatement")
 boolean shouldFieldBeIgnored(FieldNode fieldNode) {
   if (fieldNode == keyField) return true;
   if (fieldNode == ownerField) return true;
   if (getAnnotation(fieldNode, IGNORE_ANNOTATION) != null) return true;
   if (fieldNode.isFinal()) return true;
   if (fieldNode.getName().startsWith("$")) return true;
   if ((fieldNode.getModifiers() & ACC_TRANSIENT) != 0) return true;
   return false;
 }
 private static Parameter[] getParams(List<FieldNode> fields, ClassNode cNode) {
   Parameter[] parameters = new Parameter[fields.size()];
   for (int i = 0; i < parameters.length; i++) {
     FieldNode fNode = fields.get(i);
     Map<String, ClassNode> genericsSpec = createGenericsSpec(fNode.getDeclaringClass());
     extractSuperClassGenerics(fNode.getType(), cNode, genericsSpec);
     ClassNode correctedType = correctToGenericsSpecRecurse(genericsSpec, fNode.getType());
     parameters[i] = new Parameter(correctedType, fNode.getName());
   }
   return parameters;
 }
  @Test
  public void transformationOfAnnotationOnField() {
    ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class));
    this.moduleNode.addClass(classNode);

    FieldNode fieldNode = new FieldNode("test", 0, new ClassNode(Object.class), classNode, null);
    classNode.addField(fieldNode);

    fieldNode.addAnnotation(this.grabAnnotation);

    assertGrabAnnotationHasBeenTransformed();
  }
  private void preventOwnerOverride() {

    MethodBuilder.createPublicMethod(setterName(ownerField))
        .param(OBJECT_TYPE, "value")
        .statement(
            ifS(
                andX(
                    isInstanceOfX(varX("value"), ownerField.getType()),
                    notX(propX(varX("this"), ownerField.getName()))),
                assignX(propX(varX("this"), ownerField.getName()), varX("value"))))
        .addTo(annotatedClass);
  }
 private boolean shouldFieldBeInWhiteList(
     final FieldNode fieldNode, final Set<String> fieldsInTransientsList) {
   boolean shouldInclude = true;
   final int modifiers = fieldNode.getModifiers();
   if ((modifiers & Modifier.STATIC) != 0
       || (modifiers & Modifier.TRANSIENT) != 0
       || fieldsInTransientsList.contains(fieldNode.getName())
       || fieldNode.getType().equals(new ClassNode(Object.class))) {
     shouldInclude = false;
   }
   return shouldInclude;
 }
 private Statement createConstructorStatementDate(FieldNode fNode) {
   final Expression fieldExpr = new VariableExpression(fNode);
   Expression initExpr = fNode.getInitialValueExpression();
   if (initExpr == null) initExpr = new ConstantExpression(null);
   final Expression date = findArg(fNode.getName());
   return new IfStatement(
       equalsNullExpr(date),
       new IfStatement(
           equalsNullExpr(initExpr),
           assignStatement(fieldExpr, new ConstantExpression(null)),
           assignStatement(fieldExpr, cloneDateExpr(initExpr))),
       assignStatement(fieldExpr, cloneDateExpr(date)));
 }
 private Statement createConstructorStatementGuarded(ClassNode cNode, FieldNode fNode) {
   final Expression fieldExpr = new VariableExpression(fNode);
   Expression initExpr = fNode.getInitialValueExpression();
   if (initExpr == null) initExpr = new ConstantExpression(null);
   Expression unknown = findArg(fNode.getName());
   return new IfStatement(
       equalsNullExpr(unknown),
       new IfStatement(
           equalsNullExpr(initExpr),
           new EmptyStatement(),
           assignStatement(fieldExpr, checkUnresolved(cNode, fNode, initExpr))),
       assignStatement(fieldExpr, checkUnresolved(cNode, fNode, unknown)));
 }
 private void checkInterfaceFieldModifiers(FieldNode node) {
   if (!currentClass.isInterface()) return;
   if ((node.getModifiers() & (ACC_PUBLIC | ACC_STATIC | ACC_FINAL)) == 0
       || (node.getModifiers() & (ACC_PRIVATE | ACC_PROTECTED)) != 0) {
     addError(
         "The "
             + getDescription(node)
             + " is not 'public static final' but is defined in "
             + getDescription(currentClass)
             + ".",
         node);
   }
 }