/** * Check to see if the given Clazz is a duplicate * * @return null */ public static function analyzeParentConstructorCalled(CodeBase $code_base, Clazz $clazz) { // Only look at classes configured to require a call // to its parent constructor if (!in_array($clazz->getName(), Config::get()->parent_constructor_required)) { return; } // Don't worry about internal classes if ($clazz->isInternal()) { return; } // Don't worry if there's no parent class if (!$clazz->hasParentClassFQSEN()) { return; } if (!$code_base->hasClassWithFQSEN($clazz->getParentClassFQSEN())) { // This is an error, but its caught elsewhere. We'll // just roll through looking for other errors return; } $parent_clazz = $code_base->getClassByFQSEN($clazz->getParentClassFQSEN()); if (!$parent_clazz->isAbstract() && !$clazz->getIsParentConstructorCalled()) { Issue::emit(Issue::TypeParentConstructorCalled, $clazz->getContext()->getFile(), $clazz->getContext()->getLineNumberStart(), (string) $clazz->getFQSEN(), (string) $parent_clazz->getFQSEN()); } }
/** * @return bool * True if the FQSEN exists. If not, a log line is emitted */ private static function fqsenExistsForClass(FQSEN $fqsen, CodeBase $code_base, Clazz $clazz, string $issue_type) : bool { if (!$code_base->hasClassWithFQSEN($fqsen)) { Issue::emit($issue_type, $clazz->getContext()->getFile(), $clazz->getContext()->getLineNumberStart(), (string) $fqsen); return false; } return true; }
/** * @return bool * True if the FQSEN exists. If not, a log line is emitted */ private static function fqsenExistsForClass(FQSEN $fqsen, CodeBase $code_base, Clazz $clazz, string $message_template) : bool { if (!$code_base->hasClassWithFQSEN($fqsen)) { Log::err(Log::EUNDEF, sprintf($message_template, $fqsen), $clazz->getContext()->getFile(), $clazz->getContext()->getLineNumberStart()); return false; } return true; }
/** * @return bool * True if the FQSEN exists. If not, a log line is emitted */ private static function fqsenExistsForClass(FQSEN $fqsen, CodeBase $code_base, Clazz $clazz) : bool { if (!$code_base->hasClassWithFQSEN($fqsen)) { Log::err(Log::EUNDEF, "Trying to inherit from unknown class {$fqsen}", $clazz->getContext()->getFile(), $clazz->getContext()->getLineNumberStart()); return false; } return true; }
/** * @return array * Get a map from column name to row values for * this instance */ public function toRow() : array { $parent_class_fqsen = $this->clazz->hasParentClassFQSEN() ? (string) $this->clazz->getParentClassFQSEN() : null; $interface_fqsen_list_string = implode('|', array_map(function (FullyQualifiedClassName $fqsen) { return (string) $fqsen; }, $this->clazz->getInterfaceFQSENList())); $trait_fqsen_list_string = implode('|', array_map(function (FullyQualifiedClassName $fqsen) { return (string) $fqsen; }, $this->clazz->getInterfaceFQSENList())); return ['name' => (string) $this->clazz->getName(), 'type' => (string) $this->clazz->getUnionType(), 'flags' => $this->clazz->getFlags(), 'fqsen' => (string) $this->clazz->getFQSEN(), 'context' => base64_encode(serialize($this->clazz->getContext())), 'is_deprecated' => $this->clazz->isDeprecated(), 'parent_class_fqsen' => $parent_class_fqsen, 'interface_fqsen_list' => $interface_fqsen_list_string, 'trait_fqsen_list' => $trait_fqsen_list_string, 'is_parent_constructor_called' => $this->clazz->getIsParentConstructorCalled()]; }
/** * Check to see if the given Clazz is a duplicate * * @return null */ public static function analyzeDuplicateClass(CodeBase $code_base, Clazz $clazz) { // Determine if its a duplicate by looking to see if // the FQSEN is suffixed with an alternate ID. if (!$clazz->getFQSEN()->isAlternate()) { return; } $original_fqsen = $clazz->getFQSEN()->getCanonicalFQSEN(); if (!$code_base->hasClassWithFQSEN($original_fqsen)) { // If there's a missing class we'll catch that // elsewhere return; } // Get the original class $original_class = $code_base->getClassByFQSEN($original_fqsen); // Check to see if the original definition was from // an internal class if ($original_class->isInternal()) { Issue::emit(Issue::RedefineClassInternal, $clazz->getContext()->getFile(), $clazz->getContext()->getLineNumberStart(), (string) $clazz, $clazz->getContext()->getFile(), $clazz->getContext()->getLineNumberStart(), (string) $original_class); // Otherwise, print the coordinates of the original // definition } else { Issue::emit(Issue::RedefineClass, $clazz->getContext()->getFile(), $clazz->getContext()->getLineNumberStart(), (string) $clazz, $clazz->getContext()->getFile(), $clazz->getContext()->getLineNumberStart(), (string) $original_class, $original_class->getContext()->getFile(), $original_class->getContext()->getLineNumberStart()); } return; }
/** * Check to see if the given Clazz is a duplicate * * @return null */ public static function analyzeDuplicateClass(CodeBase $code_base, Clazz $clazz) { // Determine if its a duplicate by looking to see if // the FQSEN is suffixed with an alternate ID. if (!$clazz->getFQSEN()->isAlternate()) { return; } $original_fqsen = $clazz->getFQSEN()->getCanonicalFQSEN(); if (!$code_base->hasClassWithFQSEN($original_fqsen)) { // If there's a missing class we'll catch that // elsewhere return; } // Get the original class $original_class = $code_base->getClassByFQSEN($original_fqsen); // Check to see if the original definition was from // an internal class if ($original_class->isInternal()) { Log::err(Log::EREDEF, "{$clazz} defined at " . "{$clazz->getContext()->getFile()}:{$clazz->getContext()->getLineNumberStart()} " . "was previously defined as {$original_class} internally", $clazz->getContext()->getFile(), $clazz->getContext()->getLineNumberStart()); // Otherwise, print the coordinates of the original // definition } else { Log::err(Log::EREDEF, "{$clazz} defined at " . "{$clazz->getContext()->getFile()}:{$clazz->getContext()->getLineNumberStart()} " . "was previously defined as {$original_class} at " . "{$original_class->getContext()->getFile()}:{$original_class->getContext()->getLineNumberStart()}", $clazz->getContext()->getFile(), $clazz->getContext()->getLineNumberStart()); } return; }
/** * @param CodeBase $code_base * The code base in which the class exists * * @param Clazz $class * A class being analyzed * * @return void */ public function analyzeClass(CodeBase $code_base, Clazz $class) { // As an example, we test to see if the name of // the class is `Class`, and emit an issue explain that // the name is not allowed. if ($class->getName() == 'Class') { $this->emitIssue($code_base, $class->getContext(), 'DemoPluginClassName', "Class {$class->getFQSEN()} cannot be called `Class`"); } }
/** * Add a class to the code base * * @return null */ public function addClass(Clazz $class) { $this->class_map[$class->getFQSEN()] = $class; // For classes that aren't internal PHP classes if (!$class->getContext()->isInternal()) { // Associate the class with the file it was found in $this->getFileByPath($class->getContext()->getFile())->addClassFQSEN($class->getFQSEN()); } }