/*
 * $Id$
 *
 * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
 *
 * Redistribution and use of this software and associated documentation
 * ("Software"), with or without modification, are permitted provided that the
 * following conditions are met: 1. Redistributions of source code must retain
 * copyright statements and notices. Redistributions must also contain a copy
 * of this document. 2. Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the distribution. 3.
 * The name "groovy" must not be used to endorse or promote products derived
 * from this Software without prior written permission of The Codehaus. For
 * written permission, please contact info@codehaus.org. 4. Products derived
 * from this Software may not be called "groovy" nor may "groovy" appear in
 * their names without prior written permission of The Codehaus. "groovy" is a
 * registered trademark of The Codehaus. 5. Due credit should be given to The
 * Codehaus - http://groovy.codehaus.org/
 *
 * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 */
package org.codehaus.groovy.control;

import groovy.lang.GroovyClassLoader;

import java.io.IOException;
import java.io.File;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.net.URL;
import java.net.MalformedURLException;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.CompileUnit;
import org.codehaus.groovy.ast.ConstructorNode;
import org.codehaus.groovy.ast.DynamicVariable;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.ImportNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.PropertyNode;
import org.codehaus.groovy.ast.Variable;
import org.codehaus.groovy.ast.VariableScope;
import org.codehaus.groovy.ast.expr.BinaryExpression;
import org.codehaus.groovy.ast.expr.BooleanExpression;
import org.codehaus.groovy.ast.expr.ClassExpression;
import org.codehaus.groovy.ast.expr.ClosureExpression;
import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
import org.codehaus.groovy.ast.expr.DeclarationExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.ExpressionTransformer;
import org.codehaus.groovy.ast.expr.ListExpression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.PropertyExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.AssertStatement;
import org.codehaus.groovy.ast.stmt.BlockStatement;
import org.codehaus.groovy.ast.stmt.CaseStatement;
import org.codehaus.groovy.ast.stmt.CatchStatement;
import org.codehaus.groovy.ast.stmt.DoWhileStatement;
import org.codehaus.groovy.ast.stmt.ExpressionStatement;
import org.codehaus.groovy.ast.stmt.ForStatement;
import org.codehaus.groovy.ast.stmt.IfStatement;
import org.codehaus.groovy.ast.stmt.ReturnStatement;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.ast.stmt.SwitchStatement;
import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
import org.codehaus.groovy.ast.stmt.ThrowStatement;
import org.codehaus.groovy.ast.stmt.WhileStatement;
import org.codehaus.groovy.classgen.Verifier;
import org.codehaus.groovy.control.messages.ExceptionMessage;
import org.codehaus.groovy.syntax.Types;

/**
 * Visitor to resolve Types and convert VariableExpression to
 * ClassExpressions if needed. The ResolveVisitor will try to
 * find the Class for a ClassExpression and prints an error if
 * it fails to do so. Constructions like C[], foo as C, (C) foo 
 * will force creation of a ClasssExpression for C   
 *
 * Note: the method to start the resolving is  startResolving(ClassNode, SourceUnit).
 *
 *
 * @author Jochen Theodorou
 */
public class ResolveVisitor extends ClassCodeVisitorSupport implements ExpressionTransformer {
    private ClassNode currentClass;
    // note: BigInteger and BigDecimal are also imported by default
    private static final String[] DEFAULT_IMPORTS = {"java.lang.", "java.io.", "java.net.", "java.util.", "groovy.lang.", "groovy.util."};
    private CompilationUnit compilationUnit;
    private Map cachedClasses = new HashMap();
    private static final Object NO_CLASS = new Object();
    private static final Object SCRIPT = new Object();
    private SourceUnit source;
    private VariableScope currentScope;

    private boolean isTopLevelProperty = true;
    private boolean inClosure = false;

    public ResolveVisitor(CompilationUnit cu) {
        compilationUnit = cu;
    }

    public void startResolving(ClassNode node,SourceUnit source) {
        this.source = source;
        visitClass(node);
    }

    public void visitConstructor(ConstructorNode node) {
        visitAnnotations(node);
        VariableScope oldScope = currentScope;
        currentScope = node.getVariableScope();
        Parameter[] paras = node.getParameters();
        for (int i=0; i<paras.length; i++) {
            ClassNode t = paras[i].getType();
            resolveOrFail(t,node);
        }
        ClassNode[] exceptions = node.getExceptions();
        for (int i=0; i<exceptions.length; i++) {
            ClassNode t = exceptions[i];
            resolveOrFail(t,node);
        }
        Statement code = node.getCode();
        if (code!=null) code.visit(this);
        currentScope = oldScope;
    }

