classnode.java

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

JAVA
957
字号

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

    /**
     * @return the method matching the given name and parameters or null
     */
    public MethodNode getDeclaredMethod(String name, Parameter[] parameters) {
        for (Iterator iter = getMethods().iterator(); iter.hasNext();) {
            MethodNode method = (MethodNode) iter.next();
            if (name.equals(method.getName()) && parametersEqual(method.getParameters(), parameters)) {
                return method;
            }
        }
        return null;
    }

    /**
     * @return true if this node is derived from the given class node
     */
    public boolean isDerivedFrom(ClassNode type) {
        ClassNode node = this;
        while (node != null) {
            if (type.equals(node)) {
                return true;
            }
            node = node.getSuperClass();
        }
        return false;
    }

    /**
     * @return true if this class is derived from a groovy object
     *         i.e. it implements GroovyObject
     */
    public boolean isDerivedFromGroovyObject() {
        return implementsInterface(GroovyObject.class.getName());
    }

    /**
     * @param name the fully qualified name of the interface
     * @return true if this class or any base class implements the given interface
     */
    public boolean implementsInterface(String name) {
        ClassNode node = redirect();
        do {
            if (node.declaresInterface(name)) {
                return true;
            }
            node = node.getSuperClass();
        }
        while (node != null);
        return false;
    }

    /**
     * @param name the fully qualified name of the interface
     * @return true if this class declares that it implements the given interface
     */
    public boolean declaresInterface(String name) {
        ClassNode[] interfaces = redirect().getInterfaces();
        int size = interfaces.length;
        for (int i = 0; i < size; i++) {
            if (interfaces[i].getName().equals(name)) {
                return true;
            }
        }
        return false;
    }

    /**
     * @return the ClassNode of the super class of this type
     */
    public ClassNode getSuperClass() {
        if (!lazyInitDone && !isResolved()) {
            throw new GroovyBugError("Classnode#getSuperClass for "+getName()+" called before class resolving");
        }
        return redirect().getUnresolvedSuperClass();
    }
    
    public ClassNode getUnresolvedSuperClass() {
        if (!lazyInitDone) {
            lazyClassInit();
        }
        return redirect().superClass;
    }

    /**
     * Factory method to create a new MethodNode via reflection
     */
    protected MethodNode createMethodNode(Method method) {
        Parameter[] parameters = createParameters(method.getParameterTypes());
        return new MethodNode(method.getName(), method.getModifiers(), ClassHelper.make(method.getReturnType()), parameters, ClassHelper.make(method.getExceptionTypes()), EmptyStatement.INSTANCE);
    }

    /**
     * @param types
     */
    protected Parameter[] createParameters(Class[] types) {
        Parameter[] parameters = Parameter.EMPTY_ARRAY;
        int size = types.length;
        if (size > 0) {
            parameters = new Parameter[size];
            for (int i = 0; i < size; i++) {
                parameters[i] = createParameter(types[i], i);
            }
        }
        return parameters;
    }

    protected Parameter createParameter(Class parameterType, int idx) {
        return new Parameter(ClassHelper.make(parameterType), "param" + idx);
    }

    public CompileUnit getCompileUnit() {
        if (redirect!=null) return redirect().getCompileUnit();
        if (compileUnit == null && module != null) {
            compileUnit = module.getUnit();
        }
        return compileUnit;
    }
    
    protected void setCompileUnit(CompileUnit cu) {
        if (redirect!=null) redirect().setCompileUnit(cu);
        if (compileUnit!= null) compileUnit = cu;
    }

    /**
     * @return true if the two arrays are of the same size and have the same contents
     */
    protected boolean parametersEqual(Parameter[] a, Parameter[] b) {
        if (a.length == b.length) {
            boolean answer = true;
            for (int i = 0; i < a.length; i++) {
                if (!a[i].getType().equals(b[i].getType())) {
                    answer = false;
                    break;
                }
            }
            return answer;
        }
        return false;
    }

    /**
     * @return the package name of this class
     */
    public String getPackageName() {
        int idx = getName().lastIndexOf('.');
        if (idx > 0) {
            return getName().substring(0, idx);
        }
        return null;
    }

    public String getNameWithoutPackage() {
        int idx = getName().lastIndexOf('.');
        if (idx > 0) {
            return getName().substring(idx + 1);
        }
        return getName();
    }

    public void visitContents(GroovyClassVisitor visitor) {
        
        // now lets visit the contents of the class
        for (Iterator iter = getProperties().iterator(); iter.hasNext();) {
            PropertyNode pn = (PropertyNode) iter.next();
            visitor.visitProperty(pn);
        }

        for (Iterator iter = getFields().iterator(); iter.hasNext();) {
            FieldNode fn = (FieldNode) iter.next();
            visitor.visitField(fn);
        }

        for (Iterator iter = getDeclaredConstructors().iterator(); iter.hasNext();) {
            ConstructorNode cn = (ConstructorNode) iter.next();
            visitor.visitConstructor(cn);
        }

        for (Iterator iter = getMethods().iterator(); iter.hasNext();) {
            MethodNode mn = (MethodNode) iter.next();
            visitor.visitMethod(mn);
        }
    }

    public MethodNode getGetterMethod(String getterName) {
        for (Iterator iter = getMethods().iterator(); iter.hasNext();) {
            MethodNode method = (MethodNode) iter.next();
            if (getterName.equals(method.getName())
                    && ClassHelper.VOID_TYPE!=method.getReturnType()
                    && method.getParameters().length == 0) {
                return method;
            }
        }
        return null;
    }

    public MethodNode getSetterMethod(String getterName) {
        for (Iterator iter = getMethods().iterator(); iter.hasNext();) {
            MethodNode method = (MethodNode) iter.next();
            if (getterName.equals(method.getName())
                    && ClassHelper.VOID_TYPE==method.getReturnType()
                    && method.getParameters().length == 1) {
                return method;
            }
        }
        return null;
    }

    /**
     * Is this class delcared in a static method (such as a closure / inner class declared in a static method)
     */
    public boolean isStaticClass() {
        return redirect().staticClass;
    }

    public void setStaticClass(boolean staticClass) {
        redirect().staticClass = staticClass;
    }

    /**
     * @return Returns true if this inner class or closure was declared inside a script body
     */
    public boolean isScriptBody() {
        return redirect().scriptBody;
    }

    public void setScriptBody(boolean scriptBody) {
        redirect().scriptBody = scriptBody;
    }

    public boolean isScript() {
        return redirect().script || isDerivedFrom(ClassHelper.SCRIPT_TYPE);
    }

    public void setScript(boolean script) {
        redirect().script = script;
    }

    public String toString() {
        return super.toString() + "[name: " + getName() + "]";
    }

    /**
     * Returns true if the given method has a possibly matching method with the given name and arguments
     */
    public boolean hasPossibleMethod(String name, Expression arguments) {
        int count = 0;

        if (arguments instanceof TupleExpression) {
            TupleExpression tuple = (TupleExpression) arguments;
            // TODO this won't strictly be true when using list expension in argument calls
            count = tuple.getExpressions().size();
        }
        ClassNode node = this;
        do {
            for (Iterator iter = getMethods().iterator(); iter.hasNext();) {
                MethodNode method = (MethodNode) iter.next();
                if (name.equals(method.getName()) && method.getParameters().length == count) {
                    return true;
                }
            }
            node = node.getSuperClass();
        }
        while (node != null);
        return false;
    }
    
    public boolean isInterface(){
        return (getModifiers() & Opcodes.ACC_INTERFACE) > 0; 
    }
    
    public boolean isResolved(){
        return redirect().clazz!=null || (componentType != null && componentType.isResolved());
    }
    
    public boolean isArray(){
        return componentType!=null;
    }
    
    public ClassNode getComponentType() {
        return componentType;
    }
    
    public Class getTypeClass(){
        Class c = redirect().clazz;
        if (c!=null) return c;
        ClassNode component = redirect().componentType;
        if (component!=null && component.isResolved()){
            ClassNode cn = component.makeArray();
            setRedirect(cn);
            return redirect().clazz;
        }
        throw new GroovyBugError("ClassNode#getTypeClass for "+getName()+" is called before the type class is set ");
    }
    
    public boolean hasPackageName(){
        return redirect().name.indexOf('.')>0;
    }
}

⌨️ 快捷键说明

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