⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resolver.java

📁 Checkstyle 可寻找:·不能使用的或者多余的输入 ·空格更好的地方不使用跳格符
💻 JAVA
📖 第 1 页 / 共 5 页
字号:

// Transmogrify License
// 
// Copyright (c) 2001, ThoughtWorks, Inc.
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// - Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// - 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.
// Neither the name of the ThoughtWorks, Inc. nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR
// 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 com.puppycrawl.tools.checkstyle.checks.usage.transmogrify;



import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogConfigurationException;
import org.apache.commons.logging.LogFactory;

import com.puppycrawl.tools.checkstyle.api.TokenTypes;

/**
 * The resolver is responsible for traversing all the various
 * definitions in a symbol table and resolving references in them.
 *
 * @see SymbolTable
 */

public class Resolver extends DefinitionTraverser {

    /** true if the log factory has been initialized */
    private boolean mInitialized = false;

    /** Factory for creating org.apache.commons.logging.Log instances */
    private LogFactory mLogFactory;

    /**
     * constructor with <code>SymbolTable</code> to be resolved
     */
    public Resolver(SymbolTable symbolTable) {
        super(symbolTable);

        try {
            mLogFactory = LogFactory.getFactory();
        }
        catch (LogConfigurationException e) {
            System.out.println("log configuration exception" + e);
        }
        mInitialized = true;

    }

    /**
     * resolves the symbol table
     * @return <code>void</code>
     * @see #traverse()
     */
    public void resolve() {
        traverse();
    }

    protected void handleSList(SymTabAST node, Scope scope) {
        SymTabASTIterator iterator = node.getChildren();
        while (iterator.hasNext()) {
            SymTabAST current = iterator.nextChild();
            resolveExpression(current, scope, null, true);
        }
    }

    protected void handleAnonymousInnerClass(AnonymousInnerClass innerClass) {
        SymTabAST objblock = innerClass.getTreeNode();
        SymTabAST expression = (SymTabAST) objblock.getFirstChild();
        while (expression != null) {
            resolveExpression(expression, innerClass, null, true);
            expression = (SymTabAST) expression.getNextSibling();
        }
    }

    /**
     * processes a <code>ClassDef</code> and resolves references in it
     *
     * @param classDef the <code>ClassDef</code> to process
     */
    protected void handleClass(ClassDef classDef) {
        SymTabAST node = classDef.getTreeNode();

        if (node != null) {
            SymTabAST nameNode = node.findFirstToken(TokenTypes.IDENT);
            nameNode.setDefinition(classDef, classDef, true);

            SymTabAST extendsClause =
                node.findFirstToken(TokenTypes.EXTENDS_CLAUSE);
            SymTabAST extendedClassNode =
                (SymTabAST) extendsClause.getFirstChild();

            while (extendedClassNode != null) {
                IClass superClass =
                    resolveClass(extendedClassNode, classDef, null, true);
                extendedClassNode.setDefinition(superClass, classDef, true);
                extendedClassNode =
                    (SymTabAST) extendedClassNode.getNextSibling();
            }

            SymTabAST implementsNode =
                node.findFirstToken(TokenTypes.IMPLEMENTS_CLAUSE);

            if (implementsNode != null) {
                SymTabAST interfaceNode =
                    (SymTabAST) (implementsNode.getFirstChild());
                while (interfaceNode != null) {
                    resolveClass(interfaceNode, classDef, null, true);
                    interfaceNode =
                        (SymTabAST) (interfaceNode.getNextSibling());
                }
            }
        }
    }

    /**
     * processes a <code>MethodDef</code> and resolves references in it
     *
     * @param method the <code>MethodDef</code> to process
     */
    protected void handleMethod(MethodDef method) {
        SymTabAST node = method.getTreeNode();

        SymTabAST nameNode = node.findFirstToken(TokenTypes.IDENT);
        nameNode.setDefinition(method, method, true);

        // references to classes in return type
        SymTabAST returnTypeNode = node.findFirstToken(TokenTypes.TYPE);

        if (returnTypeNode != null) {
            // this is not a constructor
            resolveExpression(returnTypeNode, method, null, true);
        }

        SymTabAST throwsNode =
            node.findFirstToken(TokenTypes.LITERAL_THROWS);
        if (throwsNode != null) {
            SymTabAST exception = (SymTabAST) throwsNode.getFirstChild();
            while (exception != null) {
                // handle Checkstyle grammar
                if (exception.getType() != TokenTypes.COMMA) {
                    resolveClass(exception, method, null, true);
                }
                exception = (SymTabAST) exception.getNextSibling();
            }
        }

        // references to classes in parameters

        // the body -- this would be better its own function
        SymTabAST slist = node.findFirstToken(TokenTypes.SLIST);

        if (slist != null) {
            handleSList(slist, method);
        }
    }