    public void visitSwitch(SwitchStatement statement) {
        Expression exp = statement.getExpression();
        statement.setExpression(transform(exp));
        List list = statement.getCaseStatements();
        for (Iterator iter = list.iterator(); iter.hasNext(); ) {
            CaseStatement caseStatement = (CaseStatement) iter.next();
            caseStatement.visit(this);
        }
        statement.getDefaultStatement().visit(this);
    }

    public void visitMethod(MethodNode node) {
        visitAnnotations(node);
        VariableScope oldScope = currentScope;
        currentScope = node.getVariableScope();
        Parameter[] paras = node.getParameters();
        for (int i=0; i<paras.length; i++) {
            ClassNode t = paras[i].getType();
            resolveOrFail(t,node);
            if (paras[i].hasInitialExpression()) {
                Expression init = paras[i].getInitialExpression(); 
                paras[i].setInitialExpression(transform(init));
            }
        }
        ClassNode[] exceptions = node.getExceptions();
        for (int i=0; i<exceptions.length; i++) {
            ClassNode t = exceptions[i];
            resolveOrFail(t,node);
        }       
        resolveOrFail(node.getReturnType(),node);
        Statement code = node.getCode();
        if (code!=null) code.visit(this);
        currentScope = oldScope;
    }

    public void visitField(FieldNode node) {
        visitAnnotations(node);
        ClassNode t = node.getType();
        resolveOrFail(t,node);
        Expression init = node.getInitialExpression();
        node.setInitialValueExpression(transform(init));
    }

    public void visitProperty(PropertyNode node) {
        visitAnnotations(node);
        ClassNode t = node.getType();
        resolveOrFail(t,node);
        Statement code = node.getGetterBlock();
        if (code!=null) code.visit(this);
        code = node.getSetterBlock();
        if (code!=null) code.visit(this);
    }

    public void visitIfElse(IfStatement ifElse) {
        visitStatement(ifElse);
        ifElse.setBooleanExpression((BooleanExpression) (transform(ifElse.getBooleanExpression())));
        ifElse.getIfBlock().visit(this);
        ifElse.getElseBlock().visit(this);
    }

    private void resolveOrFail(ClassNode type, String msg, ASTNode node) {
        if (resolve(type)) return;
        addError("unable to resolve class "+type.getName()+" "+msg,node);
    }

    private void resolveOrFail(ClassNode type, ASTNode node, boolean prefereImports) {
        if (prefereImports && resolveAliasFromModule(type)) return;
        resolveOrFail(type,node);
    }
    
    private void resolveOrFail(ClassNode type, ASTNode node) {
        resolveOrFail(type,"",node);
    }

    private boolean resolve(ClassNode type) {
        String name = type.getName();
        return resolve(type,true,true,true);
    }

    private boolean resolve(ClassNode type, boolean testModuleImports, boolean testDefaultImports, boolean testStaticInnerClasses) {
        if (type.isResolved()) return true;
        if (type.isArray()) {
            ClassNode element = type.getComponentType();
            boolean resolved = resolve(element,testModuleImports,testDefaultImports,testStaticInnerClasses);
            if (resolved) {
                ClassNode cn = element.makeArray();
                type.setRedirect(cn);
            }
            return resolved;
        }

        // test if vanilla name is current class name
        if (currentClass==type) return true;
        if (currentClass.getNameWithoutPackage().equals(type.getName())) {
            type.setRedirect(currentClass);
            return true;
        }

        return  resolveFromModule(type,testModuleImports) ||
                resolveFromCompileUnit(type) ||
                resovleFromDefaultImports(type,testDefaultImports) ||
                resolveFromStaticInnerClasses(type,testStaticInnerClasses) ||
                resolveFromClassCache(type) ||
                resolveToClass(type) ||
                resolveToScript(type);

    }

    private boolean resolveFromClassCache(ClassNode type) {
        String name = type.getName();
        Object val = cachedClasses.get(name);
        if (val==null || val==NO_CLASS){
            return false;
        } else {
            setClass(type,(Class) val);
            return true;
        }
    }

