examples/plugins/composer-based/echo-checker/EchoChecker.php
public static function afterStatementAnalysis(
        PhpParser\Node\Stmt $stmt,
        Context $context,
        StatementsSource $statements_source,
        Codebase $codebase,
        array &$file_replacements = []
    ) {
        if ($stmt instanceof PhpParser\Node\Stmt\Echo_) {
            foreach ($stmt->exprs as $expr) {
                if (!isset($expr->inferredType) || $expr->inferredType->hasMixed()) {
                    if (IssueBuffer::accepts(
                        new ArgumentTypeCoercion(
                            'Echo requires an unescaped string, ' . $expr->inferredType . ' provided',
                            new CodeLocation($statements_source, $expr),
                            'echo'
                        ),
                        $statements_source->getSuppressedIssues()
                    )) {
                        // keep soldiering on
                    }

                    continue;
                }

                $types = $expr->inferredType->getTypes();

                foreach ($types as $type) {
                    if ($type instanceof \Psalm\Type\Atomic\TString
                        && !$type instanceof \Psalm\Type\Atomic\TLiteralString
                        && !$type instanceof \Psalm\Type\Atomic\THtmlEscapedString
                    ) {
                        if (IssueBuffer::accepts(
                            new ArgumentTypeCoercion(
                                'Echo requires an unescaped string, ' . $expr->inferredType . ' provided',
                                new CodeLocation($statements_source, $expr),
                                'echo'
                            ),
                            $statements_source->getSuppressedIssues()
                        )) {
                            // keep soldiering on
                        }
                    }
                }
            }
        }
    }
public static function afterStatementAnalysis(
        PhpParser\Node\Stmt $stmt,
        Context $context,
        StatementsSource $statements_source,
        Codebase $codebase,
        array &$file_replacements = []
    ) {
        if ($stmt instanceof PhpParser\Node\Stmt\Echo_) {
            foreach ($stmt->exprs as $expr) {
                if (!isset($expr->inferredType) || $expr->inferredType->hasMixed()) {
                    if (IssueBuffer::accepts(
                        new ArgumentTypeCoercion(
                            'Echo requires an unescaped string, ' . $expr->inferredType . ' provided',
                            new CodeLocation($statements_source, $expr),
                            'echo'
                        ),
                        $statements_source->getSuppressedIssues()
                    )) {
                        // keep soldiering on
                    }

                    continue;
                }

                $types = $expr->inferredType->getTypes();

                foreach ($types as $type) {
                    if ($type instanceof \Psalm\Type\Atomic\TString
                        && !$type instanceof \Psalm\Type\Atomic\TLiteralString
                        && !$type instanceof \Psalm\Type\Atomic\THtmlEscapedString
                    ) {
                        if (IssueBuffer::accepts(
                            new ArgumentTypeCoercion(
                                'Echo requires an unescaped string, ' . $expr->inferredType . ' provided',
                                new CodeLocation($statements_source, $expr),
                                'echo'
                            ),
                            $statements_source->getSuppressedIssues()
                        )) {
                            // keep soldiering on
                        }
                    }
                }
            }
        }
    }
public static function afterStatementAnalysis ( PhpParser \ Node \ Stmt $ stmt , Context $ context , StatementsSource $ statements_source , Codebase $ codebase , array & $ file_replacements = [ ] ) { if ( $ stmt instanceof PhpParser \ Node \ Stmt \ Echo_ ) { foreach ( $ stmt -> exprs as $ expr ) { if ( ! isset ( $ expr -> inferredType ) || $ expr -> inferredType -> hasMixed ( ) ) { if ( IssueBuffer :: accepts ( new ArgumentTypeCoercion ( 'Echo requires an unescaped string, ' . $ expr -> inferredType . ' provided' , new CodeLocation ( $ statements_source , $ expr ) , 'echo' ) , $ statements_source -> getSuppressedIssues ( ) ) ) { // keep soldiering on } continue ; } $ types = $ expr -> inferredType -> getTypes ( ) ; foreach ( $ types as $ type ) { if ( $ type instanceof \ Psalm \ Type \ Atomic \ TString && ! $ type instanceof \ Psalm \ Type \ Atomic \ TLiteralString && ! $ type instanceof \ Psalm \ Type \ Atomic \ THtmlEscapedString ) { if ( IssueBuffer :: accepts ( new ArgumentTypeCoercion ( 'Echo requires an unescaped string, ' . $ expr -> inferredType . ' provided' , new CodeLocation ( $ statements_source , $ expr ) , 'echo' ) , $ statements_source -> getSuppressedIssues ( ) ) ) { // keep soldiering on } } } } } }
Called after a statement has been checked

@param  FileManipulation[]   $file_replacements

@return null|false
Called after a statement has been checked