classnode.java

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

JAVA
957
字号
     * this ClassNode
     */   
    public List getAbstractMethods() {
        
        HashSet abstractNodes = new HashSet();
        // let us collect the abstract super classes and stop at the
        // first non abstract super class. If such a class still 
        // contains abstract methods, then loading that class will fail.
        // No need to be extra carefull here for that.
        ClassNode parent = this.redirect();
        do {
        	abstractNodes.add(parent);
            ClassNode[] interfaces = parent.getInterfaces();
            for (int i = 0; i < interfaces.length; i++) {
                abstractNodes.add(interfaces[i].redirect());
            }
            parent = parent.getSuperClass().redirect();
        } while (parent!=null && ((parent.getModifiers() & Opcodes.ACC_ABSTRACT) != 0));
        
        List result = new ArrayList();
        for (Iterator methIt = getAllDeclaredMethods().iterator(); methIt.hasNext();) {
            MethodNode method = (MethodNode) methIt.next();
            // add only abstract methods from abtract classes that
            // are not overwritten
            if ( abstractNodes.contains(method.getDeclaringClass().redirect()) && 
                 (method.getModifiers() & Opcodes.ACC_ABSTRACT) != 0
               ) {
                result.add(method);
            }
        }
        if (result.size() == 0) {
            return null;
        }
        else {
            return result;
        }
    }

    public List getAllDeclaredMethods() {
        return new ArrayList(getDeclaredMethodsMap().values());
    }


    protected Map getDeclaredMethodsMap() {
        // Start off with the methods from the superclass.
        ClassNode parent = getSuperClass();
        Map result = null;
        if (parent != null) {
            result = parent.getDeclaredMethodsMap();
        }
        else {
            result = new HashMap();
        }

        // add in unimplemented abstract methods from the interfaces
        ClassNode[] interfaces = getInterfaces();
        for (int i = 0; i < interfaces.length; i++) {
            ClassNode iface = interfaces[i];
            Map ifaceMethodsMap = iface.getDeclaredMethodsMap();
            for (Iterator iter = ifaceMethodsMap.keySet().iterator(); iter.hasNext();) {
                String methSig = (String) iter.next();
                if (!result.containsKey(methSig)) {
                    MethodNode methNode = (MethodNode) ifaceMethodsMap.get(methSig);
                    result.put(methSig, methNode);
                }
            }
        }

        // And add in the methods implemented in this class.
        for (Iterator iter = getMethods().iterator(); iter.hasNext();) {
            MethodNode method = (MethodNode) iter.next();
            String sig = method.getTypeDescriptor();
            result.put(sig, method);
        }
        return result;
    }

    public String getName() {
        return redirect().name;
    }
    
    public String setName(String name) {
        return redirect().name=name;
    }

    public int getModifiers() {
        return redirect().modifiers;
    }

    public List getProperties() {
        return redirect().properties;
    }

    public List getDeclaredConstructors() {
        if (!lazyInitDone) {
            lazyClassInit();
        }
        return redirect().constructors;
    }

    public ModuleNode getModule() {
        return redirect().module;
    }

    public void setModule(ModuleNode module) {
        redirect().module = module;
        if (module != null) {
            redirect().compileUnit = module.getUnit();
        }
    }

    public void addField(FieldNode node) {
        node.setDeclaringClass(redirect());
        node.setOwner(redirect());
        redirect().fields.add(node);
        redirect().fieldIndex.put(node.getName(), node);
    }

    public void addProperty(PropertyNode node) {
        node.setDeclaringClass(redirect());
        FieldNode field = node.getField();
        addField(field);

        redirect().properties.add(node);
    }

    public PropertyNode addProperty(String name,
                                    int modifiers,
                                    ClassNode type,
                                    Expression initialValueExpression,
                                    Statement getterBlock,
                                    Statement setterBlock) {
    	for (Iterator iter = getProperties().iterator(); iter.hasNext();) {
			PropertyNode pn = (PropertyNode) iter.next();
			if (pn.getName().equals(name)) return pn;
		}
        PropertyNode node =
                new PropertyNode(name, modifiers, type, redirect(), initialValueExpression, getterBlock, setterBlock);
        addProperty(node);
        return node;
    }

    public void addConstructor(ConstructorNode node) {
        node.setDeclaringClass(this);
        redirect().constructors.add(node);
    }

    public ConstructorNode addConstructor(int modifiers, Parameter[] parameters, ClassNode[] exceptions, Statement code) {
        ConstructorNode node = new ConstructorNode(modifiers, parameters, exceptions, code);
        addConstructor(node);
        return node;
    }

    public void addMethod(MethodNode node) {
        node.setDeclaringClass(this);
        redirect().methods.add(node);
    }

    /**
     * IF a method with the given name and parameters is already defined then it is returned
     * otherwise the given method is added to this node. This method is useful for
     * default method adding like getProperty() or invokeMethod() where there may already
     * be a method defined in a class and  so the default implementations should not be added
     * if already present.
     */
    public MethodNode addMethod(String name,
                                int modifiers,
                                ClassNode returnType,
                                Parameter[] parameters,
                                ClassNode[] exceptions,
                                Statement code) {
        MethodNode other = getDeclaredMethod(name, parameters);
        // lets not add duplicate methods
        if (other != null) {
            return other;
        }
        MethodNode node = new MethodNode(name, modifiers, returnType, parameters, exceptions, code);
        addMethod(node);
        return node;
    }

    /**
     * Adds a synthetic method as part of the compilation process
     */
    public MethodNode addSyntheticMethod(String name,
                                         int modifiers,
                                         ClassNode returnType,
                                         Parameter[] parameters,
                                         ClassNode[] exceptions,
                                         Statement code) {
        MethodNode answer = addMethod(name, modifiers, returnType, parameters, exceptions, code);
        answer.setSynthetic(true);
        return answer;
    }

    public FieldNode addField(String name, int modifiers, ClassNode type, Expression initialValue) {
        FieldNode node = new FieldNode(name, modifiers, type, redirect(), initialValue);
        addField(node);
        return node;
    }

    public void addInterface(ClassNode type) {
        // lets check if it already implements an interface
        boolean skip = false;
        ClassNode[] interfaces = redirect().interfaces;
        for (int i = 0; i < interfaces.length; i++) {
            if (type.equals(interfaces[i])) {
                skip = true;
            }
        }
        if (!skip) {
            ClassNode[] newInterfaces = new ClassNode[interfaces.length + 1];
            System.arraycopy(interfaces, 0, newInterfaces, 0, interfaces.length);
            newInterfaces[interfaces.length] = type;
            redirect().interfaces = newInterfaces;
        }
    }
    
    public boolean equals(Object o) {
        if (redirect!=null) return redirect().equals(o);
        ClassNode cn = (ClassNode) o;        
        return (cn.getName().equals(getName()));
    }

    public void addMixin(MixinNode mixin) {
        // lets check if it already uses a mixin
        MixinNode[] mixins = redirect().mixins;
        boolean skip = false;
        for (int i = 0; i < mixins.length; i++) {
            if (mixin.equals(mixins[i])) {
                skip = true;
            }
        }
        if (!skip) {
            MixinNode[] newMixins = new MixinNode[mixins.length + 1];
            System.arraycopy(mixins, 0, newMixins, 0, mixins.length);
            newMixins[mixins.length] = mixin;
            redirect().mixins = newMixins;
        }
    }

    public FieldNode getField(String name) {
        return (FieldNode) redirect().fieldIndex.get(name);
    }

    /**
     * @return the field node on the outer class or null if this is not an
     *         inner class
     */
    public FieldNode getOuterField(String name) {
        return null;
    }

    /**
     * Helper method to avoid casting to inner class
     */
    public ClassNode getOuterClass() {
        return null;
    }
    
    public void addObjectInitializerStatements(Statement statements) {
        objectInitializers.add(statements);
    }
    
    public List getObjectInitializerStatements() {
        return objectInitializers;
    }

    public void addStaticInitializerStatements(List staticStatements, boolean fieldInit) {
        MethodNode method = null;
        List declaredMethods = getDeclaredMethods("<clinit>");
        if (declaredMethods.isEmpty()) {
            method =
                    addMethod("<clinit>", ACC_PUBLIC | ACC_STATIC, ClassHelper.VOID_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement());
            method.setSynthetic(true);
        }
        else {
            method = (MethodNode) declaredMethods.get(0);
        }
        BlockStatement block = null;
        Statement statement = method.getCode();
        if (statement == null) {
            block = new BlockStatement();
        }
        else if (statement instanceof BlockStatement) {
            block = (BlockStatement) statement;
        }
        else {
            block = new BlockStatement();
            block.addStatement(statement);
        }
        
        // while anything inside a static initializer block is appended 
        // we don't want to append in the case we have a initialization
        // expression of a static field. In that case we want to add
        // before the other statements
        if (!fieldInit) {
            block.addStatements(staticStatements);
        } else {
            List blockStatements = block.getStatements();
            staticStatements.addAll(blockStatements);
            blockStatements.clear();
            blockStatements.addAll(staticStatements);
        }
    }

    /**
     * @return a list of methods which match the given name
     */
    public List getDeclaredMethods(String name) {
        List answer = new ArrayList();
        for (Iterator iter = getMethods().iterator(); iter.hasNext();) {
            MethodNode method = (MethodNode) iter.next();
            if (name.equals(method.getName())) {
                answer.add(method);
            }
        }
        return answer;
    }

⌨️ 快捷键说明

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