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

📄 cyclomaticcomplexityrule.java

📁 检查Java程序漏洞
💻 JAVA
字号:
/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html*/package net.sourceforge.pmd.rules;import net.sourceforge.pmd.AbstractRule;import net.sourceforge.pmd.RuleContext;import net.sourceforge.pmd.RuleViolation;import net.sourceforge.pmd.ast.ASTBlockStatement;import net.sourceforge.pmd.ast.ASTConstructorDeclaration;import net.sourceforge.pmd.ast.ASTForStatement;import net.sourceforge.pmd.ast.ASTIfStatement;import net.sourceforge.pmd.ast.ASTInterfaceDeclaration;import net.sourceforge.pmd.ast.ASTMethodDeclaration;import net.sourceforge.pmd.ast.ASTMethodDeclarator;import net.sourceforge.pmd.ast.ASTSwitchLabel;import net.sourceforge.pmd.ast.ASTSwitchStatement;import net.sourceforge.pmd.ast.ASTUnmodifiedClassDeclaration;import net.sourceforge.pmd.ast.ASTWhileStatement;import net.sourceforge.pmd.ast.Node;import net.sourceforge.pmd.ast.SimpleNode;import java.text.MessageFormat;import java.util.Stack;/** * * @author Donald A. Leckie * @since January 14, 2003 * @version $Revision: 1.12 $, $Date: 2004/04/15 19:04:26 $ */public class CyclomaticComplexityRule extends AbstractRule {    private Stack m_entryStack = new Stack();    /**     **************************************************************************     *     * @param node     * @param data     *     * @return     */    public Object visit(ASTIfStatement node, Object data) {        Entry entry = (Entry) m_entryStack.peek();        entry.m_decisionPoints++;        super.visit(node, data);        return data;    }    /**     **************************************************************************     *     * @param node     * @param data     *     * @return     */    public Object visit(ASTForStatement node, Object data) {        Entry entry = (Entry) m_entryStack.peek();        entry.m_decisionPoints++;        super.visit(node, data);        return data;    }    /**     **************************************************************************     *     * @param node     * @param data     *     * @return     */    public Object visit(ASTSwitchStatement node, Object data) {        Entry entry = (Entry) m_entryStack.peek();        int childCount = node.jjtGetNumChildren();        int lastIndex = childCount - 1;        for (int n = 0; n < lastIndex; n++) {            Node childNode = node.jjtGetChild(n);            if (childNode instanceof ASTSwitchLabel) {                childNode = node.jjtGetChild(n + 1);                if (childNode instanceof ASTBlockStatement) {                    entry.m_decisionPoints++;                }            }        }        super.visit(node, data);        return data;    }    /**     **************************************************************************     *     * @param node     * @param data     *     * @return     */    public Object visit(ASTWhileStatement node, Object data) {        Entry entry = (Entry) m_entryStack.peek();        entry.m_decisionPoints++;        super.visit(node, data);        return data;    }    /**     **************************************************************************     *     * @param node     * @param data     *     * @return     */    public Object visit(ASTUnmodifiedClassDeclaration node, Object data) {        m_entryStack.push(new Entry(node));        super.visit(node, data);        Entry classEntry = (Entry) m_entryStack.pop();        double decisionPoints = (double) classEntry.m_decisionPoints;        double methodCount = (double) classEntry.m_methodCount;        int complexityAverage = (methodCount == 0) ? 1 : (int) (Math.rint(decisionPoints / methodCount));        if ((complexityAverage >= getIntProperty("reportLevel")) || (classEntry.m_highestDecisionPoints >= getIntProperty("reportLevel"))) {            // The {0} "{1}" has a cyclomatic complexity of {2}.            RuleContext ruleContext = (RuleContext) data;            String template = getMessage();            String className = node.getImage();            String complexityHighest = String.valueOf(classEntry.m_highestDecisionPoints);            String complexity = String.valueOf(complexityAverage) + " (Highest = " + complexityHighest + ")";            String[] args = {"class", className, complexity};            String message = MessageFormat.format(template, args);            int lineNumber = node.getBeginLine();            RuleViolation ruleViolation = createRuleViolation(ruleContext, lineNumber, message);            ruleContext.getReport().addRuleViolation(ruleViolation);        }        return data;    }    /**     **************************************************************************     *     * @param node     * @param data     *     * @return     */    public Object visit(ASTMethodDeclaration node, Object data) {        Node parentNode = node.jjtGetParent();        while (parentNode != null) {            if (parentNode instanceof ASTInterfaceDeclaration) {                return data;            }            parentNode = parentNode.jjtGetParent();        }        m_entryStack.push(new Entry(node));        super.visit(node, data);        Entry methodEntry = (Entry) m_entryStack.pop();        int methodDecisionPoints = methodEntry.m_decisionPoints;        Entry classEntry = (Entry) m_entryStack.peek();        classEntry.m_methodCount++;        classEntry.m_decisionPoints += methodDecisionPoints;        if (methodDecisionPoints > classEntry.m_highestDecisionPoints) {            classEntry.m_highestDecisionPoints = methodDecisionPoints;        }        ASTMethodDeclarator methodDeclarator = null;        for (int n = 0; n < node.jjtGetNumChildren(); n++) {            Node childNode = node.jjtGetChild(n);            if (childNode instanceof ASTMethodDeclarator) {                methodDeclarator = (ASTMethodDeclarator) childNode;                break;            }        }        if (methodEntry.m_decisionPoints >= getIntProperty("reportLevel")) {            // The {0} "{1}" has a cyclomatic complexity of {2}.            RuleContext ruleContext = (RuleContext) data;            String template = getMessage();            String methodName = (methodDeclarator == null) ? "" : methodDeclarator.getImage();            String complexity = String.valueOf(methodEntry.m_decisionPoints);            String[] args = {"method", methodName, complexity};            String message = MessageFormat.format(template, args);            int lineNumber = node.getBeginLine();            RuleViolation ruleViolation = createRuleViolation(ruleContext, lineNumber, message);            ruleContext.getReport().addRuleViolation(ruleViolation);        }        return data;    }    /**     **************************************************************************     *     * @param node     * @param data     *     * @return     */    public Object visit(ASTConstructorDeclaration node, Object data) {        m_entryStack.push(new Entry(node));        super.visit(node, data);        Entry constructorEntry = (Entry) m_entryStack.pop();        int constructorDecisionPointCount = constructorEntry.m_decisionPoints;        Entry classEntry = (Entry) m_entryStack.peek();        classEntry.m_methodCount++;        classEntry.m_decisionPoints += constructorDecisionPointCount;        if (constructorDecisionPointCount > classEntry.m_highestDecisionPoints) {            classEntry.m_highestDecisionPoints = constructorDecisionPointCount;        }        if (constructorEntry.m_decisionPoints >= getIntProperty("reportLevel")) {            // The {0} "{1}" has a cyclomatic complexity of {2}.            RuleContext ruleContext = (RuleContext) data;            String template = getMessage();            String constructorName = classEntry.m_node.getImage();            String complexity = String.valueOf(constructorDecisionPointCount);            String[] args = {"constructor", constructorName, complexity};            String message = MessageFormat.format(template, args);            int lineNumber = node.getBeginLine();            RuleViolation ruleViolation = createRuleViolation(ruleContext, lineNumber, message);            ruleContext.getReport().addRuleViolation(ruleViolation);        }        return data;    }    /**     ***************************************************************************     ***************************************************************************     ***************************************************************************     */    private class Entry {        // ASTUnmodifedClassDeclaration or ASTMethodDeclarator or ASTConstructorDeclaration        private SimpleNode m_node;        public int m_decisionPoints = 1;        public int m_highestDecisionPoints;        public int m_methodCount;        /**         ***********************************************************************         *         * @param node         */        private Entry(SimpleNode node) {            m_node = node;        }    }}

⌨️ 快捷键说明

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