Get methods from ReflectionClass

@param array<string,array|string|integer> $context current compile context
@param \ReflectionClass $class instance of the ReflectionClass

@return array
509027
public static function getClassMethods($context, $class) {
        $methods = array();

        foreach ($class->getMethods() as $method) {
            $meta = static::getMeta($method);
            $methods[$meta['name']] = static::scanDependency($context, preg_replace('/public static function (.+)\\(/', "function {$context['funcprefix']}\$1(", $meta['code']), $meta['code']);
        }

        return $methods;
    }
435486
protected function getDependencies($class): array
    {
        if (isset($this->reflections[$class])) {
            return [$this->reflections[$class], $this->dependencies[$class]];
        }

        $dependencies = [];

        try {
            $reflection = new ReflectionClass($class);
        } catch (\ReflectionException $e) {
            throw new InvalidConfigException('Failed to instantiate "' . $class . '".', 0, $e);
        }

        $constructor = $reflection->getConstructor();
        if ($constructor !== null) {
            foreach ($constructor->getParameters() as $param) {
                if ($param->isDefaultValueAvailable()) {
                    $dependencies[] = $param->getDefaultValue();
                } else {
                    $c = $param->getClass();
                    /// TODO think of disallowing `Reference(null)`
                    $dependencies[] = new Reference($c === null ? null : $c->getName());
                }
            }
        }

        $this->reflections[$class] = $reflection;
        $this->dependencies[$class] = $dependencies;

        return [$reflection, $dependencies];
    }
1207889
private static function getProps($class)
    {
        if ($class == NULL) {
            return array();
        }
        $class = new \ReflectionClass($class);
        $properties = array_filter($class->getProperties(), function ($prop) use($class)
        {
            return $prop->getDeclaringClass()->name == $class->name;
        });
        return $properties;
    }
623586
public function getParameters(string $class, string $method = null){
        if(!class_exists($class)){
            throw new \InvalidArgumentException();
        }

        if($method !== null && !method_exists($class, $method)){
            throw new \InvalidArgumentException();
        }

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

        $method = $method === null ? "__construct" : $method;

        if(!array_key_exists($method, $this->params[$class])){
            if($method === "__construct" && !method_exists($class, $method)){
                $reflection = null;
            }else{
                $reflection = $this->getClass($class)->getMethod($method);
            }

            $this->params[$class][$method]  = $reflection === null
                ? []
                : $reflection->getParameters()
            ;
        }

        return $this->params[$class][$method];
    }
780566
protected function getMethodAnnotations(ReflectionClass $class, SimpleAnnotationReader $reader)
	{
		$annotations = [];

		foreach ($class->getMethods() as $method)
		{
			$results = $reader->getMethodAnnotations($method);

			if (count($results) > 0)
				$annotations[$method->name] = $results;
		}

		return $annotations;
	}
287750
public function parseClass(\ReflectionClass $class)
    {
        if (false === $filename = $class->getFilename()) {
            return array();
        }

        $content = $this->getFileContent($filename, $class->getStartLine());
        $namespace = str_replace('\\', '\\\\', $class->getNamespaceName());
        $content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content);
        $this->tokens = token_get_all('<?php ' . $content);
        $this->numTokens = count($this->tokens);
        $this->pointer = 0;

        $statements = $this->parseUseStatements($class->getNamespaceName());

        return $statements;
    }
684480
private function getClassMethods(): array
    {
        if (null !== $this->reflectionMethods) {
            return $this->reflectionMethods;
        }

        $this->reflectionMethods = [];

        $class = $this->reflectionClass;

        do {
            $this->reflectionMethods = \array_merge(
                $this->reflectionMethods,
                $class->getMethods()
            );
        } while ($class = $class->getParentClass());

        return $this->reflectionMethods;
    }
1023282
public static function getClassMethodArgs($class, string $method)
    {
        static $cache = null;

        if (null !== $cache && isset($cache[$class][$method])) {
            return $cache[$class][$method];
        }

        $reflector = new \ReflectionMethod($class, $method);
        $params = $reflector->getParameters();
        if (empty($params)) {
            $cache[$class][$method] = [];
            return [];
        }
        $args = [];
        foreach ($params as $param) {
            $args[$param->name] = [
                'optional' => $param->isOptional(),
                'variadic' => $param->isVariadic(),
            ];
            if ($param->isOptional() && $param->isDefaultValueAvailable()) {
                $args[$param->name]['default'] = $param->getDefaultValue();
            }
            if ($param->hasType()) {
                $args[$param->name]['type'] = (string)$param->getType();
            }
        }
        $cache[$class][$method] = $args;
        return $args;
    }
825333
public static function getAbstractProxiedMethods(ReflectionClass $class, ?array $excluded = null) : array
    {
        return self::doFilter($class, $excluded ?? self::$defaultExcluded, true);
    }
434217
protected static function fromClassMethodString($uses)
    {
        [$class, $method] = Str::parseCallback($uses);

        if (! method_exists($class, $method) && is_callable($class, $method)) {
            return [];
        }

        return (new ReflectionMethod($class, $method))->getParameters();
    }
