protected function parseClassDefinition(array &$tokens, ClassName $namespaceName = null, array $usedClasses)
    {
        $this->typeCheck->parseClassDefinition(func_get_args());

        $className = $this->parseClassName($tokens);
        if (null !== $namespaceName) {
            $className = $namespaceName->join($className);
        }

        $methods = array();
        $properties = array();
        $inClassBody = false;
        $accessModifier = null;
        $isStatic = null;
        $isAbstract = null;
        $source = null;
        while ($token = next($tokens)) {
            $token = $this->normalizeToken($token);

            if ($inClassBody) {
                if ('}' === $token[0]) {
                    break;
                }

                if (
                    T_PUBLIC === $token[0] ||
                    T_PROTECTED === $token[0] ||
                    T_PRIVATE === $token[0] ||
                    T_STATIC === $token[0] ||
                    T_ABSTRACT === $token[0] ||
                    T_FINAL === $token[0]
                ) {
                    $lineNumber = $token[2];
                    $token = $this->parseClassMemberModifiers(
                        $token,
                        $tokens,
                        $accessModifier,
                        $isStatic,
                        $isAbstract,
                        $source
                    );

                    if (T_FUNCTION === $token[0]) {
                        $methods[] = $this->parseMethod(
                            $className,
                            $token,
                            $tokens,
                            $accessModifier,
                            $isStatic,
                            $isAbstract,
                            $source,
                            $lineNumber
                        );
                    } elseif (T_VARIABLE === $token[0]) {
                        $properties[] = $this->parseProperty(
                            $className,
                            $token,
                            $tokens,
                            $accessModifier,
                            $isStatic,
                            $source,
                            $lineNumber
                        );
                    }

                    $accessModifier = null;
                    $isStatic = null;
                    $isAbstract = null;
                    $source = null;
                }
            } elseif ('{' === $token[0]) {
                $inClassBody = true;
            }
        }

        return new ClassDefinition(
            $className,
            $usedClasses,
            $methods,
            $properties
        );
    }
protected function parseClassDefinition(array &$tokens, ClassName $namespaceName = null, array $usedClasses)
    {
        $this->typeCheck->parseClassDefinition(func_get_args());

        $className = $this->parseClassName($tokens);
        if (null !== $namespaceName) {
            $className = $namespaceName->join($className);
        }

        $methods = array();
        $properties = array();
        $inClassBody = false;
        $accessModifier = null;
        $isStatic = null;
        $isAbstract = null;
        $source = null;
        while ($token = next($tokens)) {
            $token = $this->normalizeToken($token);

            if ($inClassBody) {
                if ('}' === $token[0]) {
                    break;
                }

                if (
                    T_PUBLIC === $token[0] ||
                    T_PROTECTED === $token[0] ||
                    T_PRIVATE === $token[0] ||
                    T_STATIC === $token[0] ||
                    T_ABSTRACT === $token[0] ||
                    T_FINAL === $token[0]
                ) {
                    $lineNumber = $token[2];
                    $token = $this->parseClassMemberModifiers(
                        $token,
                        $tokens,
                        $accessModifier,
                        $isStatic,
                        $isAbstract,
                        $source
                    );

                    if (T_FUNCTION === $token[0]) {
                        $methods[] = $this->parseMethod(
                            $className,
                            $token,
                            $tokens,
                            $accessModifier,
                            $isStatic,
                            $isAbstract,
                            $source,
                            $lineNumber
                        );
                    } elseif (T_VARIABLE === $token[0]) {
                        $properties[] = $this->parseProperty(
                            $className,
                            $token,
                            $tokens,
                            $accessModifier,
                            $isStatic,
                            $source,
                            $lineNumber
                        );
                    }

                    $accessModifier = null;
                    $isStatic = null;
                    $isAbstract = null;
                    $source = null;
                }
            } elseif ('{' === $token[0]) {
                $inClassBody = true;
            }
        }

        return new ClassDefinition(
            $className,
            $usedClasses,
            $methods,
            $properties
        );
    }
@param array<string|array>     &$tokens
@param ClassName|null          $namespaceName
@param array<array<ClassName>> $usedClasses

@return ClassDefinition