生成接口

@param \ReflectionClass $class
@return void
779864
private function generateInterface($class)
    {
        $consts = $this->getClassConsts($class);
        $methods = $this->getClassMethods($class);

        $result = '<?php' . PHP_EOL;

        $className = $class->getShortName();
        $namespace = $class->getNamespaceName();
        if('' !== $namespace)
        {
            $namespace = 'namespace ' . $namespace . ';';
        }
        $result .= <<<CODE
{$namespace}

interface {$className}
{
{$consts}{$methods}
}

CODE;
        $path = $this->savePath . '/interfaces/' . str_replace('\\', '/', $class->getNamespaceName()) . '/';
        if(!is_dir($path))
        {
            mkdir($path, 0777, true);
        }
        file_put_contents($path . $class->getShortName() . '.php', $result);
    }
11661
private function make(string $class)
    {
        if (! array_key_exists($class, $this->instances)) {

            try {

                return $this->instances[$class] = ($this->factory)($class)->value($this);

            }

            catch (ResolvingExceptionInterface $e) {

                throw new ReflectionContainerException($class, $e);

            }

        }

        return $this->instances[$class];
    }
1057989
public static function instantiateClassByConstructor($class, $args)
    {
        switch (count($args)) {
            case 0:
                return new $class();
            case 1:
                return new $class($args[0]);
            case 2:
                return new $class($args[0], $args[1]);
            case 3:
                return new $class($args[0], $args[1], $args[2]);
            case 4:
                return new $class($args[0], $args[1], $args[2], $args[3]);
            default:
                $rClass = new \ReflectionClass($class);
                return $rClass->newInstanceArgs($args);
        }
    }
1252274
private static function createMethods(\ReflectionClass $class): string
    {
        $code    = '';
        $methods = [];
        $params  = [];
        $voidMethods = [];
        foreach (self::methodsOf($class) as $method) {
            $return = true;
            $returnType = determineReturnTypeOf($method);
            if ($returnType === ': void') {
                $voidMethods[$method->getName()] = $method->getName();
                $return = false;
            }

            $param = paramsOf($method);
            /* @var $method \ReflectionMethod */
            $code .= sprintf(
                    "    %s function %s(%s)%s {\n"
                  . "        %s\$this->handleMethodCall('%s', func_get_args(), %s);\n"
                  . "    }\n",
                    ($method->isPublic() ? 'public' : 'protected'),
                    $method->getName(),
                    $param['string'],
                    $returnType,
                    $return ? 'return ' : '',
                    $method->getName(),
                    self::shouldReturnSelf($class, $method) ? 'true' : 'false'
            );
            $methods[] = "'" . $method->getName() . "' => '" . $method->getName() . "'";
            $params[$method->getName()] = $param['names'];
        }

        return $code . sprintf(
                "\n    private \$_allowedMethods = [%s];\n",
                join(', ', $methods)
        ) . sprintf(
                "\n    private \$_methodParams = %s;\n",
                var_export($params, true)
        ) . sprintf(
                "\n    private \$_voidMethods = %s;\n",
                var_export($voidMethods, true)
        );
    }
