Completed
Push — fix/15025-map-block-infinite-s... ( 9a8b21...52d6c3 )
by
unknown
63:16 queued 56:01
created

Differences::slashit()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Automattic\Jetpack\Analyzer;
4
5
use PhpParser\ParserFactory;
6
use PhpParser\NodeTraverser;
7
use PhpParser\NodeDumper;
8
use PhpParser\NodeVisitor\NameResolver;
9
10
class Differences extends PersistentList {
11
12
	private function slashit( $path ) {
13
		$path .= ( substr( $path, -1 ) == '/' ? '' : '/' );
14
		return $path;
15
	}
16
17
	/**
18
	 * Find differences between two sets of declarations.
19
	 *
20
	 * @param Declarations $new_declarations  List of new declarations.
21
	 * @param Declarations $prev_declarations List of previous declarations.
22
	 * @param string       $new_root          Path where new delcaration were scanned.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $new_root not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
23
	 * @param boolean      $find_deprecated   Include deprecated functions.
24
	 * @return void
25
	 */
26
	public function find( $new_declarations, $prev_declarations, $new_root = null, $find_deprecated = false ) {
27
		if ( $new_root ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $new_root of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
28
			$new_root = $this->slashit( $new_root );
29
		} else {
30
			echo "Warning: calling find() without \$new_root means we can't detect if files are stubbed in the new release\n";
31
		}
32
		$total                       = 0;
33
		$missing_total               = 0;
34
		$moved_total                 = 0;
35
		$moved_with_empty_file_total = 0;
36
		$deprecated_total            = 0;
37
		// for each declaration, see if it exists in the current analyzer's declarations
38
		// if not, add it to the list of differences - either as missing or different
39
		foreach ( $prev_declarations->get() as $prev_declaration ) {
40
			$matched               = false;
41
			$moved                 = false;
42
			$moved_with_empty_file = false;
43
			$deprecated            = false;
44
			foreach ( $new_declarations->get() as $new_declaration ) {
45
46
				if ( $prev_declaration->match( $new_declaration ) ) {
47
					if ( $find_deprecated && isset( $new_declaration->deprecated ) && $new_declaration->deprecated ) {
48
						$deprecated = true;
49
					}
50
51
					// echo "Comparing " . $prev_declaration->path . " to " . $new_declaration->path . "\n";
52
					if ( $prev_declaration->path !== $new_declaration->path ) {
53
54
						// if a file exists at the old location, and the new method is (we assume) autoloaded,
55
						// do not warn.
56
						// TODO: since functions are not autoloaded, we should probably still warn for them?
57
						if ( $new_root && file_exists( $new_root . $prev_declaration->path ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $new_root of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
58
							$moved_with_empty_file        = true;
59
							$moved_with_empty_file_total += 1;
60
						} else {
61
							$moved = true;
62
						}
63
					}
64
					$matched = true;
65
					break;
66
				} elseif ( $prev_declaration->partial_match( $new_declaration ) ) {
67
					// TODO this is to catch things like function args changed, method the same
68
				}
69
			}
70
71
			// do not add warnings for $moved_with_empty_file
72
			if ( $matched && $moved_with_empty_file ) {
73
				// echo "Declaration " . $prev_declaration->display_name() . " moved from " . $prev_declaration->path . " to " . $new_declaration->path . " with matching empty file at original location\n";
74
			}
75
76
			// Add differences for any detected deprecations.
77
			if ( $deprecated ) {
78
				switch ( $new_declaration->type() ) {
0 ignored issues
show
Bug introduced by
The variable $new_declaration seems to be defined by a foreach iteration on line 44. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
79
					case 'method':
80
						$this->add( new Differences\Class_Method_Deprecated( $prev_declaration, $new_declaration ) );
81
						break;
82
					case 'function':
83
						$this->add( new Differences\Function_Deprecated( $prev_declaration, $new_declaration ) );
84
						break;
85
					default:
86
						echo 'Unknown deprecated type ' . $new_declaration->type() . "\n";
87
				}
88
				$deprecated_total++;
89
90
			} elseif ( $matched && $moved ) {
91
				switch ( $prev_declaration->type() ) {
92
					case 'class':
93
						$this->add( new Differences\Class_Moved( $prev_declaration, $new_declaration ) );
94
						break;
95
					case 'class_const':
96
						$this->add( new Differences\Class_Const_Moved( $prev_declaration, $new_declaration ) );
97
						break;
98
					case 'method':
99
						$this->add( new Differences\Class_Method_Moved( $prev_declaration, $new_declaration ) );
100
						break;
101
					case 'property':
102
						$this->add( new Differences\Class_Property_Moved( $prev_declaration, $new_declaration ) );
103
						break;
104
					case 'function':
105
						$this->add( new Differences\Function_Moved( $prev_declaration, $new_declaration ) );
106
						break;
107
					default:
108
						echo 'Unknown moved type ' . $prev_declaration->type() . "\n";
109
				}
110
				$moved_total += 1;
111
			}
112
113
			if ( ! $matched ) {
114
				switch ( $prev_declaration->type() ) {
115
					case 'class':
116
						$this->add( new Differences\Class_Missing( $prev_declaration ) );
117
						break;
118
					case 'class_const':
119
						$this->add( new Differences\Class_Const_Missing( $prev_declaration ) );
120
						break;
121
					case 'method':
122
						$this->add( new Differences\Class_Method_Missing( $prev_declaration ) );
123
						break;
124
					case 'property':
125
						$this->add( new Differences\Class_Property_Missing( $prev_declaration ) );
126
						break;
127
					case 'function':
128
						$this->add( new Differences\Function_Missing( $prev_declaration ) );
129
						break;
130
					default:
131
						echo 'Unknown unmatched type ' . $prev_declaration->type() . "\n";
132
				}
133
				$missing_total += 1;
134
			}
135
136
			$total += 1;
137
		}
138
139
		echo "Total Declarations: $total\n";
140
		echo 'Total Differences: ' . count( $this->get() ) . "\n";
141
		echo 'Moved: ' . $moved_total . "\n";
142
		echo 'Moved with stubbed file: ' . $moved_with_empty_file_total . "\n";
143
		echo 'Missing: ' . $missing_total . "\n";
144
		if ( $find_deprecated ) {
145
			echo 'Deprecated: ' . $deprecated_total . "\n";
146
		}
147
	}
148
}
149