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