806790
public function loadMetadataForClass(\ReflectionClass $class)
    {
        $classMetadata = new ClassMetadata($class->getName());

        foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) {
            if (false === strpos($reflectionMethod->getName(), 'Action')) {
                continue;
            }

            if ($reflectionMethod->isAbstract()) {
                continue;
            }

            $methodMetadata = new ActionMetadata($class->getName(), $reflectionMethod->getName());

            $annotations = $this->reader->getMethodAnnotations($reflectionMethod);

            foreach ($annotations as $annotation) {
                if ($annotation instanceof \BackBee\Rest\Controller\Annotations\QueryParam) {
                    $data = array(
                        'name' => $annotation->name,
                        'key' => $annotation->key ? $annotation->key : $annotation->name,
                        'default' => $annotation->default,
                        'description' => $annotation->description,
                        'requirements' => $annotation->requirements,
                    );

                    $methodMetadata->queryParams[] = $data;
                } elseif ($annotation instanceof \BackBee\Rest\Controller\Annotations\RequestParam) {
                    $data = array(
                        'name' => $annotation->name,
                        'key' => $annotation->key ? $annotation->key : $annotation->name,
                        'default' => $annotation->default,
                        'description' => $annotation->description,
                        'requirements' => $annotation->requirements,
                    );

                    $methodMetadata->requestParams[] = $data;
                } elseif ($annotation instanceof \BackBee\Rest\Controller\Annotations\Pagination) {
                    $methodMetadata->default_start = $annotation->default_start;
                    $methodMetadata->default_count = $annotation->default_count;
                    $methodMetadata->max_count = $annotation->max_count;
                    $methodMetadata->min_count = $annotation->min_count;
                } elseif ($annotation instanceof \BackBee\Rest\Controller\Annotations\ParamConverter) {
                    $methodMetadata->param_converter_bag[] = $annotation;
                } elseif ($annotation instanceof \BackBee\Rest\Controller\Annotations\Security) {
                    $methodMetadata->security[] = $annotation;
                }
            }

            $classMetadata->addMethodMetadata($methodMetadata);
        }

        return $classMetadata;
    }
224804
public function loadMetadataForClass(\ReflectionClass $class)
    {
        foreach ($this->drivers as $driver) {
            if (null !== $metadata = $driver->loadMetadataForClass($class)) {
                return $metadata;
            }
        }
    }
414472
public function build ($class)
    {
        $reflection = new \ReflectionClass($class);
        $parameters = [];

        if (!is_null($reflection->getConstructor())) {
            $parameters = $this->getParameters($reflection->getConstructor());
        }

        return new $class(...$parameters);
    }
448833
public function loadMetadataForClass(\ReflectionClass $class)
    {
        $classMetadata = new ClassMetadata($class->name);
        $classMetadata->fileResources[] = $class->getFileName();

        foreach ($this->reader->getClassAnnotations($class) as $annotation) {
            if ($annotation instanceof NamespaceNode) {
                $classMetadata->addGraphNamespace($annotation);
            }

            if ($annotation instanceof GraphNode) {
                $classMetadata->addGraphMetadata($annotation, new MetadataValue($annotation->value));
            }
        }

        foreach ($class->getProperties() as $property) {
            foreach ($this->reader->getPropertyAnnotations($property) as $annotation) {
                if ($annotation instanceof GraphNode) {
                    $classMetadata->addGraphMetadata($annotation, new PropertyMetadata($class->name, $property->name));
                }
            }
        }

        foreach ($class->getMethods() as $method) {
            foreach ($this->reader->getMethodAnnotations($method) as $annotation) {
                if ($annotation instanceof GraphNode) {
                    $classMetadata->addGraphMetadata($annotation, new MethodMetadata($class->name, $method->name));
                }
            }
        }

        return $classMetadata;
    }
113412
public function createInstance(string $class)
    {
        $reflection = new \ReflectionClass($class);

        // If the constructor has no parameters, there is no need to resolve them
        $constructor = $reflection->getConstructor();
        if (is_null($constructor)) {
            $this->instances[$class] = new $class;

            return new $class;
        }

        // Resolve the dependencies recursively
        $dependencies = $constructor->getParameters();
        $instances = $this->resolveDependencies($dependencies);

        $o = $reflection->newInstanceArgs($instances);
        $this->instances[$class] = $o;

        return $o;
    }
1178657
public function make($class)
    {
        $controller = $this->container->make($class);
        $controller->setServer($this->makeServer());
        $controller->setView($this->makeView());
        $controller->setSession($this->makeSession());
        $controller->setUrlGenerator($this->makeUrlGenerator());

        return $controller;
    }
