{@inheritdoc}

@throws \ReflectionException
195134
public function annotatedWith($annotationName) : AbstractMatcher
    {
        if (! class_exists($annotationName)) {
            throw new InvalidAnnotationException($annotationName);
        }

        return new AnnotatedMatcher(__FUNCTION__, [$annotationName]);
    }
456284
private function setFieldValue($entity, \ReflectionProperty $reflectionProperty, $value)
    {
        if ($reflectionProperty) {
            $reflectionProperty->setAccessible(true);
            $value = $reflectionProperty->setValue($entity, $value);
        }
    }
96437
private function parseMethods()
    {
        $methods = $this->reflectionClass->getMethods(); // this still returns the methods for all parent classes
        if (!is_array($methods) || count($methods) < 1) {
            throw new RestException('Parser: The class "' . $this->class . '" doesn\'t have any methods defined.');
        }

        foreach ($methods as $m) {
            if ($m->isPublic()) {
                $methodParser = new MethodParser($this->parentClasses, $m, $this->normalize);
                $parsedMethod = $methodParser->parse();
                if ($parsedMethod) {
                    $this->parsedClass->addApiMethod($parsedMethod);
                }
            }
        }
    }
342246
public function Bind()
	{
		if ( $this->getCount() > 0)
		{
			if ( $this->getAbstractNode(0) instanceof PathExprNode )
			{
				/**
				 * @var PathExprNode $pathExpr
				 */
				$pathExpr = $this->getAbstractNode(0);
				if ( in_array( $this->_name, FuncNode::$s_aggregates ) && $this->_ns == XmlReservedNs::xQueryFunc )
				{
					$pathExpr->Unordered = true;
				}
			}
		}
		parent::Bind();
	}
374755
public function setInstance($instance) {
		$reflection = new ReflectionClass($instance);
		$name = str_replace('\\', ':', $reflection->getName());
		$this->instances[$name] = $instance;
	}
1368599
public function configure()
    {
        $configurator = $this->configurator;
        if (!($configurator instanceof ElFinderConfigurationProviderInterface)) {
            throw new \Exception('Configurator class must implement ElFinderConfigurationProviderInterface');
        }
        $parameters = $configurator->getConfiguration($this->instance);

        return $parameters;
    }
628239
protected function parse($object)
    {
        if (! is_object($object)) {
            throw new ValidationException('ErrorSource has to be an object, "' . gettype($object) . '" given.');
        }

        if (property_exists($object, 'pointer')) {
            if (! is_string($object->pointer)) {
                throw new ValidationException('property "pointer" has to be a string, "' . gettype($object->pointer) . '" given.');
            }

            $this->set('pointer', strval($object->pointer));
        }

        if (property_exists($object, 'parameter')) {
            if (! is_string($object->parameter)) {
                throw new ValidationException('property "parameter" has to be a string, "' . gettype($object->parameter) . '" given.');
            }

            $this->set('parameter', strval($object->parameter));
        }
    }
