resolvevisitor.java

来自「Groovy动态语言 运行在JVM中的动态语言 可以方便的处理业务逻辑变化大的业」· Java 代码 · 共 853 行 · 第 1/3 页

JAVA
853
字号
            // 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;
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?