    /**
     * processes a <code>BlockDef</code> and resolves references in it
     *
     * @param block the <code>BlockDef</code> to process
     */
    protected void handleBlock(BlockDef block) {
        SymTabAST node = block.getTreeNode();

        switch (node.getType()) {

            case TokenTypes.LITERAL_FOR :
                handleFor(block);
                break;

            case TokenTypes.LITERAL_IF :
                handleIf(block);
                break;

            case TokenTypes.LITERAL_WHILE :
                handleWhileAndSynchronized(block);
                break;

            case TokenTypes.LITERAL_DO :
                handleDoWhile(block);
                break;

            case TokenTypes.LITERAL_TRY :
            case TokenTypes.LITERAL_FINALLY :
                SymTabAST slist = node.findFirstToken(TokenTypes.SLIST);

                handleSList(slist, block);
                break;

            case TokenTypes.LITERAL_CATCH :
                handleCatch(block);
                break;

            case TokenTypes.LITERAL_SWITCH :
                handleSwitch(block);
                break;

            case TokenTypes.SLIST :
                handleSList(node, block);
                break;

            case TokenTypes.EXPR :
                resolveExpression(node, block, null, true);
                break;

            case TokenTypes.INSTANCE_INIT :
            case TokenTypes.STATIC_INIT :
                handleSList((SymTabAST) node.getFirstChild(), block);
                break;

            case TokenTypes.LITERAL_SYNCHRONIZED :
                handleWhileAndSynchronized(block);
                break;

            case TokenTypes.LITERAL_ASSERT :
                handleAssert(block);
                break;

            default :
                if (mInitialized) {
                    final Log log = mLogFactory.getInstance(this.getClass());
                    log.error(
                        "Unhandled block "
                            + block
                            + " of type "
                            + node.getType());
                }
        }
    }

    /**
     * @param block
     */
    private void handleAssert(BlockDef block) {
        SymTabAST node = block.getTreeNode();

        SymTabAST conditional =
            (node.findFirstToken(TokenTypes.EXPR));
        resolveExpression(conditional, block, null, true);

        SymTabAST message = (SymTabAST) conditional.getNextSibling();
        while ((message != null) && (message.getType() != TokenTypes.EXPR)) {
            message = (SymTabAST) message.getNextSibling();
        }
        if (message != null) {
            resolveExpression(message, block, null, true);
        }
    }

    /**
     * processes a switch statement and resolves references in it
     *
     * @param block the <code>BlockDef</code> to process
     */
    private void handleSwitch(BlockDef block) {
        SymTabAST node = block.getTreeNode();

        SymTabAST expr = node.findFirstToken(TokenTypes.EXPR);
        resolveExpression(expr, block, null, true);

        SymTabAST caseGroup = (SymTabAST) (expr.getNextSibling());
        while (caseGroup != null
            && (caseGroup.getType() != TokenTypes.CASE_GROUP)) {
            caseGroup = (SymTabAST) caseGroup.getNextSibling();
        }
        if (caseGroup != null) {
            while (caseGroup.getType() == TokenTypes.CASE_GROUP) {
                SymTabAST caseNode =
                    caseGroup.findFirstToken(TokenTypes.LITERAL_CASE);
                while (caseNode != null
                    && caseNode.getType() == TokenTypes.LITERAL_CASE) {
                    resolveExpression(
                        (SymTabAST) caseNode.getFirstChild(),
                        block,
                        null,
                        true);
                    caseNode = (SymTabAST) caseNode.getNextSibling();
                }

                SymTabAST caseSlist =
                    caseGroup.findFirstToken(TokenTypes.SLIST);
                handleSList(caseSlist, block);

                caseGroup = (SymTabAST) (caseGroup.getNextSibling());
            }
        }
    }

    /**
     * processes a catch block and resolves references in it
     *
     * @param block the <code>BlockDef</code> to process
     */
    private void handleCatch(BlockDef block) {
        SymTabAST node = block.getTreeNode();

        SymTabAST slist = node.findFirstToken(TokenTypes.SLIST);
        handleSList(slist, block);
    }

    /**
     * processes a for loop and resolves references in it
     *
     * @param block the <code>BlockDef</code> to process
     */
    private void handleFor(BlockDef block) {
        SymTabAST node = block.getTreeNode();

        SymTabAST body;
        SymTabAST forEach = node.findFirstToken(TokenTypes.FOR_EACH_CLAUSE);
        if (forEach == null) {
            SymTabAST init = node.findFirstToken(TokenTypes.FOR_INIT);
            // only need to handle the elist case.  if the init node is a variable
            // definition, the variable def will be handled later on in the resolution
            if (init.getFirstChild() != null) {
                if (init.getFirstChild().getType() == TokenTypes.ELIST) {
                    resolveExpression(
                        (SymTabAST) (init.getFirstChild()),
                        block,
                        null,
                        true);
                }
            }

            SymTabAST cond = node.findFirstToken(TokenTypes.FOR_CONDITION);
            if (cond.getFirstChild() != null) {
                resolveExpression(
                    (SymTabAST) (cond.getFirstChild()),
                    block,
                    null,
                    true);
            }

            SymTabAST iterator = node.findFirstToken(TokenTypes.FOR_ITERATOR);
            if (iterator.getFirstChild() != null) {
                resolveExpression(
                    (SymTabAST) (iterator.getFirstChild()),
                    block,
                    null,
                    true);
            }
            body = (SymTabAST) (iterator.getNextSibling());
        }
        else {

⌨️ 快捷键说明

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