241553
public function parse($annotation, \ReflectionClass $refClass, Endpoint $endpoint)
    {
        /** @var Annotation\Subscription $annotation */

        if (!preg_match('/\\Subscription\\\\/', $refClass->getName())) {
            $error = sprintf(
                'Annotation "@Subscription" in the class "%s" is not valid, 
            mutations can only be applied to classes inside "...Bundle\Subscription\..."',
                $refClass->getName()
            );
            throw new \RuntimeException($error);
        }

        if (!$annotation->resolver && !$refClass->hasMethod('__invoke')) {
            $error = sprintf(
                'The class "%s" should have a method "__invoke" to process the subscription.',
                $refClass->getName()
            );
            throw new \RuntimeException($error);
        }

        $subscription = new SubscriptionDefinition();
        $subscription->setType(TypeUtil::normalize($annotation->payload));

        if ($annotation->name) {
            $subscription->setName($annotation->name);
        } else {
            $subscription->setName(lcfirst(ClassUtils::getDefaultName($refClass->getName())));
        }

        if (!$subscription->getType()) {
            $nodeType = ClassUtils::getNodeFromClass($refClass->getName());
            $objectDefinition = null;
            if ($nodeType && $endpoint->hasType($nodeType)) {
                $objectDefinition = $endpoint->getType($nodeType);
            }
            if ($objectDefinition) {
                $subscription->setType($objectDefinition->getName());
                $subscription->setNode($objectDefinition->getName());
            } else {
                $error = sprintf('Does not exist any valid type for class "%s"', $refClass->getName());
                throw new \RuntimeException($error);
            }
        }

        $endpoint->addSubscription($subscription);

        if (!$annotation->payload) {
            if (class_exists($refClass->getName().'Payload')) {
                $annotation->payload = $refClass->getName().'Payload';
                if (!$endpoint->hasTypeForClass($annotation->payload)) {
                    $error = sprintf(
                        'The payload "%s" exist but does not exist a valid GraphQL type, is missing ObjectType annotation?',
                        $annotation->payload
                    );
                    throw new \RuntimeException($error);
                }
            }
        }

        // create subscription event
        $subscriptionEvent = new ObjectDefinition();
        $subscriptionEvent->setName(ucfirst($subscription->getName()).'Event');
        $field = new FieldDefinition();
        $field->setName($annotation->fieldName ?? 'data');
        $field->setDescription($annotation->fieldDescription ?? null);
        $field->setType($subscription->getType());
        $field->setNode($subscription->getNode());
        $field->setNonNull(TypeUtil::isTypeNonNull($annotation->payload));
        $field->setList(TypeUtil::isTypeList($annotation->payload));
        $field->setNonNullList(TypeUtil::isTypeNonNullList($annotation->payload));
        $subscriptionEvent->addField($field);
        $endpoint->addType($subscriptionEvent);

        // subscription response is a union between SubscriptionLink object and specific Subscription Event
        $subscriptionResponse = new UnionDefinition();
        $subscriptionResponse->setName(ucfirst($subscription->getName()).'Subscription');
        $subscriptionResponse->addType(new UnionTypeDefinition($subscriptionEvent->getName()));
        $subscriptionResponse->addType(new UnionTypeDefinition($endpoint->getTypeForClass(SubscriptionLink::class)));
        $endpoint->addType($subscriptionResponse);
        $subscription->setType(TypeUtil::normalize($subscriptionResponse->getName()));

        if (!$subscription->getType()) {
            $error = sprintf(
                'The subscription "%s" does not have a valid payload,
                 create a file called %sPayload or specify a payload.',
                $subscription->getName(),
                $refClass->getName()
            );
            throw new \RuntimeException($error);
        }

        $argAnnotations = $this->reader->getClassAnnotations($refClass);
        foreach ($argAnnotations as $argAnnotation) {
            if ($argAnnotation instanceof Annotation\Argument) {
                $this->resolveArgument($subscription, $argAnnotation);
            }
        }

        if ($annotation->node) {
            $subscription->setNode($annotation->node);
        } elseif (($node = ClassUtils::getNodeFromClass($refClass->getName())) && $endpoint->hasType($node)) {
            $subscription->setNode($node);
        }

        $subscription->setResolver($annotation->resolver ?? $refClass->getName());
        $subscription->setDeprecationReason($annotation->deprecationReason);
        $subscription->setDescription($annotation->description);

        foreach ($annotation->options as $option => $value) {
            $subscription->setMeta($option, $value);
        }
    }
417665
public function bind()
    {
        parent::bind();

        // In environments that are not a skeleton app we use an Application
        // instance to hold the paths.
        if (!$this->app->bound(Application::class)) {
            $this->app->instance(Application::class, $this->createPlaceholderApp());
        }

        $this->assignPathsToApp($this->app->make(Application::class));

        $this->app->resolving(PathFinder::class, function ($paths) {
            $this->assignBaseAppPaths($paths);
        });

        $this->app->resolving(StringConverterChain::class, function ($chain) {
            $this->addStringConverters($chain);
        });

        $this->app->resolving(TextFormatter::class, function ($formatter, $app) {
            $formatter->setLocalizer($app('Ems\Contracts\Core\Localizer'));
        });

        $this->app->bind('ems::locale-config', function ($ioc) {

            /** @var Application $app */
            $app = $ioc(Application::class);
            $storage = new NestedFileStorage();
            $storage->setUrl($app->path('ems-resources')->append('lang'));
            $storage->setNestingLevel(1);

            $provider = new ArrayProvider();
            $provider->add($storage);

            return $provider;

        }, true);

        $this->app->bind(Matcher::class, function ($ioc) {
            return new Matcher($ioc(CheckerContract::class), $ioc(ExtractorContract::class));
        }, true);

        $this->app->resolving(Formatter::class, function (Formatter $formatter, $app) {
            $formatter->setFormats($app('ems::locale-config'));
        });

        $this->app->resolving(TextParserQueue::class, function ($queue, $app) {
            $queue->add($app(VariablesTextParser::class));
        });

        $this->app->resolving(AnythingProvider::class, function ($provider, $app) {
            $provider->createObjectsWith($app);
        });

        $this->app->resolving(SupportsCustomFactory::class, function ($object) {
            $object->createObjectsBy($this->app);
        });

        $this->app->resolving(HasInjectMethods::class, function (HasInjectMethods $object) {
            $this->autoInjectDependendies($object);
        });

        $this->app->resolving(ConnectionPoolContract::class, function (ConnectionPoolContract $pool) {
            /** @return void */
            $pool->extend('php', function (UrlContract $url) {
                if ($url->scheme == 'php' || $url->scheme == 'file') {
                    return new FilesystemConnection($url);
                }
                return null;
            });
        });
    }
