3
3
* Copyright © Magento. All rights reserved.
4
4
* See COPYING.txt for license details.
5
5
*/
6
+
6
7
namespace Magento2 \Sniffs \Exceptions ;
7
8
8
9
use function array_slice ;
@@ -33,7 +34,7 @@ class ThrowCatchSniff implements Sniff
33
34
*/
34
35
public function register ()
35
36
{
36
- return [T_FUNCTION , T_CLOSURE ];
37
+ return [T_TRY ];
37
38
}
38
39
39
40
/**
@@ -42,53 +43,76 @@ public function register()
42
43
public function process (File $ phpcsFile , $ stackPtr )
43
44
{
44
45
$ tokens = $ phpcsFile ->getTokens ();
45
- if (! isset ( $ tokens [ $ stackPtr][ ' scope_closer ' ])) {
46
- // Probably an interface method no check
47
- return ;
48
- }
46
+ $ endOfStatement = $ phpcsFile -> findEndOfStatement ( $ stackPtr);
47
+
48
+ $ throwClassNames = [] ;
49
+ $ searchForNextThrow = $ stackPtr ;
49
50
50
- $ closeBrace = $ tokens [ $ stackPtr ][ ' scope_closer ' ];
51
- $ throwTags = [];
52
- $ catchTags = [] ;
51
+ // search for all throws
52
+ do {
53
+ $ throwTag = $ phpcsFile -> findNext ( T_THROW , $ searchForNextThrow , $ endOfStatement ) ;
53
54
54
- for ($ i = $ stackPtr ; $ i < $ closeBrace ; $ i ++) {
55
- $ token = $ tokens [$ i ];
56
- if ($ token ['code ' ] === T_CATCH ) {
57
- $ catchTags [] = $ token ;
58
- }
59
- if ($ token ['code ' ] === T_THROW ) {
60
- $ throwTags [] = $ i ;
55
+ if ($ throwTag === false ) {
56
+ break ;
61
57
}
62
- }
63
58
64
- if (count ($ catchTags ) === 0 || count ($ throwTags ) === 0 ) {
65
- // No catch or throw found no check
66
- return ;
59
+ $ throwClassNames [] = $ this ->getFullClassName ($ tokens , $ throwTag + 1 );
60
+
61
+ $ searchForNextThrow = $ throwTag + 1 ;
62
+ } while ($ throwTag !== false );
63
+
64
+ if (empty ($ throwClassNames )) {
65
+ return ; // is not relevant not throw in try found.
67
66
}
68
67
69
68
$ catchClassNames = [];
70
- $ throwClassNames = [];
71
69
72
- // find all relevant classes in catch
73
- foreach ($ catchTags as $ catchTag ) {
74
- $ start = $ catchTag ['parenthesis_opener ' ];
75
- $ end = $ catchTag ['parenthesis_closer ' ];
76
-
77
- $ match = $ phpcsFile ->findNext (T_STRING , $ start , $ end );
78
- $ catchClassNames [$ match ] = $ tokens [$ match ]['content ' ];
79
- }
70
+ // TRY statements need to check until the end of all CATCH statements.
71
+ do {
72
+ $ nextToken = $ phpcsFile ->findNext (T_WHITESPACE , ($ endOfStatement + 1 ), null , true );
73
+ if ($ tokens [$ nextToken ]['code ' ] === T_CATCH ) {
74
+ $ endOfStatement = $ tokens [$ nextToken ]['scope_closer ' ];
75
+ $ catchClassNames [$ nextToken ] = $ this ->getFullClassName ($ tokens , $ nextToken + 1 );
76
+ } else {
77
+ break ;
78
+ }
79
+ } while (isset ($ tokens [$ nextToken ]['scope_closer ' ]) === true );
80
80
81
- // find all relevant classes in throws
82
- foreach ($ throwTags as $ throwTag ) {
83
- $ match = $ phpcsFile ->findNext (T_STRING , $ throwTag );
84
- $ throwClassNames [] = $ tokens [$ match ]['content ' ];
81
+ if (empty ($ catchClassName )) {
82
+ return ; // is not relevant no catch found
85
83
}
86
84
87
85
$ throwClassNames = array_flip ($ throwClassNames );
88
86
foreach ($ catchClassNames as $ match => $ catchClassName ) {
89
- if (array_key_exists ( $ catchClassName , $ throwClassNames )) {
87
+ if (isset ( $ throwClassNames[ $ catchClassName ] )) {
90
88
$ phpcsFile ->addWarning ($ this ->warningMessage , $ match , $ this ->warningCode );
91
89
}
92
90
}
93
91
}
92
+
93
+ /**
94
+ * Get the full class name with namespace.
95
+ *
96
+ * @param array $tokens
97
+ * @param int $startPos
98
+ * @return string
99
+ */
100
+ private function getFullClassName (array $ tokens , int $ startPos )
101
+ {
102
+ $ fullName = "" ;
103
+ $ endOfClassName = [T_SEMICOLON => 0 , T_CLOSE_PARENTHESIS => 0 ];
104
+ for ($ i = $ startPos ; $ i <= count ($ tokens ); $ i ++) {
105
+ $ type = $ tokens [$ i ]['code ' ];
106
+
107
+ if ($ type === T_STRING || $ type === T_NS_SEPARATOR ) {
108
+ $ fullName .= $ tokens [$ i ]['content ' ];
109
+ }
110
+
111
+ if (array_key_exists ($ type , $ endOfClassName )) {
112
+ break ; // line end each
113
+ }
114
+ }
115
+
116
+ return $ fullName ;
117
+ }
94
118
}
0 commit comments