asmclassgenerator.java

来自「大名鼎鼎的java动态脚本语言。已经通过了sun的认证」· Java 代码 · 共 1,596 行 · 第 1/5 页

JAVA
1,596
字号
            );                        cw.visitSource(sourceFile,null);                        super.visitClass(classNode);            // set the optional enclosing method attribute of the current inner class//          br comment out once Groovy uses the latest CVS HEAD of ASM//            MethodNode enclosingMethod = classNode.getEnclosingMethod();//            String ownerName = BytecodeHelper.getClassInternalName(enclosingMethod.getDeclaringClass().getName());//            String descriptor = BytecodeHelper.getMethodDescriptor(enclosingMethod.getReturnType(), enclosingMethod.getParameters());//            EnclosingMethodAttribute attr = new EnclosingMethodAttribute(ownerName,enclosingMethod.getName(),descriptor);//            cw.visitAttribute(attr);            createSyntheticStaticFields();            for (Iterator iter = innerClasses.iterator(); iter.hasNext();) {                ClassNode innerClass = (ClassNode) iter.next();                String innerClassName = innerClass.getName();                String innerClassInternalName = BytecodeHelper.getClassInternalName(innerClassName);                {                    int index = innerClassName.lastIndexOf('$');                    if (index>=0) innerClassName = innerClassName.substring(index+1);                }                String outerClassName = internalClassName; // default for inner classes                MethodNode enclosingMethod = innerClass.getEnclosingMethod();                if (enclosingMethod != null) {                    // local inner classes do not specify the outer class name                    outerClassName = null;                    innerClassName = null;                }                cw.visitInnerClass(                    innerClassInternalName,                    outerClassName,                    innerClassName,                    innerClass.getModifiers());            }            // br TODO an inner class should have an entry of itself            cw.visitEnd();        }        catch (GroovyRuntimeException e) {            e.setModule(classNode.getModule());            throw e;        }    }        private String[] buildExceptions(ClassNode[] exceptions) {        if (exceptions==null) return null;        String[] ret = new String[exceptions.length];        for (int i = 0; i < exceptions.length; i++) {            ret[i] = BytecodeHelper.getClassInternalName(exceptions[i]);        }        return ret;    }        protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {        String methodType = BytecodeHelper.getMethodDescriptor(node.getReturnType(), node.getParameters());        cv = cw.visitMethod(node.getModifiers(), node.getName(), methodType, null, buildExceptions(node.getExceptions()));        helper = new BytecodeHelper(cv);        if (!node.isAbstract()) {             Statement code = node.getCode();            if (isConstructor && (code == null || !firstStatementIsSpecialConstructorCall(node))) {                // invokes the super class constructor                cv.visitVarInsn(ALOAD, 0);                cv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(classNode.getSuperClass()), "<init>", "()V");            }                        compileStack.init(node.getVariableScope(),node.getParameters(),cv, BytecodeHelper.getTypeDescription(classNode));                        super.visitConstructorOrMethod(node, isConstructor);                        if (!outputReturn || node.isVoidMethod()) {                cv.visitInsn(RETURN);            }                        compileStack.clear();                        // lets do all the exception blocks            for (Iterator iter = exceptionBlocks.iterator(); iter.hasNext();) {                Runnable runnable = (Runnable) iter.next();                runnable.run();            }            exceptionBlocks.clear();                cv.visitMaxs(0, 0);        }    }    private boolean firstStatementIsSpecialConstructorCall(MethodNode node) {        Statement code = node.getFirstStatement();        if (code == null || !(code instanceof ExpressionStatement)) return false;        Expression expression = ((ExpressionStatement)code).getExpression();        if (!(expression instanceof ConstructorCallExpression)) return false;        ConstructorCallExpression cce = (ConstructorCallExpression) expression;        return cce.isSpecialCall();    }    public void visitConstructor(ConstructorNode node) {        this.constructorNode = node;        this.methodNode = null;        outputReturn = false;        super.visitConstructor(node);    }    public void visitMethod(MethodNode node) {        this.constructorNode = null;        this.methodNode = node;        outputReturn = false;                super.visitMethod(node);    }    public void visitField(FieldNode fieldNode) {        onLineNumber(fieldNode, "visitField: " + fieldNode.getName());        ClassNode t = fieldNode.getType();        cw.visitField(            fieldNode.getModifiers(),            fieldNode.getName(),            BytecodeHelper.getTypeDescription(t),            null, //fieldValue,  //br  all the sudden that one cannot init the field here. init is done in static initilizer and instace intializer.            null);        visitAnnotations(fieldNode);    }    public void visitProperty(PropertyNode statement) {        // the verifyer created the field and the setter/getter methods, so here is        // not really something to do        onLineNumber(statement, "visitProperty:" + statement.getField().getName());        this.methodNode = null;    }    // GroovyCodeVisitor interface    //-------------------------------------------------------------------------    // Statements    //-------------------------------------------------------------------------    protected void visitStatement(Statement statement) {        String name = statement.getStatementLabel();        if (name!=null) {            Label label = compileStack.createLocalLabel(name);            cv.visitLabel(label);        }    }        public void visitBlockStatement(BlockStatement block) {        onLineNumber(block, "visitBlockStatement");        visitStatement(block);                compileStack.pushVariableScope(block.getVariableScope());        super.visitBlockStatement(block);        compileStack.pop();    }    public void visitForLoop(ForStatement loop) {        onLineNumber(loop, "visitForLoop");        visitStatement(loop);        compileStack.pushLoop(loop.getVariableScope(),loop.getStatementLabel());        //        // Declare the loop counter.        Variable variable = compileStack.defineVariable(loop.getVariable(),false);        //        // Then initialize the iterator and generate the loop control        loop.getCollectionExpression().visit(this);        asIteratorMethod.call(cv);        final int iteratorIdx = compileStack.defineTemporaryVariable("iterator", ClassHelper.make(java.util.Iterator.class),true);        Label continueLabel = compileStack.getContinueLabel();        Label breakLabel = compileStack.getBreakLabel();                cv.visitLabel(continueLabel);        cv.visitVarInsn(ALOAD, iteratorIdx);        iteratorHasNextMethod.call(cv);        // note: ifeq tests for ==0, a boolean is 0 if it is false        cv.visitJumpInsn(IFEQ, breakLabel);                cv.visitVarInsn(ALOAD, iteratorIdx);        iteratorNextMethod.call(cv);        helper.storeVar(variable);        // Generate the loop body        loop.getLoopBlock().visit(this);        cv.visitJumpInsn(GOTO, continueLabel);                cv.visitLabel(breakLabel);                compileStack.pop();    }    public void visitWhileLoop(WhileStatement loop) {        onLineNumber(loop, "visitWhileLoop");        visitStatement(loop);        compileStack.pushLoop(loop.getStatementLabel());        Label continueLabel = compileStack.getContinueLabel();        Label breakLabel = compileStack.getBreakLabel();                cv.visitLabel(continueLabel);        loop.getBooleanExpression().visit(this);        cv.visitJumpInsn(IFEQ, breakLabel);                loop.getLoopBlock().visit(this);                cv.visitJumpInsn(GOTO, continueLabel);        cv.visitLabel(breakLabel);                compileStack.pop();    }    public void visitDoWhileLoop(DoWhileStatement loop) {        onLineNumber(loop, "visitDoWhileLoop");        visitStatement(loop);        compileStack.pushLoop(loop.getStatementLabel());        Label breakLabel = compileStack.getBreakLabel();        Label continueLabel = compileStack.getContinueLabel();        cv.visitLabel(continueLabel);        loop.getLoopBlock().visit(this);        loop.getBooleanExpression().visit(this);        cv.visitJumpInsn(IFEQ, continueLabel);        cv.visitLabel(breakLabel);                compileStack.pop();    }    public void visitIfElse(IfStatement ifElse) {        onLineNumber(ifElse, "visitIfElse");        visitStatement(ifElse);        ifElse.getBooleanExpression().visit(this);                Label l0 = new Label();        cv.visitJumpInsn(IFEQ, l0);        ifElse.getIfBlock().visit(this);        Label l1 = new Label();        cv.visitJumpInsn(GOTO, l1);        cv.visitLabel(l0);        ifElse.getElseBlock().visit(this);        cv.visitLabel(l1);    }    public void visitTernaryExpression(TernaryExpression expression) {        onLineNumber(expression, "visitTernaryExpression");        expression.getBooleanExpression().visit(this);        Label l0 = new Label();        cv.visitJumpInsn(IFEQ, l0);        expression.getTrueExpression().visit(this);        Label l1 = new Label();        cv.visitJumpInsn(GOTO, l1);        cv.visitLabel(l0);        expression.getFalseExpression().visit(this);        cv.visitLabel(l1);    }    public void visitAssertStatement(AssertStatement statement) {        onLineNumber(statement, "visitAssertStatement");        visitStatement(statement);        BooleanExpression booleanExpression = statement.getBooleanExpression();        booleanExpression.visit(this);        Label l0 = new Label();        cv.visitJumpInsn(IFEQ, l0);        // do nothing        Label l1 = new Label();        cv.visitJumpInsn(GOTO, l1);        cv.visitLabel(l0);        // push expression string onto stack        String expressionText = booleanExpression.getText();        List list = new ArrayList();        addVariableNames(booleanExpression, list);        if (list.isEmpty()) {            cv.visitLdcInsn(expressionText);        }        else {            boolean first = true;            // lets create a new expression            cv.visitTypeInsn(NEW, "java/lang/StringBuffer");            cv.visitInsn(DUP);            cv.visitLdcInsn(expressionText + ". Values: ");            cv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "(Ljava/lang/String;)V");            int tempIndex = compileStack.defineTemporaryVariable("assert",true);            for (Iterator iter = list.iterator(); iter.hasNext();) {                String name = (String) iter.next();                String text = name + " = ";                if (first) {                    first = false;                }                else {                    text = ", " + text;                }                cv.visitVarInsn(ALOAD, tempIndex);                cv.visitLdcInsn(text);                cv.visitMethodInsn(                    INVOKEVIRTUAL,                    "java/lang/StringBuffer",                    "append",                    "(Ljava/lang/Object;)Ljava/lang/StringBuffer;");

⌨️ 快捷键说明

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