2689
protected function arguments(\ReflectionFunctionAbstract $reflection, $parameters = array())
    {
        $arguments = array();

        foreach ($reflection->getParameters() as $key => $parameter)
        {
            $name = $parameter->getName();

            if ($class = $parameter->getClass())
            {
                $name = $class->getName();
            }

            if (isset($parameters[$name]))
            {
                if ($parameter->isDefaultValueAvailable())
                {
                    $arguments[$name] = $parameter->getDefaultValue();
                }

                if ($parameters[$name])
                {
                    $arguments[$name] = $parameters[$name];
                }

                continue;
            }

            $arguments[$name] = $this->instance($name);
        }

        return $arguments;
    }
1087731
public function process(): void
    {
        /** @var \Closure|object $closure */
        $closure = include $this->file;

        if (!\is_callable($closure)) {
            throw new ComponentException("There is no callable structure in file `{$this->file}`");
        }

        $reflection = new \ReflectionFunction($closure);

        // check and normalize params by doc comment
        $docComment = $reflection->getDocComment();

        // get all options by one regular expression
        if (preg_match_all('/\s*\*\s*\@([a-z0-9-_]+)\s+(.*).*\s+/i', $docComment, $matches)) {
            foreach ($matches[1] as $i => $key) {
                $this->setOption($key, trim($matches[2][$i]));
            }
        }

        // init routes
        $this->initRoute();

        // get params and convert it to simple array
        $reflectionParams = $reflection->getParameters();
        // setup params and optional params
        foreach ($reflectionParams as $param) {
            $name = $param->getName();
            // if some function params is missed in description
            if (!isset($this->params[$name])) {
                $this->params[$name] = null;
            }
            if ($param->isOptional()) {
                $this->values[$name] = $param->getDefaultValue();
            }
        }
    }
1063834
protected function inject(\ReflectionFunctionAbstract $reflection, array $args = [])
    {
        // get parameters
        $parameters = $reflection->getParameters();

        // Build argument list
        $arguments = [];
        foreach ($parameters as $parameter) {
            // Get class
            $class = $parameter->getClass();

            // From argument array (class or parameter name)
            $key = $class && isset($args[$class->name]) ? $class->name : $parameter->name;
            if (array_key_exists($key, $args)) {
                $arguments[] = $args[$key];
                unset($args[$key]);
                continue;
            }

            // Delegated Lookup
            if ($class && $this->delegate->has($class->name)) {
                $arguments[] = $this->delegate->get($class->name);
                continue;
            }

            // Real class
            if ($class && class_exists($class->name)) {
                $arguments[] = $this->make($class->name);
                continue;
            }

            // Skip optional parameter with default value
            if ($parameter->isDefaultValueAvailable()) {
                $arguments[] = $parameter->getDefaultValue();
                continue;
            }

            // Couldn't resolve the dependency
            throw new Exceptions\ParameterResolutionException($reflection, $parameter);
        }

        return $arguments;
    }
28967
public function getDependency(\ReflectionParameter $parameter, \ReflectionClass $reflected)
    {
        if ($parameter->isArray() || !$parameter->getClass()) {

            if ($parameter->isArray()) {
                return 'array';
            }

            return null;
        }

        $class = $parameter->getClass()->name;

        if ($class == 'Closure') {
            return null;
        }

        $reflected = new \ReflectionClass($class);

        if ($this->provider->hasBinding($reflected->name)) {
            return $this->provider->getBinding($reflected->name);
        } else {
            // TODO: inspect this
            return $reflected->name;
        }
    }
