Arbit - project tracking

PHPMD

Browse source code

File: / source/ PHP/ PMD/ Rule/ UnusedPrivateMethod.php

Type
text/plain text/plain
Last Author
mapi
Version
284
Line Rev. Author Source
1 129 mapi <?php
2 mapi /**
3 mapi * This file is part of PHP_PMD.
4 mapi *
5 mapi * PHP Version 5
6 mapi *
7 174 mapi * Copyright (c) 2009-2010, Manuel Pichler <mapi@phpmd.org>.
8 129 mapi * All rights reserved.
9 mapi *
10 mapi * Redistribution and use in source and binary forms, with or without
11 mapi * modification, are permitted provided that the following conditions
12 mapi * are met:
13 mapi *
14 mapi * * Redistributions of source code must retain the above copyright
15 mapi * notice, this list of conditions and the following disclaimer.
16 mapi *
17 mapi * * Redistributions in binary form must reproduce the above copyright
18 mapi * notice, this list of conditions and the following disclaimer in
19 mapi * the documentation and/or other materials provided with the
20 mapi * distribution.
21 mapi *
22 mapi * * Neither the name of Manuel Pichler nor the names of his
23 mapi * contributors may be used to endorse or promote products derived
24 mapi * from this software without specific prior written permission.
25 mapi *
26 mapi * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 mapi * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 mapi * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29 mapi * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
30 mapi * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31 mapi * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32 mapi * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33 mapi * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34 mapi * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 mapi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
36 mapi * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 mapi * POSSIBILITY OF SUCH DAMAGE.
38 mapi *
39 mapi * @category PHP
40 mapi * @package PHP_PMD
41 mapi * @subpackage Rule
42 174 mapi * @author Manuel Pichler <mapi@phpmd.org>
43 150 mapi * @copyright 2009-2010 Manuel Pichler. All rights reserved.
44 129 mapi * @license http://www.opensource.org/licenses/bsd-license.php BSD License
45 mapi * @version SVN: $Id$
46 174 mapi * @link http://phpmd.org
47 129 mapi */
48 mapi
49 mapi require_once 'PHP/PMD/AbstractRule.php';
50 mapi require_once 'PHP/PMD/Rule/IClassAware.php';
51 mapi
52 mapi /**
53 134 mapi * This rule collects all private methods in a class that aren't used in any
54 129 mapi * method of the analyzed class.
55 mapi *
56 mapi * @category PHP
57 mapi * @package PHP_PMD
58 mapi * @subpackage Rule
59 174 mapi * @author Manuel Pichler <mapi@phpmd.org>
60 150 mapi * @copyright 2009-2010 Manuel Pichler. All rights reserved.
61 129 mapi * @license http://www.opensource.org/licenses/bsd-license.php BSD License
62 mapi * @version Release: @package_version@
63 174 mapi * @link http://phpmd.org
64 129 mapi */
65 134 mapi class PHP_PMD_Rule_UnusedPrivateMethod
66 129 mapi extends PHP_PMD_AbstractRule
67 mapi implements PHP_PMD_Rule_IClassAware
68 mapi {
69 mapi /**
70 134 mapi * This method checks that all private class methods are at least accessed
71 129 mapi * by one method.
72 mapi *
73 134 mapi * @param PHP_PMD_AbstractNode $class The context source code node.
74 129 mapi *
75 mapi * @return void
76 mapi */
77 134 mapi public function apply(PHP_PMD_AbstractNode $class)
78 129 mapi {
79 134 mapi foreach ($this->_collectUnusedPrivateMethods($class) as $node) {
80 mapi $this->addViolation($node, array($node->getImage()));
81 129 mapi }
82 mapi }
83 mapi
84 mapi /**
85 134 mapi * This method collects all methods in the given class that are declared
86 mapi * as private and are not used in the same class' context.
87 129 mapi *
88 200 mapi * @param PHP_PMD_Node_Class $class The context class instance.
89 129 mapi *
90 134 mapi * @return array(PHP_PMD_AbstractNode)
91 129 mapi */
92 200 mapi private function _collectUnusedPrivateMethods(PHP_PMD_Node_Class $class)
93 129 mapi {
94 134 mapi $methods = $this->_collectPrivateMethods($class);
95 mapi return $this->_removeUsedMethods($class, $methods);
96 129 mapi }
97 mapi
98 mapi /**
99 134 mapi * Collects all private methods declared in the given class node.
100 129 mapi *
101 200 mapi * @param PHP_PMD_Node_Class $class The context class instance.
102 129 mapi *
103 134 mapi * @return array(PHP_PMD_AbstractNode)
104 129 mapi */
105 200 mapi private function _collectPrivateMethods(PHP_PMD_Node_Class $class)
106 129 mapi {
107 134 mapi $methods = array();
108 mapi foreach ($class->getMethods() as $method) {
109 mapi if ($this->_acceptMethod($class, $method)) {
110 mapi $methods[strtolower($method->getImage())] = $method;
111 mapi }
112 129 mapi }
113 134 mapi return $methods;
114 129 mapi }
115 mapi
116 mapi /**
117 134 mapi * Returns <b>true</b> when the given method should be used for this rule's
118 mapi * analysis.
119 129 mapi *
120 200 mapi * @param PHP_PMD_Node_Class $class The context class instance.
121 mapi * @param PHP_PMD_Node_Method $method The context method instance.
122 129 mapi *
123 134 mapi * @return boolean
124 129 mapi */
125 134 mapi private function _acceptMethod(
126 200 mapi PHP_PMD_Node_Class $class,
127 mapi PHP_PMD_Node_Method $method
128 134 mapi ) {
129 mapi return (
130 mapi $method->isPrivate() &&
131 284 mapi false === $method->hasSuppressWarningsAnnotationFor($this) &&
132 134 mapi strcasecmp($method->getImage(), $class->getImage()) !== 0 &&
133 mapi strcasecmp($method->getImage(), '__construct') !== 0 &&
134 mapi strcasecmp($method->getImage(), '__destruct') !== 0 &&
135 mapi strcasecmp($method->getImage(), '__clone') !== 0
136 mapi );
137 129 mapi }
138 mapi
139 mapi /**
140 235 mapi * This method removes all used methods from the given methods array.
141 mapi *
142 mapi * @param PHP_PMD_Node_Class $class The context class instance.
143 mapi * @param array(PHP_PMD_Node_Method) $methods All collected private methods.
144 mapi *
145 mapi * @return array(PHP_PMD_AbstractNode)
146 mapi */
147 mapi private function _removeUsedMethods(PHP_PMD_Node_Class $class,array $methods)
148 mapi {
149 mapi foreach ($class->findChildrenOfType('MethodPostfix') as $postfix) {
150 mapi if ($this->_isClassScope($class, $postfix)) {
151 mapi unset($methods[strtolower($postfix->getImage())]);
152 mapi }
153 mapi }
154 mapi return $methods;
155 mapi }
156 mapi
157 mapi /**
158 134 mapi * This method checks that the given method postfix is accessed on an
159 129 mapi * instance or static reference to the given class.
160 mapi *
161 200 mapi * @param PHP_PMD_Node_Class $class The context class node instance.
162 mapi * @param PHP_PMD_Node_ASTNode $postfix The context method postfix node.
163 129 mapi *
164 mapi * @return boolean
165 mapi */
166 mapi private function _isClassScope(
167 200 mapi PHP_PMD_Node_Class $class,
168 129 mapi PHP_PMD_Node_ASTNode $postfix
169 mapi ) {
170 235 mapi $owner = $postfix->getParent()->getChild(0);
171 mapi if ($owner->isInstanceOf('MethodPostfix')) {
172 mapi $owner = $owner->getParent()->getParent()->getChild(0);
173 mapi }
174 129 mapi return (
175 235 mapi $owner->isInstanceOf('SelfReference') ||
176 mapi $owner->isInstanceOf('StaticReference') ||
177 129 mapi // TODO: Replace this with ThisVariable check when this AST node is
178 mapi // ported back from the design disharmony branch
179 235 mapi strcasecmp($owner->getImage(), '$this') === 0 ||
180 mapi strcasecmp($owner->getImage(), $class->getImage()) === 0
181 129 mapi );
182 mapi }
183 197 mapi }