    // NOTE: copied from GroovyClassLoader
    private long getTimeStamp(Class cls) {
        Field field;
        Long o;
        try {
            field = cls.getField(Verifier.__TIMESTAMP);
            o = (Long) field.get(null);
        } catch (Exception e) {
            return Long.MAX_VALUE;
        }
        return o.longValue();
    }

    // NOTE: copied from GroovyClassLoader
    private boolean isSourceNewer(URL source, Class cls) {
        try {
            long lastMod;

            // Special handling for file:// protocol, as getLastModified() often reports
            // incorrect results (-1)
            if (source.getProtocol().equals("file")) {
                // Coerce the file URL to a File
                String path = source.getPath().replace('/', File.separatorChar).replace('|', ':');
                File file = new File(path);
                lastMod = file.lastModified();
            }
            else {
                lastMod = source.openConnection().getLastModified();
            }
            return lastMod > getTimeStamp(cls);            
        } catch (IOException e) {
            // if the stream can't be opened, let's keep the old reference
            return false;
        }
    }


    private boolean resolveToScript(ClassNode type) {
        String name = type.getName();
        if (cachedClasses.get(name)==NO_CLASS) return false;
        if (cachedClasses.get(name)==SCRIPT) cachedClasses.put(name,NO_CLASS);
        if (name.startsWith("java.")) return type.isResolved();
        //TODO: don't ignore inner static classes completly
        if (name.indexOf('$')!=-1) return type.isResolved();
        ModuleNode module = currentClass.getModule();
        if (module.hasPackageName() && name.indexOf('.')==-1) return type.isResolved();
        // try to find a script from classpath
        GroovyClassLoader gcl = compilationUnit.getClassLoader();
        URL url = null;
        try {
            url = gcl.getResourceLoader().loadGroovySource(name);
        } catch (MalformedURLException e) {
            // fall through and let the URL be null
        }
        if (url !=null) {
            if (type.isResolved()) {
                Class cls = type.getTypeClass();
                // if the file is not newer we don't want to recompile
                if (!isSourceNewer(url,cls)) return true;
                cachedClasses.remove(type.getName());
                type.setRedirect(null);
            }
            SourceUnit su = compilationUnit.addSource(url);
            currentClass.getCompileUnit().addClassNodeToCompile(type,su);
            return true;
        }
        // type may be resolved through the classloader before
        return type.isResolved();
    }


    private boolean resolveFromStaticInnerClasses(ClassNode type, boolean testStaticInnerClasses) {
        // try to resolve a public static inner class' name
        testStaticInnerClasses &= type.hasPackageName();
        if (testStaticInnerClasses) {
            String name = type.getName();
            String replacedPointType = name;
            int lastPoint = replacedPointType.lastIndexOf('.');
            replacedPointType = new StringBuffer()
                .append(replacedPointType.substring(0, lastPoint))
                .append("$")
                .append(replacedPointType.substring(lastPoint + 1))
                .toString();
            type.setName(replacedPointType);
            if (resolve(type,false,false,true)) return true;
            type.setName(name);
        }
        return false;
    }

    private boolean resovleFromDefaultImports(ClassNode type, boolean testDefaultImports) {
        // test default imports
        testDefaultImports &= !type.hasPackageName();
        if (testDefaultImports) {
            for (int i = 0, size = DEFAULT_IMPORTS.length; i < size; i++) {
                String packagePrefix = DEFAULT_IMPORTS[i];
                String name = type.getName();
                String fqn = packagePrefix+name;
                type.setName(fqn);
                if (resolve(type,false,false,false)) return true;
                type.setName(name);
            }
            String name = type.getName();
            if (name.equals("BigInteger")) {
                type.setRedirect(ClassHelper.BigInteger_TYPE);
                return true;
            } else if (name.equals("BigDecimal")) {
                type.setRedirect(ClassHelper.BigDecimal_TYPE);
                return true;    
            }
        }
        return false;
    }

    private boolean resolveFromCompileUnit(ClassNode type) {
        // look into the compile unit if there is a class with that name
        CompileUnit compileUnit = currentClass.getCompileUnit();
        if (compileUnit == null) return false;
        ClassNode cuClass = compileUnit.getClass(type.getName());
        if (cuClass!=null) {
        	if (type!=cuClass) type.setRedirect(cuClass);
        	return true;
        }
        return false;
    }


