Phan\Language\Element\Clazz::addMethod PHP Method

addMethod() public method

Add a method to this class
public addMethod ( CodeBase $code_base, Method $method, Option | Phan\Library\None $type_option ) : null
$code_base Phan\CodeBase A reference to the code base in which the ancestor exists
$method Method The method to copy onto this class
$type_option Option | Phan\Library\None
return null
    public function addMethod(CodeBase $code_base, Method $method, $type_option)
    {
        $method_fqsen = FullyQualifiedMethodName::make($this->getFQSEN(), $method->getName(), $method->getFQSEN()->getAlternateId());
        // Don't overwrite overridden methods with
        // parent methods
        if ($code_base->hasMethodWithFQSEN($method_fqsen)) {
            // Note that we're overriding something
            $existing_method = $code_base->getMethodByFQSEN($method_fqsen);
            $existing_method->setIsOverride(true);
            // Don't add the method
            return;
        }
        if ($method->getFQSEN() !== $method_fqsen) {
            $method = clone $method;
            $method->setDefiningFQSEN($method->getFQSEN());
            $method->setFQSEN($method_fqsen);
            // If we have a parent type defined, map the method's
            // return type and parameter types through it
            if ($type_option->isDefined()) {
                // Map the method's return type
                if ($method->getUnionType()->hasTemplateType()) {
                    $method->setUnionType($method->getUnionType()->withTemplateParameterTypeMap($type_option->get()->getTemplateParameterTypeMap($code_base)));
                }
                // Map each method parameter
                $method->setParameterList(array_map(function (Parameter $parameter) use($type_option, $code_base) : Parameter {
                    if (!$parameter->getUnionType()->hasTemplateType()) {
                        return $parameter;
                    }
                    $mapped_parameter = clone $parameter;
                    $mapped_parameter->setUnionType($mapped_parameter->getUnionType()->withTemplateParameterTypeMap($type_option->get()->getTemplateParameterTypeMap($code_base)));
                    return $mapped_parameter;
                }, $method->getParameterList()));
            }
        }
        if ($method->getHasYield()) {
            // There's no phpdoc standard for template types of Generators at the moment.
            $newType = UnionType::fromFullyQualifiedString('\\Generator');
            $oldType = $method->getUnionType();
            if (!$newType->canCastToUnionType($method->getUnionType())) {
                $method->setUnionType($newType);
            }
        }
        $code_base->addMethod($method);
    }

Usage Example

Example #1
0
 /**
  * @param CodeBase $code_base
  * A reference to the entire code base in which this
  * context exists
  *
  * @param ReflectionClass $class
  * A reflection class representing a builtin class.
  *
  * @return Clazz
  * A Class structural element representing the given named
  * builtin.
  */
 public static function fromReflectionClass(CodeBase $code_base, \ReflectionClass $class) : Clazz
 {
     // Build a set of flags based on the constitution
     // of the built-in class
     $flags = 0;
     if ($class->isFinal()) {
         $flags = \ast\flags\CLASS_FINAL;
     } else {
         if ($class->isInterface()) {
             $flags = \ast\flags\CLASS_INTERFACE;
         } else {
             if ($class->isTrait()) {
                 $flags = \ast\flags\CLASS_TRAIT;
             }
         }
     }
     if ($class->isAbstract()) {
         $flags |= \ast\flags\CLASS_ABSTRACT;
     }
     $context = new Context();
     // Build a base class element
     $clazz = new Clazz($context, $class->getName(), UnionType::fromStringInContext($class->getName(), $context), $flags);
     // If this class has a parent class, add it to the
     // class info
     if ($parent_class = $class->getParentClass()) {
         $parent_class_fqsen = FullyQualifiedClassName::fromFullyQualifiedString('\\' . $parent_class->getName());
         $clazz->setParentClassFQSEN($parent_class_fqsen);
     }
     foreach ($class->getDefaultProperties() as $name => $value) {
         // TODO: whats going on here?
         $reflection_property = new \ReflectionProperty($class->getName(), $name);
         $property = new Property($context->withClassFQSEN($clazz->getFQSEN()), $name, Type::fromObject($value)->asUnionType(), 0);
         $clazz->addProperty($code_base, $property);
     }
     foreach ($class->getInterfaceNames() as $name) {
         $clazz->addInterfaceClassFQSEN(FullyQualifiedClassName::fromFullyQualifiedString('\\' . $name));
     }
     foreach ($class->getTraitNames() as $name) {
         $clazz->addTraitFQSEN(FullyQualifiedClassName::fromFullyQualifiedString('\\' . $name));
     }
     foreach ($class->getConstants() as $name => $value) {
         $clazz->addConstant($code_base, new Constant($context, $name, Type::fromObject($value)->asUnionType(), 0));
     }
     foreach ($class->getMethods() as $reflection_method) {
         $method_list = Method::methodListFromReflectionClassAndMethod($context->withClassFQSEN($clazz->getFQSEN()), $code_base, $class, $reflection_method);
         foreach ($method_list as $method) {
             $clazz->addMethod($code_base, $method);
         }
     }
     return $clazz;
 }
All Usage Examples Of Phan\Language\Element\Clazz::addMethod