@Override
  public void visitConstructorCallExpression(final ConstructorCallExpression call) {
    super.visitConstructorCallExpression(call);

    MethodNode target = (MethodNode) call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
    if (target == null && call.getLineNumber() > 0) {
      addError("Target constructor for constructor call expression hasn't been set", call);
    } else {
      if (target == null) {
        // try to find a target
        ArgumentListExpression argumentListExpression =
            InvocationWriter.makeArgumentList(call.getArguments());
        List<Expression> expressions = argumentListExpression.getExpressions();
        ClassNode[] args = new ClassNode[expressions.size()];
        for (int i = 0; i < args.length; i++) {
          args[i] = typeChooser.resolveType(expressions.get(i), classNode);
        }
        MethodNode constructor =
            findMethodOrFail(
                call, call.isSuperCall() ? classNode.getSuperClass() : classNode, "<init>", args);
        call.putNodeMetaData(DIRECT_METHOD_CALL_TARGET, constructor);
        target = constructor;
      }
    }
    if (target != null) {
      memorizeInitialExpressions(target);
    }
  }
 @Override
 public void visitMethod(final MethodNode node) {
   if (isSkipMode(node)) {
     node.putNodeMetaData(STATIC_COMPILE_NODE, false);
   }
   super.visitMethod(node);
   checkForConstructorWithCSButClassWithout(node);
 }
 @Override
 public void visitPropertyExpression(final PropertyExpression pexp) {
   super.visitPropertyExpression(pexp);
   Object dynamic = pexp.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION);
   if (dynamic != null) {
     pexp.getObjectExpression()
         .putNodeMetaData(StaticCompilationMetadataKeys.RECEIVER_OF_DYNAMIC_PROPERTY, dynamic);
   }
 }
 @Override
 public void visitForLoop(final ForStatement forLoop) {
   super.visitForLoop(forLoop);
   Expression collectionExpression = forLoop.getCollectionExpression();
   if (!(collectionExpression instanceof ClosureListExpression)) {
     final ClassNode collectionType = getType(forLoop.getCollectionExpression());
     ClassNode componentType = inferLoopElementType(collectionType);
     forLoop.getVariable().setType(componentType);
     forLoop.getVariable().setOriginType(componentType);
   }
 }
  @Override
  public void visitMethodCallExpression(final MethodCallExpression call) {
    super.visitMethodCallExpression(call);

    MethodNode target = (MethodNode) call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
    if (target != null) {
      call.setMethodTarget(target);
      memorizeInitialExpressions(target);
    }

    if (call.getMethodTarget() == null && call.getLineNumber() > 0) {
      addError("Target method for method call expression hasn't been set", call);
    }
  }
 @Override
 public void visitClass(final ClassNode node) {
   boolean skip = shouldSkipClassNode(node);
   if (!skip && !anyMethodSkip(node)) {
     node.putNodeMetaData(MopWriter.Factory.class, StaticCompilationMopWriter.FACTORY);
   }
   ClassNode oldCN = classNode;
   classNode = node;
   Iterator<InnerClassNode> innerClasses = classNode.getInnerClasses();
   while (innerClasses.hasNext()) {
     InnerClassNode innerClassNode = innerClasses.next();
     boolean innerStaticCompile = !(skip || isSkippedInnerClass(innerClassNode));
     innerClassNode.putNodeMetaData(STATIC_COMPILE_NODE, innerStaticCompile);
     innerClassNode.putNodeMetaData(
         WriterControllerFactory.class, node.getNodeMetaData(WriterControllerFactory.class));
     if (innerStaticCompile && !anyMethodSkip(innerClassNode)) {
       innerClassNode.putNodeMetaData(MopWriter.Factory.class, StaticCompilationMopWriter.FACTORY);
     }
   }
   super.visitClass(node);
   addPrivateFieldAndMethodAccessors(node);
   classNode = oldCN;
 }