/*
 * Copyright 2003-2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.codehaus.groovy.transform;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.classgen.asm.OptimizingStatementWriter;
import org.codehaus.groovy.classgen.asm.WriterControllerFactory;
import org.codehaus.groovy.classgen.asm.sc.StaticTypesWriterControllerFactoryImpl;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor;
import org.codehaus.groovy.transform.stc.StaticTypesMarker;

/**
 * Handles the implementation of the {@link groovy.transform.CompileStatic} transformation.
 *
 * @author Cedric Champeau
 */
@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
public class StaticCompileTransformation extends StaticTypesTransformation {

    private final StaticTypesWriterControllerFactoryImpl factory = new StaticTypesWriterControllerFactoryImpl();

    @Override
    public void visit(final ASTNode[] nodes, final SourceUnit source) {
        for (ClassNode classNode : source.getAST().getClasses()) {
            classNode.putNodeMetaData(WriterControllerFactory.class, factory);
        }
        super.visit(nodes, source);
    }

    @Override
    protected StaticTypeCheckingVisitor newVisitor(final SourceUnit unit, final ClassNode node) {
        return new StaticTypeCheckingVisitor(unit, node) {
            @Override
            public void visitMethodCallExpression(final MethodCallExpression call) {
                super.visitMethodCallExpression(call);

                MethodNode target = (MethodNode) call.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
                if (target!=null) call.setMethodTarget(target);

                if (call.getMethodTarget()==null) {
                    addError("Target method for method call expression hasn't been set", call);
                }
            }

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

                MethodNode target = (MethodNode) call.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
                if (target==null) {
                    addError("Target constructor for constructor call expression hasn't been set", call);
                }
            }
        };
    }

}

@@ -1337,16 +1337,83 @@
 sMarker;
+%0Aimport org.codehaus.groovy.transform.stc.TypeCheckerPluginFactory;
 %0A%0A/**%0A *
@@ -2181,24 +2181,70 @@
 assNode node
+, final TypeCheckerPluginFactory pluginFactory
 ) %7B%0A        
@@ -2290,16 +2290,31 @@
 it, node
+, pluginFactory
 ) %7B%0A    

Align with current grumpy