    private void setClass(ClassNode n, Class cls) {
        ClassNode cn = ClassHelper.make(cls);
        n.setRedirect(cn);
    }

    private void ambigousClass(ClassNode type, ClassNode iType, String name, boolean resolved){
        if (resolved && !type.getName().equals(iType.getName())) {
            addError("reference to "+name+" is ambigous, both class "+type.getName()+" and "+iType.getName()+" match",type);
        } else {
            type.setRedirect(iType);
        }
    }
    
    private boolean resolveAliasFromModule(ClassNode type) {
        ModuleNode module = currentClass.getModule();
        if (module==null) return false;
        String name = type.getName();
        
        // check module node imports aliases
        // the while loop enables a check for inner classes which are not fully imported,
        // but visible as the surrounding class is imported and the inner class is public/protected static
        String pname = name;
        int index = name.length();
        /*
         * we have a name foo.bar and an import foo.foo. This means foo.bar is possibly
         * foo.foo.bar rather than foo.bar. This means to cut at the dot in foo.bar and
         * foo for import
         */
        while (true) {
            pname = name.substring(0,index);
            ClassNode aliasedNode = module.getImport(pname);
            if (aliasedNode!=null) {
                if (pname.length()==name.length()){
                    // full match, no need to create a new class
                    type.setRedirect(aliasedNode);
                    return true;
                } else {
                    //partial match
                    String newName = aliasedNode.getName()+name.substring(pname.length());
                    type.setName(newName);
                    if (resolve(type,true,true,true)) return true;
                    // was not resolved soit was a fake match
                    type.setName(name);
                }
            }
            index = pname.lastIndexOf('.');
            if (index==-1) break;
        }
         return false;
        
    }

    private boolean resolveFromModule(ClassNode type, boolean testModuleImports) {
        ModuleNode module = currentClass.getModule();
        if (module==null) return false;

        String name = type.getName();

        if (!type.hasPackageName() && module.hasPackageName()){
            type.setName(module.getPackageName()+name);
        }
        // look into the module node if there is a class with that name
        List moduleClasses = module.getClasses();
        for (Iterator iter = moduleClasses.iterator(); iter.hasNext();) {
            ClassNode mClass = (ClassNode) iter.next();
            if (mClass.getName().equals(type.getName())){
                if (mClass!=type) type.setRedirect(mClass);
                return true;
            }
        }
        type.setName(name);

        if (testModuleImports) {
            if (resolveAliasFromModule(type)) return true;
            
            boolean resolved = false;
            if (module.hasPackageName()) { 
                // check package this class is defined in
                type.setName(module.getPackageName()+name);
                resolved = resolve(type,false,false,false);
            }
            // check module node imports packages
            List packages = module.getImportPackages();
            ClassNode iType = ClassHelper.makeWithoutCaching(name);
            for (Iterator iter = packages.iterator(); iter.hasNext();) {
                String packagePrefix = (String) iter.next();
                String fqn = packagePrefix+name;
                iType.setName(fqn);
                if (resolve(iType,false,false,true)) {
                	ambigousClass(type,iType,name,resolved);
                    return true;
                }
                iType.setName(name);
            }
            if (!resolved) type.setName(name);
            return resolved;
        }
        return false;
    }

    private boolean resolveToClass(ClassNode type) {
        String name = type.getName();
        if (cachedClasses.get(name)==NO_CLASS) return false;
        if (currentClass.getModule().hasPackageName() && name.indexOf('.')==-1) return false;
        GroovyClassLoader loader  = compilationUnit.getClassLoader();
        Class cls = null;
        try {
            // NOTE: it's important to do no lookup against script files
            // here since the GroovyClassLoader would create a new
            // CompilationUnit
            cls = loader.loadClass(name,false,true);
        } catch (ClassNotFoundException cnfe) {
            cachedClasses.put(name,SCRIPT);
            return false;
        } catch (CompilationFailedException cfe) {
            compilationUnit.getErrorCollector().addErrorAndContinue(new ExceptionMessage(cfe,true,source));
            return false;
        } 
        //TODO: the case of a NoClassDefFoundError needs a bit more research
        // a simple recompilation is not possible it seems. The current class
        // we are searching for is there, so we should mark that somehow. 
        // Basically the missing class needs to be completly compiled before
        // we can again search for the current name.
        /*catch (NoClassDefFoundError ncdfe) {
            cachedClasses.put(name,SCRIPT);
            return false;
        }*/
        if (cls==null) return false;
        cachedClasses.put(name,cls);
        setClass(type,cls);
        //NOTE: we return false here even if we found a class,
        //but we want to give a possible script a chance to recompile.
        //this can only be done if the loader was not the instance
        //defining the class.
        return cls.getClassLoader()==loader;
    }



