/** * Override the default getter to fill in a future * union type if available. * * @return UnionType */ public function getUnionType() : UnionType { if (null !== ($union_type = $this->getFutureUnionType())) { $this->getUnionType()->addUnionType($union_type); } return parent::getUnionType(); }
/** * Check to see if the given Clazz is a duplicate * * @return null */ public static function analyzeElementReferenceCounts(CodeBase $code_base, AddressableElement $element, string $issue_type) { // Don't worry about internal elements if ($element->isInternal()) { return; } // Skip methods that are overrides of other methods if ($element instanceof ClassElement) { if ($element->getIsOverride()) { return; } $class_fqsen = $element->getClassFQSEN(); // Don't analyze elements defined in a parent // class if ((string) $class_fqsen !== $element->getFQSEN()) { return; } $defining_class = $element->getClass($code_base); // Don't analyze elements on interfaces or on // abstract classes, as they're uncallable. if ($defining_class->isInterface() || $defining_class->isAbstract() || $defining_class->isTrait()) { return; } // Ignore magic methods if ($element instanceof Method) { // Doubly nested so that `$element` shows // up as Method in Phan. if ($element->getIsMagic()) { return; } } } // Skip properties on classes that have a magic // __get or __set method given that we can't track // their access if ($element instanceof Property) { $defining_class = $element->getClass($code_base); if ($defining_class->hasGetOrSetMethod($code_base)) { return; } } /* print "digraph G {\n"; foreach ($element->getReferenceList() as $file_ref) { print "\t\"{$file_ref->getFile()}\" -> \"{$element->getFileRef()->getFile()}\";\n"; } print "}\n"; */ if ($element->getReferenceCount($code_base) < 1) { if ($element->hasSuppressIssue($issue_type)) { return; } if ($element instanceof AddressableElement) { Issue::maybeEmit($code_base, $element->getContext(), $issue_type, $element->getFileRef()->getLineNumberStart(), (string) $element->getFQSEN()); } else { Issue::maybeEmit($code_base, $element->getContext(), $issue_type, $element->getFileRef()->getLineNumberStart(), (string) $element); } } }
/** * @param \phan\Context $context * The context in which the structural element lives * * @param string $name, * The name of the typed structural element * * @param UnionType $type, * A '|' delimited set of types satisfyped by this * typed structural element. * * @param int $flags, * The flags property contains node specific flags. It is * always defined, but for most nodes it is always zero. * ast\kind_uses_flags() can be used to determine whether * a certain kind has a meaningful flags value. */ public function __construct(Context $context, string $name, UnionType $type, int $flags) { parent::__construct($context, $name, $type, $flags); }
/** * @return int * The number of references to this typed structural element */ public function getReferenceCount(CodeBase $code_base) : int { $count = parent::getReferenceCount($code_base); // A function that maps a list of elements to the // total reference count for all elements $list_count = function (array $list) use($code_base) { return array_reduce($list, function (int $count, AddressableElement $element) use($code_base) { return $count + $element->getReferenceCount($code_base); }, 0); }; // Sum up counts for all dependent elements $count += $list_count($this->getPropertyList($code_base)); $count += $list_count($this->getMethodMap($code_base)); $count += $list_count($this->getConstantMap($code_base)); return $count; }
/** * Check to see if the given Clazz is a duplicate * * @return null */ public static function analyzeElementReferenceCounts(CodeBase $code_base, AddressableElement $element, string $issue_type) { // Don't worry about internal elements if ($element->isInternal()) { return; } /* print "digraph G {\n"; foreach ($element->getReferenceList() as $file_ref) { print "\t\"{$file_ref->getFile()}\" -> \"{$element->getFileRef()->getFile()}\";\n"; } print "}\n"; */ if ($element->getReferenceCount($code_base) < 1) { if ($element->hasSuppressIssue($issue_type)) { return; } if ($element instanceof AddressableElement) { Issue::emit($issue_type, $element->getFileRef()->getFile(), $element->getFileRef()->getLineNumberStart(), (string) $element->getFQSEN()); } else { Issue::emit($issue_type, $element->getFileRef()->getFile(), $element->getFileRef()->getLineNumberStart(), (string) $element); } } }
/** * @param \phan\Context $context * The context in which the structural element lives * * @param string $name, * The name of the typed structural element * * @param UnionType $type, * A '|' delimited set of types satisfyped by this * typed structural element. * * @param int $flags, * The flags property contains node specific flags. It is * always defined, but for most nodes it is always zero. * ast\kind_uses_flags() can be used to determine whether * a certain kind has a meaningful flags value. */ public function __construct(Context $context, string $name, UnionType $type, int $flags, FullyQualifiedFunctionName $fqsen) { parent::__construct($context, $name, $type, $flags, $fqsen); $this->setInternalScope(new FunctionLikeScope($context->getScope(), $fqsen)); }