Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@0
|
3 * Class create instance Test.
|
Chris@0
|
4 *
|
Chris@0
|
5 * @category PHP
|
Chris@0
|
6 * @package PHP_CodeSniffer
|
Chris@0
|
7 * @link http://pear.php.net/package/PHP_CodeSniffer
|
Chris@0
|
8 */
|
Chris@0
|
9
|
Chris@0
|
10 /**
|
Chris@0
|
11 * Class create instance Test.
|
Chris@0
|
12 *
|
Chris@0
|
13 * Checks the declaration of the class is correct.
|
Chris@0
|
14 *
|
Chris@0
|
15 * @category PHP
|
Chris@0
|
16 * @package PHP_CodeSniffer
|
Chris@0
|
17 * @link http://pear.php.net/package/PHP_CodeSniffer
|
Chris@0
|
18 */
|
Chris@0
|
19 class Drupal_Sniffs_Classes_ClassCreateInstanceSniff implements PHP_CodeSniffer_Sniff
|
Chris@0
|
20 {
|
Chris@0
|
21
|
Chris@0
|
22
|
Chris@0
|
23 /**
|
Chris@0
|
24 * Returns an array of tokens this test wants to listen for.
|
Chris@0
|
25 *
|
Chris@0
|
26 * @return array
|
Chris@0
|
27 */
|
Chris@0
|
28 public function register()
|
Chris@0
|
29 {
|
Chris@0
|
30 return array(T_NEW);
|
Chris@0
|
31
|
Chris@0
|
32 }//end register()
|
Chris@0
|
33
|
Chris@0
|
34
|
Chris@0
|
35 /**
|
Chris@0
|
36 * Processes this test, when one of its tokens is encountered.
|
Chris@0
|
37 *
|
Chris@0
|
38 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
|
Chris@0
|
39 * @param int $stackPtr The position of the current token in the
|
Chris@0
|
40 * stack passed in $tokens.
|
Chris@0
|
41 *
|
Chris@0
|
42 * @return void
|
Chris@0
|
43 */
|
Chris@0
|
44 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
|
Chris@0
|
45 {
|
Chris@0
|
46 $tokens = $phpcsFile->getTokens();
|
Chris@0
|
47
|
Chris@0
|
48 $commaOrColon = $phpcsFile->findNext([T_SEMICOLON, T_COLON, T_COMMA], ($stackPtr + 1));
|
Chris@0
|
49 if ($commaOrColon === false) {
|
Chris@0
|
50 // Syntax error, nothing we can do.
|
Chris@0
|
51 return;
|
Chris@0
|
52 }
|
Chris@0
|
53
|
Chris@0
|
54 // Search for an opening parenthesis in the current statement until the
|
Chris@0
|
55 // next semicolon or comma.
|
Chris@0
|
56 $nextParenthesis = $phpcsFile->findNext(T_OPEN_PARENTHESIS, ($stackPtr + 1), $commaOrColon);
|
Chris@0
|
57 if ($nextParenthesis === false) {
|
Chris@0
|
58 $error = 'Calling class constructors must always include parentheses';
|
Chris@0
|
59 $constructor = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
|
Chris@0
|
60 // We can invoke the fixer if we know this is a static constructor
|
Chris@0
|
61 // function call or constructor calls with namespaces, example
|
Chris@0
|
62 // "new \DOMDocument;" or constructor with class names in variables
|
Chris@0
|
63 // "new $controller;".
|
Chris@0
|
64 if ($tokens[$constructor]['code'] === T_STRING
|
Chris@0
|
65 || $tokens[$constructor]['code'] === T_NS_SEPARATOR
|
Chris@0
|
66 || ($tokens[$constructor]['code'] === T_VARIABLE
|
Chris@0
|
67 && $tokens[($constructor + 1)]['code'] === T_SEMICOLON)
|
Chris@0
|
68 ) {
|
Chris@0
|
69 // Scan to the end of possible string\namespace parts.
|
Chris@0
|
70 $nextConstructorPart = $constructor;
|
Chris@0
|
71 while (true) {
|
Chris@0
|
72 $nextConstructorPart = $phpcsFile->findNext(
|
Chris@0
|
73 PHP_CodeSniffer_Tokens::$emptyTokens,
|
Chris@0
|
74 ($nextConstructorPart + 1),
|
Chris@0
|
75 null,
|
Chris@0
|
76 true,
|
Chris@0
|
77 null,
|
Chris@0
|
78 true
|
Chris@0
|
79 );
|
Chris@0
|
80 if ($nextConstructorPart === false
|
Chris@0
|
81 || ($tokens[$nextConstructorPart]['code'] !== T_STRING
|
Chris@0
|
82 && $tokens[$nextConstructorPart]['code'] !== T_NS_SEPARATOR)
|
Chris@0
|
83 ) {
|
Chris@0
|
84 break;
|
Chris@0
|
85 }
|
Chris@0
|
86
|
Chris@0
|
87 $constructor = $nextConstructorPart;
|
Chris@0
|
88 }
|
Chris@0
|
89
|
Chris@0
|
90 $fix = $phpcsFile->addFixableError($error, $constructor, 'ParenthesisMissing');
|
Chris@0
|
91 if ($fix === true) {
|
Chris@0
|
92 $phpcsFile->fixer->addContent($constructor, '()');
|
Chris@0
|
93 }
|
Chris@0
|
94
|
Chris@0
|
95 // We can invoke the fixer if we know this is a
|
Chris@0
|
96 // constructor call with class names in an array
|
Chris@0
|
97 // example "new $controller[$i];".
|
Chris@0
|
98 } else if ($tokens[$constructor]['code'] === T_VARIABLE
|
Chris@0
|
99 && $tokens[($constructor + 1)]['code'] === T_OPEN_SQUARE_BRACKET
|
Chris@0
|
100 ) {
|
Chris@0
|
101 // Scan to the end of possible multilevel arrays.
|
Chris@0
|
102 $nextConstructorPart = $constructor;
|
Chris@0
|
103 do {
|
Chris@0
|
104 $nextConstructorPart = $tokens[($nextConstructorPart + 1)]['bracket_closer'];
|
Chris@0
|
105 } while ($tokens[($nextConstructorPart + 1)]['code'] === T_OPEN_SQUARE_BRACKET);
|
Chris@0
|
106
|
Chris@0
|
107 $fix = $phpcsFile->addFixableError($error, $nextConstructorPart, 'ParenthesisMissing');
|
Chris@0
|
108 if ($fix === true) {
|
Chris@0
|
109 $phpcsFile->fixer->addContent($nextConstructorPart, '()');
|
Chris@0
|
110 }
|
Chris@0
|
111 } else {
|
Chris@0
|
112 $phpcsFile->addError($error, $stackPtr, 'ParenthesisMissing');
|
Chris@0
|
113 }//end if
|
Chris@0
|
114 }//end if
|
Chris@0
|
115
|
Chris@0
|
116 }//end process()
|
Chris@0
|
117
|
Chris@0
|
118
|
Chris@0
|
119 }//end class
|