/**
   * 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));
    }
  }
 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 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 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();
 }
 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;
 }
 private void visitFieldNode(FieldNode fNode) {
   final ClassNode cNode = fNode.getDeclaringClass();
   final List<PropertyNode> pList = cNode.getProperties();
   PropertyNode foundProp = null;
   for (PropertyNode pNode : pList) {
     if (pNode.getName().equals(fNode.getName())) {
       foundProp = pNode;
       break;
     }
   }
   if (foundProp != null) {
     revertVisibility(fNode);
     pList.remove(foundProp);
   }
 }
  private static boolean isDirectAccessAllowed(
      FieldNode a, ClassNode receiver, boolean isSamePackage) {
    ClassNode declaringClass = a.getDeclaringClass().redirect();
    ClassNode receiverType = receiver.redirect();

    // first, direct access from within the class or inner class nodes
    if (declaringClass.equals(receiverType)) return true;
    if (receiverType instanceof InnerClassNode) {
      while (receiverType != null && receiverType instanceof InnerClassNode) {
        if (declaringClass.equals(receiverType)) return true;
        receiverType = receiverType.getOuterClass();
      }
    }

    // no getter
    return a.isPublic() || (a.isProtected() && isSamePackage);
  }
 private ClassNode getCorrectedType(ClassNode buildee, FieldNode fieldNode) {
   Map<String, ClassNode> genericsSpec = createGenericsSpec(fieldNode.getDeclaringClass());
   extractSuperClassGenerics(fieldNode.getType(), buildee, genericsSpec);
   return correctToGenericsSpecRecurse(genericsSpec, fieldNode.getType());
 }