1202088
protected function getMethods(PackageClass $package_class)
    {
        try {
            $class = new \ReflectionClass($package_class->getName());
        } catch (\ReflectionException $e) {
            return [];
        }
        $methods = $class->getMethods();

        foreach ($methods as $key => $method) {
            if ($method->name === '__construct') {
                // The interface should not contain the constructor
                unset($methods[$key]);
                continue;
            }
            $methods[$key] = new ReflectionMethod($method);
        }

        return $methods;
    }
1141870
public static function get($class)
    {
        $key = strtolower($class);

        if (isset(static::$instances[$key])) {
            return static::$instances[$key];
        }

        static::override($class);

        if (!class_exists($class)) {
            throw new ReflectionException("Class $class does not exist");
        }

        $instance = static::getInstance($class);
        static::register($class, $instance);
        return $instance;
    }
169618
private function getAnalyzers(\ReflectionClass $reflectionClass)
    {
        $analyzers = [];

        foreach ($this->getDocumentPropertiesReflection($reflectionClass) as $name => $property) {
            $directory = $this->guessDirName($property->getDeclaringClass());

            $type = $this->getPropertyAnnotationData($property);
            $type = $type !== null ? $type : $this->getEmbeddedAnnotationData($property);

            if ($type instanceof Embedded) {
                $analyzers = array_merge(
                    $analyzers,
                    $this->getAnalyzers(new \ReflectionClass($this->finder->getNamespace($type->class, $directory)))
                );
            }

            if ($type instanceof Property) {
                if (isset($type->options['analyzer'])) {
                    $analyzers[] = $type->options['analyzer'];
                }
                if (isset($type->options['search_analyzer'])) {
                    $analyzers[] = $type->options['search_analyzer'];
                }

                if (isset($type->options['fields'])) {
                    foreach ($type->options['fields'] as $field) {
                        if (isset($field['analyzer'])) {
                            $analyzers[] = $field['analyzer'];
                        }
                        if (isset($field['search_analyzer'])) {
                            $analyzers[] = $field['search_analyzer'];
                        }
                    }
                }
            }
        }
        return array_unique($analyzers);
    }
888280
private function getFromAnnotation(ReflectionClass $class): array
    {
        $sortings = Utils::getRecursiveClassAnnotations($this->getAnnotationReader(), $class, Sorting::class);

        $result = [];
        foreach ($sortings as $classWithAnnotation => $sorting) {
            foreach ($sorting->classes as $className) {
                $this->throwIfInvalidAnnotation($classWithAnnotation, 'Sorting', SortingInterface::class, $className);

                $name = lcfirst(preg_replace('~Type$~', '', Utils::getTypeName($className)));
                $result[$name] = new $className();
            }
        }

        return $result;
    }
970106
private static function getInstance($class)
    {
        //get the backtrace
        $trace = debug_backtrace();
        $args = array();
        
        //the 2nd line is the caller method
        if (isset($trace[1]['args']) && count($trace[1]['args']) > 1) {
            //get the args
            $args = $trace[1]['args'];
            //shift out the class name
            array_shift($args);
            //then maybe it's the 3rd line?
        } else if (isset($trace[2]['args']) && count($trace[2]['args']) > 0) {
            //get the args
            $args = $trace[2]['args'];
        }
        
        //if there's no args or there's no construct to accept the args
        if (count($args) === 0 || !method_exists($class, '__construct')) {
            //just return the instantiation
            return new $class;
        }
        
        //at this point, we need to vitually call the class
        $reflect = new \ReflectionClass($class);
        
        try { //to return the instantiation
            return $reflect->newInstanceArgs($args);
        } catch (\ReflectionException $e) {
            //trigger error
            Exception::i()
                ->setMessage(self::ERROR_REFLECTION)
                ->addVariable($class)
                ->addVariable('new')
                ->trigger();
        }
    }
1074658
private function getClassMethods($class)
    {
        $result = '';

        foreach($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method)
        {
            $args = [];
            $comments = [];
            foreach($method->getParameters() as $param)
            {
                // 方法参数定义
                $args[] = $this->getMethodParamDefine($param);
                $comments[] = '@var ' . ($param->getType() ?? 'mixed') . ' $' . $param->name;
            }
            $return = $method->getReturnType();
            if(null !== $return)
            {
                $comments[] = '@return ' . $return;
            }
            $args = implode(', ', $args);
            if([] === $comments)
            {
                $comment = '';
            }
            else
            {
                $comment = implode(PHP_EOL . '     * ', $comments);
                $comment = <<<COMMENT

    /**
     * {$comment}
     */
COMMENT;
            }
            if($method->isStatic())
            {
                $static = ' static';
            }
            else
            {
                $static = '';
            }
            $result .= <<<CODE
{$comment}
    public{$static} function {$method->name}({$args}){}

CODE;
        }

        return $result;
    }
652343
private function getAccessorMethod(string $class, string $property): ?array
    {
        $ucProperty = ucfirst($property);

        foreach ($this->accessorPrefixes as $prefix) {
            try {
                $reflectionMethod = new \ReflectionMethod($class, $prefix.$ucProperty);
                if ($reflectionMethod->isStatic()) {
                    continue;
                }

                if (0 === $reflectionMethod->getNumberOfRequiredParameters()) {
                    return [$reflectionMethod, $prefix];
                }
            } catch (\ReflectionException $e) {
                // Return null if the property doesn't exist
            }
        }

        return null;
    }