Completed
Push — add/admin-page-package ( 7976aa...cbfc2c )
by
unknown
136:41 queued 124:01
created

Differences   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 0
Metric Value
dl 0
loc 139
rs 9.76
c 0
b 0
f 0
wmc 33
lcom 1
cbo 14

2 Methods

Rating   Name   Duplication   Size   Complexity  
A slashit() 0 4 2
F find() 0 122 31
1
<?php
2
3
namespace Automattic\Jetpack\Analyzer;
4
5
class Differences extends PersistentList {
6
7
	private function slashit( $path ) {
8
		$path .= ( substr( $path, -1 ) == '/' ? '' : '/' );
9
		return $path;
10
	}
11
12
	/**
13
	 * Find differences between two sets of declarations.
14
	 *
15
	 * @param Declarations $new_declarations  List of new declarations.
16
	 * @param Declarations $prev_declarations List of previous declarations.
17
	 * @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...
18
	 * @param boolean      $find_deprecated   Include deprecated functions.
19
	 * @return void
20
	 */
21
	public function find( $new_declarations, $prev_declarations, $new_root = null, $find_deprecated = false ) {
22
		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...
23
			$new_root = $this->slashit( $new_root );
24
		} else {
25
			echo "Warning: calling find() without \$new_root means we can't detect if files are stubbed in the new release\n";
26
		}
27
		$total                       = 0;
28
		$missing_total               = 0;
29
		$moved_total                 = 0;
30
		$moved_with_empty_file_total = 0;
31
		$deprecated_total            = 0;
32
		// for each declaration, see if it exists in the current analyzer's declarations
33
		// if not, add it to the list of differences - either as missing or different
34
		foreach ( $prev_declarations->get() as $prev_declaration ) {
35
			$matched               = false;
36
			$moved                 = false;
37
			$moved_with_empty_file = false;
38
			$deprecated            = false;
39
			foreach ( $new_declarations->get() as $new_declaration ) {
40
41
				if ( $prev_declaration->match( $new_declaration ) ) {
42
					if ( $find_deprecated && isset( $new_declaration->deprecated ) && $new_declaration->deprecated ) {
43
						$deprecated = true;
44
					}
45
46
					// echo "Comparing " . $prev_declaration->path . " to " . $new_declaration->path . "\n";
47
					if ( $prev_declaration->path !== $new_declaration->path ) {
48
49
						// if a file exists at the old location, and the new method is (we assume) autoloaded,
50
						// do not warn.
51
						// TODO: since functions are not autoloaded, we should probably still warn for them?
52
						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...
53
							$moved_with_empty_file        = true;
54
							$moved_with_empty_file_total += 1;
55
						} else {
56
							$moved = true;
57
						}
58
					}
59
					$matched = true;
60
					break;
61
				} elseif ( $prev_declaration->partial_match( $new_declaration ) ) {
62
					// TODO this is to catch things like function args changed, method the same
63
				}
64
			}
65
66
			// do not add warnings for $moved_with_empty_file
67
			if ( $matched && $moved_with_empty_file ) {
68
				// echo "Declaration " . $prev_declaration->display_name() . " moved from " . $prev_declaration->path . " to " . $new_declaration->path . " with matching empty file at original location\n";
69
			}
70
71
			// Add differences for any detected deprecations.
72
			if ( $deprecated ) {
73
				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 39. 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...
74
					case 'method':
75
						$this->add( new Differences\Class_Method_Deprecated( $prev_declaration, $new_declaration ) );
76
						break;
77
					case 'function':
78
						$this->add( new Differences\Function_Deprecated( $prev_declaration, $new_declaration ) );
79
						break;
80
					default:
81
						echo 'Unknown deprecated type ' . $new_declaration->type() . "\n";
82
				}
83
				$deprecated_total++;
84
85
			} elseif ( $matched && $moved ) {
86
				switch ( $prev_declaration->type() ) {
87
					case 'class':
88
						$this->add( new Differences\Class_Moved( $prev_declaration, $new_declaration ) );
89
						break;
90
					case 'class_const':
91
						$this->add( new Differences\Class_Const_Moved( $prev_declaration, $new_declaration ) );
92
						break;
93
					case 'method':
94
						$this->add( new Differences\Class_Method_Moved( $prev_declaration, $new_declaration ) );
95
						break;
96
					case 'property':
97
						$this->add( new Differences\Class_Property_Moved( $prev_declaration, $new_declaration ) );
98
						break;
99
					case 'function':
100
						$this->add( new Differences\Function_Moved( $prev_declaration, $new_declaration ) );
101
						break;
102
					default:
103
						echo 'Unknown moved type ' . $prev_declaration->type() . "\n";
104
				}
105
				$moved_total += 1;
106
			}
107
108
			if ( ! $matched ) {
109
				switch ( $prev_declaration->type() ) {
110
					case 'class':
111
						$this->add( new Differences\Class_Missing( $prev_declaration ) );
112
						break;
113
					case 'class_const':
114
						$this->add( new Differences\Class_Const_Missing( $prev_declaration ) );
115
						break;
116
					case 'method':
117
						$this->add( new Differences\Class_Method_Missing( $prev_declaration ) );
118
						break;
119
					case 'property':
120
						$this->add( new Differences\Class_Property_Missing( $prev_declaration ) );
121
						break;
122
					case 'function':
123
						$this->add( new Differences\Function_Missing( $prev_declaration ) );
124
						break;
125
					default:
126
						echo 'Unknown unmatched type ' . $prev_declaration->type() . "\n";
127
				}
128
				$missing_total += 1;
129
			}
130
131
			$total += 1;
132
		}
133
134
		echo "Total Declarations: $total\n";
135
		echo 'Total Differences: ' . count( $this->get() ) . "\n";
136
		echo 'Moved: ' . $moved_total . "\n";
137
		echo 'Moved with stubbed file: ' . $moved_with_empty_file_total . "\n";
138
		echo 'Missing: ' . $missing_total . "\n";
139
		if ( $find_deprecated ) {
140
			echo 'Deprecated: ' . $deprecated_total . "\n";
141
		}
142
	}
143
}
144