protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        $map = [
            'array' => [T_ARRAY_CAST, '(array)'],
            'bool' => [T_BOOL_CAST, '(bool)'],
            'boolean' => [T_BOOL_CAST, '(bool)'],
            'double' => [T_DOUBLE_CAST, '(float)'],
            'float' => [T_DOUBLE_CAST, '(float)'],
            'int' => [T_INT_CAST, '(int)'],
            'integer' => [T_INT_CAST, '(int)'],
            'object' => [T_OBJECT_CAST, '(object)'],
            'string' => [T_STRING_CAST, '(string)'],
            // note: `'null' is dealt with later on
        ];

        $argumentsAnalyzer = new ArgumentsAnalyzer();

        foreach (array_reverse($this->findSettypeCalls($tokens)) as $candidate) {
            $functionNameIndex = $candidate[0];

            $arguments = $argumentsAnalyzer->getArguments($tokens, $candidate[1], $candidate[2]);
            if (2 !== \count($arguments)) {
                continue; // function must be overridden or used incorrectly
            }

            $prev = $tokens->getPrevMeaningfulToken($functionNameIndex);
            if (!$tokens[$prev]->isGivenKind(T_OPEN_TAG) && !$tokens[$prev]->equalsAny([';', '{'])) {
                continue; // return value of the function is used
            }

            reset($arguments);

            // --- Test first argument --------------------

            $firstArgumentStart = key($arguments);
            if ($tokens[$firstArgumentStart]->isComment() || $tokens[$firstArgumentStart]->isWhitespace()) {
                $firstArgumentStart = $tokens->getNextMeaningfulToken($firstArgumentStart);
            }

            if (!$tokens[$firstArgumentStart]->isGivenKind(T_VARIABLE)) {
                continue; // settype only works with variables pass by reference, function must be overridden
            }

            $commaIndex = $tokens->getNextMeaningfulToken($firstArgumentStart);

            if (null === $commaIndex || !$tokens[$commaIndex]->equals(',')) {
                continue; // first argument is complex statement; function must be overridden
            }

            // --- Test second argument -------------------

            next($arguments);
            $secondArgumentStart = key($arguments);
            $secondArgumentEnd = $arguments[$secondArgumentStart];

            if ($tokens[$secondArgumentStart]->isComment() || $tokens[$secondArgumentStart]->isWhitespace()) {
                $secondArgumentStart = $tokens->getNextMeaningfulToken($secondArgumentStart);
            }

            if (
                !$tokens[$secondArgumentStart]->isGivenKind(T_CONSTANT_ENCAPSED_STRING)
                || $tokens->getNextMeaningfulToken($secondArgumentStart) < $secondArgumentEnd
            ) {
                continue; // second argument is of the wrong type or is a (complex) statement of some sort (function is overridden)
            }

            // --- Test type ------------------------------

            $type = strtolower(trim($tokens[$secondArgumentStart]->getContent(), '"\'"'));

            if ('null' !== $type && !isset($map[$type])) {
                continue; // we don't know how to map
            }

            // --- Fixing ---------------------------------

            $argumentToken = $tokens[$firstArgumentStart];

            $this->removeSettypeCall(
                $tokens,
                $functionNameIndex,
                $candidate[1],
                $firstArgumentStart,
                $commaIndex,
                $secondArgumentStart,
                $candidate[2]
            );

            if ('null' === $type) {
                $this->findSettypeNullCall($tokens, $functionNameIndex, $argumentToken);
            } else {
                $this->fixSettypeCall($tokens, $functionNameIndex, $argumentToken, new Token($map[$type]));
            }
        }
    }
protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        $map = [
            'array' => [T_ARRAY_CAST, '(array)'],
            'bool' => [T_BOOL_CAST, '(bool)'],
            'boolean' => [T_BOOL_CAST, '(bool)'],
            'double' => [T_DOUBLE_CAST, '(float)'],
            'float' => [T_DOUBLE_CAST, '(float)'],
            'int' => [T_INT_CAST, '(int)'],
            'integer' => [T_INT_CAST, '(int)'],
            'object' => [T_OBJECT_CAST, '(object)'],
            'string' => [T_STRING_CAST, '(string)'],
            
        ];

        $argumentsAnalyzer = new ArgumentsAnalyzer();

        foreach (array_reverse($this->findSettypeCalls($tokens)) as $candidate) {
            $functionNameIndex = $candidate[0];

            $arguments = $argumentsAnalyzer->getArguments($tokens, $candidate[1], $candidate[2]);
            if (2 !== \count($arguments)) {
                continue; 
            }

            $prev = $tokens->getPrevMeaningfulToken($functionNameIndex);
            if (!$tokens[$prev]->isGivenKind(T_OPEN_TAG) && !$tokens[$prev]->equalsAny([';', '{'])) {
                continue; 
            }

            reset($arguments);

            

            $firstArgumentStart = key($arguments);
            if ($tokens[$firstArgumentStart]->isComment() || $tokens[$firstArgumentStart]->isWhitespace()) {
                $firstArgumentStart = $tokens->getNextMeaningfulToken($firstArgumentStart);
            }

            if (!$tokens[$firstArgumentStart]->isGivenKind(T_VARIABLE)) {
                continue; 
            }

            $commaIndex = $tokens->getNextMeaningfulToken($firstArgumentStart);

            if (null === $commaIndex || !$tokens[$commaIndex]->equals(',')) {
                continue; 
            }

            

            next($arguments);
            $secondArgumentStart = key($arguments);
            $secondArgumentEnd = $arguments[$secondArgumentStart];

            if ($tokens[$secondArgumentStart]->isComment() || $tokens[$secondArgumentStart]->isWhitespace()) {
                $secondArgumentStart = $tokens->getNextMeaningfulToken($secondArgumentStart);
            }

            if (
                !$tokens[$secondArgumentStart]->isGivenKind(T_CONSTANT_ENCAPSED_STRING)
                || $tokens->getNextMeaningfulToken($secondArgumentStart) < $secondArgumentEnd
            ) {
                continue; 
            }

            

            $type = strtolower(trim($tokens[$secondArgumentStart]->getContent(), '"\'"'));

            if ('null' !== $type && !isset($map[$type])) {
                continue; 
            }

            

            $argumentToken = $tokens[$firstArgumentStart];

            $this->removeSettypeCall(
                $tokens,
                $functionNameIndex,
                $candidate[1],
                $firstArgumentStart,
                $commaIndex,
                $secondArgumentStart,
                $candidate[2]
            );

            if ('null' === $type) {
                $this->findSettypeNullCall($tokens, $functionNameIndex, $argumentToken);
            } else {
                $this->fixSettypeCall($tokens, $functionNameIndex, $argumentToken, new Token($map[$type]));
            }
        }
    }
