License updated to GPLv3

🧲 New features
Custom user role permissions
Employee edit form updated
Employee daily task list
Attendance and employee distribution charts on dashboard
Improvements to company structure and company assets module
Improved tables for displaying data in several modules
Faster data loading (specially for employee module)
Initials based profile pictures
Re-designed login page
Re-designed user profile page
Improvements to filtering
New REST endpoints for employee qualifications

🐛 Bug fixes
Fixed, issue with managers being able to create performance reviews for employees who are not their direct reports
Fixed, issues related to using full profile image instead of using smaller version of profile image
Changing third gender to other
Improvements and fixes for internal frontend data caching
This commit is contained in:
Thilina Pituwala
2020-10-31 19:02:37 +01:00
parent 86b8345505
commit b1df0037db
29343 changed files with 867614 additions and 2191082 deletions
+21
View File
@@ -0,0 +1,21 @@
; This file is for unifying the coding style for different editors and IDEs.
; More information at http://editorconfig.org
root = true
[*]
end_of_line = lf
[*.php]
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.bat]
end_of_line = crlf
[*.yml]
indent_style = space
indent_size = 2
+38
View File
@@ -0,0 +1,38 @@
================
Authors of PHPMD
================
Main Authors/Maintainers
------------------------
- Manuel Pichler (Since 2009)
Contributors
------------
- Volker Dusch (Since 2010) / https://github.com/edorian
- timmartin (Since 2010) / https://github.com/timmartin
- Sebastian Bergmann (Since 2011) / https://github.com/sebastianbergmann
- Zsolt Takacs (Since 2011) / https://github.com/zstakacs
- Che Hodgins (Since 2011) / https://github.com/chehodgins
- Gennadiy Litvinyuk (Since 2011) / https://github.com/gennadiylitvinyuk
- Francis Besset (Since 2011) / https://github.com/francisbesset
- zerkalica (Since 2012) / https://github.com/zerkalica
- palbertini (Since 2012) / https://github.com/palbertini
- bahulneel (Since 2012) / https://github.com/bahulneel
- Willem Stuursma (Since 2012) / https://github.com/willemstuursma
- Nimlhug (Since 2012) / https://github.com/Nimlhug
- A. Martin Llano (Since 2012) / https://github.com/amllano
- Juan Basso (Since 2012) / https://github.com/jrbasso
- Brian Ridley (Since 2013) / https://github.com/ptlis
- Radosław Mejer (Since 2014) / https://github.com/radmen
- Tobias Nyholm (Since 2014) / https://github.com/Nyholm
- Gasillo (Since 2014) / https://github.com/Gasillo
- Marc Würth (Since 2014) / https://github.com/ravage84
..
Local Variables:
mode: rst
fill-column: 79
End:
vim: et syn=rst tw=79
+486
View File
@@ -0,0 +1,486 @@
phpmd-2.3.2 (2015/09/24)
========================
With this release we make the Symfony dependency superfluous.
- Implemented #312: No more hard Symfony dependency. Implemented in
commit #1da75aa.
phpmd-2.3.1 (2015/09/22)
========================
Bugfix release for issue #311 introduced with the 2.3.0 release.
- Fixed #311: Property "allow-underscore-test" does not exist. Fixed
in commit #0db4a3e.
phpmd-2.3.0 (2015/09/22)
========================
This new release contains several contributed bugfixes and additions
to PHPMD. Beside that we now have better support for language
constructs in the upcoming PHP 7.
- Fixed #272: Improve type hint. Fixed in commit #724bf76.
- Fixed #293: Declared missing method in abstract class Fixed in
commit #9b806f6.
- Fixed #297: Complete fix for timezone warning. Fixed in commit
#227d469.
- Fixed #301: Fix mixed up links in documentation. Fixed in commit
#4bc4eeb.
- Fixed #304: Fix #303, change if condition order. Fixed in commit
#3376c73.
- Implemented #232: Three new features about references, includes and
include-paths Implemented in commit #180848f.
- Implemented #241: Fix of UnusedPrivateMethod chained method calls.
Implemented in commit #7e02f38.
- Implemented #257: Add option to allow having an undercore in test
methods. Implemented in commit #3cbe76d.
- Implemented #265: Search for development code Implemented in commit
#dfa6872.
- Implemented #273: Add TooManyPublicMethods rule. Implemented in
commit #b862f1f.
- Implemented #291: Define the version constraints of deps in Composer
using the caret operator. Implemented in commit #586ccfc.
- Implemented #306: Use new Travis infrastructure. Implemented in
commit #cd1308e.
phpmd-2.2.3 (2015/05/27)
========================
Bugfix release that closes issues and adds some improvements to phpmd.
- Fixed #285: Corrected HTML TR closing tag Fixed in commit #df6280f.
- Fixed link to rules documentation Fixed in commit #20a0142.
- Implemented #281: Code cleanup Implemented in commit #5e94a65.
- Underlying PDepend version bumped. Implemented in commit #f4ddb8a.
phpmd-2.2.2 (2015/03/26)
========================
Bugfix release that closes some issues in phpmd's core and in the
project documentation.
- Fixed #271: Fix cp error in doc Fixed in commit #b73dd32.
- Fixed #270: Fixing namespace issue for OutOfBoundsException Fixed in
commit #0d4bed1.
- Fixed #80: Out ot the box usage in combination with composer of all
rules failes throws error Property $exceptions does not exist. Fixed
in commit #0d4bed1.
phpmd-2.2.1 (2015/03/01)
========================
This release integration several pull requests and closes and handful
of issues.
- Fixed #237: Display type correctly for constructors Fixed in commit
#49f19d8.
- Fixed #238: Fix link to rulesets Fixed in commit #829d110.
- Fixed #244: Fix typos in type hints Fixed in commit #b5a04ce.
- Fixed #245: Fix CamelCase vs camelCase issue in the docs Fixed in
commit #6cd03ce.
- Implemented #210: Added editorconfig Implemented in commit #22a73a7.
- Implemented #211: Added phpcs as development dependency Implemented
in commit #441398d.
- Implemented #214: Short method name exceptions Implemented in commit
#55b799b.
- Implemented #225: Refactor - remove right side whitespaces
Implemented in commit #c12fffa.
- Implemented #242: Unused "use" statement removed from RuleViolation
class Implemented in commit #966ce38.
- Implemented #243: Unused private property removed. Implemented in
commit #121d43b.
- Implemented #246: Improve WMC documentation Implemented in commit
#b1e9be9.
- Implemented #249: Remove redundant line Implemented in commit
#a9bd6cb.
phpmd-2.2.0 (2015/01/25)
========================
Closes an issue with recent symfony versions
- Fixed #226: Fixed error message for StaticAccess Fixed in commit
#efa1dcd.
- Fixed #216: Refactor - removed right side spaces Fixed in commit
#422345e.
- Implemented #221: Ignore php4 style ctor in interfaces and
namespaces Implemented in commit #b248315.
- Implemented #220: Skip check for ConstructorWithNameAsEnclosingClass
when in an interface or namespace Implemented in commit #b248315.
- Implemented #219: Do not trigger UnusedFormalParameter with some
magic methods. Implemented in commit #4d3b154.
- Implemented #218: Allow any future minor version of Symfony2 2.5
components. Implemented in commit #6317043.
- Implemented #215: Improved composer.json Implemented in commit
#6da3358.
- Implemented #196: Composer Compatible for symfony >= 2.5 and <
master/dev. Implemented in commit #6317043.
- Implemented #208: Appveyor CI for Windows Implemented in commit
#05210b6.
- Implemented #207: Added a contribution guide Implemented in commit
#d6de6a5.
- Implemented #205: Removed all @version annotations Implemented in
commit #5b1fcef.
- Implemented #204: Removed all traces of "PHP Version 5" in the file
header DocBlock Implemented in commit #c36897b.
- Implemented #203: Some improvements to the README Implemented in
commit #cc354ed.
- Implemented #201: Added the missing cleancode section to the
website. Implemented in commit #ead3368.
- Implemented #200: StaticAccess - ability to add exceptions for
specific class names Implemented in commit #b428516.
- Implemented #199: Changed the OutOfBounds exceptions when getting a
property Implemented in commit #0dad28d.
- Implemented #198: Allow unused foreach variables Implemented in
commit #98bed5a.
- Implemented #197: Allow underscore camelcase property name
Implemented in commit #6eb7dcd.
- Implemented #152: Update DepthOfInheritance.php: Using the right
condition and naming of property. Implemented in commit #e59053c.
- Implemented #97: Fixed typo in rule ElseExpression CDATA Implemented
in commit #7593f17.
phpmd-2.1.3 (2014/09/25)
========================
Bug fix release.
- Fixed #195: Missing version number in composer.json file replaced
with build.properties version number. Fixed in commit #7b8d13f.
phpmd-2.1.2 (2014/09/25)
========================
This release closes several minor issues and integrates some
outstanding pull requests.
- Fixed #164: Fixed IRC link Fixed in commit #84f2d8a.
- Fixed #165: Removed lie regarding PEAR Fixed in commit #74b9f84.
- Fixed #85: Documentation changes, fixed typo in PHPMD's online
documentation. Fixed in commit #f954dcf.
- Fixed #190: Updating composer.json Fixed in commit #45c55d8.
- Fixed #191: Superglobals are not named in CamelCase Fixed in commit
#b18ffbb.
- Fixed #192: Fix a typo. These are the 'design rules' not the 'code
size rules Fixed in commit #1eb321d.
- Implemented #182: Tweak with CamelCase matching inheritDoc
Implemented in commit #9271fc6.
- Implemented #189: Missing composer install documentation Implemented
in commit #450f91c.
phpmd-2.1.1 (2014/09/09)
========================
- Fixed #181: 404 error on your website release area
- Fixed #168: --version argument doesn't return version Fixed in
commit #3f56c37.
- Implemented #183: exceptions for CamelCaseVariableName and
UnusedLocalVariable Implemented in commit #5f9e8a2.
phpmd-2.1.0 (2014/09/08)
========================
This integrates several outstanding pull requests.
- Fixed #118: Fix [Naming]: Trait can have method same as trait's name
Fixed in commit #f93be40.
- Fixed #177: Get XML contents before parsing Fixed in commit
#e081088.
- Implemented #150: Fix for unused variables rules when handling
namespace compact() Implemented in commit #ffab9fc.
- Implemented #154: Added PHP 5.6 and HHVM to travis.yml Implemented
in commit #b5cdc74.
- Implemented #159: Allow a single underscore at the beginning
Implemented in commit #d0779c2.
- Implemented #100: Quick change to add support for exclude-pattern in
a ruleset Implemented in commit #6257a83.
- Implemented #117: --exclude not working Implemented in commit
#6257a83.
phpmd-2.0.0 (2014/05/21)
========================
This is major release of PHPMD which utilizes 2.0 engine of PDepend.
- Fixed #111: Changelog with old releases and invalid dates removed.
Fixed in commit #cdfbb8f.
- Implemented #40: Allow multiple report files Now it is possible to
render multiple report files during a single PHPMD run, just add:
--reportfile-xml report.xml --reportfile-html report.html
--reportfile-text report.txt to the PHP command line call.
Implemented in commit #e16c38c.
- Implemented #61: UnusedLocalVariable fix for compact handling in
Symfony2 Implemented in commit #a1dc403.
- Implemented #119: PDepend 2.0 support Implemented in commit
#8c3ebe1.
- Implemented #122: Add: New parameter 'ignore-whitespace' to
LongClass and LongMethod rules Implemented in commit #19c4da8.
phpmd-1.5.0 (2013/07/26)
========================
This release closes some PHP 5.4 related issues.
- Fixed #87: Fix: PHP Fatal error: Call to a member function
isInstanceOf() on a non-object Fixed in commit #9ab3b6d.
- Fixed #81: Fix error when using entire ruleset "Naming" Fixed in
commit #a473345.
- Fixed #91: (tiny) documentation typo fix Fixed in commit #2a3d304.
- Implemented #66: Added support for short variable name exceptions
Implemented in commit #1484e22.
- Implemented #73: Show available formats and rulesets Implemented in
commit #86560ce.
phpmd-1.4.1 (2012/12/14)
========================
This release integrates several pull requests.
- Fixed #56: package.xml date invalid: 2011/02/12. Fixed in commit
#575fe7b.
- Implemented #10: Fix UnusedLocalVariable to recognize compact
function. Implemented in commit #e478912.
- Implemented #58: Skip "unused formal parameter" checking when method
signature has been annotated as inherited using @inheritdoc.
Implemented in commit #158e1f5.
phpmd-1.4.0 (2012/09/07)
========================
This release integrates some longer pending pull requests and smaller
bugfixes. One major addition is support for Composer as distribution
channel.
- Fixed #51: Fixed handling of traits. Fixed in commit #22b523c.
- Implemented #11: Add getStringProperty($name) to AbstractRule.php.
Implemented in commit #b7d659f.
- Implemented #12: Update README.rst on cmd line arguments.
Implemented in commit #458d566.
- Implemented #53: Added getStringProperty and rule-setting to change
TooManyMethods ignore Regexp. Implemented in commit #bc795b6.
- Implemented #10: Provide PHPMD as composer dependency on
packagist.org. Implemented in commit #3622bb8.
phpmd-1.3.3 (2012/02/29)
========================
This release closes an issue introduced with the last release. It
closes one more regression related to PHP's memory_limit and the
Suhosin patch.
- Fixed fatal error due to bug in memory_limit modification code.
Fixed in commit #e8b546d.
phpmd-1.3.2 (2012/02/25)
========================
This release closes a minor issue in PHP_PMD's memory handling when it
is run in a PHP environment that uses the Suhosin patch and the
suhosin.memory_limit setting.
- Fixed #25450811: Alert disable memory_limit Fixed in commit
#19e4fc5.
phpmd-1.3.1 (2012/02/16)
========================
The 1.3.1 release of PHPMD closes one critical bug in PHPMD, that
causes a fatal error due to the xdebug max_nesting_level setting for
very deep self calls on methods.
- Fixed #24975295: Fatal: Maximum function nesting level reached in
ASTNode.php:425 Fixed in commit #f6550df.
phpmd-1.3.0 (2012/02/04)
========================
Version 1.3.0 now depends on PHP_Depend 1.0.0 which has support for
all the new language constructs introduced with PHP 5.4. Additionally
this release contains some minor fixes for PHPMD's rule violation
messages.
phpmd-1.2.1 (2011/10/04)
========================
The 1.2.1 release of PHPMD closes several minor issues and bugs.
Beside that we have added a contribution by Francis Besset with
additions rules for PHPMD. Finally we have updated the utilized
PHP_Depend version to a newer release.
- Fixed #14990109: False detection of unused variable Fixed in commit
#183fbd5.
- Fixed #23278127: PHPMD should exclude unused parameters from
inherited methods Fixed in commit #d162b21.
- Fixed #9355859: PHP_Depend exceptions are silently ignored Fixed in
commit #d3d553f.
- Implemented #11055167: Move PHPUnit annotations from method doc
block to class doc block Implemented in commit #7bcddde.
- Added Superglobals rule in Controversial Implemented in commit
#7176e74.
- Added rules to check CamelCase Implemented in commit #1c3c260.
phpmd-1.2.0 (2011/09/27)
========================
Version 1.2.0 is a small feature release of PHPMD that introduces the
new command line option --strict. This options forces PHPMD to apply
all rules, even if a source node contains the @SuppressWarnings
annotation.
- Controverial PHPMD rule that checks if the project under test does
not utilize PHP's super globals. Implemented in commit #0e60fb9.
- Implemented #18462127: PHPMD needs a *strict* mode. Implemented in
commit #b066b44.
phpmd-1.1.1 (2011/06/30)
========================
Version 1.1.1 of PHPMD is a pure Bugfix release that fixes an issue in
PHPMD's package manifest. This bug prevents Pyrus the PEAR2 installer
from installing PHPMD.
- Fixed #10096717: Bug in PHPMD's package manifest file. Fixed in
commit #f063bc9.
phpmd-1.1.0 (2011/03/20)
========================
Version 1.1.0 of PHPMD was released on March the 20th 2011. The key
features for this release were two new rules. The first one utilizes
the Coupling Between Objects (CBO) metric to detect strongly coupled
classes. The second one detects the usage of PHP's questionable 'goto'
statement. Beside that we have closed a minor bug in the LongVariable
rule, where also private properties with descriptive names were
reported. And finally we have replaced deprecated PHPUnit features in
the PHPMD's test suite, so that PHPMD's tests should now work with
PHPUnit 3.4.x and 3.5.x without deprecated warnings.
- Fixed #10096717: LongVariable rule should not apply on private
properties. Fixed in commit #f063bc9.
- Implemented #10474873: Add rule for PHP's goto statement.
Implemented in commit #2745a20.
- Implemented #10474987: Implement rule for CBO metric. Implemented in
commit #14277b4.
- Implemented #11012465: Replace deprecated PHPUnit features in test
suite. Implemented in commit #4adb88d.
phpmd-1.0.1 (2011/02/12)
========================
- Fixed #9930643: The include_path does not match with PHP_Depend's
new directory layout. Fixed in commit #531be78.
- Fixed #9626017: Clear temporary resources after a test has finished.
Fixed in commit #b385f15.
phpmd-1.0.0 (2011/02/05)
========================
- Fixed #9626017: Clear temporary resources after a test has finished.
Fixed in commit #b385f15.
- New source layout that follows maven's conventions for the directory
structure of a product.
- Switched to PHPUnit 3.5.x as testing framework
phpmd-0.2.8 (2010/11/25)
========================
- Improved help text for the PHPMD command line. Thanks to Volker
Dusch for this contribution. https://github.com/edorian/phpmd
- PHPMD is now compatible with next PHP_Depend release 0.10.0
phpmd-0.2.7 (2010/09/01)
========================
- Fixed #36: @SupressWarnings annotation does not work for
UnusedPrivateMethod rule. Fixed in commit #284.
- Fixed #35: Stream Writer closes STDOUT. Fixed in commit #286.
- Fixed #33: PEAR package.xml does not @php_bin@ and @bin_dir@ on
phpmd.bat. Fixed in commit #264.
phpmd-0.2.6 (2010/07/03)
========================
- Fixed #28: Unused local variable and unused parameter rule produces
false positives. Fixed in commit #245.
- Implemented #24: Implement Depth Of Inheritance Rule. Implemented in
commit #253.
- Implemented #25: Implement Number of Children Rule. Implemented in
commit #252.
- Implemented #26: Implement Rule that detects the usage of PHP's
eval() function. Implemented in commit #251.
- Implemented #27: Implement Rule that detects the usage of PHP's
exit() expression. Implemented in commit #250.
- Implemented #30: New option --version added to PHPMD's command line
interface. Implemented in commit #246.
- Names of several command line options unified with PHPUnit and
PHPCPD. The --ignore option is now --exclude and --extensions is now
--suffixes.
phpmd-0.2.5 (2010/04/03)
========================
- Fixed #17: Do not return success exit code when PHPMD detects rule
violations in analyzed source code. Fixed in commit #226.
- Fixed #19: Super globals were detected as unused variables. Fixed in
commit #218.
- Fixed #20: Local static variables were treated as unused variables.
Fixed in commit #219.
- Implemented #12: Add rule for the Weighted Methods Per Class Metric.
Implemented in commit #228.
- Implemented #16: Alternative syntax for properties in rule set files
implemented. Implemented in commit #220.
phpmd-0.2.4 (2010/03/08)
========================
- E_NOTICE bug fix in naming rule.
phpmd-0.2.3 (2010/03/04)
========================
- Fixed #6: PHP Tokenizer required but no error when installing.
- Fixed #7: UnusedLocalVariable ruleset incorrectly flags variables as
unused when used inside double quoted string. Fixed in commit #187.
- Fixed #14: ExcessivePublicCount rule should utilize PHP_Depend's cis
metric. Fixed in commit #203.
- Fixed #15: ExcessivePublicCount rule is never used. Fixed in commit
#202.
- Implemented #9: Add support for "Suppress warnings" annotations.
Implemented in commit #200.
- Implemented #10: Support for exclude element in rule-set files
added. Implemented in commit #189.
- Implemented #13: Implement naming rules, e.g. short variables,
parameter etc.
phpmd-0.2.2 (2010/01/20)
========================
- Small change to the command line interface, which did not return an
exit code != 0 when an exception occured.
phpmd-0.2.1 (2010/01/05)
========================
- Implemented #5: Allow multiple input files/directories. Implemented
in commit #158.
- Additional unit tests for multiple components added.
phpmd-0.2.0 (2009/12/30)
========================
- Implemented #2: Support for unused code fules completed. Implemented
in commit #134.
- Implemented #3: Text renderer implemented.
- Implemented #4: Implement a html renderer. Implemented in commit
#139.
- Several performance improvements.
phpmd-0.1.0 (2009/12/20)
========================
Initial release
+43
View File
@@ -0,0 +1,43 @@
How to Contribute
=================
The PHPMD project welcomes your contribution. There are several ways to help out:
* Create an [issue](https://github.com/phpmd/phpmd/issues/) on GitHub,
if you have found a bug or have an idea for a feature
* Write test cases for open bug issues
* Write patches for open bug/feature issues
* Participate on the PHPMD IRC Channel
There are a few guidelines that we need contributors to follow, so that we have a
chance of keeping on top of things.
* The code must follow the [PSR-2 coding standard](http://www.php-fig.org/psr/psr-2/).
* All code changes should be covered by unit tests
Issues
------
* Submit an [issue](https://github.com/phpmd/phpmd/issues/)
* Make sure it does not already exist.
* Clearly describe the issue including steps to reproduce, when it is a bug.
* Make sure you note the PHPMD version you use.
Coding Standard
---------------
Make sure your code changes comply with the PSR-2 coding standard by
using [PHP Codesniffer](https://github.com/squizlabs/PHP_CodeSniffer)
from within your PHPMD folder:
vendor/bin/phpcs -p --extensions=php --standard=PSR2 src > phpcs.txt
Check the ``phpcs.txt`` once it finished.
Additional Resources
--------------------
* [Existing issues](https://github.com/phpmd/phpmd/issues/)
* [General GitHub documentation](https://help.github.com/)
* [GitHub pull request documentation](https://help.github.com/send-pull-requests/)
* [PHPMD IRC Channel on freenode.org](http://webchat.freenode.net/?channels=phpmd)
+31
View File
@@ -0,0 +1,31 @@
Copyright (c) 2008-2014, Manuel Pichler <mapi@phpmd.org>.
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 Manuel Pichler nor the names of his
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.
+156
View File
@@ -0,0 +1,156 @@
PHPMD
=====
PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD. PHPMD can be seen as an user friendly frontend application for the raw metrics stream measured by PHP Depend.
http://phpmd.org
.. image:: https://poser.pugx.org/phpmd/phpmd/v/stable.svg
:target: https://packagist.org/packages/phpmd/phpmd
:alt: Latest Stable Version
.. image:: https://poser.pugx.org/phpmd/phpmd/license.svg
:target: https://packagist.org/packages/phpmd/phpmd
:alt: License
.. image:: https://travis-ci.org/phpmd/phpmd.svg?branch=master
:target: https://travis-ci.org/phpmd/phpmd
:alt: Travis Build Status
.. image:: https://ci.appveyor.com/api/projects/status/pc08owbun2y00kwk?svg=true
:target: https://ci.appveyor.com/project/phpmd/phpmd
:alt: AppVeyor Build Status
.. image:: https://scrutinizer-ci.com/g/phpmd/phpmd/badges/build.png?b=master
:target: https://scrutinizer-ci.com/g/phpmd/phpmd/build-status/master
:alt: Scrutinizer Build Status
.. image:: https://scrutinizer-ci.com/g/phpmd/phpmd/badges/quality-score.png?b=master
:target: https://scrutinizer-ci.com/g/phpmd/phpmd/?branch=master
:alt: Scrutinizer Code Quality
Installation
------------
See http://phpmd.org/download/index.html
Command line usage
------------------
Type ``phpmd [filename|directory] [report format] [ruleset file]``, i.e: ::
mapi@arwen ~ $ phpmd PHP/Depend/DbusUI/ xml rulesets/codesize.xml
While the ``rulesets/codesize.xml`` ruleset file could look like this::
<?xml version="1.0" encoding="UTF-8" ?>
<pmd version="0.0.1" timestamp="2009-12-19T22:17:18+01:00">
<file name="/projects/pdepend/PHP/Depend/DbusUI/ResultPrinter.php">
<violation beginline="67"
endline="224"
rule="TooManyMethods"
ruleset="Code Size Rules"
package="PHP_Depend\DbusUI"
class="PHP_Depend_DbusUI_ResultPrinter"
priority="3">
This class has too many methods, consider refactoring it.
</violation>
</file>
</pmd>
You can pass a file name or a directory name containing PHP source
code to PHPMD.
The `PHPMD Phar distribution`__ includes the rule set files inside
its archive, even if the "rulesets/codesize.xml" parameter above looks
like a filesystem reference.
__ http://phpmd.org/download/index.html
Command line options
--------------------
- Notice that the default output is in XML, so you can redirect it to
a file and XSLT it or whatever
- You can also use shortened names to refer to the built-in rule sets,
like this: ::
phpmd PHP/Depend/DbusUI/ xml codesize
- The command line interface also accepts the following optional arguments:
- ``--minimumpriority`` - The rule priority threshold; rules with lower
priority than they will not be used.
- ``--reportfile`` - Sends the report output to the specified file,
instead of the default output target ``STDOUT``.
- ``--suffixes`` - Comma-separated string of valid source code filename
extensions, e.g. php,phtml.
- ``--exclude`` - Comma-separated string of patterns that are used to ignore
directories.
- ``--strict`` - Also report those nodes with a @SuppressWarnings annotation.
An example command line: ::
phpmd PHP/Depend/DbusUI xml codesize --reportfile phpmd.xml --suffixes php,phtml
Using multiple rule sets
````````````````````````
PHPMD uses so called rule sets that configure/define a set of rules which will
be applied against the source under test. The default distribution of PHPMD is
already shipped with a few default sets, that can be used out-of-box. You can
call PHPMD's cli tool with a set's name to apply this configuration: ::
~ $ phpmd /path/to/source text codesize
But what if you would like to apply more than one rule set against your source?
You can also pass a list of rule set names, separated by comma to PHPMD's cli
tool: ::
~ $ phpmd /path/to/source text codesize,unusedcode,naming
You can also mix custom `rule set files`__ with build-in rule sets: ::
~ $ phpmd /path/to/source text codesize,/my/rules.xml
__ http://phpmd.org/documentation/creating-a-ruleset.html
That's it. With this behavior you can specify you own combination of rule sets
that will check the source code.
Using multiple source files and folders
```````````````````````````````````````
PHPMD also allowes you to specify multiple source directories in case you want
to create one output for certain parts of your code ::
~ $ phpmd /path/to/code,index.php,/another/place/with/code text codesize
Exit codes
----------
PHPMD's command line tool currently defines three different exit codes.
- *0*, This exit code indicates that everything worked as expected. This means
there was no error/exception and PHPMD hasn't detected any rule violation
in the code under test.
- *1*, This exit code indicates that an error/exception occured which has
interrupted PHPMD during execution.
- *2*, This exit code means that PHPMD has processed the code under test
without the occurence of an error/exception, but it has detected rule
violations in the analyzed source code.
Renderers
---------
At the moment PHPMD comes with the following three renderers:
- *xml*, which formats the report as XML.
- *text*, simple textual format.
- *html*, single HTML file with possible problems.
+25
View File
@@ -0,0 +1,25 @@
build: false
shallow_clone: false
platform: 'x86'
clone_folder: C:\projects\phpmd
branches:
except:
- gh-pages
install:
- cinst -y OpenSSL.Light
- SET PATH=C:\Program Files\OpenSSL;%PATH%
- cinst -y php
- cd c:\tools\php
- copy php.ini-production php.ini
- echo date.timezone="UTC" >> php.ini
- echo extension_dir=ext >> php.ini
- echo extension=php_openssl.dll >> php.ini
- SET PATH=C:\tools\php;%PATH%
- cd C:\projects\phpmd
- php -r "readfile('http://getcomposer.org/installer');" | php
- php composer.phar install --prefer-source --no-interaction
test_script:
- cd C:\projects\phpmd
- vendor\bin\phpunit.bat
+17
View File
@@ -0,0 +1,17 @@
project.dir =
project.uri = phpmd.org
project.name = phpmd
project.version = 2.3.2
project.stability = stable
# Disable pear support
project.pear.uri = pear.example.com
# Default coding standard
codesniffer.standard = PSR2
# Location of the version control system
project.scm.uri = github.com/${project.name}/${project.name}/commit
# Execute the following command for pdepend profiling
profile.command = ${basedir}/src/bin/phpmd '/opt/Sources/PHP/Flow3/Packages/Framework' xml naming,codesize,unusedcode,design --reportfile pmd.xml
+54
View File
@@ -0,0 +1,54 @@
{
"name": "phpmd/phpmd",
"description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.",
"keywords": [
"phpmd",
"pdepend",
"pmd",
"mess detection",
"mess detector"
],
"type": "project",
"license": "BSD-3-Clause",
"homepage": "http://phpmd.org/",
"authors": [
{
"name": "Manuel Pichler",
"homepage": "https://github.com/manuelpichler",
"email": "github@manuel-pichler.de",
"role": "Project Founder"
},
{
"name": "Marc Würth",
"homepage": "https://github.com/ravage84",
"email": "ravage@bluewin.ch",
"role": "Project Maintainer"
},
{
"name": "Other contributors",
"homepage": "https://github.com/phpmd/phpmd/graphs/contributors",
"role": "Contributors"
}
],
"support": {
"irc": "irc://irc.freenode.org/phpmd"
},
"minimum-stability" : "stable",
"require": {
"php": ">=5.3.0",
"pdepend/pdepend": "~2.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0",
"squizlabs/php_codesniffer": "^2.0"
},
"autoload": {
"psr-0": {
"PHPMD\\": "src/main/php"
}
},
"bin": ["src/bin/phpmd"],
"scripts": {
"test": "phpunit"
}
}
+122
View File
@@ -0,0 +1,122 @@
#!/usr/bin/env php
<?php
use PHPMD\TextUI\Command;
if (file_exists(__DIR__ . '/../../../../autoload.php')) {
// phpmd is part of a composer installation
require_once __DIR__ . '/../../../../autoload.php';
} else {
require_once __DIR__ . '/../../vendor/autoload.php';
// PEAR installation workaround
if (strpos('@package_version@', '@package_version') === 0) {
set_include_path(
dirname(__FILE__) . '/../main/php' .
PATH_SEPARATOR .
dirname(__FILE__) . '/../../vendor/pdepend/pdepend/src/main/php' .
PATH_SEPARATOR .
'.'
);
}
}
if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC');
}
class_alias('PHPMD\\AbstractNode', 'PHP_PMD_AbstractNode');
class_alias('PHPMD\\AbstractRenderer', 'PHP_PMD_AbstractRenderer');
class_alias('PHPMD\\AbstractRule', 'PHP_PMD_AbstractRule');
class_alias('PHPMD\\Parser', 'PHP_PMD_Parser');
class_alias('PHPMD\\ParserFactory', 'PHP_PMD_ParserFactory');
class_alias('PHPMD\\ProcessingError', 'PHP_PMD_ProcessingError');
class_alias('PHPMD\\Report', 'PHP_PMD_Report');
class_alias('PHPMD\\Rule', 'PHP_PMD_Rule');
class_alias('PHPMD\\RuleClassFileNotFoundException', 'PHP_PMD_RuleClassFileNotFoundException');
class_alias('PHPMD\\RuleClassNotFoundException', 'PHP_PMD_RuleClassNotFoundException');
class_alias('PHPMD\\RuleSet', 'PHP_PMD_RuleSet');
class_alias('PHPMD\\RuleSetFactory', 'PHP_PMD_RuleSetFactory');
class_alias('PHPMD\\RuleSetNotFoundException', 'PHP_PMD_RuleSetNotFoundException');
class_alias('PHPMD\\RuleViolation', 'PHP_PMD_RuleViolation');
class_alias('PHPMD\\Node\\AbstractCallableNode', 'PHP_PMD_Node_AbstractCallable');
class_alias('PHPMD\\Node\\AbstractNode', 'PHP_PMD_Node_AbstractNode');
class_alias('PHPMD\\Node\\AbstractTypeNode', 'PHP_PMD_Node_AbstractType');
class_alias('PHPMD\\Node\\ASTNode', 'PHP_PMD_Node_ASTNode');
class_alias('PHPMD\\Node\\Annotation', 'PHP_PMD_Node_Annotation');
class_alias('PHPMD\\Node\\Annotations', 'PHP_PMD_Node_Annotations');
class_alias('PHPMD\\Node\\ClassNode', 'PHP_PMD_Node_Class');
class_alias('PHPMD\\Node\\FunctionNode', 'PHP_PMD_Node_Function');
class_alias('PHPMD\\Node\\InterfaceNode', 'PHP_PMD_Node_Interface');
class_alias('PHPMD\\Node\\MethodNode', 'PHP_PMD_Node_Method');
class_alias('PHPMD\\Node\\TraitNode', 'PHP_PMD_Node_Trait');
class_alias('PHPMD\\Renderer\\HTMLRenderer', 'PHP_PMD_Renderer_HTMLRenderer');
class_alias('PHPMD\\Renderer\\TextRenderer', 'PHP_PMD_Renderer_TextRenderer');
class_alias('PHPMD\\Renderer\\XMLRenderer', 'PHP_PMD_Renderer_XMLRenderer');
class_alias('PHPMD\\Rule\\AbstractLocalVariable', 'PHP_PMD_Rule_AbstractLocalVariable');
class_alias('PHPMD\\Rule\\CyclomaticComplexity', 'PHP_PMD_Rule_CyclomaticComplexity');
class_alias('PHPMD\\Rule\\ClassAware', 'PHP_PMD_Rule_IClassAware');
class_alias('PHPMD\\Rule\\ExcessivePublicCount', 'PHP_PMD_Rule_ExcessivePublicCount');
class_alias('PHPMD\\Rule\\FunctionAware', 'PHP_PMD_Rule_IFunctionAware');
class_alias('PHPMD\\Rule\\InterfaceAware', 'PHP_PMD_Rule_IInterfaceAware');
class_alias('PHPMD\\Rule\\MethodAware', 'PHP_PMD_Rule_IMethodAware');
class_alias('PHPMD\\Rule\\UnusedFormalParameter', 'PHP_PMD_Rule_UnusedFormalParameter');
class_alias('PHPMD\\Rule\\UnusedLocalVariable', 'PHP_PMD_Rule_UnusedLocalVariable');
class_alias('PHPMD\\Rule\\UnusedPrivateField', 'PHP_PMD_Rule_UnusedPrivateField');
class_alias('PHPMD\\Rule\\UnusedPrivateMethod', 'PHP_PMD_Rule_UnusedPrivateMethod');
class_alias('PHPMD\\Rule\\CleanCode\\BooleanArgumentFlag', 'PHP_PMD_Rule_CleanCode_BooleanArgumentFlag');
class_alias('PHPMD\\Rule\\CleanCode\\ElseExpression', 'PHP_PMD_Rule_CleanCode_ElseExpression');
class_alias('PHPMD\\Rule\\CleanCode\\StaticAccess', 'PHP_PMD_Rule_CleanCode_StaticAccess');
class_alias('PHPMD\\Rule\\Controversial\\CamelCaseClassName', 'PHP_PMD_Rule_Controversial_CamelCaseClassName');
class_alias('PHPMD\\Rule\\Controversial\\CamelCaseMethodName', 'PHP_PMD_Rule_Controversial_CamelCaseMethodName');
class_alias('PHPMD\\Rule\\Controversial\\CamelCaseParameterName', 'PHP_PMD_Rule_Controversial_CamelCaseParameterName');
class_alias('PHPMD\\Rule\\Controversial\\CamelCasePropertyName', 'PHP_PMD_Rule_Controversial_CamelCasePropertyName');
class_alias('PHPMD\\Rule\\Controversial\\CamelCaseVariableName', 'PHP_PMD_Rule_Controversial_CamelCaseVariableName');
class_alias('PHPMD\\Rule\\Controversial\\Superglobals', 'PHP_PMD_Rule_Controversial_Superglobals');
class_alias('PHPMD\\Rule\\Design\\CouplingBetweenObjects', 'PHP_PMD_Rule_Design_CouplingBetweenObjects');
class_alias('PHPMD\\Rule\\Design\\DepthOfInheritance', 'PHP_PMD_Rule_Design_DepthOfInheritance');
class_alias('PHPMD\\Rule\\Design\\EvalExpression', 'PHP_PMD_Rule_Design_EvalExpression');
class_alias('PHPMD\\Rule\\Design\\ExitExpression', 'PHP_PMD_Rule_Design_ExitExpression');
class_alias('PHPMD\\Rule\\Design\\GotoStatement', 'PHP_PMD_Rule_Design_GotoStatement');
class_alias('PHPMD\\Rule\\Design\\LongClass', 'PHP_PMD_Rule_Design_LongClass');
class_alias('PHPMD\\Rule\\Design\\LongMethod', 'PHP_PMD_Rule_Design_LongMethod');
class_alias('PHPMD\\Rule\\Design\\LongParameterList', 'PHP_PMD_Rule_Design_LongParameterList');
class_alias('PHPMD\\Rule\\Design\\NpathComplexity', 'PHP_PMD_Rule_Design_NpathComplexity');
class_alias('PHPMD\\Rule\\Design\\NumberOfChildren', 'PHP_PMD_Rule_Design_NumberOfChildren');
class_alias('PHPMD\\Rule\\Design\\TooManyFields', 'PHP_PMD_Rule_Design_TooManyFields');
class_alias('PHPMD\\Rule\\Design\\TooManyMethods', 'PHP_PMD_Rule_Design_TooManyMethods');
class_alias('PHPMD\\Rule\\Design\\WeightedMethodCount', 'PHP_PMD_Rule_Design_WeightedMethodCount');
class_alias('PHPMD\\Rule\\Naming\\BooleanGetMethodName', 'PHP_PMD_Rule_Naming_BooleanGetMethodName');
class_alias('PHPMD\\Rule\\Naming\\ConstantNamingConventions', 'PHP_PMD_Rule_Naming_ConstantNamingConventions');
class_alias('PHPMD\\Rule\\Naming\\ConstructorWithNameAsEnclosingClass', 'PHP_PMD_Rule_Naming_ConstructorWithNameAsEnclosingClass');
class_alias('PHPMD\\Rule\\Naming\\LongVariable', 'PHP_PMD_Rule_Naming_LongVariable');
class_alias('PHPMD\\Rule\\Naming\\ShortMethodName', 'PHP_PMD_Rule_Naming_ShortMethodName');
class_alias('PHPMD\\Rule\\Naming\\ShortVariable', 'PHP_PMD_Rule_Naming_ShortVariable');
class_alias('PHPMD\\TextUI\\Command', 'PHP_PMD_TextUI_Command');
class_alias('PHPMD\\TextUI\\CommandLineOptions', 'PHP_PMD_TextUI_CommandLineOptions');
class_alias('PHPMD\\Writer\\StreamWriter', 'PHP_PMD_Writer_Stream');
// Allow as much memory as possible by default
if (extension_loaded('suhosin') && is_numeric(ini_get('suhosin.memory_limit'))) {
$limit = ini_get('memory_limit');
if (preg_match('(^(\d+)([BKMGT]))', $limit, $match)) {
$shift = array('B' => 0, 'K' => 10, 'M' => 20, 'G' => 30, 'T' => 40);
$limit = ($match[1] * (1 << $shift[$match[2]]));
}
if (ini_get('suhosin.memory_limit') > $limit && $limit > -1) {
ini_set('memory_limit', ini_get('suhosin.memory_limit'));
}
} else {
ini_set('memory_limit', -1);
}
// Check php setup for cli arguments
if (!isset($_SERVER['argv']) && !isset($argv)) {
fwrite(STDERR, 'Please enable the "register_argc_argv" directive in your php.ini', PHP_EOL);
exit(1);
} else if (!isset($argv)) {
$argv = $_SERVER['argv'];
}
// Run command line interface
exit(Command::main($argv));
+45
View File
@@ -0,0 +1,45 @@
@echo off
REM This file is part of PHP Mess Detector.
REM
REM Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
REM All rights reserved.
REM
REM Redistribution and use in source and binary forms, with or without
REM modification, are permitted provided that the following conditions
REM are met:
REM
REM * Redistributions of source code must retain the above copyright
REM notice, this list of conditions and the following disclaimer.
REM
REM * Redistributions in binary form must reproduce the above copyright
REM notice, this list of conditions and the following disclaimer in
REM the documentation and/or other materials provided with the
REM distribution.
REM
REM * Neither the name of Manuel Pichler nor the names of his
REM contributors may be used to endorse or promote products derived
REM from this software without specific prior written permission.
REM
REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
REM "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
REM LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
REM FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
REM COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
REM INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
REM BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
REM LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
REM CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
REM LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
REM ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
REM POSSIBILITY OF SUCH DAMAGE.
REM
REM $Id$
REM
if "%PHPBIN%" == "" set PHPBIN=@php_bin@
if not exist "%PHPBIN%" if "%PHP_PEAR_PHP_BIN%" neq "" goto USE_PEAR_PATH
GOTO RUN
:USE_PEAR_PATH
set PHPBIN=%PHP_PEAR_PHP_BIN%
:RUN
"%PHPBIN%" "@bin_dir@\phpmd" %*
@@ -0,0 +1,21 @@
#!/usr/bin/env php
<?php
/**
* Define global constant that marks this as PHPMD phar release.
*/
define('PHP_PMD_RELEASE', 'phar');
Phar::mapPhar( '${archive.alias}' );
// Configure include path to use this phar
set_include_path('phar://${archive.alias}/' . PATH_SEPARATOR . get_include_path());
if (isset($argv) && realpath($argv[0]) === __FILE__) {
// Load command line utility
include_once 'phar://${archive.alias}/vendor/autoload.php';
// Run command line interface
exit(\PHPMD\TextUI\Command::main($argv));
}
__HALT_COMPILER();
@@ -0,0 +1,306 @@
<?php
/**
* This file is part of PHPMD.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
use PHPMD\Node\ASTNode;
/**
* This is an abstract base class for PHPMD code nodes, it is just a wrapper
* around PDepend's object model.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
abstract class AbstractNode
{
/**
*
* @var \PDepend\Source\AST\ASTArtifact|\PDepend\Source\AST\ASTNode $node
*/
private $node = null;
/**
* The collected metrics for this node.
*
* @var array(string=>mixed) $_metrics
*/
private $metrics = null;
/**
* Constructs a new PHPMD node.
*
* @param \PDepend\Source\AST\ASTArtifact|\PDepend\Source\AST\ASTNode $node
*/
public function __construct($node)
{
$this->node = $node;
}
/**
* The magic call method is used to pipe requests from rules direct
* to the underlying PDepend ast node.
*
* @param string $name
* @param array $args
* @return mixed
* @throws \BadMethodCallException When the underlying PDepend node
* does not contain a method named <b>$name</b>.
*/
public function __call($name, array $args)
{
if (method_exists($this->getNode(), $name)) {
return call_user_func_array(array($this->getNode(), $name), $args);
}
throw new \BadMethodCallException(
sprintf('Invalid method %s() called.', $name)
);
}
/**
* Returns the parent of this node or <b>null</b> when no parent node
* exists.
*
* @return \PHPMD\AbstractNode
*/
public function getParent()
{
if (($node = $this->node->getParent()) === null) {
return null;
}
return new ASTNode($node, $this->getFileName());
}
/**
* Returns a child node at the given index.
*
* @param integer $index The child offset.
*
* @return \PHPMD\Node\ASTNode
*/
public function getChild($index)
{
return new ASTNode(
$this->node->getChild($index),
$this->getFileName()
);
}
/**
* Returns the first child of the given type or <b>null</b> when this node
* has no child of the given type.
*
* @param string $type The searched child type.
* @return \PHPMD\AbstractNode
*/
public function getFirstChildOfType($type)
{
$node = $this->node->getFirstChildOfType('PDepend\Source\AST\AST' . $type);
if ($node === null) {
return null;
}
return new ASTNode($node, $this->getFileName());
}
/**
* Searches recursive for all children of this node that are of the given
* type.
*
* @param string $type The searched child type.
* @return \PHPMD\AbstractNode[]
*/
public function findChildrenOfType($type)
{
$children = $this->node->findChildrenOfType('PDepend\Source\AST\AST' . $type);
$nodes = array();
foreach ($children as $child) {
$nodes[] = new ASTNode($child, $this->getFileName());
}
return $nodes;
}
/**
* Tests if this node represents the the given type.
*
* @param string $type The expected node type.
* @return boolean
*/
public function isInstanceOf($type)
{
$class = 'PDepend\Source\AST\AST' . $type;
return ($this->node instanceof $class);
}
/**
* Returns the image of the underlying node.
*
* @return string
*/
public function getImage()
{
return $this->node->getName();
}
/**
* Returns the source name for this node, maybe a class or interface name,
* or a package, method, function name.
*
* @return string
*/
public function getName()
{
return $this->node->getName();
}
/**
* Returns the begin line for this node in the php source code file.
*
* @return integer
*/
public function getBeginLine()
{
return $this->node->getStartLine();
}
/**
* Returns the end line for this node in the php source code file.
*
* @return integer
*/
public function getEndLine()
{
return $this->node->getEndLine();
}
/**
* Returns the name of the declaring source file.
*
* @return string
*/
public function getFileName()
{
return (string) $this->node->getCompilationUnit()->getFileName();
}
/**
* Returns the wrapped PDepend node instance.
*
* @return \PDepend\Source\AST\ASTArtifact
*/
public function getNode()
{
return $this->node;
}
/**
* Returns a textual representation/name for the concrete node type.
*
* @return string
*/
public function getType()
{
$type = explode('\\', get_class($this));
return preg_replace('(node$)', '', strtolower(array_pop($type)));
}
/**
* This method will return the metric value for the given identifier or
* <b>null</b> when no such metric exists.
*
* @param string $name The metric name or abbreviation.
*
* @return mixed
*/
public function getMetric($name)
{
if (isset($this->metrics[$name])) {
return $this->metrics[$name];
}
return null;
}
/**
* This method will set the metrics for this node.
*
* @param array(string=>mixed) $metrics The collected node metrics.
* @return void
*/
public function setMetrics(array $metrics)
{
if ($this->metrics === null) {
$this->metrics = $metrics;
}
}
/**
* Checks if this node has a suppressed annotation for the given rule
* instance.
*
* @param \PHPMD\Rule $rule
* @return boolean
*/
abstract public function hasSuppressWarningsAnnotationFor(Rule $rule);
/**
* Returns the full qualified name of a class, an interface, a method or
* a function.
*
* @return string
*/
abstract public function getQName();
/**
* Returns the name of the parent type or <b>null</b> when this node has no
* parent type.
*
* @return string
*/
abstract public function getParentName();
/**
* Returns the name of the parent package.
*
* @return string
*/
abstract public function getNamespaceName();
}
@@ -0,0 +1,111 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
/**
* Abstract base class for PHPMD rendering engines.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
abstract class AbstractRenderer
{
/**
* The associated output writer instance.
*
* @var \PHPMD\AbstractWriter
*/
private $writer = null;
/**
* Returns the associated output writer instance.
*
* @return \PHPMD\AbstractWriter
*/
public function getWriter()
{
return $this->writer;
}
/**
* Returns the associated output writer instance.
*
* @param \PHPMD\AbstractWriter $writer
* @return void
*/
public function setWriter(AbstractWriter $writer)
{
$this->writer = $writer;
}
/**
* This method will be called on all renderers before the engine starts the
* real report processing.
*
* @return void
*/
public function start()
{
// Just a hook
}
/**
* This method will be called when the engine has finished the source analysis
* phase.
*
* @param \PHPMD\Report $report
* @return void
*/
abstract public function renderReport(Report $report);
/**
* This method will be called the engine has finished the report processing
* for all registered renderers.
*
* @return void
*/
public function end()
{
// Just a hook
}
}
@@ -0,0 +1,419 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
/**
* This is the abstract base class for pmd rules.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*
* @SuppressWarnings(PHPMD)
*/
abstract class AbstractRule implements Rule
{
/**
* The name for this rule instance.
*
* @var string $_name
*/
private $name = '';
/**
* The violation message text for this rule.
*
* @var string
*/
private $message = '';
/**
* The version since when this rule is available.
*
* @var string
*/
private $since = null;
/**
* An url will external information for this rule.
*
* @var string
*/
private $externalInfoUrl = '';
/**
* An optional description for this rule.
*
* @var string
*/
private $description = '';
/**
* A list of code examples for this rule.
*
* @var array(string)
*/
private $examples = array();
/**
* The name of the parent rule-set instance.
*
* @var string
*/
private $ruleSetName = '';
/**
* The priority of this rule.
*
* @var integer
*/
private $priority = self::LOWEST_PRIORITY;
/**
* Configuration properties for this rule instance.
*
* @var array(string=>string)
*/
private $properties = array();
/**
* The report for object for this rule.
*
* @var \PHPMD\Report
*/
private $report = null;
/**
* Returns the name for this rule instance.
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Sets the name for this rule instance.
*
* @param string $name The rule name.
*
* @return void
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Returns the version since when this rule is available or <b>null</b>.
*
* @return string
*/
public function getSince()
{
return $this->since;
}
/**
* Sets the version since when this rule is available.
*
* @param string $since The version number.
*
* @return void
*/
public function setSince($since)
{
$this->since = $since;
}
/**
* Returns the violation message text for this rule.
*
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* Sets the violation message text for this rule.
*
* @param string $message The violation message
*
* @return void
*/
public function setMessage($message)
{
$this->message = $message;
}
/**
* Returns an url will external information for this rule.
*
* @return string
*/
public function getExternalInfoUrl()
{
return $this->externalInfoUrl;
}
/**
* Sets an url will external information for this rule.
*
* @param string $externalInfoUrl The info url.
*
* @return void
*/
public function setExternalInfoUrl($externalInfoUrl)
{
$this->externalInfoUrl = $externalInfoUrl;
}
/**
* Returns the description text for this rule instance.
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Sets the description text for this rule instance.
*
* @param string $description The description text.
*
* @return void
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* Returns a list of examples for this rule.
*
* @return array(string)
*/
public function getExamples()
{
return $this->examples;
}
/**
* Adds a code example for this rule.
*
* @param string $example The code example.
*
* @return void
*/
public function addExample($example)
{
$this->examples[] = $example;
}
/**
* Returns the priority of this rule.
*
* @return integer
*/
public function getPriority()
{
return $this->priority;
}
/**
* Set the priority of this rule.
*
* @param integer $priority The rule priority
*
* @return void
*/
public function setPriority($priority)
{
$this->priority = $priority;
}
/**
* Returns the name of the parent rule-set instance.
*
* @return string
*/
public function getRuleSetName()
{
return $this->ruleSetName;
}
/**
* Sets the name of the parent rule set instance.
*
* @param string $ruleSetName The rule-set name.
*
* @return void
*/
public function setRuleSetName($ruleSetName)
{
$this->ruleSetName = $ruleSetName;
}
/**
* Returns the violation report for this rule.
*
* @return \PHPMD\Report
*/
public function getReport()
{
return $this->report;
}
/**
* Sets the violation report for this rule.
*
* @param \PHPMD\Report $report
* @return void
*/
public function setReport(Report $report)
{
$this->report = $report;
}
/**
* Adds a configuration property to this rule instance.
*
* @param string $name
* @param string $value
* @return void
*/
public function addProperty($name, $value)
{
$this->properties[$name] = $value;
}
/**
* Returns the value of a configured property as a boolean or throws an
* exception when no property with <b>$name</b> exists.
*
* @param string $name
* @return boolean
* @throws \OutOfBoundsException When no property for <b>$name</b> exists.
*/
public function getBooleanProperty($name)
{
if (isset($this->properties[$name])) {
return in_array($this->properties[$name], array('true', 'on', 1));
}
throw new \OutOfBoundsException('Property "' . $name . '" does not exist.');
}
/**
* Returns the value of a configured property as an integer or throws an
* exception when no property with <b>$name</b> exists.
*
* @param string $name
* @return integer
* @throws \OutOfBoundsException When no property for <b>$name</b> exists.
*/
public function getIntProperty($name)
{
if (isset($this->properties[$name])) {
return (int) $this->properties[$name];
}
throw new \OutOfBoundsException('Property "' . $name . '" does not exist.');
}
/**
* Returns the raw string value of a configured property or throws an
* exception when no property with <b>$name</b> exists.
*
* @param string $name
* @return string
* @throws \OutOfBoundsException When no property for <b>$name</b> exists.
*/
public function getStringProperty($name)
{
if (isset($this->properties[$name])) {
return $this->properties[$name];
}
throw new \OutOfBoundsException('Property "' . $name . '" does not exist.');
}
/**
* This method adds a violation to all reports for this violation type and
* for the given <b>$node</b> instance.
*
* @param \PHPMD\AbstractNode $node
* @param array $args
* @param mixed $metric
* @return void
*/
protected function addViolation(
AbstractNode $node,
array $args = array(),
$metric = null
) {
$search = array();
$replace = array();
foreach ($args as $index => $value) {
$search[] = '{' . $index . '}';
$replace[] = $value;
}
$message = str_replace($search, $replace, $this->message);
$ruleViolation = new RuleViolation($this, $node, $message, $metric);
$this->report->addRuleViolation($ruleViolation);
}
/**
* This method should implement the violation analysis algorithm of concrete
* rule implementations. All extending classes must implement this method.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
abstract public function apply(AbstractNode $node);
}
@@ -0,0 +1,60 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
/**
* This is abstract base class for an output writer.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
abstract class AbstractWriter
{
/**
* Writes a data string to the concrete output.
*
* @param string $data
* @return void
*/
abstract public function write($data);
}
@@ -0,0 +1,150 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Node;
use PHPMD\Rule;
/**
* Wrapper around a PHP_Depend ast node.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class ASTNode extends \PHPMD\AbstractNode
{
/**
* The source file of this node.
*
* @var string
*/
private $fileName = null;
/**
* Constructs a new ast node instance.
*
* @param \PDepend\Source\AST\ASTNode $node
* @param string $fileName
*/
public function __construct(\PDepend\Source\AST\ASTNode $node, $fileName)
{
parent::__construct($node);
$this->fileName = $fileName;
}
/**
* Checks if this node has a suppressed annotation for the given rule
* instance.
*
* @param \PHPMD\Rule $rule
* @return boolean
* @SuppressWarnings("PMD.UnusedFormalParameter")
*/
public function hasSuppressWarningsAnnotationFor(Rule $rule)
{
return false;
}
/**
* Returns the source name for this node, maybe a class or interface name,
* or a package, method, function name.
*
* @return string
*/
public function getName()
{
return $this->getImage();
}
/**
* Returns the image of the underlying node.
*
* @return string
*/
public function getImage()
{
return $this->getNode()->getImage();
}
/**
* Returns the name of the declaring source file.
*
* @return string
*/
public function getFileName()
{
return $this->fileName;
}
/**
* Returns the name of the parent type or <b>null</b> when this node has no
* parent type.
*
* @return string
*/
public function getParentName()
{
return null;
}
/**
* Returns the name of the parent namespace.
*
* @return string
*/
public function getNamespaceName()
{
return null;
}
/**
* Returns the full qualified name of a class, an interface, a method or
* a function.
*
* @return string
*/
public function getQName()
{
return null;
}
}
@@ -0,0 +1,74 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Node;
use PDepend\Source\AST\AbstractASTCallable;
/**
* Abstract base class for PHP_Depend function and method wrappers.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
abstract class AbstractCallableNode extends AbstractNode
{
/**
* Constructs a new callable wrapper.
*
* @param \PDepend\Source\AST\AbstractASTCallable $node
*/
public function __construct(AbstractASTCallable $node)
{
parent::__construct($node);
}
/**
* Returns the number of parameters in the callable signature.
*
* @return integer
*/
public function getParameterCount()
{
return count($this->getNode()->getParameters());
}
}
@@ -0,0 +1,76 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Node;
use PHPMD\Rule;
/**
* Abstract base class for all code nodes.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
abstract class AbstractNode extends \PHPMD\AbstractNode
{
/**
* Annotations associated with node instance.
*
* @var \PHPMD\Node\Annotations
*/
private $annotations = null;
/**
* Checks if this node has a suppressed annotation for the given rule
* instance.
*
* @param \PHPMD\Rule $rule
* @return boolean
*/
public function hasSuppressWarningsAnnotationFor(Rule $rule)
{
if ($this->annotations === null) {
$this->annotations = new Annotations($this);
}
return $this->annotations->suppresses($rule);
}
}
@@ -0,0 +1,138 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Node;
use PDepend\Source\AST\AbstractASTClassOrInterface;
/**
* Abstract base class for classes and interfaces.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
abstract class AbstractTypeNode extends AbstractNode
{
/**
* Constructs a new generic class or interface node.
*
* @param \PDepend\Source\AST\AbstractASTClassOrInterface $node
*/
public function __construct(AbstractASTClassOrInterface $node)
{
parent::__construct($node);
}
/**
* Returns an <b>array</b> with all methods defined in the context class or
* interface.
*
* @return \PHPMD\Node\MethodNode[]
*/
public function getMethods()
{
$methods = array();
foreach ($this->getNode()->getMethods() as $method) {
$methods[] = new MethodNode($method);
}
return $methods;
}
/**
* Returns an array with the names of all methods within this class or
* interface node.
*
* @return array(string)
*/
public function getMethodNames()
{
$names = array();
foreach ($this->getNode()->getMethods() as $method) {
$names[] = $method->getName();
}
return $names;
}
/**
* Returns the number of constants declared in this type.
*
* @return integer
*/
public function getConstantCount()
{
return $this->getNode()->getConstants()->count();
}
/**
* Returns the name of the parent namespace.
*
* @return string
*/
public function getNamespaceName()
{
return $this->getNode()->getNamespace()->getName();
}
/**
* Returns the name of the parent type or <b>null</b> when this node has no
* parent type.
*
* @return string
*/
public function getParentName()
{
return null;
}
/**
* Returns the full qualified name of a class, an interface, a method or
* a function.
*
* @return string
*/
public function getQName()
{
return sprintf('%s\\%s', $this->getNamespaceName(), $this->getName());
}
}
@@ -0,0 +1,115 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Node;
use PHPMD\Rule;
/**
* Simple code annotation class.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class Annotation
{
/**
* Name of the suppress warnings annotation.
*/
const SUPPRESS_ANNOTATION = 'SuppressWarnings';
/**
* The annotation name.
*
* @var string
*/
private $name = null;
/**
* The annotation value.
*
* @var string
*/
private $value = null;
/**
* Constructs a new annotation instance.
*
* @param string $name
* @param string $value
*/
public function __construct($name, $value)
{
$this->name = $name;
$this->value = trim($value, '" ');
}
/**
* Checks if this annotation suppresses the given rule.
*
* @param \PHPMD\Rule $rule
* @return boolean
*/
public function suppresses(Rule $rule)
{
if ($this->name === self::SUPPRESS_ANNOTATION) {
return $this->isSuppressed($rule);
}
return false;
}
/**
* Checks if this annotation suppresses the given rule.
*
* @param \PHPMD\Rule $rule
* @return boolean
*/
private function isSuppressed(Rule $rule)
{
if (in_array($this->value, array('PHPMD', 'PMD'))) {
return true;
} elseif (strpos($this->value, 'PMD.' . $rule->getName()) !== false) {
return true;
}
return (stripos($rule->getName(), $this->value) !== false);
}
}
@@ -0,0 +1,100 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Node;
use PHPMD\Rule;
/**
* Collection of code annotations.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class Annotations
{
/**
* Detected annotations.
*
* @var \PHPMD\Node\Annotation[]
*/
private $annotations = array();
/**
* Regexp used to extract code annotations.
*
* @var string
*/
private $regexp = '(@([a-z_][a-z0-9_]+)\(([^\)]+)\))i';
/**
* Constructs a new collection instance.
*
* @param \PHPMD\AbstractNode $node
*/
public function __construct(\PHPMD\AbstractNode $node)
{
preg_match_all($this->regexp, $node->getDocComment(), $matches);
foreach (array_keys($matches[0]) as $i) {
$name = $matches[1][$i];
$value = trim($matches[2][$i], '" ');
$this->annotations[] = new Annotation($name, $value);
}
}
/**
* Checks if one of the annotations suppresses the given rule.
*
* @param \PHPMD\Rule $rule
* @return boolean
*/
public function suppresses(Rule $rule)
{
foreach ($this->annotations as $annotation) {
if ($annotation->suppresses($rule)) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,69 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Node;
use PDepend\Source\AST\ASTClass;
/**
* Wrapper around PHP_Depend's class objects.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class ClassNode extends AbstractTypeNode
{
/**
* The type of this class.
*/
const CLAZZ = __CLASS__;
/**
* Constructs a new class wrapper node.
*
* @param \PDepend\Source\AST\ASTClass $node
*/
public function __construct(ASTClass $node)
{
parent::__construct($node);
}
}
@@ -0,0 +1,96 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Node;
use PDepend\Source\AST\ASTFunction;
/**
* Wrapper around a PDepend function node.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class FunctionNode extends AbstractCallableNode
{
/**
* Constructs a new function wrapper.
*
* @param \PDepend\Source\AST\ASTFunction $node
*/
public function __construct(ASTFunction $node)
{
parent::__construct($node);
}
/**
* Returns the name of the parent package.
*
* @return string
*/
public function getNamespaceName()
{
return $this->getNode()->getNamespace()->getName();
}
/**
* Returns the name of the parent type or <b>null</b> when this node has no
* parent type.
*
* @return string
*/
public function getParentName()
{
return null;
}
/**
* Returns the full qualified name of a class, an interface, a method or
* a function.
*
* @return string
*/
public function getQName()
{
return sprintf('%s\\%s()', $this->getNamespaceName(), $this->getName());
}
}
@@ -0,0 +1,64 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Node;
use PDepend\Source\AST\ASTInterface;
/**
* Wrapper around PHP_Depend's interface objects.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class InterfaceNode extends AbstractTypeNode
{
/**
* Constructs a new interface wrapper instance.
*
* @param \PDepend\Source\AST\ASTInterface $node
*/
public function __construct(ASTInterface $node)
{
parent::__construct($node);
}
}
@@ -0,0 +1,183 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Node;
use PDepend\Source\AST\ASTMethod;
use PDepend\Source\AST\ASTClass;
use PDepend\Source\AST\ASTTrait;
use PHPMD\Rule;
/**
* Wrapper around a PHP_Depend method node.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class MethodNode extends AbstractCallableNode
{
/**
* Constructs a new method wrapper.
*
* @param \PDepend\Source\AST\ASTMethod $node
*/
public function __construct(ASTMethod $node)
{
parent::__construct($node);
}
/**
* Returns the name of the parent package.
*
* @return string
*/
public function getNamespaceName()
{
return $this->getNode()->getParent()->getNamespace()->getName();
}
/**
* Returns the name of the parent type or <b>null</b> when this node has no
* parent type.
*
* @return string
*/
public function getParentName()
{
return $this->getNode()->getParent()->getName();
}
/**
* Returns the full qualified name of a class, an interface, a method or
* a function.
*
* @return string
*/
public function getQName()
{
return sprintf(
'%s\\%s::%s()',
$this->getNamespaceName(),
$this->getParentName(),
$this->getName()
);
}
/**
* Returns <b>true</b> when the underlying method is declared as abstract or
* is declared as child of an interface.
*
* @return boolean
*/
public function isAbstract()
{
return $this->getNode()->isAbstract();
}
/**
* Checks if this node has a suppressed annotation for the given rule
* instance.
*
* @param \PHPMD\Rule $rule
* @return boolean
*/
public function hasSuppressWarningsAnnotationFor(Rule $rule)
{
if (parent::hasSuppressWarningsAnnotationFor($rule)) {
return true;
}
return $this->getParentType()->hasSuppressWarningsAnnotationFor($rule);
}
/**
* Returns the parent class or interface instance.
*
* @return \PHPMD\Node\AbstractTypeNode
*/
public function getParentType()
{
$parentNode = $this->getNode()->getParent();
if ($parentNode instanceof ASTTrait) {
return new TraitNode($parentNode);
}
if ($parentNode instanceof ASTClass) {
return new ClassNode($parentNode);
}
return new InterfaceNode($parentNode);
}
/**
* Returns <b>true</b> when this method is the initial method declaration.
* Otherwise this method will return <b>false</b>.
*
* @return boolean
* @since 1.2.1
*/
public function isDeclaration()
{
if ($this->isPrivate()) {
return true;
}
$methodName = strtolower($this->getName());
$parentNode = $this->getNode()->getParent();
foreach ($parentNode->getInterfaces() as $parentType) {
$methods = $parentType->getAllMethods();
if (isset($methods[$methodName])) {
return false;
}
}
if (is_object($parentType = $parentNode->getParentClass())) {
$methods = $parentType->getAllMethods();
if (isset($methods[$methodName])) {
return false;
}
}
return true;
}
}
@@ -0,0 +1,66 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Node;
use PDepend\Source\AST\ASTTrait;
/**
* Wrapper around PHP_Depend's interface objects.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class TraitNode extends AbstractTypeNode
{
/**
* Constructs a new interface wrapper instance.
*
* @param \PDepend\Source\AST\ASTTrait $node
*/
public function __construct(ASTTrait $node)
{
parent::__construct($node);
}
}
@@ -0,0 +1,239 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
/**
* This is the main facade of the PHP PMD application
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class PHPMD
{
/**
* The current PHPMD version.
*/
const VERSION = '@project.version@';
/**
* List of valid file extensions for analyzed files.
*
* @var array(string)
*/
private $fileExtensions = array('php', 'php3', 'php4', 'php5', 'inc');
/**
* List of exclude directory patterns.
*
* @var array(string)
*/
private $ignorePatterns = array('.git', '.svn', 'CVS', '.bzr', '.hg', 'SCCS');
/**
* The input source file or directory.
*
* @var string
*/
private $input;
/**
* This property will be set to <b>true</b> when an error or a violation
* was found in the processed source code.
*
* @var boolean
* @since 0.2.5
*/
private $violations = false;
/**
* Additional options for PHPMD or one of it's parser backends.
*
* @var array
* @since 1.2.0
*/
private $options = array();
/**
* This method will return <b>true</b> when the processed source code
* contains violations.
*
* @return boolean
* @since 0.2.5
*/
public function hasViolations()
{
return $this->violations;
}
/**
* Returns the input source file or directory path.
*
* @return string
*/
public function getInput()
{
return $this->input;
}
/**
* Returns an array with valid php source file extensions.
*
* @return array(string)
* @since 0.2.0
*/
public function getFileExtensions()
{
return $this->fileExtensions;
}
/**
* Sets a list of filename extensions for valid php source code files.
*
* @param array(string) $fileExtensions Extensions without leading dot.
*
* @return void
*/
public function setFileExtensions(array $fileExtensions)
{
$this->fileExtensions = $fileExtensions;
}
/**
* Returns an array with string patterns that mark a file path as invalid.
*
* @return array(string)
* @since 0.2.0
*/
public function getIgnorePattern()
{
return $this->ignorePatterns;
}
/**
* Sets a list of ignore patterns that is used to exclude directories from
* the source analysis.
*
* @param array(string) $ignorePatterns List of ignore patterns.
*
* @return void
*/
public function setIgnorePattern(array $ignorePatterns)
{
$this->ignorePatterns = array_merge(
$this->ignorePatterns,
$ignorePatterns
);
}
/**
* Returns additional options for PHPMD or one of it's parser backends.
*
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* Sets additional options for PHPMD or one of it's parser backends.
*
* @param array $options Additional backend or PHPMD options.
* @return void
*/
public function setOptions(array $options)
{
$this->options = $options;
}
/**
* This method will process all files that can be found in the given input
* path. It will apply rules defined in the comma-separated <b>$ruleSets</b>
* argument. The result will be passed to all given renderer instances.
*
* @param string $inputPath
* @param string $ruleSets
* @param \PHPMD\AbstractRenderer[] $renderers
* @param \PHPMD\RuleSetFactory $ruleSetFactory
* @return void
*/
public function processFiles(
$inputPath,
$ruleSets,
array $renderers,
RuleSetFactory $ruleSetFactory
) {
// Merge parsed excludes
$this->ignorePatterns = array_merge($this->ignorePatterns, $ruleSetFactory->getIgnorePattern($ruleSets));
$this->input = $inputPath;
$report = new Report();
$factory = new ParserFactory();
$parser = $factory->create($this);
foreach ($ruleSetFactory->createRuleSets($ruleSets) as $ruleSet) {
$parser->addRuleSet($ruleSet);
}
$report->start();
$parser->parse($report);
$report->end();
foreach ($renderers as $renderer) {
$renderer->start();
}
foreach ($renderers as $renderer) {
$renderer->renderReport($report);
}
foreach ($renderers as $renderer) {
$renderer->end();
}
$this->violations = !$report->isEmpty();
}
}
@@ -0,0 +1,309 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
use PDepend\Engine;
use PDepend\Report\CodeAwareGenerator;
use PDepend\Source\ASTVisitor\AbstractASTVisitor;
use PDepend\Metrics\Analyzer;
use PDepend\Source\AST\ASTClass;
use PDepend\Source\AST\ASTMethod;
use PDepend\Source\AST\ASTInterface;
use PDepend\Source\AST\ASTFunction;
use PDepend\Source\AST\ASTArtifactList;
use PHPMD\Node\ClassNode;
use PHPMD\Node\FunctionNode;
use PHPMD\Node\InterfaceNode;
use PHPMD\Node\MethodNode;
/**
* Simple wrapper around the php depend engine.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class Parser extends AbstractASTVisitor implements CodeAwareGenerator
{
/**
* The analysing rule-set instance.
*
* @var \PHPMD\RuleSet[]
*/
private $ruleSets = array();
/**
* The metric containing analyzer instances.
*
* @var \PDepend\Metrics\AnalyzerNodeAware[]
*/
private $analyzers = array();
/**
* The raw PDepend code nodes.
*
* @var \PDepend\Source\AST\ASTArtifactList
*/
private $artifacts = null;
/**
* The violation report used by this PDepend adapter.
*
* @var \PHPMD\Report
*/
private $report = null;
/**
* The wrapped PDepend Engine instance.
*
* @var \PDepend\Engine
*/
private $pdepend = null;
/**
* Constructs a new parser adapter instance.
*
* @param \PDepend\Engine $pdepend The context php depend instance.
*/
public function __construct(Engine $pdepend)
{
$this->pdepend = $pdepend;
}
/**
* Parses the projects source and reports all detected errors and violations.
*
* @param \PHPMD\Report $report
* @return void
*/
public function parse(Report $report)
{
$this->setReport($report);
$this->pdepend->addReportGenerator($this);
$this->pdepend->analyze();
foreach ($this->pdepend->getExceptions() as $exception) {
$report->addError(new ProcessingError($exception->getMessage()));
}
}
/**
* Adds a new analysis rule-set to this adapter.
*
* @param \PHPMD\RuleSet $ruleSet
* @return void
*/
public function addRuleSet(RuleSet $ruleSet)
{
$this->ruleSets[] = $ruleSet;
}
/**
* Sets the violation report used by the rule-set.
*
* @param \PHPMD\Report $report
* @return void
*/
public function setReport(Report $report)
{
$this->report = $report;
}
/**
* Adds an analyzer to log. If this logger accepts the given analyzer it
* with return <b>true</b>, otherwise the return value is <b>false</b>.
*
* @param \PDepend\Metrics\Analyzer $analyzer The analyzer to log.
*
* @return boolean
*/
public function log(Analyzer $analyzer)
{
$this->analyzers[] = $analyzer;
}
/**
* Closes the logger process and writes the output file.
*
* @return void
* @throws \PDepend\Report\NoLogOutputException If the no log target exists.
*/
public function close()
{
// Set max nesting level, because we may get really deep data structures
ini_set('xdebug.max_nesting_level', 8192);
foreach ($this->artifacts as $node) {
$node->accept($this);
}
}
/**
* Returns an <b>array</b> with accepted analyzer types. These types can be
* concrete analyzer classes or one of the descriptive analyzer interfaces.
*
* @return array(string)
*/
public function getAcceptedAnalyzers()
{
return array(
'pdepend.analyzer.cyclomatic_complexity',
'pdepend.analyzer.node_loc',
'pdepend.analyzer.npath_complexity',
'pdepend.analyzer.inheritance',
'pdepend.analyzer.node_count',
'pdepend.analyzer.hierarchy',
'pdepend.analyzer.crap_index',
'pdepend.analyzer.code_rank',
'pdepend.analyzer.coupling',
'pdepend.analyzer.class_level',
'pdepend.analyzer.cohesion',
);
}
/**
* Visits a class node.
*
* @param \PDepend\Source\AST\ASTClass $node
* @return void
*/
public function visitClass(ASTClass $node)
{
if (!$node->isUserDefined()) {
return;
}
$this->apply(new ClassNode($node));
parent::visitClass($node);
}
/**
* Visits a function node.
*
* @param \PDepend\Source\AST\ASTFunction $node
* @return void
*/
public function visitFunction(ASTFunction $node)
{
if ($node->getCompilationUnit()->getFileName() === null) {
return;
}
$this->apply(new FunctionNode($node));
}
/**
* Visits an interface node.
*
* @param \PDepend\Source\AST\ASTInterface $node
* @return void
*/
public function visitInterface(ASTInterface $node)
{
if (!$node->isUserDefined()) {
return;
}
$this->apply(new InterfaceNode($node));
parent::visitInterface($node);
}
/**
* Visits a method node.
*
* @param \PDepend\Source\AST\ASTMethod $node
* @return void
*/
public function visitMethod(ASTMethod $node)
{
if ($node->getCompilationUnit()->getFileName() === null) {
return;
}
$this->apply(new MethodNode($node));
}
/**
* Sets the context code nodes.
*
* @param \PDepend\Source\AST\ASTArtifactList $artifacts
* @return void
*/
public function setArtifacts(ASTArtifactList $artifacts)
{
$this->artifacts = $artifacts;
}
/**
* Applies all rule-sets to the given <b>$node</b> instance.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
private function apply(AbstractNode $node)
{
$this->collectMetrics($node);
foreach ($this->ruleSets as $ruleSet) {
$ruleSet->setReport($this->report);
$ruleSet->apply($node);
}
}
/**
* Collects the collected metrics for the given node and adds them to the
* <b>$node</b>.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
private function collectMetrics(AbstractNode $node)
{
$metrics = array();
$pdepend = $node->getNode();
foreach ($this->analyzers as $analyzer) {
$metrics = array_merge($metrics, $analyzer->getNodeMetrics($pdepend));
}
$node->setMetrics($metrics);
}
}
@@ -0,0 +1,183 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
use PDepend\Application;
use PDepend\Engine;
use PDepend\Input\ExcludePathFilter;
use PDepend\Input\ExtensionFilter;
/**
* Simple factory that is used to return a ready to use PDepend instance.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class ParserFactory
{
/**
* Mapping between phpmd option names and those used by pdepend.
*
* @var array
*/
private $phpmd2pdepend = array(
'coverage' => 'coverage-report'
);
/**
* Creates the used {@link \PHPMD\Parser} analyzer instance.
*
* @param \PHPMD\PHPMD $phpmd
* @return \PHPMD\Parser
*/
public function create(PHPMD $phpmd)
{
$pdepend = $this->createInstance();
$pdepend = $this->init($pdepend, $phpmd);
return new Parser($pdepend);
}
/**
* Creates a clean php depend instance with some base settings.
*
* @return \PDepend\Engine
*/
private function createInstance()
{
$application = new Application();
if (file_exists(getcwd() . '/pdepend.xml')) {
$application->setConfigurationFile(getcwd() . '/pdepend.xml');
} elseif (file_exists(getcwd() . '/pdepend.xml.dist')) {
$application->setConfigurationFile(getcwd() . '/pdepend.xml.dist');
}
return $application->getEngine();
}
/**
* Configures the given PDepend\Engine instance based on some user settings.
*
* @param \PDepend\Engine $pdepend
* @param \PHPMD\PHPMD $phpmd
* @return \PDepend\Engine
*/
private function init(Engine $pdepend, PHPMD $phpmd)
{
$this->initOptions($pdepend, $phpmd);
$this->initInput($pdepend, $phpmd);
$this->initIgnores($pdepend, $phpmd);
$this->initExtensions($pdepend, $phpmd);
return $pdepend;
}
/**
* Configures the input source.
*
* @param \PDepend\Engine $pdepend
* @param \PHPMD\PHPMD $phpmd
* @return void
*/
private function initInput(Engine $pdepend, PHPMD $phpmd)
{
foreach (explode(',', $phpmd->getInput()) as $path) {
if (is_dir(trim($path))) {
$pdepend->addDirectory(trim($path));
} else {
$pdepend->addFile(trim($path));
}
}
}
/**
* Initializes the ignored files and path's.
*
* @param \PDepend\Engine $pdepend
* @param \PHPMD\PHPMD $phpmd
* @return void
*/
private function initIgnores(Engine $pdepend, PHPMD $phpmd)
{
if (count($phpmd->getIgnorePattern()) > 0) {
$pdepend->addFileFilter(
new ExcludePathFilter($phpmd->getIgnorePattern())
);
}
}
/**
* Initializes the accepted php source file extensions.
*
* @param \PDepend\Engine $pdepend
* @param \PHPMD\PHPMD $phpmd
* @return void
*/
private function initExtensions(Engine $pdepend, PHPMD $phpmd)
{
if (count($phpmd->getFileExtensions()) > 0) {
$pdepend->addFileFilter(
new ExtensionFilter($phpmd->getFileExtensions())
);
}
}
/**
* Initializes additional options for pdepend.
*
* @param \PDepend\Engine $pdepend
* @param \PHPMD\PHPMD $phpmd
* @return void
*/
private function initOptions(Engine $pdepend, PHPMD $phpmd)
{
$options = array();
foreach (array_filter($phpmd->getOptions()) as $name => $value) {
if (isset($this->phpmd2pdepend[$name])) {
$options[$this->phpmd2pdepend[$name]] = $value;
}
}
$pdepend->setOptions($options);
}
}
@@ -0,0 +1,118 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.2.1
*/
namespace PHPMD;
/**
* Simple data class that we use to keep parsing errors for the report renderer.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.2.1
*/
class ProcessingError
{
/**
* The original processing error message.
*
* @var string
*/
private $message;
/**
* The source file where the processing error occurred.
*
* @var string
*/
private $file;
/**
* Constructs a new processing error instance.
*
* @param string $message
*/
public function __construct($message)
{
$this->message = $message;
$this->file = $this->extractFile($message);
}
/**
* Returns the source file where the processing error occurred.
*
* @return string
*/
public function getFile()
{
return $this->file;
}
/**
* Returns the original processing error message.
*
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* Evil hack that extracts the source file from the original exception
* message. This method should be removed once we have added the source file
* as a mandatory property to PDepend's exceptions.
*
* @param string $message
* @return string
*/
private function extractFile($message)
{
preg_match('(file: (.+)\.$| file "([^"]+)")', $message, $match);
$match = array_values(array_filter($match));
if (isset($match[1])) {
return $match[1];
}
return '';
}
}
@@ -0,0 +1,184 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Renderer;
use PHPMD\AbstractRenderer;
use PHPMD\Report;
/**
* This renderer output a simple html file with all found violations and suspect
* software artifacts.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class HTMLRenderer extends AbstractRenderer
{
/**
* This method will be called on all renderers before the engine starts the
* real report processing.
*
* @return void
*/
public function start()
{
$writer = $this->getWriter();
$writer->write('<html><head><title>PHPMD</title></head><body>');
$writer->write(PHP_EOL);
$writer->write('<center><h1>PHPMD report</h1></center>');
$writer->write('<center><h2>Problems found</h2></center>');
$writer->write(PHP_EOL);
$writer->write('<table align="center" cellspacing="0" cellpadding="3">');
$writer->write('<tr>');
$writer->write('<th>#</th><th>File</th><th>Line</th><th>Problem</th>');
$writer->write('</tr>');
$writer->write(PHP_EOL);
}
/**
* This method will be called when the engine has finished the source analysis
* phase.
*
* @param \PHPMD\Report $report
* @return void
*/
public function renderReport(Report $report)
{
$index = 0;
$writer = $this->getWriter();
foreach ($report->getRuleViolations() as $violation) {
$writer->write('<tr');
if (++$index % 2 === 1) {
$writer->write(' bgcolor="lightgrey"');
}
$writer->write('>');
$writer->write(PHP_EOL);
$writer->write('<td align="center">');
$writer->write($index);
$writer->write('</td>');
$writer->write(PHP_EOL);
$writer->write('<td>');
$writer->write(htmlentities($violation->getFileName()));
$writer->write('</td>');
$writer->write(PHP_EOL);
$writer->write('<td align="center" width="5%">');
$writer->write($violation->getBeginLine());
$writer->write('</td>');
$writer->write(PHP_EOL);
$writer->write('<td>');
if ($violation->getRule()->getExternalInfoUrl()) {
$writer->write('<a href="');
$writer->write($violation->getRule()->getExternalInfoUrl());
$writer->write('">');
}
$writer->write(htmlentities($violation->getDescription()));
if ($violation->getRule()->getExternalInfoUrl()) {
$writer->write('</a>');
}
$writer->write('</td>');
$writer->write(PHP_EOL);
$writer->write('</tr>');
$writer->write(PHP_EOL);
}
$writer->write('</table>');
$this->glomProcessingErrors($report);
}
/**
* This method will be called the engine has finished the report processing
* for all registered renderers.
*
* @return void
*/
public function end()
{
$writer = $this->getWriter();
$writer->write('</body></html>');
}
/**
* This method will render a html table with occurred processing errors.
*
* @param \PHPMD\Report $report
* @return void
* @since 1.2.1
*/
private function glomProcessingErrors(Report $report)
{
if (false === $report->hasErrors()) {
return;
}
$writer = $this->getWriter();
$writer->write('<hr />');
$writer->write('<center><h3>Processing errors</h3></center>');
$writer->write('<table align="center" cellspacing="0" cellpadding="3">');
$writer->write('<tr><th>File</th><th>Problem</th></tr>');
$index = 0;
foreach ($report->getErrors() as $error) {
$writer->write('<tr');
if (++$index % 2 === 1) {
$writer->write(' bgcolor="lightgrey"');
}
$writer->write('>');
$writer->write('<td>' . $error->getFile() . '</td>');
$writer->write('<td>' . htmlentities($error->getMessage()) . '</td>');
$writer->write('</tr>' . PHP_EOL);
}
$writer->write('</table>');
}
}
@@ -0,0 +1,86 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Renderer;
use PHPMD\AbstractRenderer;
use PHPMD\Report;
/**
* This renderer output a textual log with all found violations and suspect
* software artifacts.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class TextRenderer extends AbstractRenderer
{
/**
* This method will be called when the engine has finished the source analysis
* phase.
*
* @param \PHPMD\Report $report
* @return void
*/
public function renderReport(Report $report)
{
$writer = $this->getWriter();
$writer->write(PHP_EOL);
foreach ($report->getRuleViolations() as $violation) {
$writer->write($violation->getFileName());
$writer->write(':');
$writer->write($violation->getBeginLine());
$writer->write("\t");
$writer->write($violation->getDescription());
$writer->write(PHP_EOL);
}
foreach ($report->getErrors() as $error) {
$writer->write($error->getFile());
$writer->write("\t-\t");
$writer->write($error->getMessage());
$writer->write(PHP_EOL);
}
}
}
@@ -0,0 +1,158 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Renderer;
use PHPMD\AbstractRenderer;
use PHPMD\PHPMD;
use PHPMD\Report;
/**
* This class will render a Java-PMD compatible xml-report.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class XMLRenderer extends AbstractRenderer
{
/**
* Temporary property that holds the name of the last rendered file, it is
* used to detect the next processed file.
*
* @var string
*/
private $fileName = null;
/**
* This method will be called on all renderers before the engine starts the
* real report processing.
*
* @return void
*/
public function start()
{
$this->getWriter()->write('<?xml version="1.0" encoding="UTF-8" ?>');
$this->getWriter()->write(PHP_EOL);
}
/**
* This method will be called when the engine has finished the source analysis
* phase.
*
* @param \PHPMD\Report $report
* @return void
*/
public function renderReport(Report $report)
{
$writer = $this->getWriter();
$writer->write('<pmd version="' . PHPMD::VERSION . '" ');
$writer->write('timestamp="' . date('c') . '">');
$writer->write(PHP_EOL);
foreach ($report->getRuleViolations() as $violation) {
$fileName = $violation->getFileName();
if ($this->fileName !== $fileName) {
// Not first file
if ($this->fileName !== null) {
$writer->write(' </file>' . PHP_EOL);
}
// Store current file name
$this->fileName = $fileName;
$writer->write(' <file name="' . $fileName . '">' . PHP_EOL);
}
$rule = $violation->getRule();
$writer->write(' <violation');
$writer->write(' beginline="' . $violation->getBeginLine() . '"');
$writer->write(' endline="' . $violation->getEndLine() . '"');
$writer->write(' rule="' . $rule->getName() . '"');
$writer->write(' ruleset="' . $rule->getRuleSetName() . '"');
$this->maybeAdd('package', $violation->getNamespaceName());
$this->maybeAdd('externalInfoUrl', $rule->getExternalInfoUrl());
$this->maybeAdd('function', $violation->getFunctionName());
$this->maybeAdd('class', $violation->getClassName());
$this->maybeAdd('method', $violation->getMethodName());
//$this->_maybeAdd('variable', $violation->getVariableName());
$writer->write(' priority="' . $rule->getPriority() . '"');
$writer->write('>' . PHP_EOL);
$writer->write(' ' . $violation->getDescription() . PHP_EOL);
$writer->write(' </violation>' . PHP_EOL);
}
// Last file and at least one violation
if ($this->fileName !== null) {
$writer->write(' </file>' . PHP_EOL);
}
foreach ($report->getErrors() as $error) {
$writer->write(' <error filename="');
$writer->write($error->getFile());
$writer->write('" msg="');
$writer->write(htmlspecialchars($error->getMessage()));
$writer->write('" />' . PHP_EOL);
}
$writer->write('</pmd>' . PHP_EOL);
}
/**
* This method will write a xml attribute named <b>$attr</b> to the output
* when the given <b>$value</b> is not an empty string and is not <b>null</b>.
*
* @param string $attr The xml attribute name.
* @param string $value The attribute value.
*
* @return void
*/
private function maybeAdd($attr, $value)
{
if ($value === null || trim($value) === '') {
return;
}
$this->getWriter()->write(' ' . $attr . '="' . $value . '"');
}
}
@@ -0,0 +1,203 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
/**
* The report class collects all found violations and further information about
* a PHPMD run.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class Report
{
/**
* List of rule violations detected in the analyzed source code.
*
* @var \PHPMD\RuleViolation[]
*/
private $ruleViolations = array();
/**
* The start time for this report.
*
* @var float
*/
private $startTime = 0.0;
/**
* The end time for this report.
*
* @var float
*/
private $endTime = 0.0;
/**
* Errors that occurred while parsing the source.
*
* @var array
* @since 1.2.1
*/
private $errors = array();
/**
* Adds a rule violation to this report.
*
* @param \PHPMD\RuleViolation $violation
* @return void
*/
public function addRuleViolation(RuleViolation $violation)
{
$fileName = $violation->getFileName();
if (!isset($this->ruleViolations[$fileName])) {
$this->ruleViolations[$fileName] = array();
}
$beginLine = $violation->getBeginLine();
if (!isset($this->ruleViolations[$fileName][$beginLine])) {
$this->ruleViolations[$fileName][$beginLine] = array();
}
$this->ruleViolations[$fileName][$beginLine][] = $violation;
}
/**
* Returns <b>true</b> when this report does not contain any errors.
*
* @return boolean
* @since 0.2.5
*/
public function isEmpty()
{
return (count($this->ruleViolations) === 0);
}
/**
* Returns an iterator with all occurred rule violations.
*
* @return \Iterator
*/
public function getRuleViolations()
{
// First sort by file name
ksort($this->ruleViolations);
$violations = array();
foreach ($this->ruleViolations as $violationInLine) {
// Second sort is by line number
ksort($violationInLine);
foreach ($violationInLine as $violation) {
$violations = array_merge($violations, $violation);
}
}
return new \ArrayIterator($violations);
}
/**
* Adds a processing error that occurred while parsing the source.
*
* @param \PHPMD\ProcessingError $error
* @return void
* @since 1.2.1
*/
public function addError(ProcessingError $error)
{
$this->errors[] = $error;
}
/**
* Returns <b>true</b> when the report contains at least one processing
* error. Otherwise this method will return <b>false</b>.
*
* @return boolean
* @since 1.2.1
*/
public function hasErrors()
{
return count($this->errors) > 0;
}
/**
* Returns an iterator with all {@link \PHPMD\ProcessingError} that were
* added to this report.
*
* @return \Iterator
* @since 1.2.1
*/
public function getErrors()
{
return new \ArrayIterator($this->errors);
}
/**
* Starts the time tracking of this report instance.
*
* @return void
*/
public function start()
{
$this->startTime = microtime(true) * 1000.0;
}
/**
* Stops the time tracking of this report instance.
*
* @return void
*/
public function end()
{
$this->endTime = microtime(true) * 1000.0;
}
/**
* Returns the total time elapsed for the source analysis.
*
* @return float
*/
public function getElapsedTimeInMillis()
{
return round($this->endTime - $this->startTime);
}
}
@@ -0,0 +1,231 @@
<?php
/**
* This file is part of PHPMD.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
/**
* Base interface for a PHPMD rule.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
interface Rule
{
/**
* The default lowest rule priority.
*/
const LOWEST_PRIORITY = 5;
/**
* Returns the name for this rule instance.
*
* @return string
*/
public function getName();
/**
* Sets the name for this rule instance.
*
* @param string $name
* @return void
*/
public function setName($name);
/**
* Returns the version since when this rule is available or <b>null</b>.
*
* @return string
*/
public function getSince();
/**
* Sets the version since when this rule is available.
*
* @param string $since
* @return void
*/
public function setSince($since);
/**
* Returns the violation message text for this rule.
*
* @return string
*/
public function getMessage();
/**
* Sets the violation message text for this rule.
*
* @param string $message
* @return void
*/
public function setMessage($message);
/**
* Returns an url will external information for this rule.
*
* @return string
*/
public function getExternalInfoUrl();
/**
* Sets an url will external information for this rule.
*
* @param string $externalInfoUrl
* @return void
*/
public function setExternalInfoUrl($externalInfoUrl);
/**
* Returns the description text for this rule instance.
*
* @return string
*/
public function getDescription();
/**
* Sets the description text for this rule instance.
*
* @param string $description
* @return void
*/
public function setDescription($description);
/**
* Returns a list of examples for this rule.
*
* @return array
*/
public function getExamples();
/**
* Adds a code example for this rule.
*
* @param string $example
* @return void
*/
public function addExample($example);
/**
* Returns the priority of this rule.
*
* @return integer
*/
public function getPriority();
/**
* Set the priority of this rule.
*
* @param integer $priority
* @return void
*/
public function setPriority($priority);
/**
* Returns the name of the parent rule-set instance.
*
* @return string
*/
public function getRuleSetName();
/**
* Sets the name of the parent rule set instance.
*
* @param string $ruleSetName
* @return void
*/
public function setRuleSetName($ruleSetName);
/**
* Returns the violation report for this rule.
*
* @return \PHPMD\Report
*/
public function getReport();
/**
* Sets the violation report for this rule.
*
* @param \PHPMD\Report $report
* @return void
*/
public function setReport(\PHPMD\Report $report);
/**
* Adds a configuration property to this rule instance.
*
* @param string $name
* @param string $value
* @return void
*/
public function addProperty($name, $value);
/**
* Returns the value of a configured property as a boolean or throws an
* exception when no property with <b>$name</b> exists.
*
* @param string $name
* @return boolean
* @throws \OutOfBoundsException When no property for <b>$name</b> exists.
*/
public function getBooleanProperty($name);
/**
* Returns the value of a configured property as an integer or throws an
* exception when no property with <b>$name</b> exists.
*
* @param string $name
* @return integer
* @throws \OutOfBoundsException When no property for <b>$name</b> exists.
*/
public function getIntProperty($name);
/**
* This method should implement the violation analysis algorithm of concrete
* rule implementations. All extending classes must implement this method.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node);
}
@@ -0,0 +1,191 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 0.2.6
*/
namespace PHPMD\Rule;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Node\ASTNode;
/**
* Base class for rules that rely on local variables.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 0.2.6
*/
abstract class AbstractLocalVariable extends AbstractRule
{
/**
* PHP super globals that are available in all php scopes, so that they
* can never be unused local variables.
*
* @var array(string=>boolean)
*/
private static $superGlobals = array(
'$argc' => true,
'$argv' => true,
'$_COOKIE' => true,
'$_ENV' => true,
'$_FILES' => true,
'$_GET' => true,
'$_POST' => true,
'$_REQUEST' => true,
'$_SERVER' => true,
'$_SESSION' => true,
'$GLOBALS' => true,
'$HTTP_RAW_POST_DATA' => true,
);
/**
* Tests if the given variable node represents a local variable or if it is
* a static object property or something similar.
*
* @param \PHPMD\Node\ASTNode $variable The variable to check.
* @return boolean
*/
protected function isLocal(ASTNode $variable)
{
return (false === $variable->isThis()
&& $this->isNotSuperGlobal($variable)
&& $this->isRegularVariable($variable)
);
}
/**
* Tests if the given variable represents one of the PHP super globals
* that are available in scopes.
*
* @param \PHPMD\AbstractNode $variable
* @return boolean
*/
protected function isNotSuperGlobal(AbstractNode $variable)
{
return !isset(self::$superGlobals[$variable->getImage()]);
}
/**
* Tests if the given variable node is a regular variable an not property
* or method postfix.
*
* @param \PHPMD\Node\ASTNode $variable
* @return boolean
*/
protected function isRegularVariable(ASTNode $variable)
{
$node = $this->stripWrappedIndexExpression($variable);
$parent = $node->getParent();
if ($parent->isInstanceOf('PropertyPostfix')) {
$primaryPrefix = $parent->getParent();
if ($primaryPrefix->getParent()->isInstanceOf('MemberPrimaryPrefix')) {
return !$primaryPrefix->getParent()->isStatic();
}
return ($parent->getChild(0)->getNode() !== $node->getNode()
|| !$primaryPrefix->isStatic()
);
}
return true;
}
/**
* Removes all index expressions that are wrapped around the given node
* instance.
*
* @param \PHPMD\Node\ASTNode $node
* @return \PHPMD\Node\ASTNode
*/
protected function stripWrappedIndexExpression(ASTNode $node)
{
if (false === $this->isWrappedByIndexExpression($node)) {
return $node;
}
$parent = $node->getParent();
if ($parent->getChild(0)->getNode() === $node->getNode()) {
return $this->stripWrappedIndexExpression($parent);
}
return $node;
}
/**
* Tests if the given variable node os part of an index expression.
*
* @param \PHPMD\Node\ASTNode $node
* @return boolean
*/
protected function isWrappedByIndexExpression(ASTNode $node)
{
return ($node->getParent()->isInstanceOf('ArrayIndexExpression')
|| $node->getParent()->isInstanceOf('StringIndexExpression')
);
}
/**
* PHP is case insensitive so we should compare function names case
* insensitive.
*
* @param \PHPMD\AbstractNode $node
* @param string $name
* @return boolean
*/
protected function isFunctionNameEqual(AbstractNode $node, $name)
{
return (0 === strcasecmp(trim($node->getImage(), '\\'), $name));
}
/**
* AST puts namespace prefix to global functions called from a namespace.
* This method checks if the last part of function fully qualified name is equal to $name
*
* @param \PHPMD\AbstractNode $node
* @param string $name
* @return boolean
*/
protected function isFunctionNameEndingWith(AbstractNode $node, $name)
{
$parts = explode('\\', trim($node->getImage(), '\\'));
return (0 === strcasecmp(array_pop($parts), $name));
}
}
@@ -0,0 +1,53 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule;
/**
* This interface is used to mark a rule implementation as class aware.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
interface ClassAware
{
}
@@ -0,0 +1,85 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\CleanCode;
use PDepend\Source\AST\ASTValue;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* Check for a boolean flag in the method/function signature.
*
* Boolean flags are signs for single responsibility principle violations.
*
* @author Benjamin Eberlei <benjamin@qafoo.com>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class BooleanArgumentFlag extends AbstractRule implements MethodAware, FunctionAware
{
/**
* This method checks if a method/function has boolean flag arguments and warns about them.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($node->findChildrenOfType('FormalParameter') as $param) {
$declarator = $param->getFirstChildOfType('VariableDeclarator');
$value = $declarator->getValue();
if (false === $this->isBooleanValue($value)) {
continue;
}
$this->addViolation($param, array($node->getImage(), $declarator->getImage()));
}
}
private function isBooleanValue(ASTValue $value = null)
{
return $value && $value->isValueAvailable() && ($value->getValue() === true || $value->getValue() === false);
}
}
@@ -0,0 +1,97 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\CleanCode;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* Check if there is an else expression somewhere in the method/function and
* warn about it.
*
* Object Calisthenics teaches us, that an else expression can always be
* avoided by simple guard clause or return statements.
*
* @author Benjamin Eberlei <benjamin@qafoo.com>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class ElseExpression extends AbstractRule implements MethodAware, FunctionAware
{
/**
* This method checks if a method/function uses an else expression and add a violation for each one found.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($node->findChildrenOfType('ScopeStatement') as $scope) {
$parent = $scope->getParent();
if (false === $this->isIfOrElseIfStatement($parent)) {
continue;
}
if (false === $this->isElseScope($scope, $parent)) {
continue;
}
$this->addViolation($scope, array($node->getImage()));
}
}
private function isElseScope($scope, $parent)
{
return (
count($parent->getChildren()) === 3 &&
$scope->getNode() === $parent->getChild(2)->getNode()
);
}
private function isIfOrElseIfStatement($parent)
{
return ($parent->getName() === "if" || $parent->getName() === "elseif");
}
}
@@ -0,0 +1,123 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\CleanCode;
use PDepend\Source\AST\ASTClassOrInterfaceReference;
use PDepend\Source\AST\ASTMethodPostfix;
use PDepend\Source\AST\ASTParentReference;
use PDepend\Source\AST\ASTSelfReference;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* Check if static access is used in a method.
*
* Static access is known to cause hard dependencies between classes
* and is a bad practice.
*
* @author Benjamin Eberlei <benjamin@qafoo.com>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class StaticAccess extends AbstractRule implements MethodAware, FunctionAware
{
/**
* Method checks for use of static access and warns about it.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$exceptions = $this->getExceptionsList();
$nodes = $node->findChildrenOfType('MemberPrimaryPrefix');
foreach ($nodes as $methodCall) {
if (!$this->isStaticMethodCall($methodCall)) {
continue;
}
$className = $methodCall->getChild(0)->getNode()->getImage();
if (in_array($className, $exceptions)) {
continue;
}
$this->addViolation($methodCall, array($className, $node->getName()));
}
}
private function isStaticMethodCall($methodCall)
{
return $methodCall->getChild(0)->getNode() instanceof ASTClassOrInterfaceReference &&
$methodCall->getChild(1)->getNode() instanceof ASTMethodPostfix &&
!$this->isCallingParent($methodCall) &&
!$this->isCallingSelf($methodCall);
}
private function isCallingParent($methodCall)
{
return $methodCall->getChild(0)->getNode() instanceof ASTParentReference;
}
private function isCallingSelf($methodCall)
{
return $methodCall->getChild(0)->getNode() instanceof ASTSelfReference;
}
/**
* Gets array of exceptions from property
*
* @return array
*/
private function getExceptionsList()
{
try {
$exceptions = $this->getStringProperty('exceptions');
} catch (\OutOfBoundsException $e) {
$exceptions = '';
}
return explode(',', $exceptions);
}
}
@@ -0,0 +1,78 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
namespace PHPMD\Rule\Controversial;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
use PHPMD\Rule\InterfaceAware;
/**
* This rule class detects classes not named in CamelCase.
*
* @author Francis Besset <francis.besset@gmail.com>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
class CamelCaseClassName extends AbstractRule implements ClassAware, InterfaceAware
{
/**
* This method checks if a class is not named in CamelCase
* and emits a rule violation.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
if (!preg_match('/^[A-Z][a-zA-Z0-9]*$/', $node->getName())) {
$this->addViolation(
$node,
array(
$node->getName(),
)
);
}
}
}
@@ -0,0 +1,111 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
namespace PHPMD\Rule\Controversial;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\MethodAware;
/**
* This rule class detects methods not named in camelCase.
*
* @author Francis Besset <francis.besset@gmail.com>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
class CamelCaseMethodName extends AbstractRule implements MethodAware
{
protected $ignoredMethods = array(
'__construct',
'__destruct',
'__set',
'__get',
'__call',
'__callStatic',
'__isset',
'__unset',
'__sleep',
'__wakeup',
'__toString',
'__invoke',
'__set_state',
'__clone',
'__debugInfo',
);
/**
* This method checks if a method is not named in camelCase
* and emits a rule violation.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$methodName = $node->getName();
if (!in_array($methodName, $this->ignoredMethods)) {
if (!$this->isValid($methodName)) {
$this->addViolation(
$node,
array(
$methodName,
)
);
}
}
}
private function isValid($methodName)
{
if ($this->getBooleanProperty('allow-underscore-test') && strpos($methodName, 'test') === 0) {
return preg_match('/^test[a-zA-Z0-9]*([_][a-z][a-zA-Z0-9]*)?$/', $methodName);
}
if ($this->getBooleanProperty('allow-underscore')) {
return preg_match('/^[_]?[a-z][a-zA-Z0-9]*$/', $methodName);
}
return preg_match('/^[a-z][a-zA-Z0-9]*$/', $methodName);
}
}
@@ -0,0 +1,80 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
namespace PHPMD\Rule\Controversial;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule class detects parameters not named in camelCase.
*
* @author Francis Besset <francis.besset@gmail.com>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
class CamelCaseParameterName extends AbstractRule implements MethodAware, FunctionAware
{
/**
* This method checks if a parameter is not named in camelCase
* and emits a rule violation.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($node->getParameters() as $parameter) {
if (!preg_match('/^\$[a-z][a-zA-Z0-9]*$/', $parameter->getName())) {
$this->addViolation(
$node,
array(
$parameter->getName(),
)
);
}
}
}
}
@@ -0,0 +1,88 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
namespace PHPMD\Rule\Controversial;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
/**
* This rule class detects properties not named in camelCase.
*
* @author Francis Besset <francis.besset@gmail.com>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
class CamelCasePropertyName extends AbstractRule implements ClassAware
{
/**
* This method checks if a property is not named in camelCase
* and emits a rule violation.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$allowUnderscore = $this->getBooleanProperty('allow-underscore');
$pattern = '/^\$[a-zA-Z][a-zA-Z0-9]*$/';
if ($allowUnderscore == true) {
$pattern = '/^\$[_]?[a-zA-Z][a-zA-Z0-9]*$/';
}
foreach ($node->getProperties() as $property) {
$propertyName = $property->getName();
if (!preg_match($pattern, $propertyName)) {
$this->addViolation(
$node,
array(
$propertyName,
)
);
}
}
}
}
@@ -0,0 +1,100 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
namespace PHPMD\Rule\Controversial;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule class detects variables not named in camelCase.
*
* @author Francis Besset <francis.besset@gmail.com>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
class CamelCaseVariableName extends AbstractRule implements MethodAware, FunctionAware
{
/**
* @var array
*/
private $exceptions = array(
'$php_errormsg',
'$http_response_header',
'$GLOBALS',
'$_SERVER',
'$_GET',
'$_POST',
'$_FILES',
'$_COOKIE',
'$_SESSION',
'$_REQUEST',
'$_ENV',
);
/**
* This method checks if a variable is not named in camelCase
* and emits a rule violation.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($node->findChildrenOfType('Variable') as $variable) {
$image = $variable->getImage();
if (in_array($image, $this->exceptions)) {
continue;
}
if (preg_match('/^\$[a-z][a-zA-Z0-9]*$/', $image)) {
continue;
}
$this->addViolation($node, array($image));
}
}
}
@@ -0,0 +1,93 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
namespace PHPMD\Rule\Controversial;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule class detects the usage of superglobals.
*
* @author Francis Besset <francis.besset@gmail.com>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
class Superglobals extends AbstractRule implements MethodAware, FunctionAware
{
protected $superglobals = array(
'$GLOBALS',
'$_SERVER', '$HTTP_SERVER_VARS',
'$_GET', '$HTTP_GET_VARS',
'$_POST', '$HTTP_POST_VARS',
'$_FILES', '$HTTP_POST_FILES',
'$_COOKIE', '$HTTP_COOKIE_VARS',
'$_SESSION', '$HTTP_SESSION_VARS',
'$_REQUEST',
'$_ENV', '$HTTP_ENV_VARS',
);
/**
* This method checks if a superglobal is used
* and emits a rule violation.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($node->findChildrenOfType('Variable') as $variable) {
if (in_array($variable->getImage(), $this->superglobals)) {
$this->addViolation(
$node,
array(
$node->getName(),
$variable->getImage()
)
);
}
}
}
}
@@ -0,0 +1,82 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
/**
* This rule checks a given method or function against the configured cyclomatic
* complexity threshold.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class CyclomaticComplexity extends AbstractRule implements FunctionAware, MethodAware
{
/**
* This method checks the cyclomatic complexity for the given node against
* a configured threshold.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$threshold = $this->getIntProperty('reportLevel');
$ccn = $node->getMetric('ccn2');
if ($ccn < $threshold) {
return;
}
$this->addViolation(
$node,
array(
$node->getType(),
$node->getName(),
$ccn,
$threshold
)
);
}
}
@@ -0,0 +1,73 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
/**
* This rule class detects violations of Coupling Between Objects metric.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
class CouplingBetweenObjects extends AbstractRule implements ClassAware
{
/**
* This method should implement the violation analysis algorithm of concrete
* rule implementations. All extending classes must implement this method.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$cbo = $node->getMetric('cbo');
if ($cbo >= ($threshold = $this->getIntProperty('minimum'))) {
$this->addViolation($node, array($node->getName(), $cbo, $threshold));
}
}
}
@@ -0,0 +1,89 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
/**
* This rule will detect classes that are to deep in the inheritance tree.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class DepthOfInheritance extends AbstractRule implements ClassAware
{
/**
* This method checks the number of parents for the given class
* node.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
try {
$threshold = $this->getIntProperty('maximum');
$comparision = 1;
} catch (\OutOfBoundsException $e) {
$threshold = $this->getIntProperty('minimum');
$comparision = 2;
}
$dit = $node->getMetric('dit');
if (($comparision === 1 && $dit > $threshold) ||
($comparision === 2 && $dit >= $threshold)
) {
$this->addViolation(
$node,
array(
$node->getType(),
$node->getName(),
$dit,
$threshold
)
);
}
}
}
@@ -0,0 +1,105 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2015, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2015 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Node\MethodNode;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule class detects possible development code fragments that were left
* into the code.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2015 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @see https://github.com/phpmd/phpmd/issues/265
* @since 2.3.0
*/
class DevelopmentCodeFragment extends AbstractRule implements MethodAware, FunctionAware
{
/**
* This method checks if a given function or method contains an eval-expression
* and emits a rule violation when it exists.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($node->findChildrenOfType('FunctionPostfix') as $postfix) {
$image = strtolower($postfix->getImage());
if (false === in_array($image, $this->getSuspectImages())) {
continue;
}
$image = $node->getImage();
if ($node instanceof MethodNode) {
$image = sprintf('%s::%s', $node->getParentName(), $node->getImage());
}
$this->addViolation($postfix, array($node->getType(), $image, $postfix->getImage()));
}
}
/**
* Returns an array with function images that are normally only used during
* development.
*
* @return array
*/
private function getSuspectImages()
{
return array_map(
'strtolower',
array_map(
'trim',
explode(
',',
$this->getStringProperty('unwanted-functions')
)
)
);
}
}
@@ -0,0 +1,71 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule class detects the usage of PHP's eval-expression.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class EvalExpression extends AbstractRule implements MethodAware, FunctionAware
{
/**
* This method checks if a given function or method contains an eval-expression
* and emits a rule violation when it exists.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($node->findChildrenOfType('EvalExpression') as $eval) {
$this->addViolation($eval, array($node->getType(), $node->getName()));
}
}
}
@@ -0,0 +1,71 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule class detects the usage of PHP's exit statement.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class ExitExpression extends AbstractRule implements MethodAware, FunctionAware
{
/**
* This method checks if a given function or method contains an exit-expression
* and emits a rule violation when it exists.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($node->findChildrenOfType('ExitExpression') as $exit) {
$this->addViolation($exit, array($node->getType(), $node->getName()));
}
}
}
@@ -0,0 +1,73 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule class detects the usage of PHP's goto statement.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 1.1.0
*/
class GotoStatement extends AbstractRule implements MethodAware, FunctionAware
{
/**
* This method should implement the violation analysis algorithm of concrete
* rule implementations. All extending classes must implement this method.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($node->findChildrenOfType('GotoStatement') as $goto) {
$this->addViolation($goto, array($node->getType(), $node->getName()));
}
}
}
@@ -0,0 +1,82 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
/**
* This rule class will detect excessive long classes.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class LongClass extends AbstractRule implements ClassAware
{
/**
* This method checks the length of the given class node against a configured
* threshold.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$threshold = $this->getIntProperty('minimum');
$loc = -1;
if ($this->getBooleanProperty('ignore-whitespace')) {
$loc = $node->getMetric('eloc');
}
if (-1 === $loc) {
$loc = $node->getMetric('loc');
}
if ($loc < $threshold) {
return;
}
$this->addViolation($node, array($node->getName(), $loc, $threshold));
}
}
@@ -0,0 +1,92 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule will detect to long methods, those methods are unreadable and in
* many cases the result of copy and paste coding.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class LongMethod extends AbstractRule implements FunctionAware, MethodAware
{
/**
* This method checks the lines of code length for the given function or
* methode node against a configured threshold.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$threshold = $this->getIntProperty('minimum');
$loc = -1;
if ($this->getBooleanProperty('ignore-whitespace')) {
$loc = $node->getMetric('eloc');
}
if (-1 === $loc) {
$loc = $node->getMetric('loc');
}
if ($loc < $threshold) {
return;
}
$this->addViolation(
$node,
array(
$node->getType(),
$node->getName(),
$loc,
$threshold
)
);
}
}
@@ -0,0 +1,83 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule class checks for excessive long function and method parameter lists.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class LongParameterList extends AbstractRule implements FunctionAware, MethodAware
{
/**
* This method checks the number of arguments for the given function or method
* node against a configured threshold.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$threshold = $this->getIntProperty('minimum');
$count = $node->getParameterCount();
if ($count < $threshold) {
return;
}
$this->addViolation(
$node,
array(
$node->getType(),
$node->getName(),
$count,
$threshold
)
);
}
}
@@ -0,0 +1,84 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule will check the NPath-complexity of a method or function against the
* configured threshold.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class NpathComplexity extends AbstractRule implements FunctionAware, MethodAware
{
/**
* This method checks the acyclic complexity for the given node against a
* configured threshold.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$threshold = $this->getIntProperty('minimum');
$npath = $node->getMetric('npath');
if ($npath < $threshold) {
return;
}
$this->addViolation(
$node,
array(
$node->getType(),
$node->getName(),
$npath,
$threshold
)
);
}
}
@@ -0,0 +1,80 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
/**
* This rule will detect class that have to much direct child classes.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class NumberOfChildren extends AbstractRule implements ClassAware
{
/**
* This method checks the number of classes derived from the given class
* node.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$nocc = $node->getMetric('nocc');
$threshold = $this->getIntProperty('minimum');
if ($nocc >= $threshold) {
$this->addViolation(
$node,
array(
$node->getType(),
$node->getName(),
$nocc,
$threshold
)
);
}
}
}
@@ -0,0 +1,81 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
/**
* This rule class will detect all classes with too much fields.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class TooManyFields extends AbstractRule implements ClassAware
{
/**
* This method checks the number of methods with in a given class and checks
* this number against a configured threshold.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$threshold = $this->getIntProperty('maxfields');
$vars = $node->getMetric('vars');
if ($vars <= $threshold) {
return;
}
$this->addViolation(
$node,
array(
$node->getType(),
$node->getName(),
$vars,
$threshold
)
);
}
}
@@ -0,0 +1,111 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Node\AbstractTypeNode;
use PHPMD\Rule\ClassAware;
/**
* This rule class will detect all classes with too much methods.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class TooManyMethods extends AbstractRule implements ClassAware
{
/**
* Regular expression that filters all methods that are ignored by this rule.
*
* @var string
*/
private $ignoreRegexp;
/**
* This method checks the number of methods with in a given class and checks
* this number against a configured threshold.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$this->ignoreRegexp = $this->getStringProperty('ignorepattern');
$threshold = $this->getIntProperty('maxmethods');
if ($node->getMetric('nom') <= $threshold) {
return;
}
$nom = $this->countMethods($node);
if ($nom <= $threshold) {
return;
}
$this->addViolation(
$node,
array(
$node->getType(),
$node->getName(),
$nom,
$threshold
)
);
}
/**
* Counts all methods within the given class/interface node.
*
* @param \PHPMD\Node\AbstractTypeNode $node
* @return integer
*/
private function countMethods(AbstractTypeNode $node)
{
$count = 0;
foreach ($node->getMethodNames() as $name) {
if (preg_match($this->ignoreRegexp, $name) === 0) {
++$count;
}
}
return $count;
}
}
@@ -0,0 +1,111 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Node\AbstractTypeNode;
use PHPMD\Rule\ClassAware;
/**
* This rule class will detect all classes with too much public methods.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class TooManyPublicMethods extends AbstractRule implements ClassAware
{
/**
* Regular expression that filters all methods that are ignored by this rule.
*
* @var string
*/
private $ignoreRegexp;
/**
* This method checks the number of public methods with in a given class and checks
* this number against a configured threshold.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$this->ignoreRegexp = $this->getStringProperty('ignorepattern');
$threshold = $this->getIntProperty('maxmethods');
if ($node->getMetric('npm') <= $threshold) {
return;
}
$nom = $this->countMethods($node);
if ($nom <= $threshold) {
return;
}
$this->addViolation(
$node,
array(
$node->getType(),
$node->getName(),
$nom,
$threshold
)
);
}
/**
* Counts public methods within the given class/interface node.
*
* @param \PHPMD\Node\AbstractTypeNode $node
* @return integer
*/
private function countMethods(AbstractTypeNode $node)
{
$count = 0;
foreach ($node->getMethods() as $method) {
if ($method->getNode()->isPublic() && preg_match($this->ignoreRegexp, $method->getName()) === 0) {
++$count;
}
}
return $count;
}
}
@@ -0,0 +1,76 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 0.2.5
*/
namespace PHPMD\Rule\Design;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
/**
* This rule checks a given class against a configured weighted method count
* threshold.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @since 0.2.5
*/
class WeightedMethodCount extends AbstractRule implements ClassAware
{
/**
* This method checks the weighted method count for the given class against
* a configured threshold.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$threshold = $this->getIntProperty('maximum');
$actual = $node->getMetric('wmc');
if ($actual >= $threshold) {
$this->addViolation($node, array($node->getName(), $actual, $threshold));
}
}
}
@@ -0,0 +1,81 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
/**
* This rule checks the number of public methods and fields in a given class.
* Then it compares the number of public members against a configured threshold.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class ExcessivePublicCount extends AbstractRule implements ClassAware
{
/**
* This method checks the number of public fields and methods in the given
* class and checks that value against a configured threshold.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$threshold = $this->getIntProperty('minimum');
$cis = $node->getMetric('cis');
if ($cis < $threshold) {
return;
}
$this->addViolation(
$node,
array(
$node->getType(),
$node->getName(),
$cis,
$threshold
)
);
}
}
@@ -0,0 +1,53 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule;
/**
* This interface is used to mark a rule implementation as function aware.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
interface FunctionAware
{
}
@@ -0,0 +1,53 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule;
/**
* This interface marks a rule implementation as interface aware,
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
interface InterfaceAware
{
}
@@ -0,0 +1,53 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule;
/**
* This interface marks a rule implementation as method aware,
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
interface MethodAware
{
}
@@ -0,0 +1,125 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Naming;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Node\MethodNode;
use PHPMD\Rule\MethodAware;
/**
* This rule tests that a method which returns a boolean value does not start
* with <b>get</b> or <b>_get</b> for a getter.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class BooleanGetMethodName extends AbstractRule implements MethodAware
{
/**
* Extracts all variable and variable declarator nodes from the given node
* and checks the variable name length against the configured minimum
* length.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
if ($this->isBooleanGetMethod($node)) {
$this->addViolation($node, array($node->getImage()));
}
}
/**
* Tests if the given method matches all criteria to be an invalid
* boolean get method.
*
* @param \PHPMD\Node\MethodNode $node
* @return boolean
*/
private function isBooleanGetMethod(MethodNode $node)
{
return $this->isGetterMethodName($node)
&& $this->isReturnTypeBoolean($node)
&& $this->isParameterizedOrIgnored($node);
}
/**
* Tests if the given method starts with <b>get</b> or <b>_get</b>.
*
* @param \PHPMD\Node\MethodNode $node
* @return boolean
*/
private function isGetterMethodName(MethodNode $node)
{
return (preg_match('(^_?get)i', $node->getImage()) > 0);
}
/**
* Tests if the given method is declared with return type boolean.
*
* @param \PHPMD\Node\MethodNode $node
* @return boolean
*/
private function isReturnTypeBoolean(MethodNode $node)
{
$comment = $node->getDocComment();
return (preg_match('(\*\s*@return\s+bool(ean)?\s)i', $comment) > 0);
}
/**
* Tests if the property <b>$checkParameterizedMethods</b> is set to <b>true</b>
* or has no parameters.
*
* @param \PHPMD\Node\MethodNode $node
* @return boolean
*/
private function isParameterizedOrIgnored(MethodNode $node)
{
if ($this->getBooleanProperty('checkParameterizedMethods')) {
return $node->getParameterCount() === 0;
}
return true;
}
}
@@ -0,0 +1,74 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Naming;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
use PHPMD\Rule\InterfaceAware;
/**
* This rule detects class/interface constants that do not follow the upper
* case convention.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class ConstantNamingConventions extends AbstractRule implements ClassAware, InterfaceAware
{
/**
* Extracts all constant declarations from the given node and tests that
* the image only contains upper case characters.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($node->findChildrenOfType('ConstantDeclarator') as $declarator) {
if ($declarator->getImage() !== strtoupper($declarator->getImage())) {
$this->addViolation($declarator, array($declarator->getImage()));
}
}
}
}
@@ -0,0 +1,84 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Naming;
use PDepend\Source\AST\ASTTrait;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Node\InterfaceNode;
use PHPMD\Rule\MethodAware;
/**
* This rule class will detect methods that define a php4 style constructor
* method while has the same name as the enclosing class.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class ConstructorWithNameAsEnclosingClass extends AbstractRule implements MethodAware
{
/**
* Is method has the same name as the enclosing class
* (php4 style constructor).
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
if ($node->getNode()->getParent() instanceof ASTTrait) {
return;
}
if (strcasecmp($node->getName(), $node->getParentName()) !== 0) {
return;
}
if ($node->getParentType() instanceof InterfaceNode) {
return;
}
if ($node->getNamespaceName() !== '+global') {
return;
}
$this->addViolation($node);
}
}
@@ -0,0 +1,203 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Naming;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule class will detect variables, parameters and properties with really
* long names.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class LongVariable extends AbstractRule implements ClassAware, MethodAware, FunctionAware
{
/**
* Temporary map holding variables that were already processed in the
* current context.
*
* @var array(string=>boolean)
*/
private $processedVariables = array();
/**
* Extracts all variable and variable declarator nodes from the given node
* and checks the variable name length against the configured maximum
* length.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$this->resetProcessed();
if ($node->getType() === 'class') {
$fields = $node->findChildrenOfType('FieldDeclaration');
foreach ($fields as $field) {
if ($field->isPrivate()) {
continue;
}
$declarators = $field->findChildrenOfType('VariableDeclarator');
foreach ($declarators as $declarator) {
$this->checkNodeImage($declarator);
}
}
} else {
$declarators = $node->findChildrenOfType('VariableDeclarator');
foreach ($declarators as $declarator) {
$this->checkNodeImage($declarator);
}
$variables = $node->findChildrenOfType('Variable');
foreach ($variables as $variable) {
$this->checkNodeImage($variable);
}
}
$this->resetProcessed();
}
/**
* Checks if the variable name of the given node is smaller/equal to the
* configured threshold.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
protected function checkNodeImage(AbstractNode $node)
{
if ($this->isNotProcessed($node)) {
$this->addProcessed($node);
$this->checkMaximumLength($node);
}
}
/**
* Template method that performs the real node image check.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
protected function checkMaximumLength(AbstractNode $node)
{
$threshold = $this->getIntProperty('maximum');
if ($threshold >= strlen($node->getImage()) - 1) {
return;
}
if ($this->isNameAllowedInContext($node)) {
return;
}
$this->addViolation($node, array($node->getImage(), $threshold));
}
/**
* Checks if a short name is acceptable in the current context. For the
* moment the only context is a static member.
*
* @param \PHPMD\AbstractNode $node
* @return boolean
*/
private function isNameAllowedInContext(AbstractNode $node)
{
return $this->isChildOf($node, 'MemberPrimaryPrefix');
}
/**
* Checks if the given node is a direct or indirect child of a node with
* the given type.
*
* @param \PHPMD\AbstractNode $node
* @param string $type
* @return boolean
*/
private function isChildOf(AbstractNode $node, $type)
{
$parent = $node->getParent();
while (is_object($parent)) {
if ($parent->isInstanceOf($type)) {
return true;
}
$parent = $parent->getParent();
}
return false;
}
/**
* Resets the already processed nodes.
*
* @return void
*/
protected function resetProcessed()
{
$this->processedVariables = array();
}
/**
* Flags the given node as already processed.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
protected function addProcessed(AbstractNode $node)
{
$this->processedVariables[$node->getImage()] = true;
}
/**
* Checks if the given node was already processed.
*
* @param \PHPMD\AbstractNode $node
* @return boolean
*/
protected function isNotProcessed(AbstractNode $node)
{
return !isset($this->processedVariables[$node->getImage()]);
}
}
@@ -0,0 +1,104 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Naming;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule class will detect methods and functions with very short names.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class ShortMethodName extends AbstractRule implements MethodAware, FunctionAware
{
/**
* Extracts all variable and variable declarator nodes from the given node
* and checks the variable name length against the configured minimum
* length.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$threshold = $this->getIntProperty('minimum');
if ($threshold <= strlen($node->getName())) {
return;
}
$exceptions = $this->getExceptionsList();
if (in_array($node->getName(), $exceptions)) {
return;
}
$this->addViolation(
$node,
array(
$node->getParentName(),
$node->getName(),
$threshold
)
);
}
/**
* Gets array of exceptions from property
*
* @return array
*/
private function getExceptionsList()
{
try {
$exceptions = $this->getStringProperty('exceptions');
} catch (\OutOfBoundsException $e) {
$exceptions = '';
}
return explode(',', $exceptions);
}
}
@@ -0,0 +1,228 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule\Naming;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Rule\ClassAware;
use PHPMD\Rule\FunctionAware;
use PHPMD\Rule\MethodAware;
/**
* This rule class will detect variables, parameters and properties with short
* names.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class ShortVariable extends AbstractRule implements ClassAware, MethodAware, FunctionAware
{
/**
* Temporary map holding variables that were already processed in the
* current context.
*
* @var array(string=>boolean)
*/
private $processedVariables = array();
/**
* Extracts all variable and variable declarator nodes from the given node
* and checks the variable name length against the configured minimum
* length.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$this->resetProcessed();
if ($node->getType() === 'class') {
$fields = $node->findChildrenOfType('FieldDeclaration');
foreach ($fields as $field) {
$declarators = $field->findChildrenOfType('VariableDeclarator');
foreach ($declarators as $declarator) {
$this->checkNodeImage($declarator);
}
}
} else {
$declarators = $node->findChildrenOfType('VariableDeclarator');
foreach ($declarators as $declarator) {
$this->checkNodeImage($declarator);
}
$variables = $node->findChildrenOfType('Variable');
foreach ($variables as $variable) {
$this->checkNodeImage($variable);
}
}
$this->resetProcessed();
}
/**
* Checks if the variable name of the given node is greater/equal to the
* configured threshold or if the given node is an allowed context.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
protected function checkNodeImage(AbstractNode $node)
{
if ($this->isNotProcessed($node)) {
$this->addProcessed($node);
$this->checkMinimumLength($node);
}
}
/**
* Template method that performs the real node image check.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
protected function checkMinimumLength(AbstractNode $node)
{
$threshold = $this->getIntProperty('minimum');
if ($threshold <= strlen($node->getImage()) - 1) {
return;
}
if ($this->isNameAllowedInContext($node)) {
return;
}
$exceptions = $this->getExceptionsList();
if (in_array(substr($node->getImage(), 1), $exceptions)) {
return;
}
$this->addViolation($node, array($node->getImage(), $threshold));
}
/**
* Gets array of exceptions from property
*
* @return array
*/
private function getExceptionsList()
{
try {
$exceptions = $this->getStringProperty('exceptions');
} catch (\OutOfBoundsException $e) {
$exceptions = '';
}
return explode(',', $exceptions);
}
/**
* Checks if a short name is acceptable in the current context. For the
* moment these contexts are the init section of a for-loop and short
* variable names in catch-statements.
*
* @param \PHPMD\AbstractNode $node
* @return boolean
*/
private function isNameAllowedInContext(AbstractNode $node)
{
return $this->isChildOf($node, 'CatchStatement')
|| $this->isChildOf($node, 'ForInit')
|| $this->isChildOf($node, 'ForeachStatement')
|| $this->isChildOf($node, 'MemberPrimaryPrefix');
}
/**
* Checks if the given node is a direct or indirect child of a node with
* the given type.
*
* @param \PHPMD\AbstractNode $node
* @param string $type
* @return boolean
*/
private function isChildOf(AbstractNode $node, $type)
{
$parent = $node->getParent();
while (is_object($parent)) {
if ($parent->isInstanceOf($type)) {
return true;
}
$parent = $parent->getParent();
}
return false;
}
/**
* Resets the already processed nodes.
*
* @return void
*/
protected function resetProcessed()
{
$this->processedVariables = array();
}
/**
* Flags the given node as already processed.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
protected function addProcessed(AbstractNode $node)
{
$this->processedVariables[$node->getImage()] = true;
}
/**
* Checks if the given node was already processed.
*
* @param \PHPMD\AbstractNode $node
* @return boolean
*/
protected function isNotProcessed(AbstractNode $node)
{
return !isset($this->processedVariables[$node->getImage()]);
}
}
@@ -0,0 +1,220 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule;
use PHPMD\AbstractNode;
use PHPMD\Node\MethodNode;
/**
* This rule collects all formal parameters of a given function or method that
* are not used in a statement of the artifact's body.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class UnusedFormalParameter extends AbstractLocalVariable implements FunctionAware, MethodAware
{
/**
* Collected ast nodes.
*
* @var \PHPMD\Node\ASTNode[]
*/
private $nodes = array();
/**
* This method checks that all parameters of a given function or method are
* used at least one time within the artifacts body.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
if ($this->isAbstractMethod($node)) {
return;
}
// Magic methods should be ignored as invalid declarations are picked up by PHP.
if ($this->isMagicMethod($node)) {
return;
}
if ($this->isInheritedSignature($node)) {
return;
}
if ($this->isNotDeclaration($node)) {
return;
}
$this->nodes = array();
$this->collectParameters($node);
$this->removeUsedParameters($node);
foreach ($this->nodes as $node) {
$this->addViolation($node, array($node->getImage()));
}
}
/**
* Returns <b>true</b> when the given node is an abstract method.
*
* @param \PHPMD\AbstractNode $node
* @return boolean
*/
private function isAbstractMethod(AbstractNode $node)
{
if ($node instanceof MethodNode) {
return $node->isAbstract();
}
return false;
}
/**
* Returns <b>true</b> when the given node is method with signature declared as inherited using
* {@inheritdoc} annotation.
*
* @param \PHPMD\AbstractNode $node
* @return boolean
*/
private function isInheritedSignature(AbstractNode $node)
{
if ($node instanceof MethodNode) {
return preg_match('/\@inheritdoc/i', $node->getDocComment());
}
return false;
}
/**
* Returns <b>true</b> when the given node is a magic method signature
* @param AbstractNode $node
* @return boolean
*/
private function isMagicMethod(AbstractNode $node)
{
static $names = array(
'call',
'callStatic',
'get',
'set',
'isset',
'unset',
'set_state'
);
if ($node instanceof MethodNode) {
return preg_match('/\__(?:' . implode("|", $names) . ')/i', $node->getName());
}
return false;
}
/**
* Tests if the given <b>$node</b> is a method and if this method is also
* the initial declaration.
*
* @param \PHPMD\AbstractNode $node
* @return boolean
* @since 1.2.1
*/
private function isNotDeclaration(AbstractNode $node)
{
if ($node instanceof MethodNode) {
return !$node->isDeclaration();
}
return false;
}
/**
* This method extracts all parameters for the given function or method node
* and it stores the parameter images in the <b>$_images</b> property.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
private function collectParameters(AbstractNode $node)
{
// First collect the formal parameters container
$parameters = $node->getFirstChildOfType('FormalParameters');
// Now get all declarators in the formal parameters container
$declarators = $parameters->findChildrenOfType('VariableDeclarator');
foreach ($declarators as $declarator) {
$this->nodes[$declarator->getImage()] = $declarator;
}
}
/**
* This method collects all local variables in the body of the currently
* analyzed method or function and removes those parameters that are
* referenced by one of the collected variables.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
private function removeUsedParameters(AbstractNode $node)
{
$variables = $node->findChildrenOfType('Variable');
foreach ($variables as $variable) {
if ($this->isRegularVariable($variable)) {
unset($this->nodes[$variable->getImage()]);
}
}
/* If the method calls func_get_args() then all parameters are
* automatically referenced */
$functionCalls = $node->findChildrenOfType('FunctionPostfix');
foreach ($functionCalls as $functionCall) {
if ($this->isFunctionNameEqual($functionCall, 'func_get_args')) {
$this->nodes = array();
}
if ($this->isFunctionNameEndingWith($functionCall, 'compact')) {
foreach ($functionCall->findChildrenOfType('Literal') as $literal) {
unset($this->nodes['$' . trim($literal->getImage(), '"\'')]);
}
}
}
}
}
@@ -0,0 +1,226 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule;
use PHPMD\AbstractNode;
use PHPMD\Node\AbstractCallableNode;
use PHPMD\Node\ASTNode;
/**
* This rule collects all local variables within a given function or method
* that are not used by any code in the analyzed source artifact.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class UnusedLocalVariable extends AbstractLocalVariable implements FunctionAware, MethodAware
{
/**
* Found variable images within a single method or function.
*
* @var array(string)
*/
private $images = array();
/**
* This method checks that all local variables within the given function or
* method are used at least one time.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
$this->images = array();
$this->collectVariables($node);
$this->removeParameters($node);
foreach ($this->images as $nodes) {
if (count($nodes) === 1) {
$this->doCheckNodeImage($nodes[0]);
}
}
}
/**
* This method removes all variables from the <b>$_images</b> property that
* are also found in the formal parameters of the given method or/and
* function node.
*
* @param \PHPMD\Node\AbstractCallableNode $node
* @return void
*/
private function removeParameters(AbstractCallableNode $node)
{
// Get formal parameter container
$parameters = $node->getFirstChildOfType('FormalParameters');
// Now get all declarators in the formal parameters container
$declarators = $parameters->findChildrenOfType('VariableDeclarator');
foreach ($declarators as $declarator) {
unset($this->images[$declarator->getImage()]);
}
}
/**
* This method collects all local variable instances from the given
* method/function node and stores their image in the <b>$_images</b>
* property.
*
*
* @param \PHPMD\Node\AbstractCallableNode $node
* @return void
*/
private function collectVariables(AbstractCallableNode $node)
{
foreach ($node->findChildrenOfType('Variable') as $variable) {
if ($this->isLocal($variable)) {
$this->collectVariable($variable);
}
}
foreach ($node->findChildrenOfType('VariableDeclarator') as $variable) {
$this->collectVariable($variable);
}
foreach ($node->findChildrenOfType('FunctionPostfix') as $func) {
if ($this->isFunctionNameEndingWith($func, 'compact')) {
foreach ($func->findChildrenOfType('Literal') as $literal) {
$this->collectLiteral($literal);
}
}
}
}
/**
* Stores the given variable node in an internal list of found variables.
*
* @param \PHPMD\Node\ASTNode $node
* @return void
*/
private function collectVariable(ASTNode $node)
{
if (!isset($this->images[$node->getImage()])) {
$this->images[$node->getImage()] = array();
}
$this->images[$node->getImage()][] = $node;
}
/**
* Stores the given literal node in an internal list of found variables.
*
* @param \PHPMD\Node\ASTNode $node
* @return void
*/
private function collectLiteral(ASTNode $node)
{
$variable = '$' . trim($node->getImage(), '\'');
if (!isset($this->images[$variable])) {
$this->images[$variable] = array();
}
$this->images[$variable][] = $node;
}
/**
* Template method that performs the real node image check.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
protected function doCheckNodeImage(AbstractNode $node)
{
if ($this->isNameAllowedInContext($node)) {
return;
}
if ($this->isUnusedForeachVariableAllowed($node)) {
return;
}
$this->addViolation($node, array($node->getImage()));
}
/**
* Checks if a short name is acceptable in the current context. For the
* moment these contexts are the init section of a for-loop and short
* variable names in catch-statements.
*
* @param \PHPMD\AbstractNode $node
* @return boolean
*/
private function isNameAllowedInContext(AbstractNode $node)
{
return $this->isChildOf($node, 'CatchStatement');
}
/**
* Checks if an unused foreach variable (key or variable) is allowed.
*
* If it's not a foreach variable, it returns always false.
*
* @param \PHPMD\Node\ASTNode $variable The variable to check.
* @return bool True if allowed, else false.
*/
private function isUnusedForeachVariableAllowed(ASTNode $variable)
{
$isForeachVariable = $this->isChildOf($variable, 'ForeachStatement');
if (!$isForeachVariable) {
return false;
}
return $this->getBooleanProperty('allow-unused-foreach-variables');
}
/**
* Checks if the given node is a direct or indirect child of a node with
* the given type.
*
* @param \PHPMD\AbstractNode $node
* @param string $type
* @return boolean
*/
private function isChildOf(AbstractNode $node, $type)
{
$parent = $node->getParent();
return $parent->isInstanceOf($type);
}
}
@@ -0,0 +1,215 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Node\ASTNode;
use PHPMD\Node\ClassNode;
/**
* This rule collects all private fields in a class that aren't used in any
* method of the analyzed class.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class UnusedPrivateField extends AbstractRule implements ClassAware
{
/**
* Collected private fields/variable declarators in the currently processed
* class.
*
* @var \PHPMD\Node\ASTNode[]
*/
private $fields = array();
/**
* This method checks that all private class properties are at least accessed
* by one method.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
foreach ($this->collectUnusedPrivateFields($node) as $field) {
$this->addViolation($field, array($field->getImage()));
}
}
/**
* This method collects all private fields that aren't used by any class
* method.
*
* @param \PHPMD\Node\ClassNode $class
* @return \PHPMD\AbstractNode[]
*/
private function collectUnusedPrivateFields(ClassNode $class)
{
$this->fields = array();
$this->collectPrivateFields($class);
$this->removeUsedFields($class);
return $this->fields;
}
/**
* This method collects all private fields in the given class and stores
* them in the <b>$_fields</b> property.
*
* @param \PHPMD\Node\ClassNode $class
* @return void
*/
private function collectPrivateFields(ClassNode $class)
{
foreach ($class->findChildrenOfType('FieldDeclaration') as $declaration) {
if ($declaration->isPrivate()) {
$this->collectPrivateField($declaration);
}
}
}
/**
* This method extracts all variable declarators from the given field
* declaration and stores them in the <b>$_fields</b> property.
*
* @param \PHPMD\Node\ASTNode $declaration
* @return void
*/
private function collectPrivateField(ASTNode $declaration)
{
$fields = $declaration->findChildrenOfType('VariableDeclarator');
foreach ($fields as $field) {
$this->fields[$field->getImage()] = $field;
}
}
/**
* This method extracts all property postfix nodes from the given class and
* removes all fields from the <b>$_fields</b> property that are accessed by
* one of the postfix nodes.
*
* @param \PHPMD\Node\ClassNode $class
* @return void
*/
private function removeUsedFields(ClassNode $class)
{
foreach ($class->findChildrenOfType('PropertyPostfix') as $postfix) {
if ($this->isInScopeOfClass($class, $postfix)) {
$this->removeUsedField($postfix);
}
}
}
/**
* This method removes the field from the <b>$_fields</b> property that is
* accessed through the given property postfix node.
*
* @param \PHPMD\Node\ASTNode $postfix
* @return void
*/
private function removeUsedField(ASTNode $postfix)
{
$image = '$';
$child = $postfix->getFirstChildOfType('Identifier');
if ($postfix->getParent()->isStatic()) {
$image = '';
$child = $postfix->getFirstChildOfType('Variable');
}
if ($this->isValidPropertyNode($child)) {
unset($this->fields[$image . $child->getImage()]);
}
}
/**
* Checks if the given node is a valid property node.
*
* @param \PHPMD\Node\ASTNode $node
* @return boolean
* @since 0.2.6
*/
protected function isValidPropertyNode(ASTNode $node = null)
{
if ($node === null) {
return false;
}
$parent = $node->getParent();
while (!$parent->isInstanceOf('PropertyPostfix')) {
if ($parent->isInstanceOf('CompoundVariable')) {
return false;
}
$parent = $parent->getParent();
if (is_null($parent)) {
return false;
}
}
return true;
}
/**
* This method checks that the given property postfix is accessed on an
* instance or static reference to the given class.
*
* @param \PHPMD\Node\ClassNode $class
* @param \PHPMD\Node\ASTNode $postfix
* @return boolean
*/
protected function isInScopeOfClass(ClassNode $class, ASTNode $postfix)
{
$owner = $postfix->getParent()->getChild(0);
if ($owner->isInstanceOf('PropertyPostfix')) {
$owner = $owner->getParent()->getParent()->getChild(0);
}
return (
$owner->isInstanceOf('SelfReference') ||
$owner->isInstanceOf('StaticReference') ||
strcasecmp($owner->getImage(), '$this') === 0 ||
strcasecmp($owner->getImage(), $class->getImage()) === 0
);
}
}
@@ -0,0 +1,160 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Rule;
use PHPMD\AbstractNode;
use PHPMD\AbstractRule;
use PHPMD\Node\ASTNode;
use PHPMD\Node\ClassNode;
use PHPMD\Node\MethodNode;
/**
* This rule collects all private methods in a class that aren't used in any
* method of the analyzed class.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class UnusedPrivateMethod extends AbstractRule implements ClassAware
{
/**
* This method checks that all private class methods are at least accessed
* by one method.
*
* @param \PHPMD\AbstractNode $class
* @return void
*/
public function apply(AbstractNode $class)
{
foreach ($this->collectUnusedPrivateMethods($class) as $node) {
$this->addViolation($node, array($node->getImage()));
}
}
/**
* This method collects all methods in the given class that are declared
* as private and are not used in the same class' context.
*
* @param \PHPMD\Node\ClassNode $class
* @return \PHPMD\AbstractNode[]
*/
private function collectUnusedPrivateMethods(ClassNode $class)
{
$methods = $this->collectPrivateMethods($class);
return $this->removeUsedMethods($class, $methods);
}
/**
* Collects all private methods declared in the given class node.
*
* @param \PHPMD\Node\ClassNode $class
* @return \PHPMD\AbstractNode[]
*/
private function collectPrivateMethods(ClassNode $class)
{
$methods = array();
foreach ($class->getMethods() as $method) {
if ($this->acceptMethod($class, $method)) {
$methods[strtolower($method->getImage())] = $method;
}
}
return $methods;
}
/**
* Returns <b>true</b> when the given method should be used for this rule's
* analysis.
*
* @param \PHPMD\Node\ClassNode $class
* @param \PHPMD\Node\MethodNode $method
* @return boolean
*/
private function acceptMethod(ClassNode $class, MethodNode $method)
{
return (
$method->isPrivate() &&
false === $method->hasSuppressWarningsAnnotationFor($this) &&
strcasecmp($method->getImage(), $class->getImage()) !== 0 &&
strcasecmp($method->getImage(), '__construct') !== 0 &&
strcasecmp($method->getImage(), '__destruct') !== 0 &&
strcasecmp($method->getImage(), '__clone') !== 0
);
}
/**
* This method removes all used methods from the given methods array.
*
* @param \PHPMD\Node\ClassNode $class
* @param \PHPMD\Node\MethodNode[] $methods
* @return \PHPMD\AbstractNode[]
*/
private function removeUsedMethods(ClassNode $class, array $methods)
{
foreach ($class->findChildrenOfType('MethodPostfix') as $postfix) {
if ($this->isClassScope($class, $postfix)) {
unset($methods[strtolower($postfix->getImage())]);
}
}
return $methods;
}
/**
* This method checks that the given method postfix is accessed on an
* instance or static reference to the given class.
*
* @param \PHPMD\Node\ClassNode $class
* @param \PHPMD\Node\ASTNode $postfix
* @return boolean
*/
private function isClassScope(ClassNode $class, ASTNode $postfix)
{
$owner = $postfix->getParent()->getChild(0);
return (
$owner->isInstanceOf('MethodPostfix') ||
$owner->isInstanceOf('SelfReference') ||
$owner->isInstanceOf('StaticReference') ||
strcasecmp($owner->getImage(), '$this') === 0 ||
strcasecmp($owner->getImage(), $class->getImage()) === 0
);
}
}
@@ -0,0 +1,63 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
/**
* This type of exception is thrown when the class file for a configured rule
* does not exist within php's include path.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class RuleClassFileNotFoundException extends \RuntimeException
{
/**
* Constructs a new class file not found exception.
*
* @param string $className The rule class name.
*/
public function __construct($className)
{
parent::__construct('Cannot load source file for class: ' . $className);
}
}
@@ -0,0 +1,62 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
/**
* When a configured rule class does not exist.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class RuleClassNotFoundException extends \RuntimeException
{
/**
* Constructs a new class not found exception.
*
* @param <type> $className The configured but not found ruke class name.
*/
public function __construct($className)
{
parent::__construct('Cannot find rule class: ' . $className);
}
}
@@ -0,0 +1,297 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
/**
* This class is a collection of concrete source analysis rules.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class RuleSet implements \IteratorAggregate
{
/**
* Should this rule set force the strict mode.
*
* @var boolean
* @since 1.2.0
*/
private $strict = false;
/**
* The name of the file where this set is specified.
*
* @var string
*/
private $fileName = '';
/**
* The name of this rule-set.
*
* @var string
*/
private $name = '';
/**
* An optional description for this rule-set.
*
* @var string
*/
private $description = '';
/**
* The violation report used by the rule-set.
*
* @var \PHPMD\Report
*/
private $report;
/**
* Mapping between marker interfaces and concrete context code node classes.
*
* @var array(string=>string)
*/
private $applyTo = array(
'PHPMD\\Rule\\ClassAware' => 'PHPMD\\Node\\ClassNode',
'PHPMD\\Rule\\FunctionAware' => 'PHPMD\\Node\\FunctionNode',
'PHPMD\\Rule\\InterfaceAware' => 'PHPMD\\Node\\InterfaceNode',
'PHPMD\\Rule\\MethodAware' => 'PHPMD\\Node\\MethodNode',
);
/**
* Mapping of rules that apply to a concrete code node type.
*
* @var array(string=>array)
*/
private $rules = array(
'PHPMD\\Node\\ClassNode' => array(),
'PHPMD\\Node\\FunctionNode' => array(),
'PHPMD\\Node\\InterfaceNode' => array(),
'PHPMD\\Node\\MethodNode' => array(),
);
/**
* Returns the file name where the definition of this rule-set comes from.
*
* @return string
*/
public function getFileName()
{
return $this->fileName;
}
/**
* Sets the file name where the definition of this rule-set comes from.
*
* @param string $fileName The file name.
*
* @return void
*/
public function setFileName($fileName)
{
$this->fileName = $fileName;
}
/**
* Returns the name of this rule-set.
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Sets the name of this rule-set.
*
* @param string $name The name of this rule-set.
*
* @return void
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Returns the description text for this rule-set instance.
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Sets the description text for this rule-set instance.
*
* @param string $description The description text.
*
* @return void
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* Activates the strict mode for this rule set instance.
*
* @return void
* @since 1.2.0
*/
public function setStrict()
{
$this->strict = true;
}
/**
* Returns the violation report used by the rule-set.
*
* @return \PHPMD\Report
*/
public function getReport()
{
return $this->report;
}
/**
* Sets the violation report used by the rule-set.
*
* @param \PHPMD\Report $report
* @return void
*/
public function setReport(Report $report)
{
$this->report = $report;
}
/**
* This method returns a rule by its name or <b>null</b> if it doesn't exist.
*
* @param string $name
* @return \PHPMD\Rule
*/
public function getRuleByName($name)
{
foreach ($this->getRules() as $rule) {
if ($rule->getName() === $name) {
return $rule;
}
}
return null;
}
/**
* This method returns an iterator will all rules that belong to this
* rule-set.
*
* @return \Iterator
*/
public function getRules()
{
$result = array();
foreach ($this->rules as $rules) {
foreach ($rules as $rule) {
if (in_array($rule, $result, true) === false) {
$result[] = $rule;
}
}
}
return new \ArrayIterator($result);
}
/**
* Adds a new rule to this rule-set.
*
* @param \PHPMD\Rule $rule
* @return void
*/
public function addRule(Rule $rule)
{
foreach ($this->applyTo as $applyTo => $type) {
if ($rule instanceof $applyTo) {
$this->rules[$type][] = $rule;
}
}
}
/**
* Applies all registered rules that match against the concrete node type.
*
* @param \PHPMD\AbstractNode $node
* @return void
*/
public function apply(AbstractNode $node)
{
// Current node type
$className = get_class($node);
// Check for valid node type
if (!isset($this->rules[$className])) {
return;
}
// Apply all rules to this node
foreach ($this->rules[$className] as $rule) {
if ($node->hasSuppressWarningsAnnotationFor($rule) && !$this->strict) {
continue;
}
$rule->setReport($this->report);
$rule->apply($node);
}
}
/**
* Returns an iterator with all rules that are part of this rule-set.
*
* @return \Iterator
*/
public function getIterator()
{
return $this->getRules();
}
}
@@ -0,0 +1,568 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
/**
* This factory class is used to create the {@link \PHPMD\RuleSet} instance
* that PHPMD will use to analyze the source code.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class RuleSetFactory
{
/**
* Is the strict mode active?
*
* @var boolean
* @since 1.2.0
*/
private $strict = false;
/**
* The data directory set by PEAR or a dynamic property set within the class
* constructor.
*
* @var string
*/
private $location = '@data_dir@';
/**
* The minimum priority for rules to load.
*
* @var integer
*/
private $minimumPriority = Rule::LOWEST_PRIORITY;
/**
* Constructs a new default rule-set factory instance.
*/
public function __construct()
{
// PEAR installer workaround
if (strpos($this->location, '@data_dir') === 0) {
$this->location = __DIR__ . '/../../resources';
} else {
$this->location .= '/PHPMD/resources';
}
}
/**
* Activates the strict mode for all rule sets.
*
* @return void
* @since 1.2.0
*/
public function setStrict()
{
$this->strict = true;
}
/**
* Sets the minimum priority that a rule must have.
*
* @param integer $minimumPriority The minimum priority value.
*
* @return void
*/
public function setMinimumPriority($minimumPriority)
{
$this->minimumPriority = $minimumPriority;
}
/**
* Creates an array of rule-set instances for the given argument.
*
* @param string $ruleSetFileNames Comma-separated string of rule-set filenames or identifier.
* @return \PHPMD\RuleSet[]
*/
public function createRuleSets($ruleSetFileNames)
{
$ruleSets = array();
$ruleSetFileName = strtok($ruleSetFileNames, ',');
while ($ruleSetFileName !== false) {
$ruleSets[] = $this->createSingleRuleSet($ruleSetFileName);
$ruleSetFileName = strtok(',');
}
return $ruleSets;
}
/**
* Creates a single rule-set instance for the given filename or identifier.
*
* @param string $ruleSetOrFileName The rule-set filename or identifier.
* @return \PHPMD\RuleSet
*/
public function createSingleRuleSet($ruleSetOrFileName)
{
$fileName = $this->createRuleSetFileName($ruleSetOrFileName);
return $this->parseRuleSetNode($fileName);
}
/**
* Lists available rule-set identifiers.
*
* @return array(string)
*/
public function listAvailableRuleSets()
{
return array_merge(
self::listRuleSetsInDirectory($this->location . '/rulesets/'),
self::listRuleSetsInDirectory(getcwd() . '/rulesets/')
);
}
/**
* This method creates the filename for a rule-set identifier or it returns
* the input when it is already a filename.
*
* @param string $ruleSetOrFileName The rule-set filename or identifier.
* @return string
*/
private function createRuleSetFileName($ruleSetOrFileName)
{
if (file_exists($ruleSetOrFileName) === true) {
return $ruleSetOrFileName;
}
$fileName = $this->location . '/' . $ruleSetOrFileName;
if (file_exists($fileName) === true) {
return $fileName;
}
$fileName = $this->location . '/rulesets/' . $ruleSetOrFileName . '.xml';
if (file_exists($fileName) === true) {
return $fileName;
}
$fileName = getcwd() . '/rulesets/' . $ruleSetOrFileName . '.xml';
if (file_exists($fileName) === true) {
return $fileName;
}
foreach (explode(PATH_SEPARATOR, get_include_path()) as $includePath) {
$fileName = $includePath . '/' . $ruleSetOrFileName;
if (file_exists($fileName) === true) {
return $fileName;
}
$fileName = $includePath . '/' . $ruleSetOrFileName + ".xml";
if (file_exists($fileName) === true) {
return $fileName;
}
}
throw new RuleSetNotFoundException($ruleSetOrFileName);
}
/**
* Lists available rule-set identifiers in given directory.
*
* @param string $directory The directory to scan for rule-sets.
*
* @return array(string)
*/
private static function listRuleSetsInDirectory($directory)
{
$ruleSets = array();
if (is_dir($directory)) {
foreach (scandir($directory) as $file) {
$matches = array();
if (is_file($directory . $file) && preg_match('/^(.*)\.xml$/', $file, $matches)) {
$ruleSets[] = $matches[1];
}
}
}
return $ruleSets;
}
/**
* This method parses the rule-set definition in the given file.
*
* @param string $fileName
* @return \PHPMD\RuleSet
*/
private function parseRuleSetNode($fileName)
{
// Hide error messages
$libxml = libxml_use_internal_errors(true);
$xml = simplexml_load_string(file_get_contents($fileName));
if ($xml === false) {
// Reset error handling to previous setting
libxml_use_internal_errors($libxml);
throw new \RuntimeException(trim(libxml_get_last_error()->message));
}
$ruleSet = new RuleSet();
$ruleSet->setFileName($fileName);
$ruleSet->setName((string) $xml['name']);
if ($this->strict) {
$ruleSet->setStrict();
}
foreach ($xml->children() as $node) {
if ($node->getName() === 'php-includepath') {
$includePath = (string) $node;
if (is_dir(dirname($fileName) . DIRECTORY_SEPARATOR . $includePath)) {
$includePath = dirname($fileName) . DIRECTORY_SEPARATOR . $includePath;
$includePath = realpath($includePath);
}
$includePath = get_include_path() . PATH_SEPARATOR . $includePath;
set_include_path($includePath);
}
}
foreach ($xml->children() as $node) {
if ($node->getName() === 'description') {
$ruleSet->setDescription((string) $node);
} elseif ($node->getName() === 'rule') {
$this->parseRuleNode($ruleSet, $node);
}
}
return $ruleSet;
}
/**
* This method parses a single rule xml node. Bases on the structure of the
* xml node this method delegates the parsing process to another method in
* this class.
*
* @param \PHPMD\RuleSet $ruleSet
* @param \SimpleXMLElement $node
* @return void
*/
private function parseRuleNode(RuleSet $ruleSet, \SimpleXMLElement $node)
{
if (substr($node['ref'], -3, 3) === 'xml') {
$this->parseRuleSetReferenceNode($ruleSet, $node);
} elseif ('' === (string) $node['ref']) {
$this->parseSingleRuleNode($ruleSet, $node);
} else {
$this->parseRuleReferenceNode($ruleSet, $node);
}
}
/**
* This method parses a complete rule set that was includes a reference in
* the currently parsed ruleset.
*
* @param \PHPMD\RuleSet $ruleSet
* @param \SimpleXMLElement $ruleSetNode
* @return void
*/
private function parseRuleSetReferenceNode(RuleSet $ruleSet, \SimpleXMLElement $ruleSetNode)
{
$rules = $this->parseRuleSetReference($ruleSetNode);
foreach ($rules as $rule) {
if ($this->isIncluded($rule, $ruleSetNode)) {
$ruleSet->addRule($rule);
}
}
}
/**
* Parses a rule-set xml file referenced by the given rule-set xml element.
*
* @param \SimpleXMLElement $ruleSetNode
* @return \PHPMD\RuleSet
* @since 0.2.3
*/
private function parseRuleSetReference(\SimpleXMLElement $ruleSetNode)
{
$ruleSetFactory = new RuleSetFactory();
$ruleSetFactory->setMinimumPriority($this->minimumPriority);
return $ruleSetFactory->createSingleRuleSet((string) $ruleSetNode['ref']);
}
/**
* Checks if the given rule is included/not excluded by the given rule-set
* reference node.
*
* @param \PHPMD\Rule $rule
* @param \SimpleXMLElement $ruleSetNode
* @return boolean
* @since 0.2.3
*/
private function isIncluded(Rule $rule, \SimpleXMLElement $ruleSetNode)
{
foreach ($ruleSetNode->exclude as $exclude) {
if ($rule->getName() === (string) $exclude['name']) {
return false;
}
}
return true;
}
/**
* This method will create a single rule instance and add it to the given
* {@link \PHPMD\RuleSet} object.
*
* @param \PHPMD\RuleSet $ruleSet
* @param \SimpleXMLElement $ruleNode
* @return void
* @throws \PHPMD\RuleClassFileNotFoundException
* @throws \PHPMD\RuleClassNotFoundException
*/
private function parseSingleRuleNode(RuleSet $ruleSet, \SimpleXMLElement $ruleNode)
{
$fileName = "";
$ruleSetFolderPath = dirname($ruleSet->getFileName());
if (isset($ruleNode['file'])) {
if (is_readable((string) $ruleNode['file'])) {
$fileName = (string) $ruleNode['file'];
} elseif (is_readable($ruleSetFolderPath . DIRECTORY_SEPARATOR . (string) $ruleNode['file'])) {
$fileName = $ruleSetFolderPath . DIRECTORY_SEPARATOR . (string) $ruleNode['file'];
}
}
$className = (string) $ruleNode['class'];
if (!is_readable($fileName)) {
$fileName = strtr($className, '\\', '/') . '.php';
}
if (!is_readable($fileName)) {
$fileName = str_replace(array('\\', '_'), '/', $className) . '.php';
}
if (class_exists($className) === false) {
$handle = @fopen($fileName, 'r', true);
if ($handle === false) {
throw new RuleClassFileNotFoundException($className);
}
fclose($handle);
include_once $fileName;
if (class_exists($className) === false) {
throw new RuleClassNotFoundException($className);
}
}
/* @var $rule \PHPMD\Rule */
$rule = new $className();
$rule->setName((string) $ruleNode['name']);
$rule->setMessage((string) $ruleNode['message']);
$rule->setExternalInfoUrl((string) $ruleNode['externalInfoUrl']);
$rule->setRuleSetName($ruleSet->getName());
if (trim($ruleNode['since']) !== '') {
$rule->setSince((string) $ruleNode['since']);
}
foreach ($ruleNode->children() as $node) {
if ($node->getName() === 'description') {
$rule->setDescription((string) $node);
} elseif ($node->getName() === 'example') {
$rule->addExample((string) $node);
} elseif ($node->getName() === 'priority') {
$rule->setPriority((integer) $node);
} elseif ($node->getName() === 'properties') {
$this->parsePropertiesNode($rule, $node);
}
}
if ($rule->getPriority() <= $this->minimumPriority) {
$ruleSet->addRule($rule);
}
}
/**
* This method parses a single rule that was included from a different
* rule-set.
*
* @param \PHPMD\RuleSet $ruleSet
* @param \SimpleXMLElement $ruleNode
* @return void
*/
private function parseRuleReferenceNode(RuleSet $ruleSet, \SimpleXMLElement $ruleNode)
{
$ref = (string) $ruleNode['ref'];
$fileName = substr($ref, 0, strpos($ref, '.xml/') + 4);
$fileName = $this->createRuleSetFileName($fileName);
$ruleName = substr($ref, strpos($ref, '.xml/') + 5);
$ruleSetFactory = new RuleSetFactory();
$ruleSetRef = $ruleSetFactory->createSingleRuleSet($fileName);
$rule = $ruleSetRef->getRuleByName($ruleName);
if (trim($ruleNode['name']) !== '') {
$rule->setName((string) $ruleNode['name']);
}
if (trim($ruleNode['message']) !== '') {
$rule->setMessage((string) $ruleNode['message']);
}
if (trim($ruleNode['externalInfoUrl']) !== '') {
$rule->setExternalInfoUrl((string) $ruleNode['externalInfoUrl']);
}
foreach ($ruleNode->children() as $node) {
if ($node->getName() === 'description') {
$rule->setDescription((string) $node);
} elseif ($node->getName() === 'example') {
$rule->addExample((string) $node);
} elseif ($node->getName() === 'priority') {
$rule->setPriority((integer) $node);
} elseif ($node->getName() === 'properties') {
$this->parsePropertiesNode($rule, $node);
}
}
if ($rule->getPriority() <= $this->minimumPriority) {
$ruleSet->addRule($rule);
}
}
/**
* This method parses a xml properties structure and adds all found properties
* to the given <b>$rule</b> object.
*
* <code>
* ...
* <properties>
* <property name="foo" value="42" />
* <property name="bar" value="23" />
* ...
* </properties>
* ...
* </code>
*
* @param \PHPMD\Rule $rule
* @param \SimpleXMLElement $propertiesNode
* @return void
*/
private function parsePropertiesNode(Rule $rule, \SimpleXMLElement $propertiesNode)
{
foreach ($propertiesNode->children() as $node) {
if ($node->getName() === 'property') {
$this->addProperty($rule, $node);
}
}
}
/**
* Adds an additional property to the given <b>$rule</b> instance.
*
* @param \PHPMD\Rule $rule
* @param \SimpleXMLElement $node
* @return void
*/
private function addProperty(Rule $rule, \SimpleXMLElement $node)
{
$name = trim($node['name']);
$value = trim($this->getPropertyValue($node));
if ($name !== '' && $value !== '') {
$rule->addProperty($name, $value);
}
}
/**
* Returns the value of a property node. This value can be expressed in
* two different notations. First version is an attribute named <b>value</b>
* and the second valid notation is a child element named <b>value</b> that
* contains the value as character data.
*
* @param \SimpleXMLElement $propertyNode
* @return string
* @since 0.2.5
*/
private function getPropertyValue(\SimpleXMLElement $propertyNode)
{
if (isset($propertyNode->value)) {
return (string) $propertyNode->value;
}
return (string) $propertyNode['value'];
}
/**
* Returns an array of path exclude patterns in format described at
*
* http://pmd.sourceforge.net/pmd-5.0.4/howtomakearuleset.html#Excluding_files_from_a_ruleset
*
* @param $fileName The filename of a rule-set definition.
*
* @return array
* @throws \RuntimeException
*/
public function getIgnorePattern($fileName)
{
$excludes = array();
foreach (array_map('trim', explode(',', $fileName)) as $ruleSetFileName) {
$ruleSetFileName = $this->createRuleSetFileName($ruleSetFileName);
// Hide error messages
$libxml = libxml_use_internal_errors(true);
$xml = simplexml_load_string(file_get_contents($ruleSetFileName));
if ($xml === false) {
// Reset error handling to previous setting
libxml_use_internal_errors($libxml);
throw new \RuntimeException(trim(libxml_get_last_error()->message));
}
foreach ($xml->children() as $node) {
if ($node->getName() === 'exclude-pattern') {
$excludes[] = '' . $node;
}
}
return $excludes;
}
}
}
@@ -0,0 +1,62 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
/**
* This type of exception is thrown when a not existing rule-set was specified.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class RuleSetNotFoundException extends \RuntimeException
{
/**
* Constructs a new exception for the given rule-set identifier or file name.
*
* @param string $ruleSet The rule-set identifier or file name.
*/
public function __construct($ruleSet)
{
parent::__construct('Cannot find specified rule-set "' . $ruleSet . '".');
}
}
@@ -0,0 +1,236 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD;
use PHPMD\Node\AbstractTypeNode;
use PHPMD\Node\FunctionNode;
use PHPMD\Node\MethodNode;
/**
* This class is used as container for a single rule violation related to a source
* node.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class RuleViolation
{
/**
* The rule that causes this violation.
*
* @var \PHPMD\Rule
*/
private $rule;
/**
* The context code node for this rule violation.
*
* @var \PHPMD\AbstractNode
*/
private $node;
/**
* The description/message text that describes the violation.
*
* @var string
*/
private $description;
/**
* The raw metric value which caused this rule violation.
*
* @var mixed
*/
private $metric;
/**
* Name of the owning/context class or interface of this violation.
*
* @var string
*/
private $className = null;
/**
* The name of a method or <b>null</b> when this violation has no method
* context.
*
* @var string
*/
private $methodName = null;
/**
* The name of a function or <b>null</b> when this violation has no function
* context.
*
* @var string
*/
private $functionName = null;
/**
* Constructs a new rule violation instance.
*
* @param \PHPMD\Rule $rule
* @param \PHPMD\AbstractNode $node
* @param string $violationMessage
* @param mixed $metric
*/
public function __construct(Rule $rule, AbstractNode $node, $violationMessage, $metric = null)
{
$this->rule = $rule;
$this->node = $node;
$this->metric = $metric;
$this->description = $violationMessage;
if ($node instanceof AbstractTypeNode) {
$this->className = $node->getName();
} elseif ($node instanceof MethodNode) {
$this->className = $node->getParentName();
$this->methodName = $node->getName();
} elseif ($node instanceof FunctionNode) {
$this->functionName = $node->getName();
}
}
/**
* Returns the rule that causes this violation.
*
* @return \PHPMD\Rule
*/
public function getRule()
{
return $this->rule;
}
/**
* Returns the description/message text that describes the violation.
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Returns the raw metric value which caused this rule violation.
*
* @return mixed|null
*/
public function getMetric()
{
return $this->metric;
}
/**
* Returns the file name where this rule violation was detected.
*
* @return string
*/
public function getFileName()
{
return $this->node->getFileName();
}
/**
* Returns the first line of the node that causes this rule violation.
*
* @return integer
*/
public function getBeginLine()
{
return $this->node->getBeginLine();
}
/**
* Returns the last line of the node that causes this rule violation.
*
* @return integer
*/
public function getEndLine()
{
return $this->node->getEndLine();
}
/**
* Returns the name of the package that contains this violation.
*
* @return string
*/
public function getNamespaceName()
{
return $this->node->getNamespaceName();
}
/**
* Returns the name of the parent class or interface or <b>null</b> when there
* is no parent class.
*
* @return string
*/
public function getClassName()
{
return $this->className;
}
/**
* Returns the name of a method or <b>null</b> when this violation has no
* method context.
*
* @return string
*/
public function getMethodName()
{
return $this->methodName;
}
/**
* Returns the name of a function or <b>null</b> when this violation has no
* function context.
*
* @return string
*/
public function getFunctionName()
{
return $this->functionName;
}
}
@@ -0,0 +1,179 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\TextUI;
use PHPMD\PHPMD;
use PHPMD\RuleSetFactory;
use PHPMD\Writer\StreamWriter;
/**
* This class provides a command line interface for PHPMD
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class Command
{
/**
* Exit codes used by the phpmd command line tool.
*/
const EXIT_SUCCESS = 0,
EXIT_EXCEPTION = 1,
EXIT_VIOLATION = 2;
/**
* This method creates a PHPMD instance and configures this object based
* on the user's input, then it starts the source analysis.
*
* The return value of this method can be used as an exit code. A value
* equal to <b>EXIT_SUCCESS</b> means that no violations or errors were
* found in the analyzed code. Otherwise this method will return a value
* equal to <b>EXIT_VIOLATION</b>.
*
* @param \PHPMD\TextUI\CommandLineOptions $opts
* @param \PHPMD\RuleSetFactory $ruleSetFactory
* @return integer
*/
public function run(CommandLineOptions $opts, RuleSetFactory $ruleSetFactory)
{
if ($opts->hasVersion()) {
fwrite(STDOUT, sprintf('PHPMD %s', $this->getVersion()) . PHP_EOL);
return self::EXIT_SUCCESS;
}
// Create a report stream
$stream = $opts->getReportFile() ? fopen($opts->getReportFile(), 'wb') : STDOUT;
// Create renderer and configure output
$renderer = $opts->createRenderer();
$renderer->setWriter(new StreamWriter($stream));
$renderers = array($renderer);
foreach ($opts->getReportFiles() as $reportFormat => $reportFile) {
$reportRenderer = $opts->createRenderer($reportFormat);
$reportRenderer->setWriter(new StreamWriter(fopen($reportFile, 'wb')));
$renderers[] = $reportRenderer;
}
// Configure a rule set factory
$ruleSetFactory->setMinimumPriority($opts->getMinimumPriority());
if ($opts->hasStrict()) {
$ruleSetFactory->setStrict();
}
$phpmd = new PHPMD();
$phpmd->setOptions(
array_filter(
array(
'coverage' => $opts->getCoverageReport()
)
)
);
$extensions = $opts->getExtensions();
if ($extensions !== null) {
$phpmd->setFileExtensions(explode(',', $extensions));
}
$ignore = $opts->getIgnore();
if ($ignore !== null) {
$phpmd->setIgnorePattern(explode(',', $ignore));
}
$phpmd->processFiles(
$opts->getInputPath(),
$opts->getRuleSets(),
$renderers,
$ruleSetFactory
);
if ($phpmd->hasViolations()) {
return self::EXIT_VIOLATION;
}
return self::EXIT_SUCCESS;
}
/**
* Returns the current version number.
*
* @return string
*/
private function getVersion()
{
$build = __DIR__ . '/../../../../../build.properties';
$version = '@package_version@';
if (file_exists($build)) {
$data = @parse_ini_file($build);
$version = $data['project.version'];
}
return $version;
}
/**
* The main method that can be used by a calling shell script, the return
* value can be used as exit code.
*
* @param array $args The raw command line arguments array.
*
* @return integer
*/
public static function main(array $args)
{
try {
$ruleSetFactory = new RuleSetFactory();
$options = new CommandLineOptions($args, $ruleSetFactory->listAvailableRuleSets());
$command = new Command();
$exitCode = $command->run($options, $ruleSetFactory);
} catch (\Exception $e) {
fwrite(STDERR, $e->getMessage());
fwrite(STDERR, PHP_EOL);
$exitCode = self::EXIT_EXCEPTION;
}
return $exitCode;
}
}
@@ -0,0 +1,480 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\TextUI;
use PHPMD\Renderer\HTMLRenderer;
use PHPMD\Renderer\TextRenderer;
use PHPMD\Renderer\XMLRenderer;
use PHPMD\Rule;
/**
* This is a helper class that collects the specified cli arguments and puts them
* into accessible properties.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class CommandLineOptions
{
/**
* Error code for invalid input
*/
const INPUT_ERROR = 23;
/**
* The minimum rule priority.
*
* @var integer
*/
protected $minimumPriority = Rule::LOWEST_PRIORITY;
/**
* A php source code filename or directory.
*
* @var string
*/
protected $inputPath;
/**
* The specified report format.
*
* @var string
*/
protected $reportFormat;
/**
* An optional filename for the generated report.
*
* @var string
*/
protected $reportFile;
/**
* Additional report files.
*
* @var array
*/
protected $reportFiles = array();
/**
* A ruleset filename or a comma-separated string of ruleset filenames.
*
* @var string
*/
protected $ruleSets;
/**
* File name of a PHPUnit code coverage report.
*
* @var string
*/
protected $coverageReport;
/**
* A string of comma-separated extensions for valid php source code filenames.
*
* @var string
*/
protected $extensions;
/**
* A string of comma-separated pattern that is used to exclude directories.
*
* @var string
*/
protected $ignore;
/**
* Should the shell show the current phpmd version?
*
* @var boolean
*/
protected $version = false;
/**
* Should PHPMD run in strict mode?
*
* @var boolean
* @since 1.2.0
*/
protected $strict = false;
/**
* List of available rule-sets.
*
* @var array(string)
*/
protected $availableRuleSets = array();
/**
* Constructs a new command line options instance.
*
* @param array $args
* @param array $availableRuleSets
* @throws \InvalidArgumentException
*/
public function __construct(array $args, array $availableRuleSets = array())
{
// Remove current file name
array_shift($args);
$this->availableRuleSets = $availableRuleSets;
$arguments = array();
while (($arg = array_shift($args)) !== null) {
switch ($arg) {
case '--minimumpriority':
$this->minimumPriority = (int) array_shift($args);
break;
case '--reportfile':
$this->reportFile = array_shift($args);
break;
case '--inputfile':
array_unshift($arguments, $this->readInputFile(array_shift($args)));
break;
case '--coverage':
$this->coverageReport = array_shift($args);
break;
case '--extensions':
$this->logDeprecated('extensions', 'suffixes');
/* Deprecated: We use the suffixes option now */
case '--suffixes':
$this->extensions = array_shift($args);
break;
case '--ignore':
$this->logDeprecated('ignore', 'exclude');
/* Deprecated: We use the exclude option now */
case '--exclude':
$this->ignore = array_shift($args);
break;
case '--version':
$this->version = true;
return;
case '--strict':
$this->strict = true;
break;
case (preg_match('(^\-\-reportfile\-(xml|html|text)$)', $arg, $match) > 0):
$this->reportFiles[$match[1]] = array_shift($args);
break;
default:
$arguments[] = $arg;
break;
}
}
if (count($arguments) < 3) {
throw new \InvalidArgumentException($this->usage(), self::INPUT_ERROR);
}
$this->inputPath = (string) array_shift($arguments);
$this->reportFormat = (string) array_shift($arguments);
$this->ruleSets = (string) array_shift($arguments);
}
/**
* Returns a php source code filename or directory.
*
* @return string
*/
public function getInputPath()
{
return $this->inputPath;
}
/**
* Returns the specified report format.
*
* @return string
*/
public function getReportFormat()
{
return $this->reportFormat;
}
/**
* Returns the output filename for a generated report or <b>null</b> when
* the report should be displayed in STDOUT.
*
* @return string
*/
public function getReportFile()
{
return $this->reportFile;
}
/**
* Returns a hash with report files specified for different renderers. The
* key represents the report format and the value the report file location.
*
* @return array
*/
public function getReportFiles()
{
return $this->reportFiles;
}
/**
* Returns a ruleset filename or a comma-separated string of ruleset
*
* @return string
*/
public function getRuleSets()
{
return $this->ruleSets;
}
/**
* Returns the minimum rule priority.
*
* @return integer
*/
public function getMinimumPriority()
{
return $this->minimumPriority;
}
/**
* Returns the file name of a supplied code coverage report or <b>NULL</b>
* if the user has not supplied the --coverage option.
*
* @return string
*/
public function getCoverageReport()
{
return $this->coverageReport;
}
/**
* Returns a string of comma-separated extensions for valid php source code
* filenames or <b>null</b> when this argument was not set.
*
* @return string
*/
public function getExtensions()
{
return $this->extensions;
}
/**
* Returns string of comma-separated pattern that is used to exclude
* directories or <b>null</b> when this argument was not set.
*
* @return string
*/
public function getIgnore()
{
return $this->ignore;
}
/**
* Was the <b>--version</b> passed to PHPMD's command line interface?
*
* @return boolean
*/
public function hasVersion()
{
return $this->version;
}
/**
* Was the <b>--strict</b> option passed to PHPMD's command line interface?
*
* @return boolean
* @since 1.2.0
*/
public function hasStrict()
{
return $this->strict;
}
/**
* Creates a report renderer instance based on the user's command line
* argument.
*
* Valid renderers are:
* <ul>
* <li>xml</li>
* <li>html</li>
* <li>text</li>
* </ul>
*
* @param string $reportFormat
* @return \PHPMD\AbstractRenderer
* @throws \InvalidArgumentException When the specified renderer does not exist.
*/
public function createRenderer($reportFormat = null)
{
$reportFormat = $reportFormat ?: $this->reportFormat;
switch ($reportFormat) {
case 'xml':
return $this->createXmlRenderer();
case 'html':
return $this->createHtmlRenderer();
case 'text':
return $this->createTextRenderer();
default:
return $this->createCustomRenderer();
}
}
/**
* @return \PHPMD\Renderer\XMLRenderer
*/
protected function createXmlRenderer()
{
return new XMLRenderer();
}
/**
* @return \PHPMD\Renderer\XMLRenderer
*/
protected function createTextRenderer()
{
return new TextRenderer();
}
/**
* @return \PHPMD\Renderer\HTMLRenderer
*/
protected function createHtmlRenderer()
{
return new HTMLRenderer();
}
/**
* @return \PHPMD\AbstractRenderer
* @throws \InvalidArgumentException
*/
protected function createCustomRenderer()
{
if ($this->reportFormat !== '') {
if (class_exists($this->reportFormat)) {
return new $this->reportFormat();
}
// Try to load a custom renderer
$fileName = strtr($this->reportFormat, '_', '/') . '.php';
$fileHandle = @fopen($fileName, 'r', true);
if (is_resource($fileHandle) === false) {
$message = 'Can\'t find the custom report class: '
. $this->reportFormat;
throw new \InvalidArgumentException($message, self::INPUT_ERROR);
}
@fclose($fileHandle);
include_once $fileName;
return new $this->reportFormat();
}
$message = 'Can\'t create report with format of ' . $this->reportFormat;
throw new \InvalidArgumentException($message, self::INPUT_ERROR);
}
/**
* Returns usage information for the PHPMD command line interface.
*
* @return string
*/
public function usage()
{
return 'Mandatory arguments:' . \PHP_EOL .
'1) A php source code filename or directory. Can be a comma-' .
'separated string' . \PHP_EOL .
'2) A report format' . \PHP_EOL .
'3) A ruleset filename or a comma-separated string of ruleset' .
'filenames' . \PHP_EOL . \PHP_EOL .
'Available formats: xml, text, html.' . \PHP_EOL .
'Available rulesets: ' . implode(', ', $this->availableRuleSets) . '.' . \PHP_EOL . \PHP_EOL .
'Optional arguments that may be put after the mandatory arguments:' .
\PHP_EOL .
'--minimumpriority: rule priority threshold; rules with lower ' .
'priority than this will not be used' . \PHP_EOL .
'--reportfile: send report output to a file; default to STDOUT' .
\PHP_EOL .
'--suffixes: comma-separated string of valid source code ' .
'filename extensions, e.g. php,phtml' . \PHP_EOL .
'--exclude: comma-separated string of patterns that are used to ' .
'ignore directories' . \PHP_EOL .
'--strict: also report those nodes with a @SuppressWarnings ' .
'annotation' . \PHP_EOL;
}
/**
* Logs a deprecated option to the current user interface.
*
* @param string $deprecatedName
* @param string $newName
* @return void
*/
protected function logDeprecated($deprecatedName, $newName)
{
$message = sprintf(
'The --%s option is deprecated, please use --%s instead.',
$deprecatedName,
$newName
);
fwrite(STDERR, $message . \PHP_EOL . \PHP_EOL);
}
/**
* This method takes the given input file, reads the newline separated paths
* from that file and creates a comma separated string of the file paths. If
* the given <b>$inputFile</b> not exists, this method will throw an
* exception.
*
* @param string $inputFile Specified input file name.
* @return string
* @throws \InvalidArgumentException If the specified input file does not exist.
* @since 1.1.0
*/
protected function readInputFile($inputFile)
{
if (file_exists($inputFile)) {
return join(',', array_map('trim', file($inputFile)));
}
throw new \InvalidArgumentException("Input file '{$inputFile}' not exists.");
}
}
@@ -0,0 +1,106 @@
<?php
/**
* This file is part of PHP Mess Detector.
*
* Copyright (c) 2008-2012, Manuel Pichler <mapi@phpmd.org>.
* 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 Manuel Pichler nor the names of his
* 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.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace PHPMD\Writer;
use PHPMD\AbstractWriter;
/**
* This writer uses PHP's stream api as its output target.
*
* @author Manuel Pichler <mapi@phpmd.org>
* @copyright 2008-2014 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
class StreamWriter extends AbstractWriter
{
/**
* The stream resource handle
*
* @var resource
*/
private $stream = null;
/**
* Constructs a new stream writer instance.
*
* @param resource|string $streamResourceOrUri
*/
public function __construct($streamResourceOrUri)
{
if (is_resource($streamResourceOrUri) === true) {
$this->stream = $streamResourceOrUri;
} else {
$dirName = dirname($streamResourceOrUri);
if (file_exists($dirName) === false) {
mkdir($dirName, 0777, true);
}
if (file_exists($dirName) === false) {
$message = 'Cannot find output directory "' . $dirName . '".';
throw new \RuntimeException($message);
}
$this->stream = fopen($streamResourceOrUri, 'wb');
}
}
/**
* The dtor closes the open output resource.
*/
public function __destruct()
{
if ($this->stream !== STDOUT && is_resource($this->stream) === true) {
@fclose($this->stream);
}
$this->stream = null;
}
/**
* Writes the given <b>$data</b> fragment to the wrapper output stream.
*
* @param string $data
* @return void
*/
public function write($data)
{
fwrite($this->stream, $data);
}
}
@@ -0,0 +1,99 @@
<?xml version="1.0"?>
<ruleset name="Clean Code Rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
The Clean Code ruleset contains rules that enforce a clean code base. This includes rules from SOLID and object calisthenics.
</description>
<rule name="BooleanArgumentFlag"
since="1.4.0"
message="The method {0} has a boolean flag argument {1}, which is a certain sign of a Single Responsibility Principle violation."
class="PHPMD\Rule\CleanCode\BooleanArgumentFlag"
externalInfoUrl="http://phpmd.org/rules/cleancode.html#booleanargumentflag">
<description>
<![CDATA[
A boolean flag argument is a reliable indicator for a violation of
the Single Responsibility Principle (SRP). You can fix this problem
by extracting the logic in the boolean flag into its own class
or method.
]]>
</description>
<priority>1</priority>
<properties />
<example>
<![CDATA[
class Foo {
public function bar($flag = true) {
}
}
]]>
</example>
</rule>
<rule name="ElseExpression"
since="1.4.0"
message="The method {0} uses an else expression. Else is never necessary and you can simplify the code to work without else."
class="PHPMD\Rule\CleanCode\ElseExpression"
externalInfoUrl="http://phpmd.org/rules/cleancode.html#eleseexpression">
<description>
<![CDATA[
An if expression with an else branch is never necessary. You can rewrite the
conditions in a way that the else is not necessary and the code becomes simpler
to read. To achieve this use early return statements. To achieve this you may
need to split the code it several smaller methods. For very simple assignments
you could also use the ternary operations.
]]>
</description>
<priority>1</priority>
<properties></properties>
<example>
<![CDATA[
class Foo
{
public function bar($flag)
{
if ($flag) {
// one branch
} else {
// another branch
}
}
}
]]>
</example>
</rule>
<rule name="StaticAccess"
since="1.4.0"
message="Avoid using static access to class '{0}' in method '{1}'."
class="PHPMD\Rule\CleanCode\StaticAccess"
externalInfoUrl="http://phpmd.org/rules/cleancode.html#staticaccess">
<description>
<![CDATA[
Static access causes inexchangable dependencies to other classes and leads to hard to test code. Avoid
using static access at all costs and instead inject dependencies through the constructor. The only
case when static access is acceptable is when used for factory methods.
]]>
</description>
<priority>1</priority>
<properties>
<property name="exceptions" description="Comma-separated class name list of exceptions" value=""/>
</properties>
<example>
<![CDATA[
class Foo
{
public function bar()
{
Bar::baz();
}
}
]]>
</example>
</rule>
</ruleset>
@@ -0,0 +1,423 @@
<?xml version="1.0" encoding="UTF-8" ?>
<ruleset name="Code Size Rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
The Code Size Ruleset contains a collection of rules that find code size related problems.
</description>
<rule name="CyclomaticComplexity"
since="0.1"
message = "The {0} {1}() has a Cyclomatic Complexity of {2}. The configured cyclomatic complexity threshold is {3}."
class="PHPMD\Rule\CyclomaticComplexity"
externalInfoUrl="http://phpmd.org/rules/codesize.html#cyclomaticcomplexity">
<description>
<![CDATA[
Complexity is determined by the number of decision points in a method plus one for the
method entry. The decision points are 'if', 'while', 'for', and 'case labels'. Generally,
1-4 is low complexity, 5-7 indicates moderate complexity, 8-10 is high complexity,
and 11+ is very high complexity.
]]>
</description>
<priority>3</priority>
<properties>
<property name="reportLevel" description="The Cyclomatic Complexity reporting threshold" value="10"/>
<property name="showClassesComplexity"
description="Indicate if class average violation should be added to the report"
value="true"/>
<property name="showMethodsComplexity"
description="Indicate if class average violation should be added to the report"
value="true"/>
</properties>
<example>
<![CDATA[
// Cyclomatic Complexity = 12
class Foo {
1 public function example() {
2 if ($a == $b) {
3 if ($a1 == $b1) {
fiddle();
4 } else if ($a2 == $b2) {
fiddle();
} else {
fiddle();
}
5 } else if ($c == $d) {
6 while ($c == $d) {
fiddle();
}
7 } else if ($e == $f) {
8 for ($n = 0; $n < $h; $n++) {
fiddle();
}
} else{
switch ($z) {
9 case 1:
fiddle();
break;
10 case 2:
fiddle();
break;
11 case 3:
fiddle();
break;
12 default:
fiddle();
break;
}
}
}
}
]]>
</example>
</rule>
<rule name="NPathComplexity"
since="0.1"
message="The {0} {1}() has an NPath complexity of {2}. The configured NPath complexity threshold is {3}."
class="PHPMD\Rule\Design\NpathComplexity"
externalInfoUrl="http://phpmd.org/rules/codesize.html#npathcomplexity">
<description>
The NPath complexity of a method is the number of acyclic execution paths through that method.
A threshold of 200 is generally considered the point where measures should be taken to reduce complexity.
</description>
<priority>3</priority>
<properties>
<property name="minimum" description="The npath reporting threshold" value="200"/>
</properties>
<example>
<![CDATA[
class Foo {
function bar() {
// lots of complicated code
}
}
]]>
</example>
</rule>
<rule name="ExcessiveMethodLength"
since="0.1"
message="The {0} {1}() has {2} lines of code. Current threshold is set to {3}. Avoid really long methods."
class="PHPMD\Rule\Design\LongMethod"
externalInfoUrl="http://phpmd.org/rules/codesize.html#excessivemethodlength">
<description>
Violations of this rule usually indicate that the method is doing
too much. Try to reduce the method size by creating helper methods and removing any copy/pasted code.
</description>
<priority>3</priority>
<properties>
<property name="minimum" description="The method size reporting threshold" value="100"/>
<property name="ignore-whitespace" description="Count whitespace in reporting threshold" value="false"/>
</properties>
<example>
<![CDATA[
class Foo {
public function doSomething() {
print("Hello world!" . PHP_EOL);
print("Hello world!" . PHP_EOL);
// 98 copies omitted for brevity.
}
}
]]>
</example>
</rule>
<rule name="ExcessiveClassLength"
since="0.1"
message="The class {0} has {1} lines of code. Current threshold is {2}. Avoid really long classes."
class="PHPMD\Rule\Design\LongClass"
externalInfoUrl="http://phpmd.org/rules/codesize.html#excessiveclasslength">
<description>
Long Class files are indications that the class may be trying to
do too much. Try to break it down, and reduce the size to something
manageable.
</description>
<priority>3</priority>
<properties>
<property name="minimum" description="The class size reporting threshold" value="1000"/>
<property name="ignore-whitespace" description="Count whitespace in reporting threshold" value="false"/>
</properties>
<example>
<![CDATA[
class Foo {
public function bar() {
// 1000 lines of code
}
}
]]>
</example>
</rule>
<rule name="ExcessiveParameterList"
since="0.1"
message="The {0} {1} has {2} parameters. Consider to reduce parameter number under {3}."
class="PHPMD\Rule\Design\LongParameterList"
externalInfoUrl="http://phpmd.org/rules/codesize.html#excessiveparameterlist">
<description>
Long parameter lists can indicate that a new object should be created to
wrap the numerous parameters. Basically, try to group the parameters together.
</description>
<priority>3</priority>
<properties>
<property name="minimum" description="The parameter count reporting threshold" value="10"/>
</properties>
<example>
<![CDATA[
class Foo {
public function addData(
$p0, $p1, $p2, $p3, $p4, $p5,
$p5, $p6, $p7, $p8, $p9, $p10) {
}
}
]]>
</example>
</rule>
<rule name="ExcessivePublicCount"
since="0.1"
message="The {0} {1} has {2} public methods and attributes. Consider to reduce the number of public items under {3}."
class="PHPMD\Rule\ExcessivePublicCount"
externalInfoUrl="http://phpmd.org/rules/codesize.html#excessivepubliccount">
<description>
A large number of public methods and attributes declared in a class can indicate
the class may need to be broken up as increased effort will be required to
thoroughly test it.
</description>
<priority>3</priority>
<properties>
<property name="minimum" description="The public item reporting threshold" value="45"/>
</properties>
<example>
<![CDATA[
public class Foo {
public $value;
public $something;
public $var;
// [... more more public attributes ...]
public function doWork() {}
public function doMoreWork() {}
public function doWorkAgain() {}
// [... more more public methods ...]
}
]]>
</example>
</rule>
<rule name="TooManyFields"
since="0.1"
message="The {0} {1} has {2} fields. Consider to redesign {1} to keep the number of fields under {3}."
class="PHPMD\Rule\Design\TooManyFields"
externalInfoUrl="http://phpmd.org/rules/codesize.html#toomanyfields">
<description>
Classes that have too many fields could be redesigned to have fewer fields,
possibly through some nested object grouping of some of the information. For
example, a class with city/state/zip fields could instead have one Address
field.
</description>
<priority>3</priority>
<properties>
<property name="maxfields" description="The field count reporting threshold " value="15"/>
</properties>
<example>
<![CDATA[
class Person {
protected $one;
private $two;
private $three;
[... many more fields ...]
}
]]>
</example>
</rule>
<!--
<rule name="NcssMethodCount" message="The method {0}() has an NCSS line count of {1}"
since="3.9"
class="net.sourceforge.pmd.rules.codesize.NcssMethodCount"
externalInfoUrl="http://pmd.sourceforge.net/rules/codesize.html#NcssMethodCount">
<description>
This rule uses the NCSS (Non Commenting Source Statements) algorithm to determine the number of lines
of code for a given method. NCSS ignores comments, and counts actual statements. Using this algorithm,
lines of code that are split are counted as one.
</description>
<priority>3</priority>
<properties>
<property name="minimum" description="The method NCSS count reporting threshold" value="100"/>
</properties>
<example>
<![CDATA[
public class Foo extends Bar {
public int methd() {
super.methd();
//this method only has 1 NCSS lines
return 1;
}
}
]]>
</example>
</rule>
<rule name="NcssTypeCount" message="The type has an NCSS line count of {0}"
since="3.9"
class="net.sourceforge.pmd.rules.codesize.NcssTypeCount"
externalInfoUrl="http://pmd.sourceforge.net/rules/codesize.html#NcssTypeCount">
<description>
This rule uses the NCSS (Non Commenting Source Statements) algorithm to determine the number of lines
of code for a given type. NCSS ignores comments, and counts actual statements. Using this algorithm,
lines of code that are split are counted as one.
</description>
<priority>3</priority>
<properties>
<property name="minimum" description="The type NCSS count reporting threshold" value="1500"/>
</properties>
<example>
<![CDATA[
public class Foo extends Bar {
public Foo() {
//this class only has 6 NCSS lines
super();
super.foo();
}
}
]]>
</example></rule>
<rule name="NcssConstructorCount" message="The constructor with {0} parameters has an NCSS line count of {1}"
since="3.9"
class="net.sourceforge.pmd.rules.codesize.NcssConstructorCount"
externalInfoUrl="http://pmd.sourceforge.net/rules/codesize.html#NcssConstructorCount">
<description>
This rule uses the NCSS (Non Commenting Source Statements) algorithm to determine the number of lines
of code for a given constructor. NCSS ignores comments, and counts actual statements. Using this algorithm,
lines of code that are split are counted as one.
</description>
<priority>3</priority>
<properties>
<property name="minimum" description="The constructor NCSS count reporting threshold" value="100"/>
</properties>
<example>
<![CDATA[
public class Foo extends Bar {
public Foo() {
super();
//this constructor only has 1 NCSS lines
super.foo();
}
}
]]>
</example>
</rule>
-->
<rule name="TooManyMethods"
since="0.1"
class="PHPMD\Rule\Design\TooManyMethods"
message="The {0} {1} has {2} non-getter- and setter-methods. Consider refactoring {1} to keep number of methods under {3}."
externalInfoUrl="http://phpmd.org/rules/codesize.html#toomanymethods">
<description>
<![CDATA[
A class with too many methods is probably a good suspect for refactoring, in
order to reduce its complexity and find a way to have more fine grained objects.
By default it ignores methods starting with 'get' or 'set'.
The default was changed from 10 to 25 in PHPMD 2.3.
]]>
</description>
<priority>3</priority>
<properties>
<property name="maxmethods" description="The method count reporting threshold" value="25"/>
<property name="ignorepattern" description="Ignore methods matching this regex" value="(^(set|get))i"/>
</properties>
</rule>
<rule name="TooManyPublicMethods"
since="0.1"
class="PHPMD\Rule\Design\TooManyPublicMethods"
message="The {0} {1} has {2} public methods. Consider refactoring {1} to keep number of public methods under {3}."
externalInfoUrl="http://phpmd.org/rules/codesize.html#toomanypublicmethods">
<description>
<![CDATA[
A class with too many public methods is probably a good suspect for refactoring, in
order to reduce its complexity and find a way to have more fine grained objects.
By default it ignores methods starting with 'get' or 'set'.
]]>
</description>
<priority>3</priority>
<properties>
<property name="maxmethods" description="The method count reporting threshold" value="10"/>
<property name="ignorepattern" description="Ignore methods matching this regex" value="(^(set|get))i"/>
</properties>
</rule>
<rule name="ExcessiveClassComplexity"
since="0.2.5"
class="PHPMD\Rule\Design\WeightedMethodCount"
message="The class {0} has an overall complexity of {1} which is very high. The configured complexity threshold is {2}."
externalInfoUrl="http://phpmd.org/rules/codesize.html#excessiveclasscomplexity">
<description>
<![CDATA[
The Weighted Method Count (WMC) of a class is a good indicator of how much time
and effort is required to modify and maintain this class. The WMC metric is defined
as the sum of complexities of all methods declared in a class. A large number of
methods also means that this class has a greater potential impact on derived classes.
]]>
</description>
<priority>3</priority>
<properties>
<property name="maximum" description="The maximum WMC tolerable for a class." value="50"/>
</properties>
<example>
<![CDATA[
class Foo {
public function bar() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else if ($a2 == $b2) {
fiddle();
} else {
}
}
}
public function baz() {
if ($a == $b) {
if ($a1 == $b1) {
fiddle();
} else if ($a2 == $b2) {
fiddle();
} else {
}
}
}
// Several other complex methods
}
]]>
</example>
</rule>
</ruleset>
@@ -0,0 +1,158 @@
<?xml version="1.0"?>
<ruleset name="Controversial Rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
This ruleset contains a collection of controversial rules.
</description>
<rule name="Superglobals"
since="0.2"
message = "{0} accesses the super-global variable {1}."
class="PHPMD\Rule\Controversial\Superglobals"
externalInfoUrl="#">
<description>
<![CDATA[
Accessing a super-global variable directly is considered a bad practice.
These variables should be encapsulated in objects that are provided by a framework, for instance.
]]>
</description>
<priority>1</priority>
<properties />
<example>
<![CDATA[
class Foo {
public function bar() {
$name = $_POST['foo'];
}
}
]]>
</example>
</rule>
<rule name="CamelCaseClassName"
since="0.2"
message = "The class {0} is not named in CamelCase."
class="PHPMD\Rule\Controversial\CamelCaseClassName"
externalInfoUrl="#">
<description>
<![CDATA[
It is considered best practice to use the CamelCase notation to name classes.
]]>
</description>
<priority>1</priority>
<properties />
<example>
<![CDATA[
class class_name {
}
]]>
</example>
</rule>
<rule name="CamelCasePropertyName"
since="0.2"
message = "The property {0} is not named in camelCase."
class="PHPMD\Rule\Controversial\CamelCasePropertyName"
externalInfoUrl="#">
<description>
<![CDATA[
It is considered best practice to use the camelCase notation to name attributes.
]]>
</description>
<priority>1</priority>
<properties>
<property name="allow-underscore"
description="Allow an optional, single underscore at the beginning."
value="false" />
<property name="allow-underscore-test"
description="Is it allowed to have underscores in test method names."
value="false" />
</properties>
<example>
<![CDATA[
class ClassName {
protected $property_name;
}
]]>
</example>
</rule>
<rule name="CamelCaseMethodName"
since="0.2"
message = "The method {0} is not named in camelCase."
class="PHPMD\Rule\Controversial\CamelCaseMethodName"
externalInfoUrl="#">
<description>
<![CDATA[
It is considered best practice to use the camelCase notation to name methods.
]]>
</description>
<priority>1</priority>
<properties>
<property name="allow-underscore"
description="Allow an optional, single underscore at the beginning."
value="false" />
<property name="allow-underscore-test"
description="Is it allowed to have underscores in test method names."
value="false" />
</properties>
<example>
<![CDATA[
class ClassName {
public function get_name() {
}
}
]]>
</example>
</rule>
<rule name="CamelCaseParameterName"
since="0.2"
message = "The parameter {0} is not named in camelCase."
class="PHPMD\Rule\Controversial\CamelCaseParameterName"
externalInfoUrl="#">
<description>
<![CDATA[
It is considered best practice to use the camelCase notation to name parameters.
]]>
</description>
<priority>1</priority>
<properties />
<example>
<![CDATA[
class ClassName {
public function doSomething($user_name) {
}
}
]]>
</example>
</rule>
<rule name="CamelCaseVariableName"
since="0.2"
message = "The variable {0} is not named in camelCase."
class="PHPMD\Rule\Controversial\CamelCaseVariableName"
externalInfoUrl="#">
<description>
<![CDATA[
It is considered best practice to use the camelCase notation to name variables.
]]>
</description>
<priority>1</priority>
<properties />
<example>
<![CDATA[
class ClassName {
public function doSomething() {
$data_module = new DataModule();
}
}
]]>
</example>
</rule>
</ruleset>
@@ -0,0 +1,228 @@
<?xml version="1.0"?>
<ruleset name="Design Rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
The Code Size Ruleset contains a collection of rules that find software design related problems.
</description>
<rule name="ExitExpression"
since="0.2"
message = "The {0} {1}() contains an exit expression."
class="PHPMD\Rule\Design\ExitExpression"
externalInfoUrl="http://phpmd.org/rules/design.html#exitexpression">
<description>
<![CDATA[
An exit-expression within regular code is untestable and therefore it should
be avoided. Consider to move the exit-expression into some kind of startup
script where an error/exception code is returned to the calling environment.
]]>
</description>
<priority>1</priority>
<properties />
<example>
<![CDATA[
class Foo {
public function bar($param) {
if ($param === 42) {
exit(23);
}
}
}
]]>
</example>
</rule>
<rule name="EvalExpression"
since="0.2"
message = "The {0} {1}() contains an eval expression."
class="PHPMD\Rule\Design\EvalExpression"
externalInfoUrl="http://phpmd.org/rules/design.html#evalexpression">
<description>
<![CDATA[
An eval-expression is untestable, a security risk and bad practice. Therefore
it should be avoided. Consider to replace the eval-expression with regular
code.
]]>
</description>
<priority>1</priority>
<properties />
<example>
<![CDATA[
class Foo {
public function bar($param) {
if ($param === 42) {
eval('$param = 23;');
}
}
}
]]>
</example>
</rule>
<rule name="GotoStatement"
since="1.1.0"
message="The {0} {1}() utilizes a goto statement."
class="PHPMD\Rule\Design\GotoStatement"
externalInfoUrl="http://phpmd.org/rules/design.html#gotostatement">
<description>
<![CDATA[
Goto makes code harder to read and it is nearly impossible to understand the
control flow of an application that uses this language construct. Therefore it
should be avoided. Consider to replace Goto with regular control structures and
separate methods/function, which are easier to read.
]]>
</description>
<priority>1</priority>
<properties />
<example>
<![CDATA[
class Foo {
public function bar($param) {
A:
if ($param === 42) {
goto X;
}
Y:
if (time() % 42 === 23) {
goto Z;
}
X:
if (time() % 23 === 42) {
goto Y;
}
Z:
return 42;
}
}
]]>
</example>
</rule>
<rule name="NumberOfChildren"
since="0.2"
message = "The {0} {1} has {2} children. Consider to rebalance this class hierarchy to keep number of children under {3}."
class="PHPMD\Rule\Design\NumberOfChildren"
externalInfoUrl="http://phpmd.org/rules/design.html#numberofchildren">
<description>
<![CDATA[
A class with an excessive number of children is an indicator for an unbalanced
class hierarchy. You should consider to refactor this class hierarchy.
]]>
</description>
<priority>2</priority>
<properties>
<property name="minimum" value="15" description="Maximum number of acceptable child classes." />
</properties>
<example />
</rule>
<rule name="DepthOfInheritance"
since="0.2"
message = "The {0} {1} has {2} parents. Consider to reduce the depth of this class hierarchy to under {3}."
class="PHPMD\Rule\Design\DepthOfInheritance"
externalInfoUrl="http://phpmd.org/rules/design.html#depthofinheritance">
<description>
<![CDATA[
A class with many parents is an indicator for an unbalanced and wrong class
hierarchy. You should consider to refactor this class hierarchy.
]]>
</description>
<priority>2</priority>
<properties>
<property name="minimum" value="6" description="Maximum number of acceptable parent classes." />
</properties>
<example />
</rule>
<rule name="CouplingBetweenObjects"
since="1.1.0"
message="The class {0} has a coupling between objects value of {1}. Consider to reduce the number of dependencies under {2}."
class="PHPMD\Rule\Design\CouplingBetweenObjects"
externalInfoUrl="http://phpmd.org/rules/design.html#couplingbetweenobjects">
<description>
<![CDATA[
A class with too many dependencies has negative impacts on several quality
aspects of a class. This includes quality criteria like stability,
maintainability and understandability
]]>
</description>
<priority>2</priority>
<properties>
<property name="minimum" value="13" description="Maximum number of acceptable dependencies." />
</properties>
<example>
<![CDATA[
class Foo {
/**
* @var \foo\bar\X
*/
private $x = null;
/**
* @var \foo\bar\Y
*/
private $y = null;
/**
* @var \foo\bar\Z
*/
private $z = null;
public function setFoo(\Foo $foo) {}
public function setBar(\Bar $bar) {}
public function setBaz(\Baz $baz) {}
/**
* @return \SplObjectStorage
* @throws \OutOfRangeException
* @throws \InvalidArgumentException
* @throws \ErrorException
*/
public function process(\Iterator $it) {}
// ...
}
]]>
</example>
</rule>
<rule name="DevelopmentCodeFragment"
since="2.3.0"
message="The {0} {1}() calls the typical debug function {2}() which is mostly only used during development."
class="PHPMD\Rule\Design\DevelopmentCodeFragment"
externalInfoUrl="http://phpmd.org/rules/design.html#developmentcodefragment">
<description>
<![CDATA[
Functions like var_dump(), print_r() etc. are normally only used during development
and therefore such calls in production code are a good indicator that they were
just forgotten.
]]>
</description>
<priority>2</priority>
<properties>
<property name="unwanted-functions" value="var_dump,print_r,debug_zval_dump,debug_print_backtrace" description="Comma separated list of suspect function images." />
</properties>
<example>
<![CDATA[
class SuspectCode {
public function doSomething(array $items)
{
foreach ($items as $i => $item) {
// …
if ('qafoo' == $item) var_dump($i);
// …
}
}
}
]]>
</example>
</rule>
</ruleset>
@@ -0,0 +1,363 @@
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="Naming Rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
The Naming Ruleset contains a collection of rules about names - too long, too short, and so forth.
</description>
<rule name="ShortVariable"
since="0.2"
message="Avoid variables with short names like {0}. Configured minimum length is {1}."
class="PHPMD\Rule\Naming\ShortVariable"
externalInfoUrl="http://phpmd.org/rules/naming.html#shortvariable">
<description>
Detects when a field, local, or parameter has a very short name.
</description>
<priority>3</priority>
<properties>
<property name="minimum" description="Minimum length for a variable, property or parameter name" value="3"/>
<property name="exceptions" description="Comma-separated list of exceptions" value=""/>
</properties>
<example>
<![CDATA[
class Something {
private $q = 15; // VIOLATION - Field
public static function main( array $as ) { // VIOLATION - Formal
$r = 20 + $this->q; // VIOLATION - Local
for (int $i = 0; $i < 10; $i++) { // Not a Violation (inside FOR)
$r += $this->q;
}
}
}
]]>
</example>
</rule>
<rule name="LongVariable"
since="0.2"
message="Avoid excessively long variable names like {0}. Keep variable name length under {1}."
class="PHPMD\Rule\Naming\LongVariable"
externalInfoUrl="http://phpmd.org/rules/naming.html#longvariable">
<description>
Detects when a field, formal or local variable is declared with a long name.
</description>
<priority>3</priority>
<properties>
<property name="maximum" description="The variable length reporting threshold" value="20"/>
</properties>
<example>
<![CDATA[
class Something {
protected $reallyLongIntName = -3; // VIOLATION - Field
public static function main( array $argumentsList[] ) { // VIOLATION - Formal
$otherReallyLongName = -5; // VIOLATION - Local
for ($interestingIntIndex = 0; // VIOLATION - For
$interestingIntIndex < 10;
$interestingIntIndex++ ) {
}
}
}
]]>
</example>
</rule>
<rule name="ShortMethodName"
since="0.2"
message="Avoid using short method names like {0}::{1}(). The configured minimum method name length is {2}."
class="PHPMD\Rule\Naming\ShortMethodName"
externalInfoUrl="http://phpmd.org/rules/naming.html#shortmethodname">
<description>
Detects when very short method names are used.
</description>
<priority>3</priority>
<properties>
<property name="minimum" description="Minimum length for a method or function name" value="3"/>
<property name="exceptions" description="Comma-separated list of exceptions" value=""/>
</properties>
<example>
<![CDATA[
class ShortMethod {
public function a( $index ) { // Violation
}
}
]]>
</example>
</rule>
<rule name="ConstructorWithNameAsEnclosingClass"
since="0.2"
message="Classes should not have a constructor method with the same name as the class"
class="PHPMD\Rule\Naming\ConstructorWithNameAsEnclosingClass"
externalInfoUrl="http://phpmd.org/rules/naming.html#constructorwithnameasenclosingclass">
<description>
A constructor method should not have the same name as the enclosing class, consider
to use the PHP 5 __construct method.
</description>
<priority>3</priority>
<example>
<![CDATA[
class MyClass {
// this is bad because it is PHP 4 style
public function MyClass() {}
// this is good because it is a PHP 5 constructor
public function __construct() {}
}
]]>
</example>
</rule>
<rule name="ConstantNamingConventions"
since="0.2"
message="Constant {0} should be defined in uppercase"
class="PHPMD\Rule\Naming\ConstantNamingConventions"
externalInfoUrl="http://phpmd.org/rules/naming.html#constantnamingconventions">
<description>
Class/Interface constant nanmes should always be defined in uppercase.
</description>
<priority>4</priority>
<properties />
<example>
<![CDATA[
class Foo {
const MY_NUM = 0; // ok
const myTest = ""; // fail
}
]]>
</example>
</rule>
<rule name="BooleanGetMethodName"
since="0.2"
message="The '{0}()' method which returns a boolean should be named 'is...()' or 'has...()'"
class="PHPMD\Rule\Naming\BooleanGetMethodName"
externalInfoUrl="http://phpmd.org/rules/naming.html#booleangetmethodname">
<description>
Looks for methods named 'getX()' with 'boolean' as the return type. The convention
is to name these methods 'isX()' or 'hasX()'.
</description>
<priority>4</priority>
<properties>
<property name="checkParameterizedMethods" value="false" description="Applies only to methods without parameter when set to true" />
</properties>
<example>
<![CDATA[
class Foo {
/**
* @return boolean
*/
public function getFoo() {} // bad
/**
* @return bool
*/
public function isFoo(); // ok
/**
* @return boolean
*/
public function getFoo($bar); // ok, unless checkParameterizedMethods=true
}
]]>
</example>
</rule>
<!--
<rule name="VariableNamingConventions"
since="1.2"
message="{0} variable {1} should begin with {2}"
class="net.sourceforge.pmd.rules.VariableNamingConventions"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#VariableNamingConventions">
<description>
A variable naming conventions rule - customize this to your liking. Currently, it
checks for final variables that should be fully capitalized and non-final variables
that should not include underscores.
</description>
<priority>1</priority>
<properties>
<property name="staticPrefix" description="A prefix for static variables" value=""/>
<property name="staticSuffix" description="A suffix for static variables" value=""/>
<property name="memberPrefix" description="A prefix for member variables" value=""/>
<property name="memberSuffix" description="A suffix for member variables" value=""/>
</properties>
<example>
<![CDATA[
public class Foo {
public static final int MY_NUM = 0;
public String myTest = "";
DataModule dmTest = new DataModule();
}
]]>
</example>
</rule>
<rule name="MethodNamingConventions"
since="1.2"
message="Method name does not begin with a lower case character."
class="net.sourceforge.pmd.rules.MethodNamingConventions"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#MethodNamingConventions">
<description>
Method names should always begin with a lower case character, and should not contain underscores.
</description>
<priority>1</priority>
<example>
<![CDATA[
public class Foo {
public void fooStuff() {
}
}
]]>
</example>
</rule>
<rule name="ClassNamingConventions"
since="1.2"
message="Class names should begin with an uppercase character"
class="net.sourceforge.pmd.rules.ClassNamingConventions"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#ClassNamingConventions">
<description>
Class names should always begin with an upper case character.
</description>
<priority>1</priority>
<example>
<![CDATA[
public class Foo {}
]]>
</example>
</rule>
<rule name="AbstractNaming"
since="1.4"
message="Abstract classes should be named 'AbstractXXX'"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#AbstractNaming">
<description>
Abstract classes should be named 'AbstractXXX'.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ClassOrInterfaceDeclaration
[@Abstract='true' and @Interface='false']
[not (starts-with(@Image,'Abstract'))]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public abstract class Foo { // should be AbstractFoo
}
]]>
</example>
</rule>
<rule name="AvoidFieldNameMatchingTypeName"
since="3.0"
message="It is somewhat confusing to have a field name matching the declaring class name"
class="net.sourceforge.pmd.rules.AvoidFieldNameMatchingTypeName"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#AvoidFieldNameMatchingTypeName">
<description>
It is somewhat confusing to have a field name matching the declaring class name.
This probably means that type and or field names could be more precise.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo extends Bar {
// There's probably a better name for foo
int foo;
}
]]>
</example>
</rule>
<rule name="AvoidFieldNameMatchingMethodName"
since="3.0"
message="It is somewhat confusing to have a field name with the same name as a method"
class="net.sourceforge.pmd.rules.AvoidFieldNameMatchingMethodName"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#AvoidFieldNameMatchingMethodName">
<description>
It is somewhat confusing to have a field name with the same name as a method.
While this is totally legal, having information (field) and actions (method) is
not clear naming.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
Object bar;
// bar is data or an action or both?
void bar() {
}
}
]]>
</example>
</rule>
<rule name="NoPackage"
since="3.3"
message="All classes and interfaces must belong to a named package"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#NoPackage">
<description>
Detects when a class or interface does not have a package definition.
</description>
<priority>3</priority>
<properties>
<property name="xpath" pluginname="true">
<value>
<![CDATA[
//ClassOrInterfaceDeclaration[count(preceding::PackageDeclaration) = 0]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
// no package declaration
public class ClassInDefaultPackage {
}
]]>
</example>
</rule>
<rule name="MisleadingVariableName"
since="3.4"
message="Avoid naming non-fields with the prefix 'm_'"
class="net.sourceforge.pmd.rules.XPathRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/naming.html#MisleadingVariableName">
<description>
Detects when a non-field has a name starting with 'm_'. This usually
indicates a field and thus is confusing.
</description>
<priority>3</priority>
<properties>
<property name="xpath" pluginname="true">
<value>
<![CDATA[
//VariableDeclaratorId
[starts-with(@Image, 'm_')]
[not (../../../FieldDeclaration)]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo {
private int m_foo; // OK
public void bar(String m_baz) { // Bad
int m_boz = 42; // Bad
}
}
]]>
</example>
</rule>
-->
</ruleset>
@@ -0,0 +1,105 @@
<?xml version="1.0"?>
<ruleset name="Unused Code Rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
The Unused Code Ruleset contains a collection of rules that find unused code.
</description>
<rule name="UnusedPrivateField"
since="0.2"
message="Avoid unused private fields such as '{0}'."
class="PHPMD\Rule\UnusedPrivateField"
externalInfoUrl="http://phpmd.org/rules/unusedcode.html#unusedprivatefield">
<description>
Detects when a private field is declared and/or assigned a value, but not used.
</description>
<priority>3</priority>
<example>
<![CDATA[
class Something
{
private static $FOO = 2; // Unused
private $i = 5; // Unused
private $j = 6;
public function addOne()
{
return $this->j++;
}
}
]]>
</example>
</rule>
<rule name="UnusedLocalVariable"
since="0.2"
message="Avoid unused local variables such as '{0}'."
class="PHPMD\Rule\UnusedLocalVariable"
externalInfoUrl="http://phpmd.org/rules/unusedcode.html#unusedlocalvariable">
<description>
Detects when a local variable is declared and/or assigned, but not used.
</description>
<priority>3</priority>
<properties>
<property
name="allow-unused-foreach-variables"
description="Allow unused variables in foreach language constructs."
value="false" />
</properties>
<example>
<![CDATA[
class Foo {
public function doSomething()
{
$i = 5; // Unused
}
}
]]>
</example>
</rule>
<rule name="UnusedPrivateMethod"
since="0.2"
message="Avoid unused private methods such as '{0}'."
class="PHPMD\Rule\UnusedPrivateMethod"
externalInfoUrl="http://phpmd.org/rules/unusedcode.html#unusedprivatemethod">
<description>
Unused Private Method detects when a private method is declared but is unused.
</description>
<priority>3</priority>
<example>
<![CDATA[
class Something
{
private function foo() {} // unused
}
]]>
</example>
</rule>
<rule name="UnusedFormalParameter"
since="0.2"
message="Avoid unused parameters such as '{0}'."
class="PHPMD\Rule\UnusedFormalParameter"
externalInfoUrl="http://phpmd.org/rules/unusedcode.html#unusedformalparameter">
<description>
Avoid passing parameters to methods or constructors and then not using those parameters.
</description>
<priority>3</priority>
<example>
<![CDATA[
class Foo
{
private function bar($howdy)
{
// $howdy is not used
}
}
]]>
</example>
</rule>
</ruleset>