| Conditions | 39 |
| Paths | 1164 |
| Total Lines | 194 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 27 | public static function analyze( |
||
| 28 | StatementsAnalyzer $statements_analyzer, |
||
| 29 | PhpParser\Node\Expr\Yield_ $stmt, |
||
| 30 | Context $context |
||
| 31 | ) : bool { |
||
| 32 | $doc_comment = $stmt->getDocComment(); |
||
| 33 | |||
| 34 | $var_comments = []; |
||
| 35 | $var_comment_type = null; |
||
| 36 | |||
| 37 | $codebase = $statements_analyzer->getCodebase(); |
||
| 38 | |||
| 39 | if ($doc_comment) { |
||
| 40 | try { |
||
| 41 | $var_comments = CommentAnalyzer::getTypeFromComment( |
||
| 42 | $doc_comment, |
||
| 43 | $statements_analyzer, |
||
| 44 | $statements_analyzer->getAliases() |
||
| 45 | ); |
||
| 46 | } catch (DocblockParseException $e) { |
||
| 47 | if (IssueBuffer::accepts( |
||
| 48 | new InvalidDocblock( |
||
| 49 | (string)$e->getMessage(), |
||
| 50 | new CodeLocation($statements_analyzer->getSource(), $stmt) |
||
| 51 | ) |
||
| 52 | )) { |
||
| 53 | // fall through |
||
| 54 | } |
||
| 55 | } |
||
| 56 | |||
| 57 | foreach ($var_comments as $var_comment) { |
||
| 58 | if (!$var_comment->type) { |
||
| 59 | continue; |
||
| 60 | } |
||
| 61 | |||
| 62 | $comment_type = \Psalm\Internal\Type\TypeExpander::expandUnion( |
||
| 63 | $codebase, |
||
| 64 | $var_comment->type, |
||
| 65 | $context->self, |
||
| 66 | $context->self ? new Type\Atomic\TNamedObject($context->self) : null, |
||
| 67 | $statements_analyzer->getParentFQCLN() |
||
| 68 | ); |
||
| 69 | |||
| 70 | $type_location = null; |
||
| 71 | |||
| 72 | if ($var_comment->type_start |
||
| 73 | && $var_comment->type_end |
||
| 74 | && $var_comment->line_number |
||
| 75 | ) { |
||
| 76 | $type_location = new CodeLocation\DocblockTypeLocation( |
||
| 77 | $statements_analyzer, |
||
| 78 | $var_comment->type_start, |
||
| 79 | $var_comment->type_end, |
||
| 80 | $var_comment->line_number |
||
| 81 | ); |
||
| 82 | } |
||
| 83 | |||
| 84 | if (!$var_comment->var_id) { |
||
| 85 | $var_comment_type = $comment_type; |
||
| 86 | continue; |
||
| 87 | } |
||
| 88 | |||
| 89 | if ($codebase->find_unused_variables |
||
| 90 | && $type_location |
||
| 91 | && isset($context->vars_in_scope[$var_comment->var_id]) |
||
| 92 | && $context->vars_in_scope[$var_comment->var_id]->getId() === $comment_type->getId() |
||
| 93 | ) { |
||
| 94 | $project_analyzer = $statements_analyzer->getProjectAnalyzer(); |
||
| 95 | |||
| 96 | if ($codebase->alter_code |
||
| 97 | && isset($project_analyzer->getIssuesToFix()['UnnecessaryVarAnnotation']) |
||
| 98 | ) { |
||
| 99 | FileManipulationBuffer::addVarAnnotationToRemove($type_location); |
||
| 100 | } elseif (IssueBuffer::accepts( |
||
| 101 | new UnnecessaryVarAnnotation( |
||
| 102 | 'The @var annotation for ' . $var_comment->var_id . ' is unnecessary', |
||
| 103 | $type_location |
||
| 104 | ), |
||
| 105 | [], |
||
| 106 | true |
||
| 107 | )) { |
||
| 108 | // fall through |
||
| 109 | } |
||
| 110 | } |
||
| 111 | |||
| 112 | $context->vars_in_scope[$var_comment->var_id] = $comment_type; |
||
| 113 | } |
||
| 114 | } |
||
| 115 | |||
| 116 | if ($stmt->key) { |
||
| 117 | $context->inside_call = true; |
||
| 118 | if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->key, $context) === false) { |
||
| 119 | return false; |
||
| 120 | } |
||
| 121 | $context->inside_call = false; |
||
| 122 | } |
||
| 123 | |||
| 124 | if ($stmt->value) { |
||
| 125 | $context->inside_call = true; |
||
| 126 | if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->value, $context) === false) { |
||
| 127 | return false; |
||
| 128 | } |
||
| 129 | $context->inside_call = false; |
||
| 130 | |||
| 131 | if ($var_comment_type) { |
||
| 132 | $expression_type = clone $var_comment_type; |
||
| 133 | } elseif ($stmt_var_type = $statements_analyzer->node_data->getType($stmt->value)) { |
||
| 134 | $expression_type = clone $stmt_var_type; |
||
| 135 | } else { |
||
| 136 | $expression_type = Type::getMixed(); |
||
| 137 | } |
||
| 138 | } else { |
||
| 139 | $expression_type = Type::getEmpty(); |
||
| 140 | } |
||
| 141 | |||
| 142 | $yield_type = null; |
||
| 143 | |||
| 144 | foreach ($expression_type->getAtomicTypes() as $expression_atomic_type) { |
||
| 145 | if ($expression_atomic_type instanceof Type\Atomic\TNamedObject) { |
||
| 146 | $classlike_storage = $codebase->classlike_storage_provider->get($expression_atomic_type->value); |
||
| 147 | |||
| 148 | if ($classlike_storage->yield) { |
||
| 149 | if ($expression_atomic_type instanceof Type\Atomic\TGenericObject) { |
||
| 150 | $yield_candidate_type = InstancePropertyFetchAnalyzer::localizePropertyType( |
||
| 151 | $codebase, |
||
| 152 | clone $classlike_storage->yield, |
||
| 153 | $expression_atomic_type, |
||
| 154 | $classlike_storage, |
||
| 155 | $classlike_storage |
||
| 156 | ); |
||
| 157 | |||
| 158 | if ($yield_type) { |
||
| 159 | $yield_type = Type::combineUnionTypes( |
||
| 160 | $yield_type, |
||
| 161 | $yield_candidate_type, |
||
| 162 | $codebase |
||
| 163 | ); |
||
| 164 | } else { |
||
| 165 | $yield_type = $yield_candidate_type; |
||
| 166 | } |
||
| 167 | } else { |
||
| 168 | $yield_type = Type::getMixed(); |
||
| 169 | } |
||
| 170 | } |
||
| 171 | } |
||
| 172 | } |
||
| 173 | |||
| 174 | if ($yield_type) { |
||
| 175 | $expression_type->substitute($expression_type, $yield_type); |
||
| 176 | } |
||
| 177 | |||
| 178 | $statements_analyzer->node_data->setType($stmt, $expression_type); |
||
| 179 | |||
| 180 | $source = $statements_analyzer->getSource(); |
||
| 181 | |||
| 182 | if ($source instanceof FunctionLikeAnalyzer |
||
| 183 | && !($source->getSource() instanceof TraitAnalyzer) |
||
| 184 | ) { |
||
| 185 | $source->examineParamTypes($statements_analyzer, $context, $codebase, $stmt); |
||
| 186 | |||
| 187 | $storage = $source->getFunctionLikeStorage($statements_analyzer); |
||
| 188 | |||
| 189 | if ($storage->return_type && !$yield_type) { |
||
| 190 | foreach ($storage->return_type->getAtomicTypes() as $atomic_return_type) { |
||
| 191 | if ($atomic_return_type instanceof Type\Atomic\TNamedObject |
||
| 192 | && $atomic_return_type->value === 'Generator' |
||
| 193 | ) { |
||
| 194 | if ($atomic_return_type instanceof Type\Atomic\TGenericObject) { |
||
| 195 | if (!$atomic_return_type->type_params[2]->isVoid()) { |
||
| 196 | $statements_analyzer->node_data->setType( |
||
| 197 | $stmt, |
||
| 198 | Type::combineUnionTypes( |
||
| 199 | clone $atomic_return_type->type_params[2], |
||
| 200 | $expression_type, |
||
| 201 | $codebase |
||
| 202 | ) |
||
| 203 | ); |
||
| 204 | } |
||
| 205 | } else { |
||
| 206 | $statements_analyzer->node_data->setType( |
||
| 207 | $stmt, |
||
| 208 | Type::combineUnionTypes( |
||
| 209 | Type::getMixed(), |
||
| 210 | $expression_type |
||
| 211 | ) |
||
| 212 | ); |
||
| 213 | } |
||
| 214 | } |
||
| 215 | } |
||
| 216 | } |
||
| 217 | } |
||
| 218 | |||
| 219 | return true; |
||
| 220 | } |
||
| 221 | } |
||
| 222 |