protected function applyFix ( \ SplFileInfo $ file , Tokens $ tokens ) { $ map = [ 'array' => [ T_ARRAY_CAST , '(array)' ] , 'bool' => [ T_BOOL_CAST , '(bool)' ] , 'boolean' => [ T_BOOL_CAST , '(bool)' ] , 'double' => [ T_DOUBLE_CAST , '(float)' ] , 'float' => [ T_DOUBLE_CAST , '(float)' ] , 'int' => [ T_INT_CAST , '(int)' ] , 'integer' => [ T_INT_CAST , '(int)' ] , 'object' => [ T_OBJECT_CAST , '(object)' ] , 'string' => [ T_STRING_CAST , '(string)' ] , // note: `'null' is dealt with later on ] ; $ argumentsAnalyzer = new ArgumentsAnalyzer ( ) ; foreach ( array_reverse ( $ this -> findSettypeCalls ( $ tokens ) ) as $ candidate ) { $ functionNameIndex = $ candidate [ 0 ] ; $ arguments = $ argumentsAnalyzer -> getArguments ( $ tokens , $ candidate [ 1 ] , $ candidate [ 2 ] ) ; if ( 2 !== \ count ( $ arguments ) ) { continue ; // function must be overridden or used incorrectly } $ prev = $ tokens -> getPrevMeaningfulToken ( $ functionNameIndex ) ; if ( ! $ tokens [ $ prev ] -> isGivenKind ( T_OPEN_TAG ) && ! $ tokens [ $ prev ] -> equalsAny ( [ ';' , '{' ] ) ) { continue ; // return value of the function is used } reset ( $ arguments ) ; // --- Test first argument -------------------- $ firstArgumentStart = key ( $ arguments ) ; if ( $ tokens [ $ firstArgumentStart ] -> isComment ( ) || $ tokens [ $ firstArgumentStart ] -> isWhitespace ( ) ) { $ firstArgumentStart = $ tokens -> getNextMeaningfulToken ( $ firstArgumentStart ) ; } if ( ! $ tokens [ $ firstArgumentStart ] -> isGivenKind ( T_VARIABLE ) ) { continue ; // settype only works with variables pass by reference, function must be overridden } $ commaIndex = $ tokens -> getNextMeaningfulToken ( $ firstArgumentStart ) ; if ( null === $ commaIndex || ! $ tokens [ $ commaIndex ] -> equals ( ',' ) ) { continue ; // first argument is complex statement; function must be overridden } // --- Test second argument ------------------- next ( $ arguments ) ; $ secondArgumentStart = key ( $ arguments ) ; $ secondArgumentEnd = $ arguments [ $ secondArgumentStart ] ; if ( $ tokens [ $ secondArgumentStart ] -> isComment ( ) || $ tokens [ $ secondArgumentStart ] -> isWhitespace ( ) ) { $ secondArgumentStart = $ tokens -> getNextMeaningfulToken ( $ secondArgumentStart ) ; } if ( ! $ tokens [ $ secondArgumentStart ] -> isGivenKind ( T_CONSTANT_ENCAPSED_STRING ) || $ tokens -> getNextMeaningfulToken ( $ secondArgumentStart ) < $ secondArgumentEnd ) { continue ; // second argument is of the wrong type or is a (complex) statement of some sort (function is overridden) } // --- Test type ------------------------------ $ type = strtolower ( trim ( $ tokens [ $ secondArgumentStart ] -> getContent ( ) , '"\'"' ) ) ; if ( 'null' !== $ type && ! isset ( $ map [ $ type ] ) ) { continue ; // we don't know how to map } // --- Fixing --------------------------------- $ argumentToken = $ tokens [ $ firstArgumentStart ] ; $ this -> removeSettypeCall ( $ tokens , $ functionNameIndex , $ candidate [ 1 ] , $ firstArgumentStart , $ commaIndex , $ secondArgumentStart , $ candidate [ 2 ] ) ; if ( 'null' === $ type ) { $ this -> findSettypeNullCall ( $ tokens , $ functionNameIndex , $ argumentToken ) ; } else { $ this -> fixSettypeCall ( $ tokens , $ functionNameIndex , $ argumentToken , new Token ( $ map [ $ type ] ) ) ; } } }
{@inheritdoc}
{