@@ -1461,23 +1461,12 @@ protected function is_in_isset_or_empty( $stackPtr ) {
14611461 }
14621462
14631463 if ( \T_STRING === $ previous_code && 'array_key_exists ' === $ this ->tokens [ $ previous_non_empty ]['content ' ] ) {
1464- $ before_function = $ this ->phpcsFile ->findPrevious ( Tokens::$ emptyTokens , ( $ previous_non_empty - 1 ), null , true , null , true );
1465-
1466- if ( false !== $ before_function ) {
1467- if ( \T_OBJECT_OPERATOR === $ this ->tokens [ $ before_function ]['code ' ]
1468- || \T_DOUBLE_COLON === $ this ->tokens [ $ before_function ]['code ' ]
1469- ) {
1470- // Method call.
1471- return false ;
1472- }
1464+ if ( $ this ->is_class_object_call ( $ previous_non_empty ) === true ) {
1465+ return false ;
1466+ }
14731467
1474- if ( \T_NS_SEPARATOR === $ this ->tokens [ $ before_function ]['code ' ] ) {
1475- $ before_before = $ this ->phpcsFile ->findPrevious ( Tokens::$ emptyTokens , ( $ before_function - 1 ), null , true , null , true );
1476- if ( false !== $ before_before && \T_STRING === $ this ->tokens [ $ before_before ]['code ' ] ) {
1477- // Namespaced function call.
1478- return false ;
1479- }
1480- }
1468+ if ( $ this ->is_token_namespaced ( $ previous_non_empty ) === true ) {
1469+ return false ;
14811470 }
14821471
14831472 $ second_param = $ this ->get_function_call_parameter ( $ previous_non_empty , 2 );
@@ -1489,6 +1478,71 @@ protected function is_in_isset_or_empty( $stackPtr ) {
14891478 return false ;
14901479 }
14911480
1481+ /**
1482+ * Check if a particular token is a (static or non-static) call to a class method or property.
1483+ *
1484+ * @internal Note: this may still mistake a namespaced function imported via a `use` statement for
1485+ * a global function!
1486+ *
1487+ * @since 2.1.0
1488+ *
1489+ * @param int $stackPtr The index of the token in the stack.
1490+ *
1491+ * @return bool
1492+ */
1493+ protected function is_class_object_call ( $ stackPtr ) {
1494+ $ before = $ this ->phpcsFile ->findPrevious ( Tokens::$ emptyTokens , ( $ stackPtr - 1 ), null , true , null , true );
1495+
1496+ if ( false === $ before ) {
1497+ return false ;
1498+ }
1499+
1500+ if ( \T_OBJECT_OPERATOR !== $ this ->tokens [ $ before ]['code ' ]
1501+ && \T_DOUBLE_COLON !== $ this ->tokens [ $ before ]['code ' ]
1502+ ) {
1503+ return false ;
1504+ }
1505+
1506+ return true ;
1507+ }
1508+
1509+ /**
1510+ * Check if a particular token is prefixed with a namespace.
1511+ *
1512+ * @internal This will give a false positive if the file is not namespaced and the token is prefixed
1513+ * with `namespace\`.
1514+ *
1515+ * @since 2.1.0
1516+ *
1517+ * @param int $stackPtr The index of the token in the stack.
1518+ *
1519+ * @return bool
1520+ */
1521+ protected function is_token_namespaced ( $ stackPtr ) {
1522+ $ prev = $ this ->phpcsFile ->findPrevious ( Tokens::$ emptyTokens , ( $ stackPtr - 1 ), null , true , null , true );
1523+
1524+ if ( false === $ prev ) {
1525+ return false ;
1526+ }
1527+
1528+ if ( \T_NS_SEPARATOR !== $ this ->tokens [ $ prev ]['code ' ] ) {
1529+ return false ;
1530+ }
1531+
1532+ $ before_prev = $ this ->phpcsFile ->findPrevious ( Tokens::$ emptyTokens , ( $ prev - 1 ), null , true , null , true );
1533+ if ( false === $ before_prev ) {
1534+ return false ;
1535+ }
1536+
1537+ if ( \T_STRING !== $ this ->tokens [ $ before_prev ]['code ' ]
1538+ && \T_NAMESPACE !== $ this ->tokens [ $ before_prev ]['code ' ]
1539+ ) {
1540+ return false ;
1541+ }
1542+
1543+ return true ;
1544+ }
1545+
14921546 /**
14931547 * Check if something is only being sanitized.
14941548 *
@@ -1853,22 +1907,14 @@ protected function is_validated( $stackPtr, $array_key = null, $in_condition_onl
18531907 continue 2 ;
18541908 }
18551909
1856- $ previous_non_empty = $ this ->phpcsFile ->findPrevious ( Tokens::$ emptyTokens , ( $ i - 1 ), null , true , null , true );
1857- if ( false !== $ previous_non_empty ) {
1858- if ( \T_OBJECT_OPERATOR === $ this ->tokens [ $ previous_non_empty ]['code ' ]
1859- || \T_DOUBLE_COLON === $ this ->tokens [ $ previous_non_empty ]['code ' ]
1860- ) {
1861- // Method call.
1862- continue 2 ;
1863- }
1910+ if ( $ this ->is_class_object_call ( $ i ) === true ) {
1911+ // Method call.
1912+ continue 2 ;
1913+ }
18641914
1865- if ( \T_NS_SEPARATOR === $ this ->tokens [ $ previous_non_empty ]['code ' ] ) {
1866- $ pprev = $ this ->phpcsFile ->findPrevious ( Tokens::$ emptyTokens , ( $ previous_non_empty - 1 ), null , true , null , true );
1867- if ( false !== $ pprev && \T_STRING === $ this ->tokens [ $ pprev ]['code ' ] ) {
1868- // Namespaced function call.
1869- continue 2 ;
1870- }
1871- }
1915+ if ( $ this ->is_token_namespaced ( $ i ) === true ) {
1916+ // Namespaced function call.
1917+ continue 2 ;
18721918 }
18731919
18741920 $ params = $ this ->get_function_call_parameters ( $ i );
@@ -2680,10 +2726,7 @@ public function is_use_of_global_constant( $stackPtr ) {
26802726 return false ;
26812727 }
26822728
2683- if ( false !== $ prev
2684- && \T_NS_SEPARATOR === $ this ->tokens [ $ prev ]['code ' ]
2685- && \T_STRING === $ this ->tokens [ ( $ prev - 1 ) ]['code ' ]
2686- ) {
2729+ if ( $ this ->is_token_namespaced ( $ stackPtr ) === true ) {
26872730 // Namespaced constant of the same name.
26882731 return false ;
26892732 }
0 commit comments