    public Expression transform(Expression exp) {
        if (exp==null) return null;
        if (exp instanceof VariableExpression) {
            return transformVariableExpression((VariableExpression) exp);
        } else if (exp.getClass()==PropertyExpression.class) {
            return transformPropertyExpression((PropertyExpression) exp);
        } else if (exp instanceof DeclarationExpression) {
            return transformDeclarationExpression((DeclarationExpression)exp);
        } else if (exp instanceof BinaryExpression) {
            return transformBinaryExpression((BinaryExpression)exp);
        } else if (exp instanceof MethodCallExpression) {
            return transformMethodCallExpression((MethodCallExpression)exp);
        } else if (exp instanceof ClosureExpression) {
        	return transformClosureExpression((ClosureExpression) exp);
        } else if (exp instanceof ConstructorCallExpression) {
        	return transformConstructorCallExpression((ConstructorCallExpression) exp);
        } else {
            resolveOrFail(exp.getType(),exp);
            return exp.transformExpression(this);
        }
    }


    private String lookupClassName(PropertyExpression pe) {
        String name = "";
        for (Expression it = pe; it!=null; it = ((PropertyExpression)it).getObjectExpression()) {
            if (it instanceof VariableExpression) {
                VariableExpression ve = (VariableExpression) it;
                // stop at super and this
                if (ve==VariableExpression.SUPER_EXPRESSION || ve==VariableExpression.THIS_EXPRESSION) {
                    return null;
                }
                name= ve.getName()+"."+name;
                break;
            } 
            // anything other than PropertyExpressions, ClassExpression or
            // VariableExpressions will stop resolving
            else if (!(it.getClass()==PropertyExpression.class)) {
                return null;
            } else {
                PropertyExpression current = (PropertyExpression) it;
                String propertyPart = current.getPropertyAsString();
                // the class property stops resolving, dynamic property names too
                if (propertyPart==null || propertyPart.equals("class")) {
                    return null;
                }
                name = propertyPart+"."+name;
            }
        }
        if (name.length()>0) return name.substring(0,name.length()-1);
        return null;
    }

    // iterate from the inner most to the outer and check for classes
    // this check will ignore a .class property, for Exmaple Integer.class will be
    // a PropertyExpression with the ClassExpression of Integer as objectExpression
    // and class as property
    private Expression correctClassClassChain(PropertyExpression pe){
        LinkedList stack = new LinkedList();
        ClassExpression found = null;
        for (Expression it = pe; it!=null; it = ((PropertyExpression)it).getObjectExpression()) {
            if (it instanceof ClassExpression) {
                found = (ClassExpression) it;
                break;
            } else if (! (it.getClass()==PropertyExpression.class)) {
                return pe;
            }
            stack.addFirst(it);
        }
        if (found==null) return pe;

        if (stack.isEmpty()) return pe;
        Object stackElement = stack.removeFirst();
        if (!(stackElement.getClass()==PropertyExpression.class)) return pe;
        PropertyExpression classPropertyExpression = (PropertyExpression) stackElement;
        String propertyNamePart = classPropertyExpression.getPropertyAsString();
        if (propertyNamePart==null || ! propertyNamePart.equals("class")) return pe;

        if (stack.isEmpty()) return found;
        stackElement = stack.removeFirst();
        if (!(stackElement.getClass()==PropertyExpression.class)) return pe;
        PropertyExpression classPropertyExpressionContainer = (PropertyExpression) stackElement;

        classPropertyExpressionContainer.setObjectExpression(found);
        return pe;
    }
    