254400
public function getPostConstruct(\ReflectionClass $class)
    {
        $methods = $class->getMethods();
        foreach ($methods as $method) {
            /* @var $annotation PostConstruct|null */
            $annotation = $this->reader->getMethodAnnotation($method, PostConstruct::class);
            if ($annotation instanceof PostConstruct) {
                return $method;
            }
        }
    }
1097161
private function instantiate($class, array $parameters = [])
    {
        if (is_callable($class)) {
            return $class($this, $parameters);
        }
        $reflector = new \ReflectionClass($class);

        if (!$reflector->isInstantiable()) {
            //Try to give a descriptive exception message
            if ($reflector->isAbstract()) {
                throw new \InvalidArgumentException("Class {$class} is abstract and can not be instantiated.");
            }
            if ($reflector->isInterface()) {
                throw new \InvalidArgumentException("{$class} is an interface and can not be instantiated.");
            }
            throw new \InvalidArgumentException("Class {$class} can not be instantiated.");
        }

        $constructor = $reflector->getConstructor();

        if ($constructor === null || $constructor->getNumberOfParameters() === 0) {
            //Since the class has no constructor, it can not be instantiated with ReflectionClass

            //Also, if the class has no constructor arguments, it is cheaper to instantiate it directly
            //Although this has the downside of disallowing variable sized argument lists if
            //no arguments are required by the constructor signature.
            return new $class;
        }

        $constructorArgs = $constructor->getParameters();
        $arguments       = $this->resolveDependencies($constructorArgs, $parameters);

        if (!empty($parameters)) {
            //We need to sort the arguments because ReflectionClass passes them by order, not by index
            ksort($arguments);
        }

        return $reflector->newInstanceArgs($arguments);
    }
490622
public function executeClass($class)
    {
        $classReflection = new \ReflectionClass($class);
        $bag = new ExecutedBag();

        $classExecuted = $this->parse($classReflection->getDocComment())
            ->execute();


        $bag->set(
            'properties',
            $this->executeProperties($classReflection->getProperties())
        );

        $methods = $classReflection->getMethods();


        $bag->set('methods',
            $this->executeMethods($methods)
        );


        foreach ($classExecuted as $item => $value) {
            $bag->set($item, $value);
        }

        return $bag;
    }
112392
private function collectCacheMethods(ReflectionClass $class)
    {
        $methods = [];
        foreach ($class->getMethods() as $method) {
            $annotations = $this->collectMethodCacheAnnotations($method);
            if ($annotations->count()) {
                $methods[$method->getName()] = $annotations;
            }
        }

        return $methods;
    }