474057
public function map(ConfiguratorFactory $configuratorFactory, \ReflectionClass $reflectionClass)
    {
        /** @var CrudConfigurator $crudConfigurator */
        $crudConfigurator = $configuratorFactory->getConfigurator(CrudConfigurator::class);
        /** @var PageConfigurator $pageConfigurator */
        $pageConfigurator = $configuratorFactory->getConfigurator(PageConfigurator::class);
        /** @var GridConfigurator $gridConfigurator */
        $gridConfigurator = $configuratorFactory->getConfigurator(GridConfigurator::class);
        /** @var PluginConfigurator $pluginConfigurator */
        $pluginConfigurator = $configuratorFactory->getConfigurator(PluginConfigurator::class);
        /** @var SecurityConfigurator $securityConfigurator */
        $securityConfigurator = $configuratorFactory->getConfigurator(SecurityConfigurator::class);
        /** @var UtilConfigurator $utilConfigurator */
        $utilConfigurator = $configuratorFactory->getConfigurator(UtilConfigurator::class);

        $classAnnotations = $this->extractorFactory->extract($reflectionClass, Extractor::CLASS_ANNOTATION);
        foreach ($classAnnotations as $annotation) {
            if ($annotation instanceof Crud) {
                $crudConfigurator->setCrud($this->mergeCrudConfiguration($crudConfigurator->getCrud(), $annotation));
                $configuratorFactory->addConfigurator($crudConfigurator);
            }

            if ($annotation instanceof Page) {
                $pageConfigurator->setPage($annotation);
                $configuratorFactory->addConfigurator($pageConfigurator);
            }

            if ($annotation instanceof Grid) {
                $gridConfigurator->setGrid($this->mergeGridConfiguration($gridConfigurator->getGrid(), $annotation));
                $configuratorFactory->addConfigurator($gridConfigurator);
            }

            if ($annotation instanceof Plugin) {
                $pluginConfigurator->setPlugin($annotation);
                $configuratorFactory->addConfigurator($pluginConfigurator);
            }

            if ($annotation instanceof Security) {
                $securityConfigurator->setSecurity($annotation);
                $configuratorFactory->addConfigurator($securityConfigurator);
            }

            if ($annotation instanceof Util) {
                $utilConfigurator->setUtil($annotation);
                $configuratorFactory->addConfigurator($utilConfigurator);
            }
        }

        return $configuratorFactory;
    }
1213082
protected function saveToCache()
    {
        if (!is_object($this->dataCache)) {
            throw new Exception('A cache must be injected before initializing the Reflection Service.', 1232044697);
        }
        $data = [];
        $propertyNames = [
            'reflectedClassNames',
            'classPropertyNames',
            'classMethodNames',
            'classTagsValues',
            'methodTagsValues',
            'methodParameters',
            'propertyTagsValues',
            'taggedClasses',
            'classSchemata'
        ];
        foreach ($propertyNames as $propertyName) {
            $data[$propertyName] = $this->{$propertyName};
        }
        $this->dataCache->set($this->cacheIdentifier, $data);
        $this->dataCacheNeedsUpdate = false;
    }
621778
public function parse($annotation, \ReflectionClass $refClass, Endpoint $endpoint)
    {
        $field = new FieldDefinition();

        if ($annotation->name) {
            $field->setName($annotation->name);
        } else {
            $field->setName(lcfirst(ClassUtils::getDefaultName($refClass->getName())));
        }

        $objectType = null;
        preg_match('/(\w+)\\\\Field\\\\(\w+)$/', $refClass->getName(), $matches);
        if (!isset($matches[1]) || !$endpoint->hasType($matches[1])) {
            $error = sprintf('Can`t resolve a valid object type for field "%s"', $refClass->getName());
            throw new \RuntimeException($error);
        }
        /** @var ObjectDefinitionInterface $objectDefinition */
        $objectDefinition = $endpoint->getType($matches[1]);
        $objectDefinition->addField($field);

        $argAnnotations = $this->reader->getClassAnnotations($refClass);
        foreach ($argAnnotations as $argAnnotation) {
            if ($argAnnotation instanceof Annotation\Argument) {
                $this->resolveArgument($field, $argAnnotation);
            }
        }

        $field->setType(TypeUtil::normalize($annotation->type));
        $field->setList(TypeUtil::isTypeList($annotation->type));
        $field->setResolver($annotation->resolver ?? $refClass->getName());
        $field->setDeprecationReason($annotation->deprecationReason);
        $field->setDescription($annotation->description);
        $field->setComplexity($annotation->complexity);
        $field->setMaxConcurrentUsage($annotation->maxConcurrentUsage);

        foreach ($annotation->options as $option => $value) {
            $field->setMeta($option, $value);
        }

        if ($objectDefinition instanceof InterfaceDefinition) {
            $implementors = $objectDefinition->getImplementors();
            foreach ($implementors as $implementor) {
                $childType = $endpoint->getType($implementor);
                if ($childType instanceof FieldsAwareDefinitionInterface) {
                    $childType->addField($field);
                }
            }
        }
    }
189306
public function validate() {
		parent::validate();

		if ($this->getName() === null) {
			throw new ValidationException("'name' can't be null", 'name', $this);
		}
		if ($this->getType() === null) {
			throw new ValidationException("'type' can't be null", 'type', $this);
		}
	}