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,78 @@ 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 );
49
47
50
- $ closeBrace = $ tokens [$ stackPtr ]['scope_closer ' ];
51
- $ throwTags = [];
52
- $ catchTags = [];
48
+ $ throwClassNames = [];
49
+ $ searchForNextThrow = $ stackPtr ;
53
50
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 ;
51
+ // search for all throws
52
+ do {
53
+ $ throwTag = $ phpcsFile ->findNext (T_THROW , $ searchForNextThrow , $ endOfStatement );
54
+
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
-
72
- // find all relevant classes in catch
73
- foreach ($ catchTags as $ catchTag ) {
74
- $ start = $ catchTag ['parenthesis_opener ' ];
75
- $ end = $ catchTag ['parenthesis_closer ' ];
76
69
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 ($ catchClassNames )) {
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 , $ startPos )
101
+ {
102
+ $ fullName = "" ;
103
+ $ endOfClassName = [T_SEMICOLON => 0 , T_CLOSE_PARENTHESIS => 0 ];
104
+
105
+ $ tokenCount = count ($ tokens );
106
+ for ($ i = $ startPos ; $ i <= $ tokenCount ; $ i ++) {
107
+ $ type = $ tokens [$ i ]['code ' ];
108
+
109
+ if ($ type === T_STRING || $ type === T_NS_SEPARATOR ) {
110
+ $ fullName .= $ tokens [$ i ]['content ' ];
111
+ }
112
+
113
+ if (array_key_exists ($ type , $ endOfClassName )) {
114
+ break ; // line end each
115
+ }
116
+ }
117
+
118
+ return $ fullName ;
119
+ }
94
120
}
0 commit comments