658219
public function parseEntity($class)
    {
        $reflectionClass = new ReflectionClass($class);

        // scan class annotations
        $classAnnotations = $this->reader->getClassAnnotations($reflectionClass);

        // init class metadata
        $entityMetadata = new EntityDefinition([
            'class' => $class,
            'morphClass' => $this->generateMorphClass($class),
            'table' => new TableDefinition([
                'name' => $this->generateTableName($class),
                'columns' => [],
            ]),
            'versionTable' => false,
        
            'softDeletes' => false,
            'timestamps' => false,
            
            'touches' => [],
            'with' => [],

            'columns' => [],
            'attributes' => [],
            'embeddeds' => [],
            'relations' => [],
        ]);

        // find entity parameters and plugins
        foreach ($classAnnotations as $annotation) {
            // entity parameters
            if ($annotation instanceof \ProAI\Datamapper\Annotations\Entity) {
                if (! empty($annotation->morphClass)) {
                    $entityMetadata['morphClass'] = $annotation->morphClass;
                }
                if (! empty($annotation->touches)) {
                    $entityMetadata['touches'] = $annotation->touches;
                }
                if (! empty($annotation->with)) {
                    $entityMetadata['with'] = $annotation->with;
                }
            }

            // softdeletes
            if ($annotation instanceof \ProAI\Datamapper\Annotations\SoftDeletes) {
                $entityMetadata['softDeletes'] = true;
            }

            // table name
            if ($annotation instanceof \ProAI\Datamapper\Annotations\Table) {
                $entityMetadata['table']['name'] = $annotation->name;
            }

            // timestamps
            if ($annotation instanceof \ProAI\Datamapper\Annotations\Timestamps) {
                $entityMetadata['timestamps'] = true;
            }
        }

        // find versionable annotation (2nd loop, because table name is required)
        foreach ($classAnnotations as $annotation) {
            if ($annotation instanceof \ProAI\Datamapper\Annotations\Versionable) {
                $entityMetadata['versionTable'] = new TableDefinition([
                    'name' => $entityMetadata['table']['name'] . '_version',
                    'columns' => [],
                ]);
            }
        }

        // find columns and embedded classes
        foreach ($reflectionClass->getProperties() as $reflectionProperty) {
            $name = $this->getSanitizedName($reflectionProperty->getName(), $entityMetadata['class']);
            $propertyAnnotations = $this->reader->getPropertyAnnotations($reflectionProperty);

            foreach ($propertyAnnotations as $annotation) {
                // column
                if ($annotation instanceof \ProAI\Datamapper\Annotations\Column) {
                    $this->setAdditionalColumnProperties($name, $annotation, $propertyAnnotations);

                    $this->parseColumn($name, $annotation, $entityMetadata, false, true);
                }

                // embedded class
                if ($annotation instanceof \ProAI\Datamapper\Annotations\Embedded) {
                    $this->parseEmbeddedClass($name, $annotation, $entityMetadata, true);
                }
            }
        }

        // check primary key
        $this->validator->validatePrimaryKey($entityMetadata);

        // find relationships (2nd loop, because primary key column is required for foreign keys)
        foreach ($reflectionClass->getProperties() as $reflectionProperty) {
            $name = $this->getSanitizedName($reflectionProperty->getName(), $entityMetadata['class']);
            $propertyAnnotations = $this->reader->getPropertyAnnotations($reflectionProperty);

            foreach ($propertyAnnotations as $annotation) {
                // column
                if ($annotation instanceof \ProAI\Datamapper\Annotations\Column) {
                    $this->setAdditionalColumnProperties($name, $annotation, $propertyAnnotations);

                    $entityMetadata['attributes'][] = $this->parseColumn($name, $annotation, $entityMetadata);
                }

                // embedded class
                if ($annotation instanceof \ProAI\Datamapper\Annotations\Embedded) {
                    $entityMetadata['embeddeds'][] = $this->parseEmbeddedClass($name, $annotation, $entityMetadata);
                }

                // relation
                if ($annotation instanceof \ProAI\Datamapper\Annotations\Relation) {
                    $entityMetadata['relations'][] = $this->parseRelation($name, $annotation, $entityMetadata);
                }
            }
        }

        // check timestamps extension
        if (! empty($entityMetadata['timestamps'])) {
            $this->validator->validateTimestamps($entityMetadata);
        }

        // check softDeletes extension
        if (! empty($entityMetadata['softDeletes'])) {
            $this->validator->validateSoftDeletes($entityMetadata);
        }

        // check version extension
        if (! empty($entityMetadata['versionTable'])) {
            $this->validator->validateVersionTable($entityMetadata);
        }

        return $entityMetadata;
    }
181369
protected function getApi($class)
    {
        $class = "\\" . __NAMESPACE__ . "\\Api\\" . $class;

        if ( ! class_exists($class)) {
            throw new InCommonException(sprintf('%s API handler does not exist.', $class));
        }

        if ( ! array_key_exists($class, $this->apis)) {
            $this->apis[$class] = new $class($this->client);
        }

        return $this->apis[$class];
    }
1090945
private function create_with_args( $class, array $args ) {

		switch ( count( $args ) ) {
			case 0:
				return new $class();
			case 1:
				return new $class( reset( $args ) );
			case 2:
				return new $class( reset( $args ), end( $args ) );
		}

		return ( new \ReflectionClass( $class ) )->newInstanceArgs( $args );
	}