    protected Expression transformPropertyExpression(PropertyExpression pe) {
        boolean itlp = isTopLevelProperty;
        
        Expression objectExpression = pe.getObjectExpression();
        isTopLevelProperty = !(objectExpression.getClass()==PropertyExpression.class);
        objectExpression = transform(objectExpression);
        Expression property = transform(pe.getProperty());
        isTopLevelProperty = itlp;
        
        boolean spreadSafe = pe.isSpreadSafe();
        pe = new PropertyExpression(objectExpression,property,pe.isSafe());
        pe.setSpreadSafe(spreadSafe);
        
        String className = lookupClassName(pe);
        if (className!=null) {
            ClassNode type = ClassHelper.make(className);
            if (resolve(type)) return new ClassExpression(type);
        }  
        if (objectExpression instanceof ClassExpression && pe.getPropertyAsString()!=null){
            // possibly a inner class
            ClassExpression ce = (ClassExpression) objectExpression;
            ClassNode type = ClassHelper.make(ce.getType().getName()+"$"+pe.getPropertyAsString());
            if (resolve(type,false,false,false)) return new ClassExpression(type);
        }
        if (isTopLevelProperty) return correctClassClassChain(pe);
        
        return pe;
    }
       
    protected Expression transformVariableExpression(VariableExpression ve) {
        if (ve.getName().equals("this"))  return VariableExpression.THIS_EXPRESSION;
        if (ve.getName().equals("super")) return VariableExpression.SUPER_EXPRESSION;
        Variable v = ve.getAccessedVariable();
        if (v instanceof DynamicVariable) {
            ClassNode t = ClassHelper.make(ve.getName());
            if (resolve(t)) {
                // the name is a type so remove it from the scoping
                // as it is only a classvariable, it is only in 
                // referencedClassVariables, but must be removed
                // for each parentscope too
                for (VariableScope scope = currentScope; scope!=null && !scope.isRoot(); scope = scope.getParent()) {
                    if (scope.isRoot()) break;
                    if (scope.getReferencedClassVariables().remove(ve.getName())==null) break;
                }
                ClassExpression ce = new ClassExpression(t);
                ce.setSourcePosition(ve);
                return ce;
            } else if (!inClosure && ve.isInStaticContext()) {
                addError("the name "+v.getName()+" doesn't refer to a declared variable or class. The static"+
                         " scope requires to declare variables before using them. If the variable should have"+
                         " been a class check the spelling.",ve);
            }
        }
        resolveOrFail(ve.getType(),ve);
        return ve;
    }
    
    protected Expression transformBinaryExpression(BinaryExpression be) {
        Expression left = transform(be.getLeftExpression());
        if (be.getOperation().getType()==Types.ASSIGNMENT_OPERATOR && left instanceof ClassExpression){
            ClassExpression  ce = (ClassExpression) left;
            addError("you tried to assign a value to "+ce.getType().getName(),be.getLeftExpression());
            return be;
        }
        if (left instanceof ClassExpression && be.getRightExpression() instanceof ListExpression) {
            // we have C[] if the list is empty -> should be an array then!
            ListExpression list = (ListExpression) be.getRightExpression();
            ClassExpression ce = (ClassExpression) left;
            if (list.getExpressions().isEmpty()) {
                return new ClassExpression(left.getType().makeArray());
            }
        }
        Expression right = transform(be.getRightExpression());
        Expression ret = new BinaryExpression(left,be.getOperation(),right);
        ret.setSourcePosition(be);
        return ret;
    }
    
    protected Expression transformClosureExpression(ClosureExpression ce) {
        boolean oldInClosure = inClosure;
        inClosure = true;
        Parameter[] paras = ce.getParameters();
        if (paras!=null) {
	        for (int i=0; i<paras.length; i++) {
	            ClassNode t = paras[i].getType();
	            resolveOrFail(t,ce);
	        }
        }
        Statement code = ce.getCode();
        if (code!=null) code.visit(this);
    	ClosureExpression newCe= new ClosureExpression(paras,code);
        newCe.setVariableScope(ce.getVariableScope());
        newCe.setSourcePosition(ce);
        inClosure = oldInClosure;
        return newCe;
    }
    
    protected Expression transformConstructorCallExpression(ConstructorCallExpression cce){
    	ClassNode type = cce.getType();
    	resolveOrFail(type,cce);
    	Expression expr = cce.transformExpression(this);
        return expr;
    }
    
    protected Expression transformMethodCallExpression(MethodCallExpression mce) {
        Expression obj = mce.getObjectExpression();
        Expression newObject = transform(obj);
        Expression args = transform(mce.getArguments());
        Expression method = transform(mce.getMethod());
        MethodCallExpression ret = new MethodCallExpression(newObject,method,args);
        ret.setSafe(mce.isSafe());
        ret.setImplicitThis(mce.isImplicitThis());
        ret.setSpreadSafe(mce.isSpreadSafe());
        ret.setSourcePosition(mce);
        return ret;
    }
    
