Automattic /
jetpack
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace Automattic\Jetpack\Analyzer; |
||
| 4 | |||
| 5 | use PhpParser\Node; |
||
| 6 | |||
| 7 | /** |
||
| 8 | * Shared code that probably should be a trait |
||
| 9 | */ |
||
| 10 | class Utils { |
||
| 11 | /** |
||
| 12 | * parses the node used to describe parameter defaults into a string for easy comparison |
||
| 13 | */ |
||
| 14 | static function get_param_default_as_string( $default, $current_class ) { |
||
| 15 | if ( $default instanceof Node\Expr\Array_ ) { |
||
| 16 | return 'array()'; |
||
| 17 | } elseif ( $default instanceof Node\Expr\ConstFetch ) { |
||
| 18 | return $default->name->toCodeString(); |
||
| 19 | } elseif ( $default instanceof Node\Scalar\LNumber || $default instanceof Node\Scalar\DNumber ) { |
||
| 20 | return $default->value; |
||
| 21 | } elseif ( $default instanceof Node\Scalar\String_ ) { |
||
| 22 | return '\'' . $default->value . '\''; |
||
| 23 | } elseif ( $default instanceof Node\Expr\UnaryMinus ) { |
||
| 24 | return '-' . self::get_param_default_as_string( $default->expr, $current_class ); |
||
| 25 | } elseif ( $default instanceof Node\Expr\UnaryPlus ) { |
||
| 26 | return '+' . self::get_param_default_as_string( $default->expr, $current_class ); |
||
| 27 | } elseif ( $default instanceof Node\Expr\ClassConstFetch ) { |
||
| 28 | return self::node_to_class_name( $default->class, $current_class ) . '::' . $default->name->name; |
||
| 29 | } else { |
||
| 30 | return $default; |
||
| 31 | } |
||
| 32 | } |
||
| 33 | |||
| 34 | static function node_to_class_name( $node, $class_for_self = null ) { |
||
| 35 | if ( $node instanceof Node\Expr\Variable |
||
| 36 | || $node instanceof Node\Stmt\Class_ ) { |
||
| 37 | $class_name = $node->name; |
||
| 38 | } elseif ( $node instanceof Node\Name ) { |
||
| 39 | $class_name = '\\' . implode( '\\', $node->parts ); |
||
| 40 | } elseif ( $node instanceof Node\Expr\PropertyFetch ) { |
||
| 41 | $class_name = |
||
| 42 | '$' |
||
| 43 | . self::maybe_stringify( $node->var->name ) |
||
| 44 | . '->' . self::maybe_stringify( $node->name->name ); |
||
| 45 | View Code Duplication | } elseif ( $node instanceof Node\Expr\ArrayDimFetch ) { |
|
| 46 | |||
| 47 | $class_name = |
||
| 48 | '$' |
||
| 49 | . self::maybe_stringify( $node->var->name ) |
||
| 50 | . '[' . self::maybe_stringify( $node->dim->value ) |
||
| 51 | . ']'; |
||
| 52 | } else { |
||
| 53 | if ( method_exists( $node, 'toCodeString' ) ) { |
||
| 54 | $class_name = $node->toCodeString(); |
||
| 55 | } else { |
||
| 56 | $class_name = get_class( $node ); |
||
| 57 | } |
||
| 58 | } |
||
| 59 | |||
| 60 | if ( $class_name === '\\self' && ! is_null( $class_for_self ) ) { |
||
| 61 | $class_name = $class_for_self; |
||
| 62 | } |
||
| 63 | |||
| 64 | return $class_name; |
||
| 65 | } |
||
| 66 | |||
| 67 | static function maybe_stringify( $object ) { |
||
| 68 | $is_stringifiable = ( |
||
| 69 | is_string( $object ) |
||
| 70 | || ( |
||
| 71 | is_object( $object ) |
||
| 72 | && method_exists( $object, '__toString' ) |
||
| 73 | ) |
||
| 74 | ); |
||
| 75 | |||
| 76 | if ( $is_stringifiable ) { |
||
| 77 | return (string) $object; |
||
| 78 | } |
||
| 79 | |||
| 80 | if ( is_null( $object ) ) { |
||
| 81 | return ''; |
||
| 82 | } |
||
| 83 | |||
| 84 | // Objects that need additional recursion to properly stringify |
||
| 85 | // are of no interest to us because we won't know what classes |
||
| 86 | // or methods they use without runtime analysis. |
||
| 87 | return get_class( $object ); |
||
| 88 | } |
||
| 89 | |||
| 90 | /** |
||
| 91 | * Check if a node has a docblock containing a specific comment string. |
||
| 92 | * |
||
| 93 | * @param PhpParser/Node $node Current node we are parsing. |
||
|
0 ignored issues
–
show
|
|||
| 94 | * @param string $comment Comment to match. |
||
| 95 | * @return boolean |
||
| 96 | */ |
||
| 97 | public static function has_doc_comment( $node, $comment ) { |
||
| 98 | if ( $node->getDocComment() && false !== strpos( $node->getDocComment(), $comment ) ) { |
||
| 99 | return true; |
||
| 100 | } |
||
| 101 | |||
| 102 | return false; |
||
| 103 | } |
||
| 104 | |||
| 105 | /** |
||
| 106 | * Check if a node contains a call to a function name. |
||
| 107 | * Any part of the function name will be matched. |
||
| 108 | * |
||
| 109 | * @param PhpParser/Node $node Current node we are parsing. |
||
|
0 ignored issues
–
show
The doc-type
PhpParser/Node could not be parsed: Unknown type name "PhpParser/Node" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. Loading history...
|
|||
| 110 | * @param string $name Function name to match. |
||
| 111 | * @return boolean |
||
| 112 | */ |
||
| 113 | public static function has_function_call( $node, $name ) { |
||
| 114 | if ( empty( $node->getStmts() ) ) { |
||
| 115 | return false; |
||
| 116 | } |
||
| 117 | |||
| 118 | foreach ( $node->getStmts() as $stmt ) { |
||
| 119 | if ( ! $stmt instanceof Node\Stmt\Expression || ! $stmt->expr instanceof Node\Expr\FuncCall ) { |
||
|
0 ignored issues
–
show
The class
PhpParser\Node\Stmt\Expression does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. Loading history...
The class
PhpParser\Node\Expr\FuncCall does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. Loading history...
|
|||
| 120 | continue; |
||
| 121 | } |
||
| 122 | if ( false !== strpos( $stmt->expr->name->toCodeString(), $name ) ) { |
||
| 123 | return true; |
||
| 124 | } |
||
| 125 | } |
||
| 126 | |||
| 127 | return false; |
||
| 128 | } |
||
| 129 | |||
| 130 | } |
||
| 131 |
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.