    protected Expression transformDeclarationExpression(DeclarationExpression de) {
        Expression oldLeft = de.getLeftExpression();
        Expression left = transform(oldLeft);
        if (left!=oldLeft){
            ClassExpression  ce = (ClassExpression) left;
            addError("you tried to assign a value to "+ce.getType().getName(),oldLeft);
            return de;
        }
        Expression right = transform(de.getRightExpression());
        if (right==de.getRightExpression()) return de;
        return new DeclarationExpression((VariableExpression) left,de.getOperation(),right);
    }
    
    public void visitAnnotations(AnnotatedNode node) {
        Map annotionMap = node.getAnnotations();
        if (annotionMap.isEmpty()) return;
        Iterator it = annotionMap.values().iterator(); 
        while (it.hasNext()) {
            AnnotationNode an = (AnnotationNode) it.next();
            //skip builtin properties
            if (an.isBuiltIn()) continue;
            ClassNode type = an.getClassNode();
            resolveOrFail(type,"unable to find class for annotation",an);
        }
    }

    public void visitClass(ClassNode node) {
        ClassNode oldNode = currentClass;
        currentClass = node;
        
        ModuleNode module = node.getModule();
        if (!module.hasImportsResolved()) {
           List l = module.getImports();
           for (Iterator iter = l.iterator(); iter.hasNext();) {
               ImportNode element = (ImportNode) iter.next();
               ClassNode type = element.getType();
               if (resolve(type,false,false,false)) continue;
               addError("unable to resolve class "+type.getName(),type);
           }
           module.setImportsResolved(true);
        }
        
        ClassNode sn = node.getUnresolvedSuperClass();
        if (sn!=null) resolveOrFail(sn,node,true);
        ClassNode[] interfaces = node.getInterfaces();
        for (int i=0; i<interfaces.length; i++) {
            resolveOrFail(interfaces[i],node,true);
        }        
        super.visitClass(node);
        currentClass = oldNode;        
    }
    
    public void visitReturnStatement(ReturnStatement statement) {
       statement.setExpression(transform(statement.getExpression()));
    }

    public void visitAssertStatement(AssertStatement as) {
        as.setBooleanExpression((BooleanExpression) (transform(as.getBooleanExpression())));
        as.setMessageExpression(transform(as.getMessageExpression()));
    }
    
    public void visitCaseStatement(CaseStatement statement) {
    	statement.setExpression(transform(statement.getExpression()));
    	statement.getCode().visit(this);
    }

    public void visitCatchStatement(CatchStatement cs) {
        resolveOrFail(cs.getExceptionType(),cs);
        if (cs.getExceptionType()==ClassHelper.DYNAMIC_TYPE) {
            cs.getVariable().setType(ClassHelper.make(Exception.class));
        } 
        super.visitCatchStatement(cs);
    }

    public void visitDoWhileLoop(DoWhileStatement loop) {
        loop.setBooleanExpression((BooleanExpression) (transform(loop.getBooleanExpression())));
        super.visitDoWhileLoop(loop);
    }
    
    public void visitForLoop(ForStatement forLoop) {
        forLoop.setCollectionExpression(transform(forLoop.getCollectionExpression()));
        resolveOrFail(forLoop.getVariableType(),forLoop);
        super.visitForLoop(forLoop);
    }
    
    public void visitSynchronizedStatement(SynchronizedStatement sync) {
        sync.setExpression(transform(sync.getExpression()));
        super.visitSynchronizedStatement(sync);
    }
    
    public void visitThrowStatement(ThrowStatement ts) {
        ts.setExpression(transform(ts.getExpression()));
    }
    
    public void visitWhileLoop(WhileStatement loop) {
    	loop.setBooleanExpression((BooleanExpression) transform(loop.getBooleanExpression()));
    	super.visitWhileLoop(loop);
    }
    
    public void visitExpressionStatement(ExpressionStatement es) {
        es.setExpression(transform(es.getExpression()));
    }
    
    public void visitBlockStatement(BlockStatement block) {
        VariableScope oldScope = currentScope;
        currentScope = block.getVariableScope();
        super.visitBlockStatement(block);
        currentScope = oldScope;
    }

    protected SourceUnit getSourceUnit() {
        return source;
    }
}
