the middle of the idiots
This commit is contained in:
		
							
								
								
									
										5
									
								
								qwen/php/vendor/nikic/fast-route/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								qwen/php/vendor/nikic/fast-route/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
/vendor/
 | 
			
		||||
.idea/
 | 
			
		||||
 | 
			
		||||
# ignore lock file since we have no extra dependencies
 | 
			
		||||
composer.lock
 | 
			
		||||
							
								
								
									
										1
									
								
								qwen/php/vendor/nikic/fast-route/.hhconfig
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								qwen/php/vendor/nikic/fast-route/.hhconfig
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
assume_php=false
 | 
			
		||||
							
								
								
									
										20
									
								
								qwen/php/vendor/nikic/fast-route/.travis.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								qwen/php/vendor/nikic/fast-route/.travis.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
sudo: false
 | 
			
		||||
language: php
 | 
			
		||||
 | 
			
		||||
php:
 | 
			
		||||
  - 5.4
 | 
			
		||||
  - 5.5
 | 
			
		||||
  - 5.6
 | 
			
		||||
  - 7.0
 | 
			
		||||
  - 7.1
 | 
			
		||||
  - 7.2
 | 
			
		||||
  - hhvm
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
  - ./vendor/bin/phpunit
 | 
			
		||||
 | 
			
		||||
before_install:
 | 
			
		||||
  - travis_retry composer self-update
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  - composer install
 | 
			
		||||
							
								
								
									
										126
									
								
								qwen/php/vendor/nikic/fast-route/FastRoute.hhi
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								qwen/php/vendor/nikic/fast-route/FastRoute.hhi
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,126 @@
 | 
			
		||||
<?hh // decl
 | 
			
		||||
 | 
			
		||||
namespace FastRoute {
 | 
			
		||||
    class BadRouteException extends \LogicException {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    interface RouteParser {
 | 
			
		||||
        public function parse(string $route): array<array>;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class RouteCollector {
 | 
			
		||||
        public function __construct(RouteParser $routeParser, DataGenerator $dataGenerator);
 | 
			
		||||
        public function addRoute(mixed $httpMethod, string $route, mixed $handler): void;
 | 
			
		||||
        public function getData(): array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class Route {
 | 
			
		||||
        public function __construct(string $httpMethod, mixed $handler, string $regex, array $variables);
 | 
			
		||||
        public function matches(string $str): bool;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    interface DataGenerator {
 | 
			
		||||
        public function addRoute(string $httpMethod, array $routeData, mixed $handler);
 | 
			
		||||
        public function getData(): array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    interface Dispatcher {
 | 
			
		||||
        const int NOT_FOUND = 0;
 | 
			
		||||
        const int FOUND = 1;
 | 
			
		||||
        const int METHOD_NOT_ALLOWED = 2;
 | 
			
		||||
        public function dispatch(string $httpMethod, string $uri): array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function simpleDispatcher(
 | 
			
		||||
        (function(RouteCollector): void) $routeDefinitionCallback,
 | 
			
		||||
        shape(
 | 
			
		||||
          ?'routeParser' => classname<RouteParser>,
 | 
			
		||||
          ?'dataGenerator' => classname<DataGenerator>,
 | 
			
		||||
          ?'dispatcher' => classname<Dispatcher>,
 | 
			
		||||
          ?'routeCollector' => classname<RouteCollector>,
 | 
			
		||||
        ) $options = shape()): Dispatcher;
 | 
			
		||||
 | 
			
		||||
    function cachedDispatcher(
 | 
			
		||||
        (function(RouteCollector): void) $routeDefinitionCallback,
 | 
			
		||||
        shape(
 | 
			
		||||
          ?'routeParser' => classname<RouteParser>,
 | 
			
		||||
          ?'dataGenerator' => classname<DataGenerator>,
 | 
			
		||||
          ?'dispatcher' => classname<Dispatcher>,
 | 
			
		||||
          ?'routeCollector' => classname<RouteCollector>,
 | 
			
		||||
          ?'cacheDisabled' => bool,
 | 
			
		||||
          ?'cacheFile' => string,
 | 
			
		||||
        ) $options = shape()): Dispatcher;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\DataGenerator {
 | 
			
		||||
    abstract class RegexBasedAbstract implements \FastRoute\DataGenerator {
 | 
			
		||||
        protected abstract function getApproxChunkSize();
 | 
			
		||||
        protected abstract function processChunk($regexToRoutesMap);
 | 
			
		||||
 | 
			
		||||
        public function addRoute(string $httpMethod, array $routeData, mixed $handler): void;
 | 
			
		||||
        public function getData(): array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class CharCountBased extends RegexBasedAbstract {
 | 
			
		||||
        protected function getApproxChunkSize(): int;
 | 
			
		||||
        protected function processChunk(array<string, string> $regexToRoutesMap): array<string, mixed>;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class GroupCountBased extends RegexBasedAbstract {
 | 
			
		||||
        protected function getApproxChunkSize(): int;
 | 
			
		||||
        protected function processChunk(array<string, string> $regexToRoutesMap): array<string, mixed>;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class GroupPosBased extends RegexBasedAbstract {
 | 
			
		||||
        protected function getApproxChunkSize(): int;
 | 
			
		||||
        protected function processChunk(array<string, string> $regexToRoutesMap): array<string, mixed>;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class MarkBased extends RegexBasedAbstract {
 | 
			
		||||
        protected function getApproxChunkSize(): int;
 | 
			
		||||
        protected function processChunk(array<string, string> $regexToRoutesMap): array<string, mixed>;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\Dispatcher {
 | 
			
		||||
    abstract class RegexBasedAbstract implements \FastRoute\Dispatcher {
 | 
			
		||||
        protected abstract function dispatchVariableRoute(array<array> $routeData, string $uri): array;
 | 
			
		||||
 | 
			
		||||
        public function dispatch(string $httpMethod, string $uri): array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class GroupPosBased extends RegexBasedAbstract {
 | 
			
		||||
        public function __construct(array $data);
 | 
			
		||||
        protected function dispatchVariableRoute(array<array> $routeData, string $uri): array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class GroupCountBased extends RegexBasedAbstract {
 | 
			
		||||
        public function __construct(array $data);
 | 
			
		||||
        protected function dispatchVariableRoute(array<array> $routeData, string $uri): array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class CharCountBased extends RegexBasedAbstract {
 | 
			
		||||
        public function __construct(array $data);
 | 
			
		||||
        protected function dispatchVariableRoute(array<array> $routeData, string $uri): array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class MarkBased extends RegexBasedAbstract {
 | 
			
		||||
        public function __construct(array $data);
 | 
			
		||||
        protected function dispatchVariableRoute(array<array> $routeData, string $uri): array;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\RouteParser {
 | 
			
		||||
    class Std implements \FastRoute\RouteParser {
 | 
			
		||||
        const string VARIABLE_REGEX = <<<'REGEX'
 | 
			
		||||
\{
 | 
			
		||||
    \s* ([a-zA-Z][a-zA-Z0-9_]*) \s*
 | 
			
		||||
    (?:
 | 
			
		||||
        : \s* ([^{}]*(?:\{(?-1)\}[^{}]*)*)
 | 
			
		||||
    )?
 | 
			
		||||
\}
 | 
			
		||||
REGEX;
 | 
			
		||||
        const string DEFAULT_DISPATCH_REGEX = '[^/]+';
 | 
			
		||||
        public function parse(string $route): array<array>;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								qwen/php/vendor/nikic/fast-route/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								qwen/php/vendor/nikic/fast-route/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
Copyright (c) 2013 by Nikita Popov.
 | 
			
		||||
 | 
			
		||||
Some rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are
 | 
			
		||||
met:
 | 
			
		||||
 | 
			
		||||
    * Redistributions of source code must retain the above copyright
 | 
			
		||||
      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
    * Redistributions in binary form must reproduce the above
 | 
			
		||||
      copyright notice, this list of conditions and the following
 | 
			
		||||
      disclaimer in the documentation and/or other materials provided
 | 
			
		||||
      with the distribution.
 | 
			
		||||
 | 
			
		||||
    * The names of the contributors may not be used to endorse or
 | 
			
		||||
      promote products derived from this software without specific
 | 
			
		||||
      prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
							
								
								
									
										313
									
								
								qwen/php/vendor/nikic/fast-route/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								qwen/php/vendor/nikic/fast-route/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,313 @@
 | 
			
		||||
FastRoute - Fast request router for PHP
 | 
			
		||||
=======================================
 | 
			
		||||
 | 
			
		||||
This library provides a fast implementation of a regular expression based router. [Blog post explaining how the
 | 
			
		||||
implementation works and why it is fast.][blog_post]
 | 
			
		||||
 | 
			
		||||
Install
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
To install with composer:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
composer require nikic/fast-route
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Requires PHP 5.4 or newer.
 | 
			
		||||
 | 
			
		||||
Usage
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
Here's a basic usage example:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
require '/path/to/vendor/autoload.php';
 | 
			
		||||
 | 
			
		||||
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
 | 
			
		||||
    $r->addRoute('GET', '/users', 'get_all_users_handler');
 | 
			
		||||
    // {id} must be a number (\d+)
 | 
			
		||||
    $r->addRoute('GET', '/user/{id:\d+}', 'get_user_handler');
 | 
			
		||||
    // The /{title} suffix is optional
 | 
			
		||||
    $r->addRoute('GET', '/articles/{id:\d+}[/{title}]', 'get_article_handler');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Fetch method and URI from somewhere
 | 
			
		||||
$httpMethod = $_SERVER['REQUEST_METHOD'];
 | 
			
		||||
$uri = $_SERVER['REQUEST_URI'];
 | 
			
		||||
 | 
			
		||||
// Strip query string (?foo=bar) and decode URI
 | 
			
		||||
if (false !== $pos = strpos($uri, '?')) {
 | 
			
		||||
    $uri = substr($uri, 0, $pos);
 | 
			
		||||
}
 | 
			
		||||
$uri = rawurldecode($uri);
 | 
			
		||||
 | 
			
		||||
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
 | 
			
		||||
switch ($routeInfo[0]) {
 | 
			
		||||
    case FastRoute\Dispatcher::NOT_FOUND:
 | 
			
		||||
        // ... 404 Not Found
 | 
			
		||||
        break;
 | 
			
		||||
    case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
 | 
			
		||||
        $allowedMethods = $routeInfo[1];
 | 
			
		||||
        // ... 405 Method Not Allowed
 | 
			
		||||
        break;
 | 
			
		||||
    case FastRoute\Dispatcher::FOUND:
 | 
			
		||||
        $handler = $routeInfo[1];
 | 
			
		||||
        $vars = $routeInfo[2];
 | 
			
		||||
        // ... call $handler with $vars
 | 
			
		||||
        break;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Defining routes
 | 
			
		||||
 | 
			
		||||
The routes are defined by calling the `FastRoute\simpleDispatcher()` function, which accepts
 | 
			
		||||
a callable taking a `FastRoute\RouteCollector` instance. The routes are added by calling
 | 
			
		||||
`addRoute()` on the collector instance:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
$r->addRoute($method, $routePattern, $handler);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `$method` is an uppercase HTTP method string for which a certain route should match. It
 | 
			
		||||
is possible to specify multiple valid methods using an array:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
// These two calls
 | 
			
		||||
$r->addRoute('GET', '/test', 'handler');
 | 
			
		||||
$r->addRoute('POST', '/test', 'handler');
 | 
			
		||||
// Are equivalent to this one call
 | 
			
		||||
$r->addRoute(['GET', 'POST'], '/test', 'handler');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
By default the `$routePattern` uses a syntax where `{foo}` specifies a placeholder with name `foo`
 | 
			
		||||
and matching the regex `[^/]+`. To adjust the pattern the placeholder matches, you can specify
 | 
			
		||||
a custom pattern by writing `{bar:[0-9]+}`. Some examples:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
// Matches /user/42, but not /user/xyz
 | 
			
		||||
$r->addRoute('GET', '/user/{id:\d+}', 'handler');
 | 
			
		||||
 | 
			
		||||
// Matches /user/foobar, but not /user/foo/bar
 | 
			
		||||
$r->addRoute('GET', '/user/{name}', 'handler');
 | 
			
		||||
 | 
			
		||||
// Matches /user/foo/bar as well
 | 
			
		||||
$r->addRoute('GET', '/user/{name:.+}', 'handler');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Custom patterns for route placeholders cannot use capturing groups. For example `{lang:(en|de)}`
 | 
			
		||||
is not a valid placeholder, because `()` is a capturing group. Instead you can use either
 | 
			
		||||
`{lang:en|de}` or `{lang:(?:en|de)}`.
 | 
			
		||||
 | 
			
		||||
Furthermore parts of the route enclosed in `[...]` are considered optional, so that `/foo[bar]`
 | 
			
		||||
will match both `/foo` and `/foobar`. Optional parts are only supported in a trailing position,
 | 
			
		||||
not in the middle of a route.
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
// This route
 | 
			
		||||
$r->addRoute('GET', '/user/{id:\d+}[/{name}]', 'handler');
 | 
			
		||||
// Is equivalent to these two routes
 | 
			
		||||
$r->addRoute('GET', '/user/{id:\d+}', 'handler');
 | 
			
		||||
$r->addRoute('GET', '/user/{id:\d+}/{name}', 'handler');
 | 
			
		||||
 | 
			
		||||
// Multiple nested optional parts are possible as well
 | 
			
		||||
$r->addRoute('GET', '/user[/{id:\d+}[/{name}]]', 'handler');
 | 
			
		||||
 | 
			
		||||
// This route is NOT valid, because optional parts can only occur at the end
 | 
			
		||||
$r->addRoute('GET', '/user[/{id:\d+}]/{name}', 'handler');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `$handler` parameter does not necessarily have to be a callback, it could also be a controller
 | 
			
		||||
class name or any other kind of data you wish to associate with the route. FastRoute only tells you
 | 
			
		||||
which handler corresponds to your URI, how you interpret it is up to you.
 | 
			
		||||
 | 
			
		||||
#### Shorcut methods for common request methods
 | 
			
		||||
 | 
			
		||||
For the `GET`, `POST`, `PUT`, `PATCH`, `DELETE` and `HEAD` request methods shortcut methods are available. For example:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
$r->get('/get-route', 'get_handler');
 | 
			
		||||
$r->post('/post-route', 'post_handler');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Is equivalent to:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
$r->addRoute('GET', '/get-route', 'get_handler');
 | 
			
		||||
$r->addRoute('POST', '/post-route', 'post_handler');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Route Groups
 | 
			
		||||
 | 
			
		||||
Additionally, you can specify routes inside of a group. All routes defined inside a group will have a common prefix.
 | 
			
		||||
 | 
			
		||||
For example, defining your routes as:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
$r->addGroup('/admin', function (RouteCollector $r) {
 | 
			
		||||
    $r->addRoute('GET', '/do-something', 'handler');
 | 
			
		||||
    $r->addRoute('GET', '/do-another-thing', 'handler');
 | 
			
		||||
    $r->addRoute('GET', '/do-something-else', 'handler');
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Will have the same result as:
 | 
			
		||||
 | 
			
		||||
 ```php
 | 
			
		||||
$r->addRoute('GET', '/admin/do-something', 'handler');
 | 
			
		||||
$r->addRoute('GET', '/admin/do-another-thing', 'handler');
 | 
			
		||||
$r->addRoute('GET', '/admin/do-something-else', 'handler');
 | 
			
		||||
 ```
 | 
			
		||||
 | 
			
		||||
Nested groups are also supported, in which case the prefixes of all the nested groups are combined.
 | 
			
		||||
 | 
			
		||||
### Caching
 | 
			
		||||
 | 
			
		||||
The reason `simpleDispatcher` accepts a callback for defining the routes is to allow seamless
 | 
			
		||||
caching. By using `cachedDispatcher` instead of `simpleDispatcher` you can cache the generated
 | 
			
		||||
routing data and construct the dispatcher from the cached information:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
$dispatcher = FastRoute\cachedDispatcher(function(FastRoute\RouteCollector $r) {
 | 
			
		||||
    $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0');
 | 
			
		||||
    $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1');
 | 
			
		||||
    $r->addRoute('GET', '/user/{name}', 'handler2');
 | 
			
		||||
}, [
 | 
			
		||||
    'cacheFile' => __DIR__ . '/route.cache', /* required */
 | 
			
		||||
    'cacheDisabled' => IS_DEBUG_ENABLED,     /* optional, enabled by default */
 | 
			
		||||
]);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The second parameter to the function is an options array, which can be used to specify the cache
 | 
			
		||||
file location, among other things.
 | 
			
		||||
 | 
			
		||||
### Dispatching a URI
 | 
			
		||||
 | 
			
		||||
A URI is dispatched by calling the `dispatch()` method of the created dispatcher. This method
 | 
			
		||||
accepts the HTTP method and a URI. Getting those two bits of information (and normalizing them
 | 
			
		||||
appropriately) is your job - this library is not bound to the PHP web SAPIs.
 | 
			
		||||
 | 
			
		||||
The `dispatch()` method returns an array whose first element contains a status code. It is one
 | 
			
		||||
of `Dispatcher::NOT_FOUND`, `Dispatcher::METHOD_NOT_ALLOWED` and `Dispatcher::FOUND`. For the
 | 
			
		||||
method not allowed status the second array element contains a list of HTTP methods allowed for
 | 
			
		||||
the supplied URI. For example:
 | 
			
		||||
 | 
			
		||||
    [FastRoute\Dispatcher::METHOD_NOT_ALLOWED, ['GET', 'POST']]
 | 
			
		||||
 | 
			
		||||
> **NOTE:** The HTTP specification requires that a `405 Method Not Allowed` response include the
 | 
			
		||||
`Allow:` header to detail available methods for the requested resource. Applications using FastRoute
 | 
			
		||||
should use the second array element to add this header when relaying a 405 response.
 | 
			
		||||
 | 
			
		||||
For the found status the second array element is the handler that was associated with the route
 | 
			
		||||
and the third array element is a dictionary of placeholder names to their values. For example:
 | 
			
		||||
 | 
			
		||||
    /* Routing against GET /user/nikic/42 */
 | 
			
		||||
 | 
			
		||||
    [FastRoute\Dispatcher::FOUND, 'handler0', ['name' => 'nikic', 'id' => '42']]
 | 
			
		||||
 | 
			
		||||
### Overriding the route parser and dispatcher
 | 
			
		||||
 | 
			
		||||
The routing process makes use of three components: A route parser, a data generator and a
 | 
			
		||||
dispatcher. The three components adhere to the following interfaces:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute;
 | 
			
		||||
 | 
			
		||||
interface RouteParser {
 | 
			
		||||
    public function parse($route);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface DataGenerator {
 | 
			
		||||
    public function addRoute($httpMethod, $routeData, $handler);
 | 
			
		||||
    public function getData();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface Dispatcher {
 | 
			
		||||
    const NOT_FOUND = 0, FOUND = 1, METHOD_NOT_ALLOWED = 2;
 | 
			
		||||
 | 
			
		||||
    public function dispatch($httpMethod, $uri);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The route parser takes a route pattern string and converts it into an array of route infos, where
 | 
			
		||||
each route info is again an array of it's parts. The structure is best understood using an example:
 | 
			
		||||
 | 
			
		||||
    /* The route /user/{id:\d+}[/{name}] converts to the following array: */
 | 
			
		||||
    [
 | 
			
		||||
        [
 | 
			
		||||
            '/user/',
 | 
			
		||||
            ['id', '\d+'],
 | 
			
		||||
        ],
 | 
			
		||||
        [
 | 
			
		||||
            '/user/',
 | 
			
		||||
            ['id', '\d+'],
 | 
			
		||||
            '/',
 | 
			
		||||
            ['name', '[^/]+'],
 | 
			
		||||
        ],
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
This array can then be passed to the `addRoute()` method of a data generator. After all routes have
 | 
			
		||||
been added the `getData()` of the generator is invoked, which returns all the routing data required
 | 
			
		||||
by the dispatcher. The format of this data is not further specified - it is tightly coupled to
 | 
			
		||||
the corresponding dispatcher.
 | 
			
		||||
 | 
			
		||||
The dispatcher accepts the routing data via a constructor and provides a `dispatch()` method, which
 | 
			
		||||
you're already familiar with.
 | 
			
		||||
 | 
			
		||||
The route parser can be overwritten individually (to make use of some different pattern syntax),
 | 
			
		||||
however the data generator and dispatcher should always be changed as a pair, as the output from
 | 
			
		||||
the former is tightly coupled to the input of the latter. The reason the generator and the
 | 
			
		||||
dispatcher are separate is that only the latter is needed when using caching (as the output of
 | 
			
		||||
the former is what is being cached.)
 | 
			
		||||
 | 
			
		||||
When using the `simpleDispatcher` / `cachedDispatcher` functions from above the override happens
 | 
			
		||||
through the options array:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
 | 
			
		||||
    /* ... */
 | 
			
		||||
}, [
 | 
			
		||||
    'routeParser' => 'FastRoute\\RouteParser\\Std',
 | 
			
		||||
    'dataGenerator' => 'FastRoute\\DataGenerator\\GroupCountBased',
 | 
			
		||||
    'dispatcher' => 'FastRoute\\Dispatcher\\GroupCountBased',
 | 
			
		||||
]);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The above options array corresponds to the defaults. By replacing `GroupCountBased` by
 | 
			
		||||
`GroupPosBased` you could switch to a different dispatching strategy.
 | 
			
		||||
 | 
			
		||||
### A Note on HEAD Requests
 | 
			
		||||
 | 
			
		||||
The HTTP spec requires servers to [support both GET and HEAD methods][2616-511]:
 | 
			
		||||
 | 
			
		||||
> The methods GET and HEAD MUST be supported by all general-purpose servers
 | 
			
		||||
 | 
			
		||||
To avoid forcing users to manually register HEAD routes for each resource we fallback to matching an
 | 
			
		||||
available GET route for a given resource. The PHP web SAPI transparently removes the entity body
 | 
			
		||||
from HEAD responses so this behavior has no effect on the vast majority of users.
 | 
			
		||||
 | 
			
		||||
However, implementers using FastRoute outside the web SAPI environment (e.g. a custom server) MUST
 | 
			
		||||
NOT send entity bodies generated in response to HEAD requests. If you are a non-SAPI user this is
 | 
			
		||||
*your responsibility*; FastRoute has no purview to prevent you from breaking HTTP in such cases.
 | 
			
		||||
 | 
			
		||||
Finally, note that applications MAY always specify their own HEAD method route for a given
 | 
			
		||||
resource to bypass this behavior entirely.
 | 
			
		||||
 | 
			
		||||
### Credits
 | 
			
		||||
 | 
			
		||||
This library is based on a router that [Levi Morrison][levi] implemented for the Aerys server.
 | 
			
		||||
 | 
			
		||||
A large number of tests, as well as HTTP compliance considerations, were provided by [Daniel Lowrey][rdlowrey].
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[2616-511]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.1 "RFC 2616 Section 5.1.1"
 | 
			
		||||
[blog_post]: http://nikic.github.io/2014/02/18/Fast-request-routing-using-regular-expressions.html
 | 
			
		||||
[levi]: https://github.com/morrisonlevi
 | 
			
		||||
[rdlowrey]: https://github.com/rdlowrey
 | 
			
		||||
							
								
								
									
										24
									
								
								qwen/php/vendor/nikic/fast-route/composer.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								qwen/php/vendor/nikic/fast-route/composer.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "nikic/fast-route",
 | 
			
		||||
  "description": "Fast request router for PHP",
 | 
			
		||||
  "keywords": ["routing", "router"],
 | 
			
		||||
  "license": "BSD-3-Clause",
 | 
			
		||||
  "authors": [
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Nikita Popov",
 | 
			
		||||
      "email": "nikic@php.net"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "autoload": {
 | 
			
		||||
    "psr-4": {
 | 
			
		||||
      "FastRoute\\": "src/"
 | 
			
		||||
    },
 | 
			
		||||
    "files": ["src/functions.php"]
 | 
			
		||||
  },
 | 
			
		||||
  "require": {
 | 
			
		||||
    "php": ">=5.4.0"
 | 
			
		||||
  },
 | 
			
		||||
  "require-dev": {
 | 
			
		||||
    "phpunit/phpunit": "^4.8.35|~5.7"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								qwen/php/vendor/nikic/fast-route/phpunit.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								qwen/php/vendor/nikic/fast-route/phpunit.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
 | 
			
		||||
<phpunit backupGlobals="false"
 | 
			
		||||
         backupStaticAttributes="false"
 | 
			
		||||
         colors="true"
 | 
			
		||||
         convertErrorsToExceptions="true"
 | 
			
		||||
         convertNoticesToExceptions="true"
 | 
			
		||||
         convertWarningsToExceptions="true"
 | 
			
		||||
         processIsolation="false"
 | 
			
		||||
         syntaxCheck="false"
 | 
			
		||||
         bootstrap="test/bootstrap.php"
 | 
			
		||||
        >
 | 
			
		||||
    <testsuites>
 | 
			
		||||
        <testsuite name="FastRoute Tests">
 | 
			
		||||
            <directory>./test/</directory>
 | 
			
		||||
        </testsuite>
 | 
			
		||||
    </testsuites>
 | 
			
		||||
 | 
			
		||||
    <filter>
 | 
			
		||||
        <whitelist>
 | 
			
		||||
            <directory>./src/</directory>
 | 
			
		||||
        </whitelist>
 | 
			
		||||
    </filter>
 | 
			
		||||
</phpunit>
 | 
			
		||||
							
								
								
									
										28
									
								
								qwen/php/vendor/nikic/fast-route/psalm.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								qwen/php/vendor/nikic/fast-route/psalm.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<psalm
 | 
			
		||||
    name="Example Psalm config with recommended defaults"
 | 
			
		||||
    stopOnFirstError="false"
 | 
			
		||||
    useDocblockTypes="true"
 | 
			
		||||
    totallyTyped="false"
 | 
			
		||||
    requireVoidReturnType="false"
 | 
			
		||||
>
 | 
			
		||||
    <projectFiles>
 | 
			
		||||
        <directory name="src" />
 | 
			
		||||
    </projectFiles>
 | 
			
		||||
 | 
			
		||||
    <issueHandlers>
 | 
			
		||||
        <LessSpecificReturnType errorLevel="info" />
 | 
			
		||||
 | 
			
		||||
        <!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
 | 
			
		||||
        <DeprecatedMethod errorLevel="info" />
 | 
			
		||||
 | 
			
		||||
        <MissingClosureReturnType errorLevel="info" />
 | 
			
		||||
        <MissingReturnType errorLevel="info" />
 | 
			
		||||
        <MissingPropertyType errorLevel="info" />
 | 
			
		||||
        <InvalidDocblock errorLevel="info" />
 | 
			
		||||
        <MisplacedRequiredParam errorLevel="info" />
 | 
			
		||||
 | 
			
		||||
        <PropertyNotSetInConstructor errorLevel="info" />
 | 
			
		||||
        <MissingConstructor errorLevel="info" />
 | 
			
		||||
    </issueHandlers>
 | 
			
		||||
</psalm>
 | 
			
		||||
							
								
								
									
										7
									
								
								qwen/php/vendor/nikic/fast-route/src/BadRouteException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								qwen/php/vendor/nikic/fast-route/src/BadRouteException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute;
 | 
			
		||||
 | 
			
		||||
class BadRouteException extends \LogicException
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute;
 | 
			
		||||
 | 
			
		||||
interface DataGenerator
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a route to the data generator. The route data uses the
 | 
			
		||||
     * same format that is returned by RouterParser::parser().
 | 
			
		||||
     *
 | 
			
		||||
     * The handler doesn't necessarily need to be a callable, it
 | 
			
		||||
     * can be arbitrary data that will be returned when the route
 | 
			
		||||
     * matches.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $httpMethod
 | 
			
		||||
     * @param array $routeData
 | 
			
		||||
     * @param mixed $handler
 | 
			
		||||
     */
 | 
			
		||||
    public function addRoute($httpMethod, $routeData, $handler);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns dispatcher data in some unspecified format, which
 | 
			
		||||
     * depends on the used method of dispatch.
 | 
			
		||||
     */
 | 
			
		||||
    public function getData();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator/CharCountBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator/CharCountBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\DataGenerator;
 | 
			
		||||
 | 
			
		||||
class CharCountBased extends RegexBasedAbstract
 | 
			
		||||
{
 | 
			
		||||
    protected function getApproxChunkSize()
 | 
			
		||||
    {
 | 
			
		||||
        return 30;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function processChunk($regexToRoutesMap)
 | 
			
		||||
    {
 | 
			
		||||
        $routeMap = [];
 | 
			
		||||
        $regexes = [];
 | 
			
		||||
 | 
			
		||||
        $suffixLen = 0;
 | 
			
		||||
        $suffix = '';
 | 
			
		||||
        $count = count($regexToRoutesMap);
 | 
			
		||||
        foreach ($regexToRoutesMap as $regex => $route) {
 | 
			
		||||
            $suffixLen++;
 | 
			
		||||
            $suffix .= "\t";
 | 
			
		||||
 | 
			
		||||
            $regexes[] = '(?:' . $regex . '/(\t{' . $suffixLen . '})\t{' . ($count - $suffixLen) . '})';
 | 
			
		||||
            $routeMap[$suffix] = [$route->handler, $route->variables];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $regex = '~^(?|' . implode('|', $regexes) . ')$~';
 | 
			
		||||
        return ['regex' => $regex, 'suffix' => '/' . $suffix, 'routeMap' => $routeMap];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator/GroupCountBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator/GroupCountBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\DataGenerator;
 | 
			
		||||
 | 
			
		||||
class GroupCountBased extends RegexBasedAbstract
 | 
			
		||||
{
 | 
			
		||||
    protected function getApproxChunkSize()
 | 
			
		||||
    {
 | 
			
		||||
        return 10;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function processChunk($regexToRoutesMap)
 | 
			
		||||
    {
 | 
			
		||||
        $routeMap = [];
 | 
			
		||||
        $regexes = [];
 | 
			
		||||
        $numGroups = 0;
 | 
			
		||||
        foreach ($regexToRoutesMap as $regex => $route) {
 | 
			
		||||
            $numVariables = count($route->variables);
 | 
			
		||||
            $numGroups = max($numGroups, $numVariables);
 | 
			
		||||
 | 
			
		||||
            $regexes[] = $regex . str_repeat('()', $numGroups - $numVariables);
 | 
			
		||||
            $routeMap[$numGroups + 1] = [$route->handler, $route->variables];
 | 
			
		||||
 | 
			
		||||
            ++$numGroups;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $regex = '~^(?|' . implode('|', $regexes) . ')$~';
 | 
			
		||||
        return ['regex' => $regex, 'routeMap' => $routeMap];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator/GroupPosBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator/GroupPosBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\DataGenerator;
 | 
			
		||||
 | 
			
		||||
class GroupPosBased extends RegexBasedAbstract
 | 
			
		||||
{
 | 
			
		||||
    protected function getApproxChunkSize()
 | 
			
		||||
    {
 | 
			
		||||
        return 10;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function processChunk($regexToRoutesMap)
 | 
			
		||||
    {
 | 
			
		||||
        $routeMap = [];
 | 
			
		||||
        $regexes = [];
 | 
			
		||||
        $offset = 1;
 | 
			
		||||
        foreach ($regexToRoutesMap as $regex => $route) {
 | 
			
		||||
            $regexes[] = $regex;
 | 
			
		||||
            $routeMap[$offset] = [$route->handler, $route->variables];
 | 
			
		||||
 | 
			
		||||
            $offset += count($route->variables);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $regex = '~^(?:' . implode('|', $regexes) . ')$~';
 | 
			
		||||
        return ['regex' => $regex, 'routeMap' => $routeMap];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator/MarkBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator/MarkBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\DataGenerator;
 | 
			
		||||
 | 
			
		||||
class MarkBased extends RegexBasedAbstract
 | 
			
		||||
{
 | 
			
		||||
    protected function getApproxChunkSize()
 | 
			
		||||
    {
 | 
			
		||||
        return 30;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function processChunk($regexToRoutesMap)
 | 
			
		||||
    {
 | 
			
		||||
        $routeMap = [];
 | 
			
		||||
        $regexes = [];
 | 
			
		||||
        $markName = 'a';
 | 
			
		||||
        foreach ($regexToRoutesMap as $regex => $route) {
 | 
			
		||||
            $regexes[] = $regex . '(*MARK:' . $markName . ')';
 | 
			
		||||
            $routeMap[$markName] = [$route->handler, $route->variables];
 | 
			
		||||
 | 
			
		||||
            ++$markName;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $regex = '~^(?|' . implode('|', $regexes) . ')$~';
 | 
			
		||||
        return ['regex' => $regex, 'routeMap' => $routeMap];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										186
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								qwen/php/vendor/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,186 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\DataGenerator;
 | 
			
		||||
 | 
			
		||||
use FastRoute\BadRouteException;
 | 
			
		||||
use FastRoute\DataGenerator;
 | 
			
		||||
use FastRoute\Route;
 | 
			
		||||
 | 
			
		||||
abstract class RegexBasedAbstract implements DataGenerator
 | 
			
		||||
{
 | 
			
		||||
    /** @var mixed[][] */
 | 
			
		||||
    protected $staticRoutes = [];
 | 
			
		||||
 | 
			
		||||
    /** @var Route[][] */
 | 
			
		||||
    protected $methodToRegexToRoutesMap = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return int
 | 
			
		||||
     */
 | 
			
		||||
    abstract protected function getApproxChunkSize();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return mixed[]
 | 
			
		||||
     */
 | 
			
		||||
    abstract protected function processChunk($regexToRoutesMap);
 | 
			
		||||
 | 
			
		||||
    public function addRoute($httpMethod, $routeData, $handler)
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->isStaticRoute($routeData)) {
 | 
			
		||||
            $this->addStaticRoute($httpMethod, $routeData, $handler);
 | 
			
		||||
        } else {
 | 
			
		||||
            $this->addVariableRoute($httpMethod, $routeData, $handler);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return mixed[]
 | 
			
		||||
     */
 | 
			
		||||
    public function getData()
 | 
			
		||||
    {
 | 
			
		||||
        if (empty($this->methodToRegexToRoutesMap)) {
 | 
			
		||||
            return [$this->staticRoutes, []];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [$this->staticRoutes, $this->generateVariableRouteData()];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return mixed[]
 | 
			
		||||
     */
 | 
			
		||||
    private function generateVariableRouteData()
 | 
			
		||||
    {
 | 
			
		||||
        $data = [];
 | 
			
		||||
        foreach ($this->methodToRegexToRoutesMap as $method => $regexToRoutesMap) {
 | 
			
		||||
            $chunkSize = $this->computeChunkSize(count($regexToRoutesMap));
 | 
			
		||||
            $chunks = array_chunk($regexToRoutesMap, $chunkSize, true);
 | 
			
		||||
            $data[$method] = array_map([$this, 'processChunk'], $chunks);
 | 
			
		||||
        }
 | 
			
		||||
        return $data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param int
 | 
			
		||||
     * @return int
 | 
			
		||||
     */
 | 
			
		||||
    private function computeChunkSize($count)
 | 
			
		||||
    {
 | 
			
		||||
        $numParts = max(1, round($count / $this->getApproxChunkSize()));
 | 
			
		||||
        return (int) ceil($count / $numParts);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param mixed[]
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    private function isStaticRoute($routeData)
 | 
			
		||||
    {
 | 
			
		||||
        return count($routeData) === 1 && is_string($routeData[0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function addStaticRoute($httpMethod, $routeData, $handler)
 | 
			
		||||
    {
 | 
			
		||||
        $routeStr = $routeData[0];
 | 
			
		||||
 | 
			
		||||
        if (isset($this->staticRoutes[$httpMethod][$routeStr])) {
 | 
			
		||||
            throw new BadRouteException(sprintf(
 | 
			
		||||
                'Cannot register two routes matching "%s" for method "%s"',
 | 
			
		||||
                $routeStr, $httpMethod
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isset($this->methodToRegexToRoutesMap[$httpMethod])) {
 | 
			
		||||
            foreach ($this->methodToRegexToRoutesMap[$httpMethod] as $route) {
 | 
			
		||||
                if ($route->matches($routeStr)) {
 | 
			
		||||
                    throw new BadRouteException(sprintf(
 | 
			
		||||
                        'Static route "%s" is shadowed by previously defined variable route "%s" for method "%s"',
 | 
			
		||||
                        $routeStr, $route->regex, $httpMethod
 | 
			
		||||
                    ));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->staticRoutes[$httpMethod][$routeStr] = $handler;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function addVariableRoute($httpMethod, $routeData, $handler)
 | 
			
		||||
    {
 | 
			
		||||
        list($regex, $variables) = $this->buildRegexForRoute($routeData);
 | 
			
		||||
 | 
			
		||||
        if (isset($this->methodToRegexToRoutesMap[$httpMethod][$regex])) {
 | 
			
		||||
            throw new BadRouteException(sprintf(
 | 
			
		||||
                'Cannot register two routes matching "%s" for method "%s"',
 | 
			
		||||
                $regex, $httpMethod
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->methodToRegexToRoutesMap[$httpMethod][$regex] = new Route(
 | 
			
		||||
            $httpMethod, $handler, $regex, $variables
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param mixed[]
 | 
			
		||||
     * @return mixed[]
 | 
			
		||||
     */
 | 
			
		||||
    private function buildRegexForRoute($routeData)
 | 
			
		||||
    {
 | 
			
		||||
        $regex = '';
 | 
			
		||||
        $variables = [];
 | 
			
		||||
        foreach ($routeData as $part) {
 | 
			
		||||
            if (is_string($part)) {
 | 
			
		||||
                $regex .= preg_quote($part, '~');
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            list($varName, $regexPart) = $part;
 | 
			
		||||
 | 
			
		||||
            if (isset($variables[$varName])) {
 | 
			
		||||
                throw new BadRouteException(sprintf(
 | 
			
		||||
                    'Cannot use the same placeholder "%s" twice', $varName
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($this->regexHasCapturingGroups($regexPart)) {
 | 
			
		||||
                throw new BadRouteException(sprintf(
 | 
			
		||||
                    'Regex "%s" for parameter "%s" contains a capturing group',
 | 
			
		||||
                    $regexPart, $varName
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $variables[$varName] = $varName;
 | 
			
		||||
            $regex .= '(' . $regexPart . ')';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [$regex, $variables];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    private function regexHasCapturingGroups($regex)
 | 
			
		||||
    {
 | 
			
		||||
        if (false === strpos($regex, '(')) {
 | 
			
		||||
            // Needs to have at least a ( to contain a capturing group
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Semi-accurate detection for capturing groups
 | 
			
		||||
        return (bool) preg_match(
 | 
			
		||||
            '~
 | 
			
		||||
                (?:
 | 
			
		||||
                    \(\?\(
 | 
			
		||||
                  | \[ [^\]\\\\]* (?: \\\\ . [^\]\\\\]* )* \]
 | 
			
		||||
                  | \\\\ .
 | 
			
		||||
                ) (*SKIP)(*FAIL) |
 | 
			
		||||
                \(
 | 
			
		||||
                (?!
 | 
			
		||||
                    \? (?! <(?![!=]) | P< | \' )
 | 
			
		||||
                  | \*
 | 
			
		||||
                )
 | 
			
		||||
            ~x',
 | 
			
		||||
            $regex
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute;
 | 
			
		||||
 | 
			
		||||
interface Dispatcher
 | 
			
		||||
{
 | 
			
		||||
    const NOT_FOUND = 0;
 | 
			
		||||
    const FOUND = 1;
 | 
			
		||||
    const METHOD_NOT_ALLOWED = 2;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Dispatches against the provided HTTP method verb and URI.
 | 
			
		||||
     *
 | 
			
		||||
     * Returns array with one of the following formats:
 | 
			
		||||
     *
 | 
			
		||||
     *     [self::NOT_FOUND]
 | 
			
		||||
     *     [self::METHOD_NOT_ALLOWED, ['GET', 'OTHER_ALLOWED_METHODS']]
 | 
			
		||||
     *     [self::FOUND, $handler, ['varName' => 'value', ...]]
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $httpMethod
 | 
			
		||||
     * @param string $uri
 | 
			
		||||
     *
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    public function dispatch($httpMethod, $uri);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher/CharCountBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher/CharCountBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\Dispatcher;
 | 
			
		||||
 | 
			
		||||
class CharCountBased extends RegexBasedAbstract
 | 
			
		||||
{
 | 
			
		||||
    public function __construct($data)
 | 
			
		||||
    {
 | 
			
		||||
        list($this->staticRouteMap, $this->variableRouteData) = $data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function dispatchVariableRoute($routeData, $uri)
 | 
			
		||||
    {
 | 
			
		||||
        foreach ($routeData as $data) {
 | 
			
		||||
            if (!preg_match($data['regex'], $uri . $data['suffix'], $matches)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            list($handler, $varNames) = $data['routeMap'][end($matches)];
 | 
			
		||||
 | 
			
		||||
            $vars = [];
 | 
			
		||||
            $i = 0;
 | 
			
		||||
            foreach ($varNames as $varName) {
 | 
			
		||||
                $vars[$varName] = $matches[++$i];
 | 
			
		||||
            }
 | 
			
		||||
            return [self::FOUND, $handler, $vars];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [self::NOT_FOUND];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher/GroupCountBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher/GroupCountBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\Dispatcher;
 | 
			
		||||
 | 
			
		||||
class GroupCountBased extends RegexBasedAbstract
 | 
			
		||||
{
 | 
			
		||||
    public function __construct($data)
 | 
			
		||||
    {
 | 
			
		||||
        list($this->staticRouteMap, $this->variableRouteData) = $data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function dispatchVariableRoute($routeData, $uri)
 | 
			
		||||
    {
 | 
			
		||||
        foreach ($routeData as $data) {
 | 
			
		||||
            if (!preg_match($data['regex'], $uri, $matches)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            list($handler, $varNames) = $data['routeMap'][count($matches)];
 | 
			
		||||
 | 
			
		||||
            $vars = [];
 | 
			
		||||
            $i = 0;
 | 
			
		||||
            foreach ($varNames as $varName) {
 | 
			
		||||
                $vars[$varName] = $matches[++$i];
 | 
			
		||||
            }
 | 
			
		||||
            return [self::FOUND, $handler, $vars];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [self::NOT_FOUND];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher/GroupPosBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher/GroupPosBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\Dispatcher;
 | 
			
		||||
 | 
			
		||||
class GroupPosBased extends RegexBasedAbstract
 | 
			
		||||
{
 | 
			
		||||
    public function __construct($data)
 | 
			
		||||
    {
 | 
			
		||||
        list($this->staticRouteMap, $this->variableRouteData) = $data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function dispatchVariableRoute($routeData, $uri)
 | 
			
		||||
    {
 | 
			
		||||
        foreach ($routeData as $data) {
 | 
			
		||||
            if (!preg_match($data['regex'], $uri, $matches)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // find first non-empty match
 | 
			
		||||
            for ($i = 1; '' === $matches[$i]; ++$i);
 | 
			
		||||
 | 
			
		||||
            list($handler, $varNames) = $data['routeMap'][$i];
 | 
			
		||||
 | 
			
		||||
            $vars = [];
 | 
			
		||||
            foreach ($varNames as $varName) {
 | 
			
		||||
                $vars[$varName] = $matches[$i++];
 | 
			
		||||
            }
 | 
			
		||||
            return [self::FOUND, $handler, $vars];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [self::NOT_FOUND];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher/MarkBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher/MarkBased.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\Dispatcher;
 | 
			
		||||
 | 
			
		||||
class MarkBased extends RegexBasedAbstract
 | 
			
		||||
{
 | 
			
		||||
    public function __construct($data)
 | 
			
		||||
    {
 | 
			
		||||
        list($this->staticRouteMap, $this->variableRouteData) = $data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function dispatchVariableRoute($routeData, $uri)
 | 
			
		||||
    {
 | 
			
		||||
        foreach ($routeData as $data) {
 | 
			
		||||
            if (!preg_match($data['regex'], $uri, $matches)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            list($handler, $varNames) = $data['routeMap'][$matches['MARK']];
 | 
			
		||||
 | 
			
		||||
            $vars = [];
 | 
			
		||||
            $i = 0;
 | 
			
		||||
            foreach ($varNames as $varName) {
 | 
			
		||||
                $vars[$varName] = $matches[++$i];
 | 
			
		||||
            }
 | 
			
		||||
            return [self::FOUND, $handler, $vars];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [self::NOT_FOUND];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										88
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher/RegexBasedAbstract.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								qwen/php/vendor/nikic/fast-route/src/Dispatcher/RegexBasedAbstract.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\Dispatcher;
 | 
			
		||||
 | 
			
		||||
use FastRoute\Dispatcher;
 | 
			
		||||
 | 
			
		||||
abstract class RegexBasedAbstract implements Dispatcher
 | 
			
		||||
{
 | 
			
		||||
    /** @var mixed[][] */
 | 
			
		||||
    protected $staticRouteMap = [];
 | 
			
		||||
 | 
			
		||||
    /** @var mixed[] */
 | 
			
		||||
    protected $variableRouteData = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return mixed[]
 | 
			
		||||
     */
 | 
			
		||||
    abstract protected function dispatchVariableRoute($routeData, $uri);
 | 
			
		||||
 | 
			
		||||
    public function dispatch($httpMethod, $uri)
 | 
			
		||||
    {
 | 
			
		||||
        if (isset($this->staticRouteMap[$httpMethod][$uri])) {
 | 
			
		||||
            $handler = $this->staticRouteMap[$httpMethod][$uri];
 | 
			
		||||
            return [self::FOUND, $handler, []];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $varRouteData = $this->variableRouteData;
 | 
			
		||||
        if (isset($varRouteData[$httpMethod])) {
 | 
			
		||||
            $result = $this->dispatchVariableRoute($varRouteData[$httpMethod], $uri);
 | 
			
		||||
            if ($result[0] === self::FOUND) {
 | 
			
		||||
                return $result;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // For HEAD requests, attempt fallback to GET
 | 
			
		||||
        if ($httpMethod === 'HEAD') {
 | 
			
		||||
            if (isset($this->staticRouteMap['GET'][$uri])) {
 | 
			
		||||
                $handler = $this->staticRouteMap['GET'][$uri];
 | 
			
		||||
                return [self::FOUND, $handler, []];
 | 
			
		||||
            }
 | 
			
		||||
            if (isset($varRouteData['GET'])) {
 | 
			
		||||
                $result = $this->dispatchVariableRoute($varRouteData['GET'], $uri);
 | 
			
		||||
                if ($result[0] === self::FOUND) {
 | 
			
		||||
                    return $result;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If nothing else matches, try fallback routes
 | 
			
		||||
        if (isset($this->staticRouteMap['*'][$uri])) {
 | 
			
		||||
            $handler = $this->staticRouteMap['*'][$uri];
 | 
			
		||||
            return [self::FOUND, $handler, []];
 | 
			
		||||
        }
 | 
			
		||||
        if (isset($varRouteData['*'])) {
 | 
			
		||||
            $result = $this->dispatchVariableRoute($varRouteData['*'], $uri);
 | 
			
		||||
            if ($result[0] === self::FOUND) {
 | 
			
		||||
                return $result;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Find allowed methods for this URI by matching against all other HTTP methods as well
 | 
			
		||||
        $allowedMethods = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($this->staticRouteMap as $method => $uriMap) {
 | 
			
		||||
            if ($method !== $httpMethod && isset($uriMap[$uri])) {
 | 
			
		||||
                $allowedMethods[] = $method;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($varRouteData as $method => $routeData) {
 | 
			
		||||
            if ($method === $httpMethod) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $result = $this->dispatchVariableRoute($routeData, $uri);
 | 
			
		||||
            if ($result[0] === self::FOUND) {
 | 
			
		||||
                $allowedMethods[] = $method;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If there are no allowed methods the route simply does not exist
 | 
			
		||||
        if ($allowedMethods) {
 | 
			
		||||
            return [self::METHOD_NOT_ALLOWED, $allowedMethods];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [self::NOT_FOUND];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								qwen/php/vendor/nikic/fast-route/src/Route.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								qwen/php/vendor/nikic/fast-route/src/Route.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute;
 | 
			
		||||
 | 
			
		||||
class Route
 | 
			
		||||
{
 | 
			
		||||
    /** @var string */
 | 
			
		||||
    public $httpMethod;
 | 
			
		||||
 | 
			
		||||
    /** @var string */
 | 
			
		||||
    public $regex;
 | 
			
		||||
 | 
			
		||||
    /** @var array */
 | 
			
		||||
    public $variables;
 | 
			
		||||
 | 
			
		||||
    /** @var mixed */
 | 
			
		||||
    public $handler;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a route (value object).
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $httpMethod
 | 
			
		||||
     * @param mixed  $handler
 | 
			
		||||
     * @param string $regex
 | 
			
		||||
     * @param array  $variables
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($httpMethod, $handler, $regex, $variables)
 | 
			
		||||
    {
 | 
			
		||||
        $this->httpMethod = $httpMethod;
 | 
			
		||||
        $this->handler = $handler;
 | 
			
		||||
        $this->regex = $regex;
 | 
			
		||||
        $this->variables = $variables;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Tests whether this route matches the given string.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $str
 | 
			
		||||
     *
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    public function matches($str)
 | 
			
		||||
    {
 | 
			
		||||
        $regex = '~^' . $this->regex . '$~';
 | 
			
		||||
        return (bool) preg_match($regex, $str);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										152
									
								
								qwen/php/vendor/nikic/fast-route/src/RouteCollector.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								qwen/php/vendor/nikic/fast-route/src/RouteCollector.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute;
 | 
			
		||||
 | 
			
		||||
class RouteCollector
 | 
			
		||||
{
 | 
			
		||||
    /** @var RouteParser */
 | 
			
		||||
    protected $routeParser;
 | 
			
		||||
 | 
			
		||||
    /** @var DataGenerator */
 | 
			
		||||
    protected $dataGenerator;
 | 
			
		||||
 | 
			
		||||
    /** @var string */
 | 
			
		||||
    protected $currentGroupPrefix;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a route collector.
 | 
			
		||||
     *
 | 
			
		||||
     * @param RouteParser   $routeParser
 | 
			
		||||
     * @param DataGenerator $dataGenerator
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(RouteParser $routeParser, DataGenerator $dataGenerator)
 | 
			
		||||
    {
 | 
			
		||||
        $this->routeParser = $routeParser;
 | 
			
		||||
        $this->dataGenerator = $dataGenerator;
 | 
			
		||||
        $this->currentGroupPrefix = '';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a route to the collection.
 | 
			
		||||
     *
 | 
			
		||||
     * The syntax used in the $route string depends on the used route parser.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|string[] $httpMethod
 | 
			
		||||
     * @param string $route
 | 
			
		||||
     * @param mixed  $handler
 | 
			
		||||
     */
 | 
			
		||||
    public function addRoute($httpMethod, $route, $handler)
 | 
			
		||||
    {
 | 
			
		||||
        $route = $this->currentGroupPrefix . $route;
 | 
			
		||||
        $routeDatas = $this->routeParser->parse($route);
 | 
			
		||||
        foreach ((array) $httpMethod as $method) {
 | 
			
		||||
            foreach ($routeDatas as $routeData) {
 | 
			
		||||
                $this->dataGenerator->addRoute($method, $routeData, $handler);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a route group with a common prefix.
 | 
			
		||||
     *
 | 
			
		||||
     * All routes created in the passed callback will have the given group prefix prepended.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $prefix
 | 
			
		||||
     * @param callable $callback
 | 
			
		||||
     */
 | 
			
		||||
    public function addGroup($prefix, callable $callback)
 | 
			
		||||
    {
 | 
			
		||||
        $previousGroupPrefix = $this->currentGroupPrefix;
 | 
			
		||||
        $this->currentGroupPrefix = $previousGroupPrefix . $prefix;
 | 
			
		||||
        $callback($this);
 | 
			
		||||
        $this->currentGroupPrefix = $previousGroupPrefix;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a GET route to the collection
 | 
			
		||||
     * 
 | 
			
		||||
     * This is simply an alias of $this->addRoute('GET', $route, $handler)
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $route
 | 
			
		||||
     * @param mixed  $handler
 | 
			
		||||
     */
 | 
			
		||||
    public function get($route, $handler)
 | 
			
		||||
    {
 | 
			
		||||
        $this->addRoute('GET', $route, $handler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a POST route to the collection
 | 
			
		||||
     * 
 | 
			
		||||
     * This is simply an alias of $this->addRoute('POST', $route, $handler)
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $route
 | 
			
		||||
     * @param mixed  $handler
 | 
			
		||||
     */
 | 
			
		||||
    public function post($route, $handler)
 | 
			
		||||
    {
 | 
			
		||||
        $this->addRoute('POST', $route, $handler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a PUT route to the collection
 | 
			
		||||
     * 
 | 
			
		||||
     * This is simply an alias of $this->addRoute('PUT', $route, $handler)
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $route
 | 
			
		||||
     * @param mixed  $handler
 | 
			
		||||
     */
 | 
			
		||||
    public function put($route, $handler)
 | 
			
		||||
    {
 | 
			
		||||
        $this->addRoute('PUT', $route, $handler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a DELETE route to the collection
 | 
			
		||||
     * 
 | 
			
		||||
     * This is simply an alias of $this->addRoute('DELETE', $route, $handler)
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $route
 | 
			
		||||
     * @param mixed  $handler
 | 
			
		||||
     */
 | 
			
		||||
    public function delete($route, $handler)
 | 
			
		||||
    {
 | 
			
		||||
        $this->addRoute('DELETE', $route, $handler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a PATCH route to the collection
 | 
			
		||||
     * 
 | 
			
		||||
     * This is simply an alias of $this->addRoute('PATCH', $route, $handler)
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $route
 | 
			
		||||
     * @param mixed  $handler
 | 
			
		||||
     */
 | 
			
		||||
    public function patch($route, $handler)
 | 
			
		||||
    {
 | 
			
		||||
        $this->addRoute('PATCH', $route, $handler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a HEAD route to the collection
 | 
			
		||||
     *
 | 
			
		||||
     * This is simply an alias of $this->addRoute('HEAD', $route, $handler)
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $route
 | 
			
		||||
     * @param mixed  $handler
 | 
			
		||||
     */
 | 
			
		||||
    public function head($route, $handler)
 | 
			
		||||
    {
 | 
			
		||||
        $this->addRoute('HEAD', $route, $handler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the collected route data, as provided by the data generator.
 | 
			
		||||
     *
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    public function getData()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->dataGenerator->getData();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								qwen/php/vendor/nikic/fast-route/src/RouteParser.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								qwen/php/vendor/nikic/fast-route/src/RouteParser.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute;
 | 
			
		||||
 | 
			
		||||
interface RouteParser
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Parses a route string into multiple route data arrays.
 | 
			
		||||
     *
 | 
			
		||||
     * The expected output is defined using an example:
 | 
			
		||||
     *
 | 
			
		||||
     * For the route string "/fixedRoutePart/{varName}[/moreFixed/{varName2:\d+}]", if {varName} is interpreted as
 | 
			
		||||
     * a placeholder and [...] is interpreted as an optional route part, the expected result is:
 | 
			
		||||
     *
 | 
			
		||||
     * [
 | 
			
		||||
     *     // first route: without optional part
 | 
			
		||||
     *     [
 | 
			
		||||
     *         "/fixedRoutePart/",
 | 
			
		||||
     *         ["varName", "[^/]+"],
 | 
			
		||||
     *     ],
 | 
			
		||||
     *     // second route: with optional part
 | 
			
		||||
     *     [
 | 
			
		||||
     *         "/fixedRoutePart/",
 | 
			
		||||
     *         ["varName", "[^/]+"],
 | 
			
		||||
     *         "/moreFixed/",
 | 
			
		||||
     *         ["varName2", [0-9]+"],
 | 
			
		||||
     *     ],
 | 
			
		||||
     * ]
 | 
			
		||||
     *
 | 
			
		||||
     * Here one route string was converted into two route data arrays.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $route Route string to parse
 | 
			
		||||
     *
 | 
			
		||||
     * @return mixed[][] Array of route data arrays
 | 
			
		||||
     */
 | 
			
		||||
    public function parse($route);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										87
									
								
								qwen/php/vendor/nikic/fast-route/src/RouteParser/Std.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								qwen/php/vendor/nikic/fast-route/src/RouteParser/Std.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\RouteParser;
 | 
			
		||||
 | 
			
		||||
use FastRoute\BadRouteException;
 | 
			
		||||
use FastRoute\RouteParser;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parses route strings of the following form:
 | 
			
		||||
 *
 | 
			
		||||
 * "/user/{name}[/{id:[0-9]+}]"
 | 
			
		||||
 */
 | 
			
		||||
class Std implements RouteParser
 | 
			
		||||
{
 | 
			
		||||
    const VARIABLE_REGEX = <<<'REGEX'
 | 
			
		||||
\{
 | 
			
		||||
    \s* ([a-zA-Z_][a-zA-Z0-9_-]*) \s*
 | 
			
		||||
    (?:
 | 
			
		||||
        : \s* ([^{}]*(?:\{(?-1)\}[^{}]*)*)
 | 
			
		||||
    )?
 | 
			
		||||
\}
 | 
			
		||||
REGEX;
 | 
			
		||||
    const DEFAULT_DISPATCH_REGEX = '[^/]+';
 | 
			
		||||
 | 
			
		||||
    public function parse($route)
 | 
			
		||||
    {
 | 
			
		||||
        $routeWithoutClosingOptionals = rtrim($route, ']');
 | 
			
		||||
        $numOptionals = strlen($route) - strlen($routeWithoutClosingOptionals);
 | 
			
		||||
 | 
			
		||||
        // Split on [ while skipping placeholders
 | 
			
		||||
        $segments = preg_split('~' . self::VARIABLE_REGEX . '(*SKIP)(*F) | \[~x', $routeWithoutClosingOptionals);
 | 
			
		||||
        if ($numOptionals !== count($segments) - 1) {
 | 
			
		||||
            // If there are any ] in the middle of the route, throw a more specific error message
 | 
			
		||||
            if (preg_match('~' . self::VARIABLE_REGEX . '(*SKIP)(*F) | \]~x', $routeWithoutClosingOptionals)) {
 | 
			
		||||
                throw new BadRouteException('Optional segments can only occur at the end of a route');
 | 
			
		||||
            }
 | 
			
		||||
            throw new BadRouteException("Number of opening '[' and closing ']' does not match");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $currentRoute = '';
 | 
			
		||||
        $routeDatas = [];
 | 
			
		||||
        foreach ($segments as $n => $segment) {
 | 
			
		||||
            if ($segment === '' && $n !== 0) {
 | 
			
		||||
                throw new BadRouteException('Empty optional part');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $currentRoute .= $segment;
 | 
			
		||||
            $routeDatas[] = $this->parsePlaceholders($currentRoute);
 | 
			
		||||
        }
 | 
			
		||||
        return $routeDatas;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parses a route string that does not contain optional segments.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string
 | 
			
		||||
     * @return mixed[]
 | 
			
		||||
     */
 | 
			
		||||
    private function parsePlaceholders($route)
 | 
			
		||||
    {
 | 
			
		||||
        if (!preg_match_all(
 | 
			
		||||
            '~' . self::VARIABLE_REGEX . '~x', $route, $matches,
 | 
			
		||||
            PREG_OFFSET_CAPTURE | PREG_SET_ORDER
 | 
			
		||||
        )) {
 | 
			
		||||
            return [$route];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $offset = 0;
 | 
			
		||||
        $routeData = [];
 | 
			
		||||
        foreach ($matches as $set) {
 | 
			
		||||
            if ($set[0][1] > $offset) {
 | 
			
		||||
                $routeData[] = substr($route, $offset, $set[0][1] - $offset);
 | 
			
		||||
            }
 | 
			
		||||
            $routeData[] = [
 | 
			
		||||
                $set[1][0],
 | 
			
		||||
                isset($set[2]) ? trim($set[2][0]) : self::DEFAULT_DISPATCH_REGEX
 | 
			
		||||
            ];
 | 
			
		||||
            $offset = $set[0][1] + strlen($set[0][0]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($offset !== strlen($route)) {
 | 
			
		||||
            $routeData[] = substr($route, $offset);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $routeData;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								qwen/php/vendor/nikic/fast-route/src/bootstrap.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								qwen/php/vendor/nikic/fast-route/src/bootstrap.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute;
 | 
			
		||||
 | 
			
		||||
require __DIR__ . '/functions.php';
 | 
			
		||||
 | 
			
		||||
spl_autoload_register(function ($class) {
 | 
			
		||||
    if (strpos($class, 'FastRoute\\') === 0) {
 | 
			
		||||
        $name = substr($class, strlen('FastRoute'));
 | 
			
		||||
        require __DIR__ . strtr($name, '\\', DIRECTORY_SEPARATOR) . '.php';
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										74
									
								
								qwen/php/vendor/nikic/fast-route/src/functions.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								qwen/php/vendor/nikic/fast-route/src/functions.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute;
 | 
			
		||||
 | 
			
		||||
if (!function_exists('FastRoute\simpleDispatcher')) {
 | 
			
		||||
    /**
 | 
			
		||||
     * @param callable $routeDefinitionCallback
 | 
			
		||||
     * @param array $options
 | 
			
		||||
     *
 | 
			
		||||
     * @return Dispatcher
 | 
			
		||||
     */
 | 
			
		||||
    function simpleDispatcher(callable $routeDefinitionCallback, array $options = [])
 | 
			
		||||
    {
 | 
			
		||||
        $options += [
 | 
			
		||||
            'routeParser' => 'FastRoute\\RouteParser\\Std',
 | 
			
		||||
            'dataGenerator' => 'FastRoute\\DataGenerator\\GroupCountBased',
 | 
			
		||||
            'dispatcher' => 'FastRoute\\Dispatcher\\GroupCountBased',
 | 
			
		||||
            'routeCollector' => 'FastRoute\\RouteCollector',
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        /** @var RouteCollector $routeCollector */
 | 
			
		||||
        $routeCollector = new $options['routeCollector'](
 | 
			
		||||
            new $options['routeParser'], new $options['dataGenerator']
 | 
			
		||||
        );
 | 
			
		||||
        $routeDefinitionCallback($routeCollector);
 | 
			
		||||
 | 
			
		||||
        return new $options['dispatcher']($routeCollector->getData());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param callable $routeDefinitionCallback
 | 
			
		||||
     * @param array $options
 | 
			
		||||
     *
 | 
			
		||||
     * @return Dispatcher
 | 
			
		||||
     */
 | 
			
		||||
    function cachedDispatcher(callable $routeDefinitionCallback, array $options = [])
 | 
			
		||||
    {
 | 
			
		||||
        $options += [
 | 
			
		||||
            'routeParser' => 'FastRoute\\RouteParser\\Std',
 | 
			
		||||
            'dataGenerator' => 'FastRoute\\DataGenerator\\GroupCountBased',
 | 
			
		||||
            'dispatcher' => 'FastRoute\\Dispatcher\\GroupCountBased',
 | 
			
		||||
            'routeCollector' => 'FastRoute\\RouteCollector',
 | 
			
		||||
            'cacheDisabled' => false,
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        if (!isset($options['cacheFile'])) {
 | 
			
		||||
            throw new \LogicException('Must specify "cacheFile" option');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!$options['cacheDisabled'] && file_exists($options['cacheFile'])) {
 | 
			
		||||
            $dispatchData = require $options['cacheFile'];
 | 
			
		||||
            if (!is_array($dispatchData)) {
 | 
			
		||||
                throw new \RuntimeException('Invalid cache file "' . $options['cacheFile'] . '"');
 | 
			
		||||
            }
 | 
			
		||||
            return new $options['dispatcher']($dispatchData);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $routeCollector = new $options['routeCollector'](
 | 
			
		||||
            new $options['routeParser'], new $options['dataGenerator']
 | 
			
		||||
        );
 | 
			
		||||
        $routeDefinitionCallback($routeCollector);
 | 
			
		||||
 | 
			
		||||
        /** @var RouteCollector $routeCollector */
 | 
			
		||||
        $dispatchData = $routeCollector->getData();
 | 
			
		||||
        if (!$options['cacheDisabled']) {
 | 
			
		||||
            file_put_contents(
 | 
			
		||||
                $options['cacheFile'],
 | 
			
		||||
                '<?php return ' . var_export($dispatchData, true) . ';'
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new $options['dispatcher']($dispatchData);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								qwen/php/vendor/nikic/fast-route/test/Dispatcher/CharCountBasedTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								qwen/php/vendor/nikic/fast-route/test/Dispatcher/CharCountBasedTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\Dispatcher;
 | 
			
		||||
 | 
			
		||||
class CharCountBasedTest extends DispatcherTest
 | 
			
		||||
{
 | 
			
		||||
    protected function getDispatcherClass()
 | 
			
		||||
    {
 | 
			
		||||
        return 'FastRoute\\Dispatcher\\CharCountBased';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function getDataGeneratorClass()
 | 
			
		||||
    {
 | 
			
		||||
        return 'FastRoute\\DataGenerator\\CharCountBased';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										581
									
								
								qwen/php/vendor/nikic/fast-route/test/Dispatcher/DispatcherTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										581
									
								
								qwen/php/vendor/nikic/fast-route/test/Dispatcher/DispatcherTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,581 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\Dispatcher;
 | 
			
		||||
 | 
			
		||||
use FastRoute\RouteCollector;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
abstract class DispatcherTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Delegate dispatcher selection to child test classes
 | 
			
		||||
     */
 | 
			
		||||
    abstract protected function getDispatcherClass();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delegate dataGenerator selection to child test classes
 | 
			
		||||
     */
 | 
			
		||||
    abstract protected function getDataGeneratorClass();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set appropriate options for the specific Dispatcher class we're testing
 | 
			
		||||
     */
 | 
			
		||||
    private function generateDispatcherOptions()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            'dataGenerator' => $this->getDataGeneratorClass(),
 | 
			
		||||
            'dispatcher' => $this->getDispatcherClass()
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider provideFoundDispatchCases
 | 
			
		||||
     */
 | 
			
		||||
    public function testFoundDispatches($method, $uri, $callback, $handler, $argDict)
 | 
			
		||||
    {
 | 
			
		||||
        $dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions());
 | 
			
		||||
        $info = $dispatcher->dispatch($method, $uri);
 | 
			
		||||
        $this->assertSame($dispatcher::FOUND, $info[0]);
 | 
			
		||||
        $this->assertSame($handler, $info[1]);
 | 
			
		||||
        $this->assertSame($argDict, $info[2]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider provideNotFoundDispatchCases
 | 
			
		||||
     */
 | 
			
		||||
    public function testNotFoundDispatches($method, $uri, $callback)
 | 
			
		||||
    {
 | 
			
		||||
        $dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions());
 | 
			
		||||
        $routeInfo = $dispatcher->dispatch($method, $uri);
 | 
			
		||||
        $this->assertArrayNotHasKey(1, $routeInfo,
 | 
			
		||||
            'NOT_FOUND result must only contain a single element in the returned info array'
 | 
			
		||||
        );
 | 
			
		||||
        $this->assertSame($dispatcher::NOT_FOUND, $routeInfo[0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider provideMethodNotAllowedDispatchCases
 | 
			
		||||
     */
 | 
			
		||||
    public function testMethodNotAllowedDispatches($method, $uri, $callback, $availableMethods)
 | 
			
		||||
    {
 | 
			
		||||
        $dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions());
 | 
			
		||||
        $routeInfo = $dispatcher->dispatch($method, $uri);
 | 
			
		||||
        $this->assertArrayHasKey(1, $routeInfo,
 | 
			
		||||
            'METHOD_NOT_ALLOWED result must return an array of allowed methods at index 1'
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        list($routedStatus, $methodArray) = $dispatcher->dispatch($method, $uri);
 | 
			
		||||
        $this->assertSame($dispatcher::METHOD_NOT_ALLOWED, $routedStatus);
 | 
			
		||||
        $this->assertSame($availableMethods, $methodArray);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @expectedException \FastRoute\BadRouteException
 | 
			
		||||
     * @expectedExceptionMessage Cannot use the same placeholder "test" twice
 | 
			
		||||
     */
 | 
			
		||||
    public function testDuplicateVariableNameError()
 | 
			
		||||
    {
 | 
			
		||||
        \FastRoute\simpleDispatcher(function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/foo/{test}/{test:\d+}', 'handler0');
 | 
			
		||||
        }, $this->generateDispatcherOptions());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @expectedException \FastRoute\BadRouteException
 | 
			
		||||
     * @expectedExceptionMessage Cannot register two routes matching "/user/([^/]+)" for method "GET"
 | 
			
		||||
     */
 | 
			
		||||
    public function testDuplicateVariableRoute()
 | 
			
		||||
    {
 | 
			
		||||
        \FastRoute\simpleDispatcher(function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user/{id}', 'handler0'); // oops, forgot \d+ restriction ;)
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}', 'handler1');
 | 
			
		||||
        }, $this->generateDispatcherOptions());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @expectedException \FastRoute\BadRouteException
 | 
			
		||||
     * @expectedExceptionMessage Cannot register two routes matching "/user" for method "GET"
 | 
			
		||||
     */
 | 
			
		||||
    public function testDuplicateStaticRoute()
 | 
			
		||||
    {
 | 
			
		||||
        \FastRoute\simpleDispatcher(function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/user', 'handler1');
 | 
			
		||||
        }, $this->generateDispatcherOptions());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @expectedException \FastRoute\BadRouteException
 | 
			
		||||
     * @expectedExceptionMessage Static route "/user/nikic" is shadowed by previously defined variable route "/user/([^/]+)" for method "GET"
 | 
			
		||||
     */
 | 
			
		||||
    public function testShadowedStaticRoute()
 | 
			
		||||
    {
 | 
			
		||||
        \FastRoute\simpleDispatcher(function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/user/nikic', 'handler1');
 | 
			
		||||
        }, $this->generateDispatcherOptions());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @expectedException \FastRoute\BadRouteException
 | 
			
		||||
     * @expectedExceptionMessage Regex "(en|de)" for parameter "lang" contains a capturing group
 | 
			
		||||
     */
 | 
			
		||||
    public function testCapturing()
 | 
			
		||||
    {
 | 
			
		||||
        \FastRoute\simpleDispatcher(function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/{lang:(en|de)}', 'handler0');
 | 
			
		||||
        }, $this->generateDispatcherOptions());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function provideFoundDispatchCases()
 | 
			
		||||
    {
 | 
			
		||||
        $cases = [];
 | 
			
		||||
 | 
			
		||||
        // 0 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/resource/123/456', 'handler0');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/resource/123/456';
 | 
			
		||||
        $handler = 'handler0';
 | 
			
		||||
        $argDict = [];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 1 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/handler0', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/handler1', 'handler1');
 | 
			
		||||
            $r->addRoute('GET', '/handler2', 'handler2');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/handler2';
 | 
			
		||||
        $handler = 'handler2';
 | 
			
		||||
        $argDict = [];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 2 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1');
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}', 'handler2');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/user/rdlowrey';
 | 
			
		||||
        $handler = 'handler2';
 | 
			
		||||
        $argDict = ['name' => 'rdlowrey'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 3 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        // reuse $callback from #2
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/user/12345';
 | 
			
		||||
        $handler = 'handler1';
 | 
			
		||||
        $argDict = ['id' => '12345'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 4 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        // reuse $callback from #3
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/user/NaN';
 | 
			
		||||
        $handler = 'handler2';
 | 
			
		||||
        $argDict = ['name' => 'NaN'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 5 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        // reuse $callback from #4
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/user/rdlowrey/12345';
 | 
			
		||||
        $handler = 'handler0';
 | 
			
		||||
        $argDict = ['name' => 'rdlowrey', 'id' => '12345'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 6 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/user/12345/extension', 'handler1');
 | 
			
		||||
            $r->addRoute('GET', '/user/{id:[0-9]+}.{extension}', 'handler2');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/user/12345.svg';
 | 
			
		||||
        $handler = 'handler2';
 | 
			
		||||
        $argDict = ['id' => '12345', 'extension' => 'svg'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 7 ----- Test GET method fallback on HEAD route miss ------------------------------------>
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler1');
 | 
			
		||||
            $r->addRoute('GET', '/static0', 'handler2');
 | 
			
		||||
            $r->addRoute('GET', '/static1', 'handler3');
 | 
			
		||||
            $r->addRoute('HEAD', '/static1', 'handler4');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'HEAD';
 | 
			
		||||
        $uri = '/user/rdlowrey';
 | 
			
		||||
        $handler = 'handler0';
 | 
			
		||||
        $argDict = ['name' => 'rdlowrey'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 8 ----- Test GET method fallback on HEAD route miss ------------------------------------>
 | 
			
		||||
 | 
			
		||||
        // reuse $callback from #7
 | 
			
		||||
 | 
			
		||||
        $method = 'HEAD';
 | 
			
		||||
        $uri = '/user/rdlowrey/1234';
 | 
			
		||||
        $handler = 'handler1';
 | 
			
		||||
        $argDict = ['name' => 'rdlowrey', 'id' => '1234'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 9 ----- Test GET method fallback on HEAD route miss ------------------------------------>
 | 
			
		||||
 | 
			
		||||
        // reuse $callback from #8
 | 
			
		||||
 | 
			
		||||
        $method = 'HEAD';
 | 
			
		||||
        $uri = '/static0';
 | 
			
		||||
        $handler = 'handler2';
 | 
			
		||||
        $argDict = [];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 10 ---- Test existing HEAD route used if available (no fallback) ----------------------->
 | 
			
		||||
 | 
			
		||||
        // reuse $callback from #9
 | 
			
		||||
 | 
			
		||||
        $method = 'HEAD';
 | 
			
		||||
        $uri = '/static1';
 | 
			
		||||
        $handler = 'handler4';
 | 
			
		||||
        $argDict = [];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 11 ---- More specified routes are not shadowed by less specific of another method ------>
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}', 'handler0');
 | 
			
		||||
            $r->addRoute('POST', '/user/{name:[a-z]+}', 'handler1');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'POST';
 | 
			
		||||
        $uri = '/user/rdlowrey';
 | 
			
		||||
        $handler = 'handler1';
 | 
			
		||||
        $argDict = ['name' => 'rdlowrey'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 12 ---- Handler of more specific routes is used, if it occurs first -------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}', 'handler0');
 | 
			
		||||
            $r->addRoute('POST', '/user/{name:[a-z]+}', 'handler1');
 | 
			
		||||
            $r->addRoute('POST', '/user/{name}', 'handler2');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'POST';
 | 
			
		||||
        $uri = '/user/rdlowrey';
 | 
			
		||||
        $handler = 'handler1';
 | 
			
		||||
        $argDict = ['name' => 'rdlowrey'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 13 ---- Route with constant suffix ----------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}/edit', 'handler1');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/user/rdlowrey/edit';
 | 
			
		||||
        $handler = 'handler1';
 | 
			
		||||
        $argDict = ['name' => 'rdlowrey'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $handler, $argDict];
 | 
			
		||||
 | 
			
		||||
        // 14 ---- Handle multiple methods with the same handler ---------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute(['GET', 'POST'], '/user', 'handlerGetPost');
 | 
			
		||||
            $r->addRoute(['DELETE'], '/user', 'handlerDelete');
 | 
			
		||||
            $r->addRoute([], '/user', 'handlerNone');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $argDict = [];
 | 
			
		||||
        $cases[] = ['GET', '/user', $callback, 'handlerGetPost', $argDict];
 | 
			
		||||
        $cases[] = ['POST', '/user', $callback, 'handlerGetPost', $argDict];
 | 
			
		||||
        $cases[] = ['DELETE', '/user', $callback, 'handlerDelete', $argDict];
 | 
			
		||||
 | 
			
		||||
        // 17 ----
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('POST', '/user.json', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/{entity}.json', 'handler1');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['GET', '/user.json', $callback, 'handler1', ['entity' => 'user']];
 | 
			
		||||
 | 
			
		||||
        // 18 ----
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '', 'handler0');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['GET', '', $callback, 'handler0', []];
 | 
			
		||||
 | 
			
		||||
        // 19 ----
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('HEAD', '/a/{foo}', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/b/{foo}', 'handler1');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['HEAD', '/b/bar', $callback, 'handler1', ['foo' => 'bar']];
 | 
			
		||||
 | 
			
		||||
        // 20 ----
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('HEAD', '/a', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/b', 'handler1');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['HEAD', '/b', $callback, 'handler1', []];
 | 
			
		||||
 | 
			
		||||
        // 21 ----
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/foo', 'handler0');
 | 
			
		||||
            $r->addRoute('HEAD', '/{bar}', 'handler1');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['HEAD', '/foo', $callback, 'handler1', ['bar' => 'foo']];
 | 
			
		||||
 | 
			
		||||
        // 22 ----
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('*', '/user', 'handler0');
 | 
			
		||||
            $r->addRoute('*', '/{user}', 'handler1');
 | 
			
		||||
            $r->addRoute('GET', '/user', 'handler2');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['GET', '/user', $callback, 'handler2', []];
 | 
			
		||||
 | 
			
		||||
        // 23 ----
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('*', '/user', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/user', 'handler1');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['POST', '/user', $callback, 'handler0', []];
 | 
			
		||||
 | 
			
		||||
        // 24 ----
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['HEAD', '/user', $callback, 'handler1', []];
 | 
			
		||||
 | 
			
		||||
        // 25 ----
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/{bar}', 'handler0');
 | 
			
		||||
            $r->addRoute('*', '/foo', 'handler1');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['GET', '/foo', $callback, 'handler0', ['bar' => 'foo']];
 | 
			
		||||
 | 
			
		||||
        // 26 ----
 | 
			
		||||
 | 
			
		||||
        $callback = function(RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user', 'handler0');
 | 
			
		||||
            $r->addRoute('*', '/{foo:.*}', 'handler1');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['POST', '/bar', $callback, 'handler1', ['foo' => 'bar']];
 | 
			
		||||
 | 
			
		||||
        // x -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        return $cases;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function provideNotFoundDispatchCases()
 | 
			
		||||
    {
 | 
			
		||||
        $cases = [];
 | 
			
		||||
 | 
			
		||||
        // 0 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/resource/123/456', 'handler0');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/not-found';
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback];
 | 
			
		||||
 | 
			
		||||
        // 1 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        // reuse callback from #0
 | 
			
		||||
        $method = 'POST';
 | 
			
		||||
        $uri = '/not-found';
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback];
 | 
			
		||||
 | 
			
		||||
        // 2 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        // reuse callback from #1
 | 
			
		||||
        $method = 'PUT';
 | 
			
		||||
        $uri = '/not-found';
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback];
 | 
			
		||||
 | 
			
		||||
        // 3 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/handler0', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/handler1', 'handler1');
 | 
			
		||||
            $r->addRoute('GET', '/handler2', 'handler2');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/not-found';
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback];
 | 
			
		||||
 | 
			
		||||
        // 4 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/user/{id:[0-9]+}', 'handler1');
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}', 'handler2');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/not-found';
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback];
 | 
			
		||||
 | 
			
		||||
        // 5 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        // reuse callback from #4
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/user/rdlowrey/12345/not-found';
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback];
 | 
			
		||||
 | 
			
		||||
        // 6 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        // reuse callback from #5
 | 
			
		||||
        $method = 'HEAD';
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback];
 | 
			
		||||
 | 
			
		||||
        // x -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        return $cases;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function provideMethodNotAllowedDispatchCases()
 | 
			
		||||
    {
 | 
			
		||||
        $cases = [];
 | 
			
		||||
 | 
			
		||||
        // 0 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/resource/123/456', 'handler0');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'POST';
 | 
			
		||||
        $uri = '/resource/123/456';
 | 
			
		||||
        $allowedMethods = ['GET'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $allowedMethods];
 | 
			
		||||
 | 
			
		||||
        // 1 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/resource/123/456', 'handler0');
 | 
			
		||||
            $r->addRoute('POST', '/resource/123/456', 'handler1');
 | 
			
		||||
            $r->addRoute('PUT', '/resource/123/456', 'handler2');
 | 
			
		||||
            $r->addRoute('*', '/', 'handler3');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'DELETE';
 | 
			
		||||
        $uri = '/resource/123/456';
 | 
			
		||||
        $allowedMethods = ['GET', 'POST', 'PUT'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $allowedMethods];
 | 
			
		||||
 | 
			
		||||
        // 2 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('GET', '/user/{name}/{id:[0-9]+}', 'handler0');
 | 
			
		||||
            $r->addRoute('POST', '/user/{name}/{id:[0-9]+}', 'handler1');
 | 
			
		||||
            $r->addRoute('PUT', '/user/{name}/{id:[0-9]+}', 'handler2');
 | 
			
		||||
            $r->addRoute('PATCH', '/user/{name}/{id:[0-9]+}', 'handler3');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'DELETE';
 | 
			
		||||
        $uri = '/user/rdlowrey/42';
 | 
			
		||||
        $allowedMethods = ['GET', 'POST', 'PUT', 'PATCH'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $allowedMethods];
 | 
			
		||||
 | 
			
		||||
        // 3 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('POST', '/user/{name}', 'handler1');
 | 
			
		||||
            $r->addRoute('PUT', '/user/{name:[a-z]+}', 'handler2');
 | 
			
		||||
            $r->addRoute('PATCH', '/user/{name:[a-z]+}', 'handler3');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $method = 'GET';
 | 
			
		||||
        $uri = '/user/rdlowrey';
 | 
			
		||||
        $allowedMethods = ['POST', 'PUT', 'PATCH'];
 | 
			
		||||
 | 
			
		||||
        $cases[] = [$method, $uri, $callback, $allowedMethods];
 | 
			
		||||
 | 
			
		||||
        // 4 -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute(['GET', 'POST'], '/user', 'handlerGetPost');
 | 
			
		||||
            $r->addRoute(['DELETE'], '/user', 'handlerDelete');
 | 
			
		||||
            $r->addRoute([], '/user', 'handlerNone');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['PUT', '/user', $callback, ['GET', 'POST', 'DELETE']];
 | 
			
		||||
 | 
			
		||||
        // 5
 | 
			
		||||
 | 
			
		||||
        $callback = function (RouteCollector $r) {
 | 
			
		||||
            $r->addRoute('POST', '/user.json', 'handler0');
 | 
			
		||||
            $r->addRoute('GET', '/{entity}.json', 'handler1');
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        $cases[] = ['PUT', '/user.json', $callback, ['POST', 'GET']];
 | 
			
		||||
 | 
			
		||||
        // x -------------------------------------------------------------------------------------->
 | 
			
		||||
 | 
			
		||||
        return $cases;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								qwen/php/vendor/nikic/fast-route/test/Dispatcher/GroupCountBasedTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								qwen/php/vendor/nikic/fast-route/test/Dispatcher/GroupCountBasedTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\Dispatcher;
 | 
			
		||||
 | 
			
		||||
class GroupCountBasedTest extends DispatcherTest
 | 
			
		||||
{
 | 
			
		||||
    protected function getDispatcherClass()
 | 
			
		||||
    {
 | 
			
		||||
        return 'FastRoute\\Dispatcher\\GroupCountBased';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function getDataGeneratorClass()
 | 
			
		||||
    {
 | 
			
		||||
        return 'FastRoute\\DataGenerator\\GroupCountBased';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								qwen/php/vendor/nikic/fast-route/test/Dispatcher/GroupPosBasedTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								qwen/php/vendor/nikic/fast-route/test/Dispatcher/GroupPosBasedTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\Dispatcher;
 | 
			
		||||
 | 
			
		||||
class GroupPosBasedTest extends DispatcherTest
 | 
			
		||||
{
 | 
			
		||||
    protected function getDispatcherClass()
 | 
			
		||||
    {
 | 
			
		||||
        return 'FastRoute\\Dispatcher\\GroupPosBased';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function getDataGeneratorClass()
 | 
			
		||||
    {
 | 
			
		||||
        return 'FastRoute\\DataGenerator\\GroupPosBased';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								qwen/php/vendor/nikic/fast-route/test/Dispatcher/MarkBasedTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								qwen/php/vendor/nikic/fast-route/test/Dispatcher/MarkBasedTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\Dispatcher;
 | 
			
		||||
 | 
			
		||||
class MarkBasedTest extends DispatcherTest
 | 
			
		||||
{
 | 
			
		||||
    public function setUp()
 | 
			
		||||
    {
 | 
			
		||||
        preg_match('/(*MARK:A)a/', 'a', $matches);
 | 
			
		||||
        if (!isset($matches['MARK'])) {
 | 
			
		||||
            $this->markTestSkipped('PHP 5.6 required for MARK support');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function getDispatcherClass()
 | 
			
		||||
    {
 | 
			
		||||
        return 'FastRoute\\Dispatcher\\MarkBased';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function getDataGeneratorClass()
 | 
			
		||||
    {
 | 
			
		||||
        return 'FastRoute\\DataGenerator\\MarkBased';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								qwen/php/vendor/nikic/fast-route/test/HackTypechecker/HackTypecheckerTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								qwen/php/vendor/nikic/fast-route/test/HackTypechecker/HackTypecheckerTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute;
 | 
			
		||||
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class HackTypecheckerTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    const SERVER_ALREADY_RUNNING_CODE = 77;
 | 
			
		||||
 | 
			
		||||
    public function testTypechecks($recurse = true)
 | 
			
		||||
    {
 | 
			
		||||
        if (!defined('HHVM_VERSION')) {
 | 
			
		||||
            $this->markTestSkipped('HHVM only');
 | 
			
		||||
        }
 | 
			
		||||
        if (!version_compare(HHVM_VERSION, '3.9.0', '>=')) {
 | 
			
		||||
          $this->markTestSkipped('classname<T> requires HHVM 3.9+');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // The typechecker recurses the whole tree, so it makes sure
 | 
			
		||||
        // that everything in fixtures/ is valid when this runs.
 | 
			
		||||
 | 
			
		||||
        $output = [];
 | 
			
		||||
        $exit_code = null;
 | 
			
		||||
        exec(
 | 
			
		||||
            'hh_server --check ' . escapeshellarg(__DIR__ . '/../../') . ' 2>&1',
 | 
			
		||||
            $output,
 | 
			
		||||
            $exit_code
 | 
			
		||||
        );
 | 
			
		||||
        if ($exit_code === self::SERVER_ALREADY_RUNNING_CODE) {
 | 
			
		||||
            $this->assertTrue(
 | 
			
		||||
              $recurse,
 | 
			
		||||
              'Typechecker still running after running hh_client stop'
 | 
			
		||||
            );
 | 
			
		||||
            // Server already running - 3.10 => 3.11 regression:
 | 
			
		||||
            // https://github.com/facebook/hhvm/issues/6646
 | 
			
		||||
            exec('hh_client stop 2>/dev/null');
 | 
			
		||||
            $this->testTypechecks(/* recurse = */ false);
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        $this->assertSame(0, $exit_code, implode("\n", $output));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								qwen/php/vendor/nikic/fast-route/test/HackTypechecker/fixtures/all_options.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								qwen/php/vendor/nikic/fast-route/test/HackTypechecker/fixtures/all_options.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
<?hh
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\TestFixtures;
 | 
			
		||||
 | 
			
		||||
function all_options_simple(): \FastRoute\Dispatcher {
 | 
			
		||||
    return \FastRoute\simpleDispatcher(
 | 
			
		||||
      $collector ==> {},
 | 
			
		||||
      shape(
 | 
			
		||||
        'routeParser' => \FastRoute\RouteParser\Std::class,
 | 
			
		||||
        'dataGenerator' => \FastRoute\DataGenerator\GroupCountBased::class,
 | 
			
		||||
        'dispatcher' => \FastRoute\Dispatcher\GroupCountBased::class,
 | 
			
		||||
        'routeCollector' => \FastRoute\RouteCollector::class,
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function all_options_cached(): \FastRoute\Dispatcher {
 | 
			
		||||
    return \FastRoute\cachedDispatcher(
 | 
			
		||||
      $collector ==> {},
 | 
			
		||||
      shape(
 | 
			
		||||
        'routeParser' => \FastRoute\RouteParser\Std::class,
 | 
			
		||||
        'dataGenerator' => \FastRoute\DataGenerator\GroupCountBased::class,
 | 
			
		||||
        'dispatcher' => \FastRoute\Dispatcher\GroupCountBased::class,
 | 
			
		||||
        'routeCollector' => \FastRoute\RouteCollector::class,
 | 
			
		||||
        'cacheFile' => '/dev/null',
 | 
			
		||||
        'cacheDisabled' => false,
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								qwen/php/vendor/nikic/fast-route/test/HackTypechecker/fixtures/empty_options.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								qwen/php/vendor/nikic/fast-route/test/HackTypechecker/fixtures/empty_options.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
<?hh
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\TestFixtures;
 | 
			
		||||
 | 
			
		||||
function empty_options_simple(): \FastRoute\Dispatcher {
 | 
			
		||||
    return \FastRoute\simpleDispatcher($collector ==> {}, shape());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function empty_options_cached(): \FastRoute\Dispatcher {
 | 
			
		||||
    return \FastRoute\cachedDispatcher($collector ==> {}, shape());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								qwen/php/vendor/nikic/fast-route/test/HackTypechecker/fixtures/no_options.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								qwen/php/vendor/nikic/fast-route/test/HackTypechecker/fixtures/no_options.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
<?hh
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\TestFixtures;
 | 
			
		||||
 | 
			
		||||
function no_options_simple(): \FastRoute\Dispatcher {
 | 
			
		||||
    return \FastRoute\simpleDispatcher($collector ==> {});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function no_options_cached(): \FastRoute\Dispatcher {
 | 
			
		||||
    return \FastRoute\cachedDispatcher($collector ==> {});
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										108
									
								
								qwen/php/vendor/nikic/fast-route/test/RouteCollectorTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								qwen/php/vendor/nikic/fast-route/test/RouteCollectorTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute;
 | 
			
		||||
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class RouteCollectorTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    public function testShortcuts()
 | 
			
		||||
    {
 | 
			
		||||
        $r = new DummyRouteCollector();
 | 
			
		||||
 | 
			
		||||
        $r->delete('/delete', 'delete');
 | 
			
		||||
        $r->get('/get', 'get');
 | 
			
		||||
        $r->head('/head', 'head');
 | 
			
		||||
        $r->patch('/patch', 'patch');
 | 
			
		||||
        $r->post('/post', 'post');
 | 
			
		||||
        $r->put('/put', 'put');
 | 
			
		||||
 | 
			
		||||
        $expected = [
 | 
			
		||||
            ['DELETE', '/delete', 'delete'],
 | 
			
		||||
            ['GET', '/get', 'get'],
 | 
			
		||||
            ['HEAD', '/head', 'head'],
 | 
			
		||||
            ['PATCH', '/patch', 'patch'],
 | 
			
		||||
            ['POST', '/post', 'post'],
 | 
			
		||||
            ['PUT', '/put', 'put'],
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        $this->assertSame($expected, $r->routes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testGroups()
 | 
			
		||||
    {
 | 
			
		||||
        $r = new DummyRouteCollector();
 | 
			
		||||
 | 
			
		||||
        $r->delete('/delete', 'delete');
 | 
			
		||||
        $r->get('/get', 'get');
 | 
			
		||||
        $r->head('/head', 'head');
 | 
			
		||||
        $r->patch('/patch', 'patch');
 | 
			
		||||
        $r->post('/post', 'post');
 | 
			
		||||
        $r->put('/put', 'put');
 | 
			
		||||
 | 
			
		||||
        $r->addGroup('/group-one', function (DummyRouteCollector $r) {
 | 
			
		||||
            $r->delete('/delete', 'delete');
 | 
			
		||||
            $r->get('/get', 'get');
 | 
			
		||||
            $r->head('/head', 'head');
 | 
			
		||||
            $r->patch('/patch', 'patch');
 | 
			
		||||
            $r->post('/post', 'post');
 | 
			
		||||
            $r->put('/put', 'put');
 | 
			
		||||
 | 
			
		||||
            $r->addGroup('/group-two', function (DummyRouteCollector $r) {
 | 
			
		||||
                $r->delete('/delete', 'delete');
 | 
			
		||||
                $r->get('/get', 'get');
 | 
			
		||||
                $r->head('/head', 'head');
 | 
			
		||||
                $r->patch('/patch', 'patch');
 | 
			
		||||
                $r->post('/post', 'post');
 | 
			
		||||
                $r->put('/put', 'put');
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $r->addGroup('/admin', function (DummyRouteCollector $r) {
 | 
			
		||||
            $r->get('-some-info', 'admin-some-info');
 | 
			
		||||
        });
 | 
			
		||||
        $r->addGroup('/admin-', function (DummyRouteCollector $r) {
 | 
			
		||||
            $r->get('more-info', 'admin-more-info');
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $expected = [
 | 
			
		||||
            ['DELETE', '/delete', 'delete'],
 | 
			
		||||
            ['GET', '/get', 'get'],
 | 
			
		||||
            ['HEAD', '/head', 'head'],
 | 
			
		||||
            ['PATCH', '/patch', 'patch'],
 | 
			
		||||
            ['POST', '/post', 'post'],
 | 
			
		||||
            ['PUT', '/put', 'put'],
 | 
			
		||||
            ['DELETE', '/group-one/delete', 'delete'],
 | 
			
		||||
            ['GET', '/group-one/get', 'get'],
 | 
			
		||||
            ['HEAD', '/group-one/head', 'head'],
 | 
			
		||||
            ['PATCH', '/group-one/patch', 'patch'],
 | 
			
		||||
            ['POST', '/group-one/post', 'post'],
 | 
			
		||||
            ['PUT', '/group-one/put', 'put'],
 | 
			
		||||
            ['DELETE', '/group-one/group-two/delete', 'delete'],
 | 
			
		||||
            ['GET', '/group-one/group-two/get', 'get'],
 | 
			
		||||
            ['HEAD', '/group-one/group-two/head', 'head'],
 | 
			
		||||
            ['PATCH', '/group-one/group-two/patch', 'patch'],
 | 
			
		||||
            ['POST', '/group-one/group-two/post', 'post'],
 | 
			
		||||
            ['PUT', '/group-one/group-two/put', 'put'],
 | 
			
		||||
            ['GET', '/admin-some-info', 'admin-some-info'],
 | 
			
		||||
            ['GET', '/admin-more-info', 'admin-more-info'],
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        $this->assertSame($expected, $r->routes);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class DummyRouteCollector extends RouteCollector
 | 
			
		||||
{
 | 
			
		||||
    public $routes = [];
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function addRoute($method, $route, $handler)
 | 
			
		||||
    {
 | 
			
		||||
        $route = $this->currentGroupPrefix . $route;
 | 
			
		||||
        $this->routes[] = [$method, $route, $handler];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										154
									
								
								qwen/php/vendor/nikic/fast-route/test/RouteParser/StdTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								qwen/php/vendor/nikic/fast-route/test/RouteParser/StdTest.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace FastRoute\RouteParser;
 | 
			
		||||
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class StdTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /** @dataProvider provideTestParse */
 | 
			
		||||
    public function testParse($routeString, $expectedRouteDatas)
 | 
			
		||||
    {
 | 
			
		||||
        $parser = new Std();
 | 
			
		||||
        $routeDatas = $parser->parse($routeString);
 | 
			
		||||
        $this->assertSame($expectedRouteDatas, $routeDatas);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @dataProvider provideTestParseError */
 | 
			
		||||
    public function testParseError($routeString, $expectedExceptionMessage)
 | 
			
		||||
    {
 | 
			
		||||
        $parser = new Std();
 | 
			
		||||
        $this->setExpectedException('FastRoute\\BadRouteException', $expectedExceptionMessage);
 | 
			
		||||
        $parser->parse($routeString);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function provideTestParse()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            [
 | 
			
		||||
                '/test',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/test'],
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/test/{param}',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/test/', ['param', '[^/]+']],
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/te{ param }st',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/te', ['param', '[^/]+'], 'st']
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/test/{param1}/test2/{param2}',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/test/', ['param1', '[^/]+'], '/test2/', ['param2', '[^/]+']]
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/test/{param:\d+}',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/test/', ['param', '\d+']]
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/test/{ param : \d{1,9} }',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/test/', ['param', '\d{1,9}']]
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/test[opt]',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/test'],
 | 
			
		||||
                    ['/testopt'],
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/test[/{param}]',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/test'],
 | 
			
		||||
                    ['/test/', ['param', '[^/]+']],
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/{param}[opt]',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/', ['param', '[^/]+']],
 | 
			
		||||
                    ['/', ['param', '[^/]+'], 'opt']
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/test[/{name}[/{id:[0-9]+}]]',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/test'],
 | 
			
		||||
                    ['/test/', ['name', '[^/]+']],
 | 
			
		||||
                    ['/test/', ['name', '[^/]+'], '/', ['id', '[0-9]+']],
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '',
 | 
			
		||||
                [
 | 
			
		||||
                    [''],
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '[test]',
 | 
			
		||||
                [
 | 
			
		||||
                    [''],
 | 
			
		||||
                    ['test'],
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/{foo-bar}',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/', ['foo-bar', '[^/]+']]
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/{_foo:.*}',
 | 
			
		||||
                [
 | 
			
		||||
                    ['/', ['_foo', '.*']]
 | 
			
		||||
                ]
 | 
			
		||||
            ],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function provideTestParseError()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            [
 | 
			
		||||
                '/test[opt',
 | 
			
		||||
                "Number of opening '[' and closing ']' does not match"
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/test[opt[opt2]',
 | 
			
		||||
                "Number of opening '[' and closing ']' does not match"
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/testopt]',
 | 
			
		||||
                "Number of opening '[' and closing ']' does not match"
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/test[]',
 | 
			
		||||
                'Empty optional part'
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/test[[opt]]',
 | 
			
		||||
                'Empty optional part'
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '[[test]]',
 | 
			
		||||
                'Empty optional part'
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                '/test[/opt]/required',
 | 
			
		||||
                'Optional segments can only occur at the end of a route'
 | 
			
		||||
            ],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								qwen/php/vendor/nikic/fast-route/test/bootstrap.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								qwen/php/vendor/nikic/fast-route/test/bootstrap.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
require_once __DIR__ . '/../src/functions.php';
 | 
			
		||||
 | 
			
		||||
spl_autoload_register(function ($class) {
 | 
			
		||||
    if (strpos($class, 'FastRoute\\') === 0) {
 | 
			
		||||
        $dir = strcasecmp(substr($class, -4), 'Test') ? 'src/' : 'test/';
 | 
			
		||||
        $name = substr($class, strlen('FastRoute'));
 | 
			
		||||
        require __DIR__ . '/../' . $dir . strtr($name, '\\', DIRECTORY_SEPARATOR) . '.php';
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										29
									
								
								qwen/php/vendor/nikic/php-parser/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								qwen/php/vendor/nikic/php-parser/LICENSE
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
BSD 3-Clause License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2011, Nikita Popov
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
1. Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
3. Neither the name of the copyright holder nor the names of its
 | 
			
		||||
   contributors may be used to endorse or promote products derived from
 | 
			
		||||
   this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
							
								
								
									
										233
									
								
								qwen/php/vendor/nikic/php-parser/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								qwen/php/vendor/nikic/php-parser/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,233 @@
 | 
			
		||||
PHP Parser
 | 
			
		||||
==========
 | 
			
		||||
 | 
			
		||||
[](https://coveralls.io/github/nikic/PHP-Parser?branch=master)
 | 
			
		||||
 | 
			
		||||
This is a PHP parser written in PHP. Its purpose is to simplify static code analysis and
 | 
			
		||||
manipulation.
 | 
			
		||||
 | 
			
		||||
[**Documentation for version 5.x**][doc_master] (current; for running on PHP >= 7.4; for parsing PHP 7.0 to PHP 8.4, with limited support for parsing PHP 5.x).
 | 
			
		||||
 | 
			
		||||
[Documentation for version 4.x][doc_4_x] (supported; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 8.3).
 | 
			
		||||
 | 
			
		||||
Features
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
The main features provided by this library are:
 | 
			
		||||
 | 
			
		||||
 * Parsing PHP 7, and PHP 8 code into an abstract syntax tree (AST).
 | 
			
		||||
   * Invalid code can be parsed into a partial AST.
 | 
			
		||||
   * The AST contains accurate location information.
 | 
			
		||||
 * Dumping the AST in human-readable form.
 | 
			
		||||
 * Converting an AST back to PHP code.
 | 
			
		||||
   * Formatting can be preserved for partially changed ASTs.
 | 
			
		||||
 * Infrastructure to traverse and modify ASTs.
 | 
			
		||||
 * Resolution of namespaced names.
 | 
			
		||||
 * Evaluation of constant expressions.
 | 
			
		||||
 * Builders to simplify AST construction for code generation.
 | 
			
		||||
 * Converting an AST into JSON and back.
 | 
			
		||||
 | 
			
		||||
Quick Start
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Install the library using [composer](https://getcomposer.org):
 | 
			
		||||
 | 
			
		||||
    php composer.phar require nikic/php-parser
 | 
			
		||||
 | 
			
		||||
Parse some PHP code into an AST and dump the result in human-readable form:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
use PhpParser\Error;
 | 
			
		||||
use PhpParser\NodeDumper;
 | 
			
		||||
use PhpParser\ParserFactory;
 | 
			
		||||
 | 
			
		||||
$code = <<<'CODE'
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
function test($foo)
 | 
			
		||||
{
 | 
			
		||||
    var_dump($foo);
 | 
			
		||||
}
 | 
			
		||||
CODE;
 | 
			
		||||
 | 
			
		||||
$parser = (new ParserFactory())->createForNewestSupportedVersion();
 | 
			
		||||
try {
 | 
			
		||||
    $ast = $parser->parse($code);
 | 
			
		||||
} catch (Error $error) {
 | 
			
		||||
    echo "Parse error: {$error->getMessage()}\n";
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$dumper = new NodeDumper;
 | 
			
		||||
echo $dumper->dump($ast) . "\n";
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This dumps an AST looking something like this:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
array(
 | 
			
		||||
    0: Stmt_Function(
 | 
			
		||||
        attrGroups: array(
 | 
			
		||||
        )
 | 
			
		||||
        byRef: false
 | 
			
		||||
        name: Identifier(
 | 
			
		||||
            name: test
 | 
			
		||||
        )
 | 
			
		||||
        params: array(
 | 
			
		||||
            0: Param(
 | 
			
		||||
                attrGroups: array(
 | 
			
		||||
                )
 | 
			
		||||
                flags: 0
 | 
			
		||||
                type: null
 | 
			
		||||
                byRef: false
 | 
			
		||||
                variadic: false
 | 
			
		||||
                var: Expr_Variable(
 | 
			
		||||
                    name: foo
 | 
			
		||||
                )
 | 
			
		||||
                default: null
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        returnType: null
 | 
			
		||||
        stmts: array(
 | 
			
		||||
            0: Stmt_Expression(
 | 
			
		||||
                expr: Expr_FuncCall(
 | 
			
		||||
                    name: Name(
 | 
			
		||||
                        name: var_dump
 | 
			
		||||
                    )
 | 
			
		||||
                    args: array(
 | 
			
		||||
                        0: Arg(
 | 
			
		||||
                            name: null
 | 
			
		||||
                            value: Expr_Variable(
 | 
			
		||||
                                name: foo
 | 
			
		||||
                            )
 | 
			
		||||
                            byRef: false
 | 
			
		||||
                            unpack: false
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Let's traverse the AST and perform some kind of modification. For example, drop all function bodies:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Stmt\Function_;
 | 
			
		||||
use PhpParser\NodeTraverser;
 | 
			
		||||
use PhpParser\NodeVisitorAbstract;
 | 
			
		||||
 | 
			
		||||
$traverser = new NodeTraverser();
 | 
			
		||||
$traverser->addVisitor(new class extends NodeVisitorAbstract {
 | 
			
		||||
    public function enterNode(Node $node) {
 | 
			
		||||
        if ($node instanceof Function_) {
 | 
			
		||||
            // Clean out the function body
 | 
			
		||||
            $node->stmts = [];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
$ast = $traverser->traverse($ast);
 | 
			
		||||
echo $dumper->dump($ast) . "\n";
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This gives us an AST where the `Function_::$stmts` are empty:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
array(
 | 
			
		||||
    0: Stmt_Function(
 | 
			
		||||
        attrGroups: array(
 | 
			
		||||
        )
 | 
			
		||||
        byRef: false
 | 
			
		||||
        name: Identifier(
 | 
			
		||||
            name: test
 | 
			
		||||
        )
 | 
			
		||||
        params: array(
 | 
			
		||||
            0: Param(
 | 
			
		||||
                attrGroups: array(
 | 
			
		||||
                )
 | 
			
		||||
                type: null
 | 
			
		||||
                byRef: false
 | 
			
		||||
                variadic: false
 | 
			
		||||
                var: Expr_Variable(
 | 
			
		||||
                    name: foo
 | 
			
		||||
                )
 | 
			
		||||
                default: null
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        returnType: null
 | 
			
		||||
        stmts: array(
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Finally, we can convert the new AST back to PHP code:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
use PhpParser\PrettyPrinter;
 | 
			
		||||
 | 
			
		||||
$prettyPrinter = new PrettyPrinter\Standard;
 | 
			
		||||
echo $prettyPrinter->prettyPrintFile($ast);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This gives us our original code, minus the `var_dump()` call inside the function:
 | 
			
		||||
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
function test($foo)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For a more comprehensive introduction, see the documentation.
 | 
			
		||||
 | 
			
		||||
Documentation
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
 1. [Introduction](doc/0_Introduction.markdown)
 | 
			
		||||
 2. [Usage of basic components](doc/2_Usage_of_basic_components.markdown)
 | 
			
		||||
 | 
			
		||||
Component documentation:
 | 
			
		||||
 | 
			
		||||
 * [Walking the AST](doc/component/Walking_the_AST.markdown)
 | 
			
		||||
   * Node visitors
 | 
			
		||||
   * Modifying the AST from a visitor
 | 
			
		||||
   * Short-circuiting traversals
 | 
			
		||||
   * Interleaved visitors
 | 
			
		||||
   * Simple node finding API
 | 
			
		||||
   * Parent and sibling references
 | 
			
		||||
 * [Name resolution](doc/component/Name_resolution.markdown)
 | 
			
		||||
   * Name resolver options
 | 
			
		||||
   * Name resolution context
 | 
			
		||||
 * [Pretty printing](doc/component/Pretty_printing.markdown)
 | 
			
		||||
   * Converting AST back to PHP code
 | 
			
		||||
   * Customizing formatting
 | 
			
		||||
   * Formatting-preserving code transformations
 | 
			
		||||
 * [AST builders](doc/component/AST_builders.markdown)
 | 
			
		||||
   * Fluent builders for AST nodes
 | 
			
		||||
 * [Lexer](doc/component/Lexer.markdown)
 | 
			
		||||
   * Emulation
 | 
			
		||||
   * Tokens, positions and attributes
 | 
			
		||||
 * [Error handling](doc/component/Error_handling.markdown)
 | 
			
		||||
   * Column information for errors
 | 
			
		||||
   * Error recovery (parsing of syntactically incorrect code)
 | 
			
		||||
 * [Constant expression evaluation](doc/component/Constant_expression_evaluation.markdown)
 | 
			
		||||
   * Evaluating constant/property/etc initializers
 | 
			
		||||
   * Handling errors and unsupported expressions
 | 
			
		||||
 * [JSON representation](doc/component/JSON_representation.markdown)
 | 
			
		||||
   * JSON encoding and decoding of ASTs
 | 
			
		||||
 * [Performance](doc/component/Performance.markdown)
 | 
			
		||||
   * Disabling Xdebug
 | 
			
		||||
   * Reusing objects
 | 
			
		||||
   * Garbage collection impact
 | 
			
		||||
 * [Frequently asked questions](doc/component/FAQ.markdown)
 | 
			
		||||
   * Parent and sibling references
 | 
			
		||||
 | 
			
		||||
 [doc_3_x]: https://github.com/nikic/PHP-Parser/tree/3.x/doc
 | 
			
		||||
 [doc_4_x]: https://github.com/nikic/PHP-Parser/tree/4.x/doc
 | 
			
		||||
 [doc_master]: https://github.com/nikic/PHP-Parser/tree/master/doc
 | 
			
		||||
							
								
								
									
										206
									
								
								qwen/php/vendor/nikic/php-parser/bin/php-parse
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										206
									
								
								qwen/php/vendor/nikic/php-parser/bin/php-parse
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,206 @@
 | 
			
		||||
#!/usr/bin/env php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
foreach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php'] as $file) {
 | 
			
		||||
    if (file_exists($file)) {
 | 
			
		||||
        require $file;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ini_set('xdebug.max_nesting_level', 3000);
 | 
			
		||||
 | 
			
		||||
// Disable Xdebug var_dump() output truncation
 | 
			
		||||
ini_set('xdebug.var_display_max_children', -1);
 | 
			
		||||
ini_set('xdebug.var_display_max_data', -1);
 | 
			
		||||
ini_set('xdebug.var_display_max_depth', -1);
 | 
			
		||||
 | 
			
		||||
list($operations, $files, $attributes) = parseArgs($argv);
 | 
			
		||||
 | 
			
		||||
/* Dump nodes by default */
 | 
			
		||||
if (empty($operations)) {
 | 
			
		||||
    $operations[] = 'dump';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (empty($files)) {
 | 
			
		||||
    showHelp("Must specify at least one file.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$parser = (new PhpParser\ParserFactory())->createForVersion($attributes['version']);
 | 
			
		||||
$dumper = new PhpParser\NodeDumper([
 | 
			
		||||
    'dumpComments' => true,
 | 
			
		||||
    'dumpPositions' => $attributes['with-positions'],
 | 
			
		||||
]);
 | 
			
		||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
 | 
			
		||||
 | 
			
		||||
$traverser = new PhpParser\NodeTraverser();
 | 
			
		||||
$traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver);
 | 
			
		||||
 | 
			
		||||
foreach ($files as $file) {
 | 
			
		||||
    if ($file === '-') {
 | 
			
		||||
        $code = file_get_contents('php://stdin');
 | 
			
		||||
        fwrite(STDERR, "====> Stdin:\n");
 | 
			
		||||
    } else if (strpos($file, '<?php') === 0) {
 | 
			
		||||
        $code = $file;
 | 
			
		||||
        fwrite(STDERR, "====> Code $code\n");
 | 
			
		||||
    } else {
 | 
			
		||||
        if (!file_exists($file)) {
 | 
			
		||||
            fwrite(STDERR, "File $file does not exist.\n");
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $code = file_get_contents($file);
 | 
			
		||||
        fwrite(STDERR, "====> File $file:\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ($attributes['with-recovery']) {
 | 
			
		||||
        $errorHandler = new PhpParser\ErrorHandler\Collecting;
 | 
			
		||||
        $stmts = $parser->parse($code, $errorHandler);
 | 
			
		||||
        foreach ($errorHandler->getErrors() as $error) {
 | 
			
		||||
            $message = formatErrorMessage($error, $code, $attributes['with-column-info']);
 | 
			
		||||
            fwrite(STDERR, $message . "\n");
 | 
			
		||||
        }
 | 
			
		||||
        if (null === $stmts) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        try {
 | 
			
		||||
            $stmts = $parser->parse($code);
 | 
			
		||||
        } catch (PhpParser\Error $error) {
 | 
			
		||||
            $message = formatErrorMessage($error, $code, $attributes['with-column-info']);
 | 
			
		||||
            fwrite(STDERR, $message . "\n");
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    foreach ($operations as $operation) {
 | 
			
		||||
        if ('dump' === $operation) {
 | 
			
		||||
            fwrite(STDERR, "==> Node dump:\n");
 | 
			
		||||
            echo $dumper->dump($stmts, $code), "\n";
 | 
			
		||||
        } elseif ('pretty-print' === $operation) {
 | 
			
		||||
            fwrite(STDERR, "==> Pretty print:\n");
 | 
			
		||||
            echo $prettyPrinter->prettyPrintFile($stmts), "\n";
 | 
			
		||||
        } elseif ('json-dump' === $operation) {
 | 
			
		||||
            fwrite(STDERR, "==> JSON dump:\n");
 | 
			
		||||
            echo json_encode($stmts, JSON_PRETTY_PRINT), "\n";
 | 
			
		||||
        } elseif ('var-dump' === $operation) {
 | 
			
		||||
            fwrite(STDERR, "==> var_dump():\n");
 | 
			
		||||
            var_dump($stmts);
 | 
			
		||||
        } elseif ('resolve-names' === $operation) {
 | 
			
		||||
            fwrite(STDERR, "==> Resolved names.\n");
 | 
			
		||||
            $stmts = $traverser->traverse($stmts);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function formatErrorMessage(PhpParser\Error $e, $code, $withColumnInfo) {
 | 
			
		||||
    if ($withColumnInfo && $e->hasColumnInfo()) {
 | 
			
		||||
        return $e->getMessageWithColumnInfo($code);
 | 
			
		||||
    } else {
 | 
			
		||||
        return $e->getMessage();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showHelp($error = '') {
 | 
			
		||||
    if ($error) {
 | 
			
		||||
        fwrite(STDERR, $error . "\n\n");
 | 
			
		||||
    }
 | 
			
		||||
    fwrite($error ? STDERR : STDOUT, <<<'OUTPUT'
 | 
			
		||||
Usage: php-parse [operations] file1.php [file2.php ...]
 | 
			
		||||
   or: php-parse [operations] "<?php code"
 | 
			
		||||
Turn PHP source code into an abstract syntax tree.
 | 
			
		||||
 | 
			
		||||
Operations is a list of the following options (--dump by default):
 | 
			
		||||
 | 
			
		||||
    -d, --dump              Dump nodes using NodeDumper
 | 
			
		||||
    -p, --pretty-print      Pretty print file using PrettyPrinter\Standard
 | 
			
		||||
    -j, --json-dump         Print json_encode() result
 | 
			
		||||
        --var-dump          var_dump() nodes (for exact structure)
 | 
			
		||||
    -N, --resolve-names     Resolve names using NodeVisitor\NameResolver
 | 
			
		||||
    -c, --with-column-info  Show column-numbers for errors (if available)
 | 
			
		||||
    -P, --with-positions    Show positions in node dumps
 | 
			
		||||
    -r, --with-recovery     Use parsing with error recovery
 | 
			
		||||
        --version=VERSION   Target specific PHP version (default: newest)
 | 
			
		||||
    -h, --help              Display this page
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
    php-parse -d -p -N -d file.php
 | 
			
		||||
 | 
			
		||||
    Dumps nodes, pretty prints them, then resolves names and dumps them again.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
OUTPUT
 | 
			
		||||
    );
 | 
			
		||||
    exit($error ? 1 : 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function parseArgs($args) {
 | 
			
		||||
    $operations = [];
 | 
			
		||||
    $files = [];
 | 
			
		||||
    $attributes = [
 | 
			
		||||
        'with-column-info' => false,
 | 
			
		||||
        'with-positions' => false,
 | 
			
		||||
        'with-recovery' => false,
 | 
			
		||||
        'version' => PhpParser\PhpVersion::getNewestSupported(),
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    array_shift($args);
 | 
			
		||||
    $parseOptions = true;
 | 
			
		||||
    foreach ($args as $arg) {
 | 
			
		||||
        if (!$parseOptions) {
 | 
			
		||||
            $files[] = $arg;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch ($arg) {
 | 
			
		||||
            case '--dump':
 | 
			
		||||
            case '-d':
 | 
			
		||||
                $operations[] = 'dump';
 | 
			
		||||
                break;
 | 
			
		||||
            case '--pretty-print':
 | 
			
		||||
            case '-p':
 | 
			
		||||
                $operations[] = 'pretty-print';
 | 
			
		||||
                break;
 | 
			
		||||
            case '--json-dump':
 | 
			
		||||
            case '-j':
 | 
			
		||||
                $operations[] = 'json-dump';
 | 
			
		||||
                break;
 | 
			
		||||
            case '--var-dump':
 | 
			
		||||
                $operations[] = 'var-dump';
 | 
			
		||||
                break;
 | 
			
		||||
            case '--resolve-names':
 | 
			
		||||
            case '-N';
 | 
			
		||||
                $operations[] = 'resolve-names';
 | 
			
		||||
                break;
 | 
			
		||||
            case '--with-column-info':
 | 
			
		||||
            case '-c';
 | 
			
		||||
                $attributes['with-column-info'] = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case '--with-positions':
 | 
			
		||||
            case '-P':
 | 
			
		||||
                $attributes['with-positions'] = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case '--with-recovery':
 | 
			
		||||
            case '-r':
 | 
			
		||||
                $attributes['with-recovery'] = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case '--help':
 | 
			
		||||
            case '-h';
 | 
			
		||||
                showHelp();
 | 
			
		||||
                break;
 | 
			
		||||
            case '--':
 | 
			
		||||
                $parseOptions = false;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                if (preg_match('/^--version=(.*)$/', $arg, $matches)) {
 | 
			
		||||
                    $attributes['version'] = PhpParser\PhpVersion::fromString($matches[1]);
 | 
			
		||||
                } elseif ($arg[0] === '-' && \strlen($arg[0]) > 1) {
 | 
			
		||||
                    showHelp("Invalid operation $arg.");
 | 
			
		||||
                } else {
 | 
			
		||||
                    $files[] = $arg;
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return [$operations, $files, $attributes];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								qwen/php/vendor/nikic/php-parser/composer.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								qwen/php/vendor/nikic/php-parser/composer.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "nikic/php-parser",
 | 
			
		||||
    "type": "library",
 | 
			
		||||
    "description": "A PHP parser written in PHP",
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "php",
 | 
			
		||||
        "parser"
 | 
			
		||||
    ],
 | 
			
		||||
    "license": "BSD-3-Clause",
 | 
			
		||||
    "authors": [
 | 
			
		||||
        {
 | 
			
		||||
            "name": "Nikita Popov"
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "require": {
 | 
			
		||||
        "php": ">=7.4",
 | 
			
		||||
        "ext-tokenizer": "*",
 | 
			
		||||
        "ext-json": "*",
 | 
			
		||||
        "ext-ctype": "*"
 | 
			
		||||
    },
 | 
			
		||||
    "require-dev": {
 | 
			
		||||
        "phpunit/phpunit": "^9.0",
 | 
			
		||||
        "ircmaxell/php-yacc": "^0.0.7"
 | 
			
		||||
    },
 | 
			
		||||
    "extra": {
 | 
			
		||||
        "branch-alias": {
 | 
			
		||||
            "dev-master": "5.x-dev"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "autoload": {
 | 
			
		||||
        "psr-4": {
 | 
			
		||||
            "PhpParser\\": "lib/PhpParser"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "autoload-dev": {
 | 
			
		||||
        "psr-4": {
 | 
			
		||||
            "PhpParser\\": "test/PhpParser/"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "bin": [
 | 
			
		||||
        "bin/php-parse"
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
interface Builder {
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Node The built node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): Node;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										150
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/ClassConst.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/ClassConst.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Modifiers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Const_;
 | 
			
		||||
use PhpParser\Node\Identifier;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class ClassConst implements PhpParser\Builder {
 | 
			
		||||
    protected int $flags = 0;
 | 
			
		||||
    /** @var array<string, mixed> */
 | 
			
		||||
    protected array $attributes = [];
 | 
			
		||||
    /** @var list<Const_> */
 | 
			
		||||
    protected array $constants = [];
 | 
			
		||||
 | 
			
		||||
    /** @var list<Node\AttributeGroup> */
 | 
			
		||||
    protected array $attributeGroups = [];
 | 
			
		||||
    /** @var Identifier|Node\Name|Node\ComplexType|null */
 | 
			
		||||
    protected ?Node $type = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a class constant builder
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Identifier $name Name
 | 
			
		||||
     * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value Value
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($name, $value) {
 | 
			
		||||
        $this->constants = [new Const_($name, BuilderHelpers::normalizeValue($value))];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add another constant to const group
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Identifier $name Name
 | 
			
		||||
     * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value Value
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addConst($name, $value) {
 | 
			
		||||
        $this->constants[] = new Const_($name, BuilderHelpers::normalizeValue($value));
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the constant public.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePublic() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the constant protected.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeProtected() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the constant private.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePrivate() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the constant final.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeFinal() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets doc comment for the constant.
 | 
			
		||||
     *
 | 
			
		||||
     * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function setDocComment($docComment) {
 | 
			
		||||
        $this->attributes = [
 | 
			
		||||
            'comments' => [BuilderHelpers::normalizeDocComment($docComment)]
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds an attribute group.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Attribute|Node\AttributeGroup $attribute
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addAttribute($attribute) {
 | 
			
		||||
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the constant type.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Node\Name|Identifier|Node\ComplexType $type
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setType($type) {
 | 
			
		||||
        $this->type = BuilderHelpers::normalizeType($type);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built class node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt\ClassConst The built constant node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): PhpParser\Node {
 | 
			
		||||
        return new Stmt\ClassConst(
 | 
			
		||||
            $this->constants,
 | 
			
		||||
            $this->flags,
 | 
			
		||||
            $this->attributes,
 | 
			
		||||
            $this->attributeGroups,
 | 
			
		||||
            $this->type
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										151
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Class_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Class_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Modifiers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Name;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class Class_ extends Declaration {
 | 
			
		||||
    protected string $name;
 | 
			
		||||
    protected ?Name $extends = null;
 | 
			
		||||
    /** @var list<Name> */
 | 
			
		||||
    protected array $implements = [];
 | 
			
		||||
    protected int $flags = 0;
 | 
			
		||||
    /** @var list<Stmt\TraitUse> */
 | 
			
		||||
    protected array $uses = [];
 | 
			
		||||
    /** @var list<Stmt\ClassConst> */
 | 
			
		||||
    protected array $constants = [];
 | 
			
		||||
    /** @var list<Stmt\Property> */
 | 
			
		||||
    protected array $properties = [];
 | 
			
		||||
    /** @var list<Stmt\ClassMethod> */
 | 
			
		||||
    protected array $methods = [];
 | 
			
		||||
    /** @var list<Node\AttributeGroup> */
 | 
			
		||||
    protected array $attributeGroups = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a class builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the class
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(string $name) {
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Extends a class.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Name|string $class Name of class to extend
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function extend($class) {
 | 
			
		||||
        $this->extends = BuilderHelpers::normalizeName($class);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Implements one or more interfaces.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Name|string ...$interfaces Names of interfaces to implement
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function implement(...$interfaces) {
 | 
			
		||||
        foreach ($interfaces as $interface) {
 | 
			
		||||
            $this->implements[] = BuilderHelpers::normalizeName($interface);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the class abstract.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeAbstract() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::ABSTRACT);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the class final.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeFinal() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::FINAL);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the class readonly.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeReadonly() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addClassModifier($this->flags, Modifiers::READONLY);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a statement.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Stmt|PhpParser\Builder $stmt The statement to add
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addStmt($stmt) {
 | 
			
		||||
        $stmt = BuilderHelpers::normalizeNode($stmt);
 | 
			
		||||
 | 
			
		||||
        if ($stmt instanceof Stmt\Property) {
 | 
			
		||||
            $this->properties[] = $stmt;
 | 
			
		||||
        } elseif ($stmt instanceof Stmt\ClassMethod) {
 | 
			
		||||
            $this->methods[] = $stmt;
 | 
			
		||||
        } elseif ($stmt instanceof Stmt\TraitUse) {
 | 
			
		||||
            $this->uses[] = $stmt;
 | 
			
		||||
        } elseif ($stmt instanceof Stmt\ClassConst) {
 | 
			
		||||
            $this->constants[] = $stmt;
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds an attribute group.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Attribute|Node\AttributeGroup $attribute
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addAttribute($attribute) {
 | 
			
		||||
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built class node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt\Class_ The built class node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): PhpParser\Node {
 | 
			
		||||
        return new Stmt\Class_($this->name, [
 | 
			
		||||
            'flags' => $this->flags,
 | 
			
		||||
            'extends' => $this->extends,
 | 
			
		||||
            'implements' => $this->implements,
 | 
			
		||||
            'stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods),
 | 
			
		||||
            'attrGroups' => $this->attributeGroups,
 | 
			
		||||
        ], $this->attributes);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
 | 
			
		||||
abstract class Declaration implements PhpParser\Builder {
 | 
			
		||||
    /** @var array<string, mixed> */
 | 
			
		||||
    protected array $attributes = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a statement.
 | 
			
		||||
     *
 | 
			
		||||
     * @param PhpParser\Node\Stmt|PhpParser\Builder $stmt The statement to add
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    abstract public function addStmt($stmt);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds multiple statements.
 | 
			
		||||
     *
 | 
			
		||||
     * @param (PhpParser\Node\Stmt|PhpParser\Builder)[] $stmts The statements to add
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addStmts(array $stmts) {
 | 
			
		||||
        foreach ($stmts as $stmt) {
 | 
			
		||||
            $this->addStmt($stmt);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets doc comment for the declaration.
 | 
			
		||||
     *
 | 
			
		||||
     * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function setDocComment($docComment) {
 | 
			
		||||
        $this->attributes['comments'] = [
 | 
			
		||||
            BuilderHelpers::normalizeDocComment($docComment)
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Identifier;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class EnumCase implements PhpParser\Builder {
 | 
			
		||||
    /** @var Identifier|string */
 | 
			
		||||
    protected $name;
 | 
			
		||||
    protected ?Node\Expr $value = null;
 | 
			
		||||
    /** @var array<string, mixed> */
 | 
			
		||||
    protected array $attributes = [];
 | 
			
		||||
 | 
			
		||||
    /** @var list<Node\AttributeGroup> */
 | 
			
		||||
    protected array $attributeGroups = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an enum case builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Identifier $name Name
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($name) {
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the value.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Expr|string|int $value
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setValue($value) {
 | 
			
		||||
        $this->value = BuilderHelpers::normalizeValue($value);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets doc comment for the constant.
 | 
			
		||||
     *
 | 
			
		||||
     * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function setDocComment($docComment) {
 | 
			
		||||
        $this->attributes = [
 | 
			
		||||
            'comments' => [BuilderHelpers::normalizeDocComment($docComment)]
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds an attribute group.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Attribute|Node\AttributeGroup $attribute
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addAttribute($attribute) {
 | 
			
		||||
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built enum case node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt\EnumCase The built constant node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): PhpParser\Node {
 | 
			
		||||
        return new Stmt\EnumCase(
 | 
			
		||||
            $this->name,
 | 
			
		||||
            $this->value,
 | 
			
		||||
            $this->attributeGroups,
 | 
			
		||||
            $this->attributes
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Enum_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Enum_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Identifier;
 | 
			
		||||
use PhpParser\Node\Name;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class Enum_ extends Declaration {
 | 
			
		||||
    protected string $name;
 | 
			
		||||
    protected ?Identifier $scalarType = null;
 | 
			
		||||
    /** @var list<Name> */
 | 
			
		||||
    protected array $implements = [];
 | 
			
		||||
    /** @var list<Stmt\TraitUse> */
 | 
			
		||||
    protected array $uses = [];
 | 
			
		||||
    /** @var list<Stmt\EnumCase> */
 | 
			
		||||
    protected array $enumCases = [];
 | 
			
		||||
    /** @var list<Stmt\ClassConst> */
 | 
			
		||||
    protected array $constants = [];
 | 
			
		||||
    /** @var list<Stmt\ClassMethod> */
 | 
			
		||||
    protected array $methods = [];
 | 
			
		||||
    /** @var list<Node\AttributeGroup> */
 | 
			
		||||
    protected array $attributeGroups = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an enum builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the enum
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(string $name) {
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the scalar type.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Identifier $scalarType
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setScalarType($scalarType) {
 | 
			
		||||
        $this->scalarType = BuilderHelpers::normalizeType($scalarType);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Implements one or more interfaces.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Name|string ...$interfaces Names of interfaces to implement
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function implement(...$interfaces) {
 | 
			
		||||
        foreach ($interfaces as $interface) {
 | 
			
		||||
            $this->implements[] = BuilderHelpers::normalizeName($interface);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a statement.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Stmt|PhpParser\Builder $stmt The statement to add
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addStmt($stmt) {
 | 
			
		||||
        $stmt = BuilderHelpers::normalizeNode($stmt);
 | 
			
		||||
 | 
			
		||||
        if ($stmt instanceof Stmt\EnumCase) {
 | 
			
		||||
            $this->enumCases[] = $stmt;
 | 
			
		||||
        } elseif ($stmt instanceof Stmt\ClassMethod) {
 | 
			
		||||
            $this->methods[] = $stmt;
 | 
			
		||||
        } elseif ($stmt instanceof Stmt\TraitUse) {
 | 
			
		||||
            $this->uses[] = $stmt;
 | 
			
		||||
        } elseif ($stmt instanceof Stmt\ClassConst) {
 | 
			
		||||
            $this->constants[] = $stmt;
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds an attribute group.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Attribute|Node\AttributeGroup $attribute
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addAttribute($attribute) {
 | 
			
		||||
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built class node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt\Enum_ The built enum node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): PhpParser\Node {
 | 
			
		||||
        return new Stmt\Enum_($this->name, [
 | 
			
		||||
            'scalarType' => $this->scalarType,
 | 
			
		||||
            'implements' => $this->implements,
 | 
			
		||||
            'stmts' => array_merge($this->uses, $this->enumCases, $this->constants, $this->methods),
 | 
			
		||||
            'attrGroups' => $this->attributeGroups,
 | 
			
		||||
        ], $this->attributes);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
 | 
			
		||||
abstract class FunctionLike extends Declaration {
 | 
			
		||||
    protected bool $returnByRef = false;
 | 
			
		||||
    /** @var Node\Param[] */
 | 
			
		||||
    protected array $params = [];
 | 
			
		||||
 | 
			
		||||
    /** @var Node\Identifier|Node\Name|Node\ComplexType|null */
 | 
			
		||||
    protected ?Node $returnType = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make the function return by reference.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeReturnByRef() {
 | 
			
		||||
        $this->returnByRef = true;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a parameter.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Param|Param $param The parameter to add
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addParam($param) {
 | 
			
		||||
        $param = BuilderHelpers::normalizeNode($param);
 | 
			
		||||
 | 
			
		||||
        if (!$param instanceof Node\Param) {
 | 
			
		||||
            throw new \LogicException(sprintf('Expected parameter node, got "%s"', $param->getType()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->params[] = $param;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds multiple parameters.
 | 
			
		||||
     *
 | 
			
		||||
     * @param (Node\Param|Param)[] $params The parameters to add
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addParams(array $params) {
 | 
			
		||||
        foreach ($params as $param) {
 | 
			
		||||
            $this->addParam($param);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the return type for PHP 7.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Node\Name|Node\Identifier|Node\ComplexType $type
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function setReturnType($type) {
 | 
			
		||||
        $this->returnType = BuilderHelpers::normalizeType($type);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class Function_ extends FunctionLike {
 | 
			
		||||
    protected string $name;
 | 
			
		||||
    /** @var list<Stmt> */
 | 
			
		||||
    protected array $stmts = [];
 | 
			
		||||
 | 
			
		||||
    /** @var list<Node\AttributeGroup> */
 | 
			
		||||
    protected array $attributeGroups = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a function builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the function
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(string $name) {
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a statement.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node|PhpParser\Builder $stmt The statement to add
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addStmt($stmt) {
 | 
			
		||||
        $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds an attribute group.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Attribute|Node\AttributeGroup $attribute
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addAttribute($attribute) {
 | 
			
		||||
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built function node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt\Function_ The built function node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): Node {
 | 
			
		||||
        return new Stmt\Function_($this->name, [
 | 
			
		||||
            'byRef'      => $this->returnByRef,
 | 
			
		||||
            'params'     => $this->params,
 | 
			
		||||
            'returnType' => $this->returnType,
 | 
			
		||||
            'stmts'      => $this->stmts,
 | 
			
		||||
            'attrGroups' => $this->attributeGroups,
 | 
			
		||||
        ], $this->attributes);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Name;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class Interface_ extends Declaration {
 | 
			
		||||
    protected string $name;
 | 
			
		||||
    /** @var list<Name> */
 | 
			
		||||
    protected array $extends = [];
 | 
			
		||||
    /** @var list<Stmt\ClassConst> */
 | 
			
		||||
    protected array $constants = [];
 | 
			
		||||
    /** @var list<Stmt\ClassMethod> */
 | 
			
		||||
    protected array $methods = [];
 | 
			
		||||
    /** @var list<Node\AttributeGroup> */
 | 
			
		||||
    protected array $attributeGroups = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an interface builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the interface
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(string $name) {
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Extends one or more interfaces.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Name|string ...$interfaces Names of interfaces to extend
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function extend(...$interfaces) {
 | 
			
		||||
        foreach ($interfaces as $interface) {
 | 
			
		||||
            $this->extends[] = BuilderHelpers::normalizeName($interface);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a statement.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Stmt|PhpParser\Builder $stmt The statement to add
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addStmt($stmt) {
 | 
			
		||||
        $stmt = BuilderHelpers::normalizeNode($stmt);
 | 
			
		||||
 | 
			
		||||
        if ($stmt instanceof Stmt\ClassConst) {
 | 
			
		||||
            $this->constants[] = $stmt;
 | 
			
		||||
        } elseif ($stmt instanceof Stmt\ClassMethod) {
 | 
			
		||||
            // we erase all statements in the body of an interface method
 | 
			
		||||
            $stmt->stmts = null;
 | 
			
		||||
            $this->methods[] = $stmt;
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds an attribute group.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Attribute|Node\AttributeGroup $attribute
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addAttribute($attribute) {
 | 
			
		||||
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built interface node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt\Interface_ The built interface node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): PhpParser\Node {
 | 
			
		||||
        return new Stmt\Interface_($this->name, [
 | 
			
		||||
            'extends' => $this->extends,
 | 
			
		||||
            'stmts' => array_merge($this->constants, $this->methods),
 | 
			
		||||
            'attrGroups' => $this->attributeGroups,
 | 
			
		||||
        ], $this->attributes);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										147
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,147 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Modifiers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class Method extends FunctionLike {
 | 
			
		||||
    protected string $name;
 | 
			
		||||
 | 
			
		||||
    protected int $flags = 0;
 | 
			
		||||
 | 
			
		||||
    /** @var list<Stmt>|null */
 | 
			
		||||
    protected ?array $stmts = [];
 | 
			
		||||
 | 
			
		||||
    /** @var list<Node\AttributeGroup> */
 | 
			
		||||
    protected array $attributeGroups = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a method builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the method
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(string $name) {
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the method public.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePublic() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the method protected.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeProtected() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the method private.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePrivate() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the method static.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeStatic() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::STATIC);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the method abstract.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeAbstract() {
 | 
			
		||||
        if (!empty($this->stmts)) {
 | 
			
		||||
            throw new \LogicException('Cannot make method with statements abstract');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::ABSTRACT);
 | 
			
		||||
        $this->stmts = null; // abstract methods don't have statements
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the method final.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeFinal() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a statement.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node|PhpParser\Builder $stmt The statement to add
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addStmt($stmt) {
 | 
			
		||||
        if (null === $this->stmts) {
 | 
			
		||||
            throw new \LogicException('Cannot add statements to an abstract method');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds an attribute group.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Attribute|Node\AttributeGroup $attribute
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addAttribute($attribute) {
 | 
			
		||||
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built method node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt\ClassMethod The built method node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): Node {
 | 
			
		||||
        return new Stmt\ClassMethod($this->name, [
 | 
			
		||||
            'flags'      => $this->flags,
 | 
			
		||||
            'byRef'      => $this->returnByRef,
 | 
			
		||||
            'params'     => $this->params,
 | 
			
		||||
            'returnType' => $this->returnType,
 | 
			
		||||
            'stmts'      => $this->stmts,
 | 
			
		||||
            'attrGroups' => $this->attributeGroups,
 | 
			
		||||
        ], $this->attributes);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class Namespace_ extends Declaration {
 | 
			
		||||
    private ?Node\Name $name;
 | 
			
		||||
    /** @var Stmt[] */
 | 
			
		||||
    private array $stmts = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a namespace builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Name|string|null $name Name of the namespace
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($name) {
 | 
			
		||||
        $this->name = null !== $name ? BuilderHelpers::normalizeName($name) : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a statement.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node|PhpParser\Builder $stmt The statement to add
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addStmt($stmt) {
 | 
			
		||||
        $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt\Namespace_ The built node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): Node {
 | 
			
		||||
        return new Stmt\Namespace_($this->name, $this->stmts, $this->attributes);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										171
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,171 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Modifiers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
 | 
			
		||||
class Param implements PhpParser\Builder {
 | 
			
		||||
    protected string $name;
 | 
			
		||||
    protected ?Node\Expr $default = null;
 | 
			
		||||
    /** @var Node\Identifier|Node\Name|Node\ComplexType|null */
 | 
			
		||||
    protected ?Node $type = null;
 | 
			
		||||
    protected bool $byRef = false;
 | 
			
		||||
    protected int $flags = 0;
 | 
			
		||||
    protected bool $variadic = false;
 | 
			
		||||
    /** @var list<Node\AttributeGroup> */
 | 
			
		||||
    protected array $attributeGroups = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a parameter builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the parameter
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(string $name) {
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets default value for the parameter.
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $value Default value to use
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function setDefault($value) {
 | 
			
		||||
        $this->default = BuilderHelpers::normalizeValue($value);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets type for the parameter.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Node\Name|Node\Identifier|Node\ComplexType $type Parameter type
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function setType($type) {
 | 
			
		||||
        $this->type = BuilderHelpers::normalizeType($type);
 | 
			
		||||
        if ($this->type == 'void') {
 | 
			
		||||
            throw new \LogicException('Parameter type cannot be void');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make the parameter accept the value by reference.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeByRef() {
 | 
			
		||||
        $this->byRef = true;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make the parameter variadic
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeVariadic() {
 | 
			
		||||
        $this->variadic = true;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the (promoted) parameter public.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePublic() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the (promoted) parameter protected.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeProtected() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the (promoted) parameter private.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePrivate() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the (promoted) parameter readonly.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeReadonly() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::READONLY);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gives the promoted property private(set) visibility.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePrivateSet() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE_SET);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gives the promoted property protected(set) visibility.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeProtectedSet() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED_SET);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds an attribute group.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Attribute|Node\AttributeGroup $attribute
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addAttribute($attribute) {
 | 
			
		||||
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built parameter node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Node\Param The built parameter node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): Node {
 | 
			
		||||
        return new Node\Param(
 | 
			
		||||
            new Node\Expr\Variable($this->name),
 | 
			
		||||
            $this->default, $this->type, $this->byRef, $this->variadic, [], $this->flags, $this->attributeGroups
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										223
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,223 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Modifiers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Identifier;
 | 
			
		||||
use PhpParser\Node\Name;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
use PhpParser\Node\ComplexType;
 | 
			
		||||
 | 
			
		||||
class Property implements PhpParser\Builder {
 | 
			
		||||
    protected string $name;
 | 
			
		||||
 | 
			
		||||
    protected int $flags = 0;
 | 
			
		||||
 | 
			
		||||
    protected ?Node\Expr $default = null;
 | 
			
		||||
    /** @var array<string, mixed> */
 | 
			
		||||
    protected array $attributes = [];
 | 
			
		||||
    /** @var null|Identifier|Name|ComplexType */
 | 
			
		||||
    protected ?Node $type = null;
 | 
			
		||||
    /** @var list<Node\AttributeGroup> */
 | 
			
		||||
    protected array $attributeGroups = [];
 | 
			
		||||
    /** @var list<Node\PropertyHook> */
 | 
			
		||||
    protected array $hooks = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a property builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the property
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(string $name) {
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the property public.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePublic() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the property protected.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeProtected() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the property private.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePrivate() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the property static.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeStatic() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::STATIC);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the property readonly.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeReadonly() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::READONLY);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the property abstract. Requires at least one property hook to be specified as well.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeAbstract() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::ABSTRACT);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Makes the property final.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeFinal() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gives the property private(set) visibility.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePrivateSet() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE_SET);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gives the property protected(set) visibility.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeProtectedSet() {
 | 
			
		||||
        $this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED_SET);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets default value for the property.
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $value Default value to use
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function setDefault($value) {
 | 
			
		||||
        $this->default = BuilderHelpers::normalizeValue($value);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets doc comment for the property.
 | 
			
		||||
     *
 | 
			
		||||
     * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function setDocComment($docComment) {
 | 
			
		||||
        $this->attributes = [
 | 
			
		||||
            'comments' => [BuilderHelpers::normalizeDocComment($docComment)]
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the property type for PHP 7.4+.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Name|Identifier|ComplexType $type
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setType($type) {
 | 
			
		||||
        $this->type = BuilderHelpers::normalizeType($type);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds an attribute group.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Attribute|Node\AttributeGroup $attribute
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addAttribute($attribute) {
 | 
			
		||||
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a property hook.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addHook(Node\PropertyHook $hook) {
 | 
			
		||||
        $this->hooks[] = $hook;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built class node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt\Property The built property node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): PhpParser\Node {
 | 
			
		||||
        if ($this->flags & Modifiers::ABSTRACT && !$this->hooks) {
 | 
			
		||||
            throw new PhpParser\Error('Only hooked properties may be declared abstract');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new Stmt\Property(
 | 
			
		||||
            $this->flags !== 0 ? $this->flags : Modifiers::PUBLIC,
 | 
			
		||||
            [
 | 
			
		||||
                new Node\PropertyItem($this->name, $this->default)
 | 
			
		||||
            ],
 | 
			
		||||
            $this->attributes,
 | 
			
		||||
            $this->type,
 | 
			
		||||
            $this->attributeGroups,
 | 
			
		||||
            $this->hooks
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Builder;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class TraitUse implements Builder {
 | 
			
		||||
    /** @var Node\Name[] */
 | 
			
		||||
    protected array $traits = [];
 | 
			
		||||
    /** @var Stmt\TraitUseAdaptation[] */
 | 
			
		||||
    protected array $adaptations = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a trait use builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Name|string ...$traits Names of used traits
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(...$traits) {
 | 
			
		||||
        foreach ($traits as $trait) {
 | 
			
		||||
            $this->and($trait);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds used trait.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Name|string $trait Trait name
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function and($trait) {
 | 
			
		||||
        $this->traits[] = BuilderHelpers::normalizeName($trait);
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds trait adaptation.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Stmt\TraitUseAdaptation|Builder\TraitUseAdaptation $adaptation Trait adaptation
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function with($adaptation) {
 | 
			
		||||
        $adaptation = BuilderHelpers::normalizeNode($adaptation);
 | 
			
		||||
 | 
			
		||||
        if (!$adaptation instanceof Stmt\TraitUseAdaptation) {
 | 
			
		||||
            throw new \LogicException('Adaptation must have type TraitUseAdaptation');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->adaptations[] = $adaptation;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Node The built node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): Node {
 | 
			
		||||
        return new Stmt\TraitUse($this->traits, $this->adaptations);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										145
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Builder;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Modifiers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class TraitUseAdaptation implements Builder {
 | 
			
		||||
    private const TYPE_UNDEFINED  = 0;
 | 
			
		||||
    private const TYPE_ALIAS      = 1;
 | 
			
		||||
    private const TYPE_PRECEDENCE = 2;
 | 
			
		||||
 | 
			
		||||
    protected int $type;
 | 
			
		||||
    protected ?Node\Name $trait;
 | 
			
		||||
    protected Node\Identifier $method;
 | 
			
		||||
    protected ?int $modifier = null;
 | 
			
		||||
    protected ?Node\Identifier $alias = null;
 | 
			
		||||
    /** @var Node\Name[] */
 | 
			
		||||
    protected array $insteadof = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a trait use adaptation builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Name|string|null $trait Name of adapted trait
 | 
			
		||||
     * @param Node\Identifier|string $method Name of adapted method
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($trait, $method) {
 | 
			
		||||
        $this->type = self::TYPE_UNDEFINED;
 | 
			
		||||
 | 
			
		||||
        $this->trait = is_null($trait) ? null : BuilderHelpers::normalizeName($trait);
 | 
			
		||||
        $this->method = BuilderHelpers::normalizeIdentifier($method);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets alias of method.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Identifier|string $alias Alias for adapted method
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function as($alias) {
 | 
			
		||||
        if ($this->type === self::TYPE_UNDEFINED) {
 | 
			
		||||
            $this->type = self::TYPE_ALIAS;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($this->type !== self::TYPE_ALIAS) {
 | 
			
		||||
            throw new \LogicException('Cannot set alias for not alias adaptation buider');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->alias = BuilderHelpers::normalizeIdentifier($alias);
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets adapted method public.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePublic() {
 | 
			
		||||
        $this->setModifier(Modifiers::PUBLIC);
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets adapted method protected.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makeProtected() {
 | 
			
		||||
        $this->setModifier(Modifiers::PROTECTED);
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets adapted method private.
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function makePrivate() {
 | 
			
		||||
        $this->setModifier(Modifiers::PRIVATE);
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds overwritten traits.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Name|string ...$traits Traits for overwrite
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function insteadof(...$traits) {
 | 
			
		||||
        if ($this->type === self::TYPE_UNDEFINED) {
 | 
			
		||||
            if (is_null($this->trait)) {
 | 
			
		||||
                throw new \LogicException('Precedence adaptation must have trait');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $this->type = self::TYPE_PRECEDENCE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($this->type !== self::TYPE_PRECEDENCE) {
 | 
			
		||||
            throw new \LogicException('Cannot add overwritten traits for not precedence adaptation buider');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($traits as $trait) {
 | 
			
		||||
            $this->insteadof[] = BuilderHelpers::normalizeName($trait);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function setModifier(int $modifier): void {
 | 
			
		||||
        if ($this->type === self::TYPE_UNDEFINED) {
 | 
			
		||||
            $this->type = self::TYPE_ALIAS;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($this->type !== self::TYPE_ALIAS) {
 | 
			
		||||
            throw new \LogicException('Cannot set access modifier for not alias adaptation buider');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_null($this->modifier)) {
 | 
			
		||||
            $this->modifier = $modifier;
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new \LogicException('Multiple access type modifiers are not allowed');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Node The built node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): Node {
 | 
			
		||||
        switch ($this->type) {
 | 
			
		||||
            case self::TYPE_ALIAS:
 | 
			
		||||
                return new Stmt\TraitUseAdaptation\Alias($this->trait, $this->method, $this->modifier, $this->alias);
 | 
			
		||||
            case self::TYPE_PRECEDENCE:
 | 
			
		||||
                return new Stmt\TraitUseAdaptation\Precedence($this->trait, $this->method, $this->insteadof);
 | 
			
		||||
            default:
 | 
			
		||||
                throw new \LogicException('Type of adaptation is not defined');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class Trait_ extends Declaration {
 | 
			
		||||
    protected string $name;
 | 
			
		||||
    /** @var list<Stmt\TraitUse> */
 | 
			
		||||
    protected array $uses = [];
 | 
			
		||||
    /** @var list<Stmt\ClassConst> */
 | 
			
		||||
    protected array $constants = [];
 | 
			
		||||
    /** @var list<Stmt\Property> */
 | 
			
		||||
    protected array $properties = [];
 | 
			
		||||
    /** @var list<Stmt\ClassMethod> */
 | 
			
		||||
    protected array $methods = [];
 | 
			
		||||
    /** @var list<Node\AttributeGroup> */
 | 
			
		||||
    protected array $attributeGroups = [];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an interface builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the interface
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(string $name) {
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a statement.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Stmt|PhpParser\Builder $stmt The statement to add
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addStmt($stmt) {
 | 
			
		||||
        $stmt = BuilderHelpers::normalizeNode($stmt);
 | 
			
		||||
 | 
			
		||||
        if ($stmt instanceof Stmt\Property) {
 | 
			
		||||
            $this->properties[] = $stmt;
 | 
			
		||||
        } elseif ($stmt instanceof Stmt\ClassMethod) {
 | 
			
		||||
            $this->methods[] = $stmt;
 | 
			
		||||
        } elseif ($stmt instanceof Stmt\TraitUse) {
 | 
			
		||||
            $this->uses[] = $stmt;
 | 
			
		||||
        } elseif ($stmt instanceof Stmt\ClassConst) {
 | 
			
		||||
            $this->constants[] = $stmt;
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds an attribute group.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Attribute|Node\AttributeGroup $attribute
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function addAttribute($attribute) {
 | 
			
		||||
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built trait node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt\Trait_ The built interface node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): PhpParser\Node {
 | 
			
		||||
        return new Stmt\Trait_(
 | 
			
		||||
            $this->name, [
 | 
			
		||||
                'stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods),
 | 
			
		||||
                'attrGroups' => $this->attributeGroups,
 | 
			
		||||
            ], $this->attributes
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Builder;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Builder;
 | 
			
		||||
use PhpParser\BuilderHelpers;
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class Use_ implements Builder {
 | 
			
		||||
    protected Node\Name $name;
 | 
			
		||||
    /** @var Stmt\Use_::TYPE_* */
 | 
			
		||||
    protected int $type;
 | 
			
		||||
    protected ?string $alias = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a name use (alias) builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Name|string $name Name of the entity (namespace, class, function, constant) to alias
 | 
			
		||||
     * @param Stmt\Use_::TYPE_* $type One of the Stmt\Use_::TYPE_* constants
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct($name, int $type) {
 | 
			
		||||
        $this->name = BuilderHelpers::normalizeName($name);
 | 
			
		||||
        $this->type = $type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets alias for used name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $alias Alias to use (last component of full name by default)
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this The builder instance (for fluid interface)
 | 
			
		||||
     */
 | 
			
		||||
    public function as(string $alias) {
 | 
			
		||||
        $this->alias = $alias;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the built node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt\Use_ The built node
 | 
			
		||||
     */
 | 
			
		||||
    public function getNode(): Node {
 | 
			
		||||
        return new Stmt\Use_([
 | 
			
		||||
            new Node\UseItem($this->name, $this->alias)
 | 
			
		||||
        ], $this->type);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										375
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										375
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,375 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Node\Arg;
 | 
			
		||||
use PhpParser\Node\Expr;
 | 
			
		||||
use PhpParser\Node\Expr\BinaryOp\Concat;
 | 
			
		||||
use PhpParser\Node\Identifier;
 | 
			
		||||
use PhpParser\Node\Name;
 | 
			
		||||
use PhpParser\Node\Scalar\String_;
 | 
			
		||||
use PhpParser\Node\Stmt\Use_;
 | 
			
		||||
 | 
			
		||||
class BuilderFactory {
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an attribute node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Name $name Name of the attribute
 | 
			
		||||
     * @param array $args Attribute named arguments
 | 
			
		||||
     */
 | 
			
		||||
    public function attribute($name, array $args = []): Node\Attribute {
 | 
			
		||||
        return new Node\Attribute(
 | 
			
		||||
            BuilderHelpers::normalizeName($name),
 | 
			
		||||
            $this->args($args)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a namespace builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param null|string|Node\Name $name Name of the namespace
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Namespace_ The created namespace builder
 | 
			
		||||
     */
 | 
			
		||||
    public function namespace($name): Builder\Namespace_ {
 | 
			
		||||
        return new Builder\Namespace_($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a class builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the class
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Class_ The created class builder
 | 
			
		||||
     */
 | 
			
		||||
    public function class(string $name): Builder\Class_ {
 | 
			
		||||
        return new Builder\Class_($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an interface builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the interface
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Interface_ The created interface builder
 | 
			
		||||
     */
 | 
			
		||||
    public function interface(string $name): Builder\Interface_ {
 | 
			
		||||
        return new Builder\Interface_($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a trait builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the trait
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Trait_ The created trait builder
 | 
			
		||||
     */
 | 
			
		||||
    public function trait(string $name): Builder\Trait_ {
 | 
			
		||||
        return new Builder\Trait_($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an enum builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the enum
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Enum_ The created enum builder
 | 
			
		||||
     */
 | 
			
		||||
    public function enum(string $name): Builder\Enum_ {
 | 
			
		||||
        return new Builder\Enum_($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a trait use builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Name|string ...$traits Trait names
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\TraitUse The created trait use builder
 | 
			
		||||
     */
 | 
			
		||||
    public function useTrait(...$traits): Builder\TraitUse {
 | 
			
		||||
        return new Builder\TraitUse(...$traits);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a trait use adaptation builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Name|string|null $trait Trait name
 | 
			
		||||
     * @param Node\Identifier|string $method Method name
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\TraitUseAdaptation The created trait use adaptation builder
 | 
			
		||||
     */
 | 
			
		||||
    public function traitUseAdaptation($trait, $method = null): Builder\TraitUseAdaptation {
 | 
			
		||||
        if ($method === null) {
 | 
			
		||||
            $method = $trait;
 | 
			
		||||
            $trait = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new Builder\TraitUseAdaptation($trait, $method);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a method builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the method
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Method The created method builder
 | 
			
		||||
     */
 | 
			
		||||
    public function method(string $name): Builder\Method {
 | 
			
		||||
        return new Builder\Method($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a parameter builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the parameter
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Param The created parameter builder
 | 
			
		||||
     */
 | 
			
		||||
    public function param(string $name): Builder\Param {
 | 
			
		||||
        return new Builder\Param($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a property builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the property
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Property The created property builder
 | 
			
		||||
     */
 | 
			
		||||
    public function property(string $name): Builder\Property {
 | 
			
		||||
        return new Builder\Property($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a function builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Name of the function
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Function_ The created function builder
 | 
			
		||||
     */
 | 
			
		||||
    public function function(string $name): Builder\Function_ {
 | 
			
		||||
        return new Builder\Function_($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a namespace/class use builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Name|string $name Name of the entity (namespace or class) to alias
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Use_ The created use builder
 | 
			
		||||
     */
 | 
			
		||||
    public function use($name): Builder\Use_ {
 | 
			
		||||
        return new Builder\Use_($name, Use_::TYPE_NORMAL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a function use builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Name|string $name Name of the function to alias
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Use_ The created use function builder
 | 
			
		||||
     */
 | 
			
		||||
    public function useFunction($name): Builder\Use_ {
 | 
			
		||||
        return new Builder\Use_($name, Use_::TYPE_FUNCTION);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a constant use builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Name|string $name Name of the const to alias
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\Use_ The created use const builder
 | 
			
		||||
     */
 | 
			
		||||
    public function useConst($name): Builder\Use_ {
 | 
			
		||||
        return new Builder\Use_($name, Use_::TYPE_CONSTANT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a class constant builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Identifier $name Name
 | 
			
		||||
     * @param Node\Expr|bool|null|int|float|string|array $value Value
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\ClassConst The created use const builder
 | 
			
		||||
     */
 | 
			
		||||
    public function classConst($name, $value): Builder\ClassConst {
 | 
			
		||||
        return new Builder\ClassConst($name, $value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an enum case builder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Identifier $name Name
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder\EnumCase The created use const builder
 | 
			
		||||
     */
 | 
			
		||||
    public function enumCase($name): Builder\EnumCase {
 | 
			
		||||
        return new Builder\EnumCase($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates node a for a literal value.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Expr|bool|null|int|float|string|array|\UnitEnum $value $value
 | 
			
		||||
     */
 | 
			
		||||
    public function val($value): Expr {
 | 
			
		||||
        return BuilderHelpers::normalizeValue($value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates variable node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Expr $name Name
 | 
			
		||||
     */
 | 
			
		||||
    public function var($name): Expr\Variable {
 | 
			
		||||
        if (!\is_string($name) && !$name instanceof Expr) {
 | 
			
		||||
            throw new \LogicException('Variable name must be string or Expr');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new Expr\Variable($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normalizes an argument list.
 | 
			
		||||
     *
 | 
			
		||||
     * Creates Arg nodes for all arguments and converts literal values to expressions.
 | 
			
		||||
     *
 | 
			
		||||
     * @param array $args List of arguments to normalize
 | 
			
		||||
     *
 | 
			
		||||
     * @return list<Arg>
 | 
			
		||||
     */
 | 
			
		||||
    public function args(array $args): array {
 | 
			
		||||
        $normalizedArgs = [];
 | 
			
		||||
        foreach ($args as $key => $arg) {
 | 
			
		||||
            if (!($arg instanceof Arg)) {
 | 
			
		||||
                $arg = new Arg(BuilderHelpers::normalizeValue($arg));
 | 
			
		||||
            }
 | 
			
		||||
            if (\is_string($key)) {
 | 
			
		||||
                $arg->name = BuilderHelpers::normalizeIdentifier($key);
 | 
			
		||||
            }
 | 
			
		||||
            $normalizedArgs[] = $arg;
 | 
			
		||||
        }
 | 
			
		||||
        return $normalizedArgs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a function call node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Name|Expr $name Function name
 | 
			
		||||
     * @param array $args Function arguments
 | 
			
		||||
     */
 | 
			
		||||
    public function funcCall($name, array $args = []): Expr\FuncCall {
 | 
			
		||||
        return new Expr\FuncCall(
 | 
			
		||||
            BuilderHelpers::normalizeNameOrExpr($name),
 | 
			
		||||
            $this->args($args)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a method call node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Expr $var Variable the method is called on
 | 
			
		||||
     * @param string|Identifier|Expr $name Method name
 | 
			
		||||
     * @param array $args Method arguments
 | 
			
		||||
     */
 | 
			
		||||
    public function methodCall(Expr $var, $name, array $args = []): Expr\MethodCall {
 | 
			
		||||
        return new Expr\MethodCall(
 | 
			
		||||
            $var,
 | 
			
		||||
            BuilderHelpers::normalizeIdentifierOrExpr($name),
 | 
			
		||||
            $this->args($args)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a static method call node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Name|Expr $class Class name
 | 
			
		||||
     * @param string|Identifier|Expr $name Method name
 | 
			
		||||
     * @param array $args Method arguments
 | 
			
		||||
     */
 | 
			
		||||
    public function staticCall($class, $name, array $args = []): Expr\StaticCall {
 | 
			
		||||
        return new Expr\StaticCall(
 | 
			
		||||
            BuilderHelpers::normalizeNameOrExpr($class),
 | 
			
		||||
            BuilderHelpers::normalizeIdentifierOrExpr($name),
 | 
			
		||||
            $this->args($args)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an object creation node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Name|Expr $class Class name
 | 
			
		||||
     * @param array $args Constructor arguments
 | 
			
		||||
     */
 | 
			
		||||
    public function new($class, array $args = []): Expr\New_ {
 | 
			
		||||
        return new Expr\New_(
 | 
			
		||||
            BuilderHelpers::normalizeNameOrExpr($class),
 | 
			
		||||
            $this->args($args)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a constant fetch node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Name $name Constant name
 | 
			
		||||
     */
 | 
			
		||||
    public function constFetch($name): Expr\ConstFetch {
 | 
			
		||||
        return new Expr\ConstFetch(BuilderHelpers::normalizeName($name));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a property fetch node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Expr $var Variable holding object
 | 
			
		||||
     * @param string|Identifier|Expr $name Property name
 | 
			
		||||
     */
 | 
			
		||||
    public function propertyFetch(Expr $var, $name): Expr\PropertyFetch {
 | 
			
		||||
        return new Expr\PropertyFetch($var, BuilderHelpers::normalizeIdentifierOrExpr($name));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a class constant fetch node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Name|Expr $class Class name
 | 
			
		||||
     * @param string|Identifier|Expr $name Constant name
 | 
			
		||||
     */
 | 
			
		||||
    public function classConstFetch($class, $name): Expr\ClassConstFetch {
 | 
			
		||||
        return new Expr\ClassConstFetch(
 | 
			
		||||
            BuilderHelpers::normalizeNameOrExpr($class),
 | 
			
		||||
            BuilderHelpers::normalizeIdentifierOrExpr($name)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates nested Concat nodes from a list of expressions.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Expr|string ...$exprs Expressions or literal strings
 | 
			
		||||
     */
 | 
			
		||||
    public function concat(...$exprs): Concat {
 | 
			
		||||
        $numExprs = count($exprs);
 | 
			
		||||
        if ($numExprs < 2) {
 | 
			
		||||
            throw new \LogicException('Expected at least two expressions');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $lastConcat = $this->normalizeStringExpr($exprs[0]);
 | 
			
		||||
        for ($i = 1; $i < $numExprs; $i++) {
 | 
			
		||||
            $lastConcat = new Concat($lastConcat, $this->normalizeStringExpr($exprs[$i]));
 | 
			
		||||
        }
 | 
			
		||||
        return $lastConcat;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string|Expr $expr
 | 
			
		||||
     */
 | 
			
		||||
    private function normalizeStringExpr($expr): Expr {
 | 
			
		||||
        if ($expr instanceof Expr) {
 | 
			
		||||
            return $expr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (\is_string($expr)) {
 | 
			
		||||
            return new String_($expr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new \LogicException('Expected string or Expr');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										338
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,338 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Node\ComplexType;
 | 
			
		||||
use PhpParser\Node\Expr;
 | 
			
		||||
use PhpParser\Node\Identifier;
 | 
			
		||||
use PhpParser\Node\Name;
 | 
			
		||||
use PhpParser\Node\Name\FullyQualified;
 | 
			
		||||
use PhpParser\Node\NullableType;
 | 
			
		||||
use PhpParser\Node\Scalar;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class defines helpers used in the implementation of builders. Don't use it directly.
 | 
			
		||||
 *
 | 
			
		||||
 * @internal
 | 
			
		||||
 */
 | 
			
		||||
final class BuilderHelpers {
 | 
			
		||||
    /**
 | 
			
		||||
     * Normalizes a node: Converts builder objects to nodes.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node|Builder $node The node to normalize
 | 
			
		||||
     *
 | 
			
		||||
     * @return Node The normalized node
 | 
			
		||||
     */
 | 
			
		||||
    public static function normalizeNode($node): Node {
 | 
			
		||||
        if ($node instanceof Builder) {
 | 
			
		||||
            return $node->getNode();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($node instanceof Node) {
 | 
			
		||||
            return $node;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new \LogicException('Expected node or builder object');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normalizes a node to a statement.
 | 
			
		||||
     *
 | 
			
		||||
     * Expressions are wrapped in a Stmt\Expression node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node|Builder $node The node to normalize
 | 
			
		||||
     *
 | 
			
		||||
     * @return Stmt The normalized statement node
 | 
			
		||||
     */
 | 
			
		||||
    public static function normalizeStmt($node): Stmt {
 | 
			
		||||
        $node = self::normalizeNode($node);
 | 
			
		||||
        if ($node instanceof Stmt) {
 | 
			
		||||
            return $node;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($node instanceof Expr) {
 | 
			
		||||
            return new Stmt\Expression($node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new \LogicException('Expected statement or expression node');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normalizes strings to Identifier.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Identifier $name The identifier to normalize
 | 
			
		||||
     *
 | 
			
		||||
     * @return Identifier The normalized identifier
 | 
			
		||||
     */
 | 
			
		||||
    public static function normalizeIdentifier($name): Identifier {
 | 
			
		||||
        if ($name instanceof Identifier) {
 | 
			
		||||
            return $name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (\is_string($name)) {
 | 
			
		||||
            return new Identifier($name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new \LogicException('Expected string or instance of Node\Identifier');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normalizes strings to Identifier, also allowing expressions.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Identifier|Expr $name The identifier to normalize
 | 
			
		||||
     *
 | 
			
		||||
     * @return Identifier|Expr The normalized identifier or expression
 | 
			
		||||
     */
 | 
			
		||||
    public static function normalizeIdentifierOrExpr($name) {
 | 
			
		||||
        if ($name instanceof Identifier || $name instanceof Expr) {
 | 
			
		||||
            return $name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (\is_string($name)) {
 | 
			
		||||
            return new Identifier($name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new \LogicException('Expected string or instance of Node\Identifier or Node\Expr');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normalizes a name: Converts string names to Name nodes.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Name|string $name The name to normalize
 | 
			
		||||
     *
 | 
			
		||||
     * @return Name The normalized name
 | 
			
		||||
     */
 | 
			
		||||
    public static function normalizeName($name): Name {
 | 
			
		||||
        if ($name instanceof Name) {
 | 
			
		||||
            return $name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_string($name)) {
 | 
			
		||||
            if (!$name) {
 | 
			
		||||
                throw new \LogicException('Name cannot be empty');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($name[0] === '\\') {
 | 
			
		||||
                return new Name\FullyQualified(substr($name, 1));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (0 === strpos($name, 'namespace\\')) {
 | 
			
		||||
                return new Name\Relative(substr($name, strlen('namespace\\')));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new Name($name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new \LogicException('Name must be a string or an instance of Node\Name');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normalizes a name: Converts string names to Name nodes, while also allowing expressions.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Expr|Name|string $name The name to normalize
 | 
			
		||||
     *
 | 
			
		||||
     * @return Name|Expr The normalized name or expression
 | 
			
		||||
     */
 | 
			
		||||
    public static function normalizeNameOrExpr($name) {
 | 
			
		||||
        if ($name instanceof Expr) {
 | 
			
		||||
            return $name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!is_string($name) && !($name instanceof Name)) {
 | 
			
		||||
            throw new \LogicException(
 | 
			
		||||
                'Name must be a string or an instance of Node\Name or Node\Expr'
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return self::normalizeName($name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normalizes a type: Converts plain-text type names into proper AST representation.
 | 
			
		||||
     *
 | 
			
		||||
     * In particular, builtin types become Identifiers, custom types become Names and nullables
 | 
			
		||||
     * are wrapped in NullableType nodes.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string|Name|Identifier|ComplexType $type The type to normalize
 | 
			
		||||
     *
 | 
			
		||||
     * @return Name|Identifier|ComplexType The normalized type
 | 
			
		||||
     */
 | 
			
		||||
    public static function normalizeType($type) {
 | 
			
		||||
        if (!is_string($type)) {
 | 
			
		||||
            if (
 | 
			
		||||
                !$type instanceof Name && !$type instanceof Identifier &&
 | 
			
		||||
                !$type instanceof ComplexType
 | 
			
		||||
            ) {
 | 
			
		||||
                throw new \LogicException(
 | 
			
		||||
                    'Type must be a string, or an instance of Name, Identifier or ComplexType'
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            return $type;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $nullable = false;
 | 
			
		||||
        if (strlen($type) > 0 && $type[0] === '?') {
 | 
			
		||||
            $nullable = true;
 | 
			
		||||
            $type = substr($type, 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $builtinTypes = [
 | 
			
		||||
            'array',
 | 
			
		||||
            'callable',
 | 
			
		||||
            'bool',
 | 
			
		||||
            'int',
 | 
			
		||||
            'float',
 | 
			
		||||
            'string',
 | 
			
		||||
            'iterable',
 | 
			
		||||
            'void',
 | 
			
		||||
            'object',
 | 
			
		||||
            'null',
 | 
			
		||||
            'false',
 | 
			
		||||
            'mixed',
 | 
			
		||||
            'never',
 | 
			
		||||
            'true',
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        $lowerType = strtolower($type);
 | 
			
		||||
        if (in_array($lowerType, $builtinTypes)) {
 | 
			
		||||
            $type = new Identifier($lowerType);
 | 
			
		||||
        } else {
 | 
			
		||||
            $type = self::normalizeName($type);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $notNullableTypes = [
 | 
			
		||||
            'void', 'mixed', 'never',
 | 
			
		||||
        ];
 | 
			
		||||
        if ($nullable && in_array((string) $type, $notNullableTypes)) {
 | 
			
		||||
            throw new \LogicException(sprintf('%s type cannot be nullable', $type));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $nullable ? new NullableType($type) : $type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normalizes a value: Converts nulls, booleans, integers,
 | 
			
		||||
     * floats, strings and arrays into their respective nodes
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value The value to normalize
 | 
			
		||||
     *
 | 
			
		||||
     * @return Expr The normalized value
 | 
			
		||||
     */
 | 
			
		||||
    public static function normalizeValue($value): Expr {
 | 
			
		||||
        if ($value instanceof Node\Expr) {
 | 
			
		||||
            return $value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_null($value)) {
 | 
			
		||||
            return new Expr\ConstFetch(
 | 
			
		||||
                new Name('null')
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_bool($value)) {
 | 
			
		||||
            return new Expr\ConstFetch(
 | 
			
		||||
                new Name($value ? 'true' : 'false')
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_int($value)) {
 | 
			
		||||
            return new Scalar\Int_($value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_float($value)) {
 | 
			
		||||
            return new Scalar\Float_($value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_string($value)) {
 | 
			
		||||
            return new Scalar\String_($value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_array($value)) {
 | 
			
		||||
            $items = [];
 | 
			
		||||
            $lastKey = -1;
 | 
			
		||||
            foreach ($value as $itemKey => $itemValue) {
 | 
			
		||||
                // for consecutive, numeric keys don't generate keys
 | 
			
		||||
                if (null !== $lastKey && ++$lastKey === $itemKey) {
 | 
			
		||||
                    $items[] = new Node\ArrayItem(
 | 
			
		||||
                        self::normalizeValue($itemValue)
 | 
			
		||||
                    );
 | 
			
		||||
                } else {
 | 
			
		||||
                    $lastKey = null;
 | 
			
		||||
                    $items[] = new Node\ArrayItem(
 | 
			
		||||
                        self::normalizeValue($itemValue),
 | 
			
		||||
                        self::normalizeValue($itemKey)
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new Expr\Array_($items);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($value instanceof \UnitEnum) {
 | 
			
		||||
            return new Expr\ClassConstFetch(new FullyQualified(\get_class($value)), new Identifier($value->name));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new \LogicException('Invalid value');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Comment\Doc|string $docComment The doc comment to normalize
 | 
			
		||||
     *
 | 
			
		||||
     * @return Comment\Doc The normalized doc comment
 | 
			
		||||
     */
 | 
			
		||||
    public static function normalizeDocComment($docComment): Comment\Doc {
 | 
			
		||||
        if ($docComment instanceof Comment\Doc) {
 | 
			
		||||
            return $docComment;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_string($docComment)) {
 | 
			
		||||
            return new Comment\Doc($docComment);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new \LogicException('Doc comment must be a string or an instance of PhpParser\Comment\Doc');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Normalizes a attribute: Converts attribute to the Attribute Group if needed.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Node\Attribute|Node\AttributeGroup $attribute
 | 
			
		||||
     *
 | 
			
		||||
     * @return Node\AttributeGroup The Attribute Group
 | 
			
		||||
     */
 | 
			
		||||
    public static function normalizeAttribute($attribute): Node\AttributeGroup {
 | 
			
		||||
        if ($attribute instanceof Node\AttributeGroup) {
 | 
			
		||||
            return $attribute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!($attribute instanceof Node\Attribute)) {
 | 
			
		||||
            throw new \LogicException('Attribute must be an instance of PhpParser\Node\Attribute or PhpParser\Node\AttributeGroup');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new Node\AttributeGroup([$attribute]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a modifier and returns new modifier bitmask.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $modifiers Existing modifiers
 | 
			
		||||
     * @param int $modifier Modifier to set
 | 
			
		||||
     *
 | 
			
		||||
     * @return int New modifiers
 | 
			
		||||
     */
 | 
			
		||||
    public static function addModifier(int $modifiers, int $modifier): int {
 | 
			
		||||
        Modifiers::verifyModifier($modifiers, $modifier);
 | 
			
		||||
        return $modifiers | $modifier;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a modifier and returns new modifier bitmask.
 | 
			
		||||
     * @return int New modifiers
 | 
			
		||||
     */
 | 
			
		||||
    public static function addClassModifier(int $existingModifiers, int $modifierToSet): int {
 | 
			
		||||
        Modifiers::verifyClassModifier($existingModifiers, $modifierToSet);
 | 
			
		||||
        return $existingModifiers | $modifierToSet;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										209
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Comment.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Comment.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,209 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
class Comment implements \JsonSerializable {
 | 
			
		||||
    protected string $text;
 | 
			
		||||
    protected int $startLine;
 | 
			
		||||
    protected int $startFilePos;
 | 
			
		||||
    protected int $startTokenPos;
 | 
			
		||||
    protected int $endLine;
 | 
			
		||||
    protected int $endFilePos;
 | 
			
		||||
    protected int $endTokenPos;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a comment node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $text Comment text (including comment delimiters like /*)
 | 
			
		||||
     * @param int $startLine Line number the comment started on
 | 
			
		||||
     * @param int $startFilePos File offset the comment started on
 | 
			
		||||
     * @param int $startTokenPos Token offset the comment started on
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        string $text,
 | 
			
		||||
        int $startLine = -1, int $startFilePos = -1, int $startTokenPos = -1,
 | 
			
		||||
        int $endLine = -1, int $endFilePos = -1, int $endTokenPos = -1
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->text = $text;
 | 
			
		||||
        $this->startLine = $startLine;
 | 
			
		||||
        $this->startFilePos = $startFilePos;
 | 
			
		||||
        $this->startTokenPos = $startTokenPos;
 | 
			
		||||
        $this->endLine = $endLine;
 | 
			
		||||
        $this->endFilePos = $endFilePos;
 | 
			
		||||
        $this->endTokenPos = $endTokenPos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the comment text.
 | 
			
		||||
     *
 | 
			
		||||
     * @return string The comment text (including comment delimiters like /*)
 | 
			
		||||
     */
 | 
			
		||||
    public function getText(): string {
 | 
			
		||||
        return $this->text;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the line number the comment started on.
 | 
			
		||||
     *
 | 
			
		||||
     * @return int Line number (or -1 if not available)
 | 
			
		||||
     * @phpstan-return -1|positive-int
 | 
			
		||||
     */
 | 
			
		||||
    public function getStartLine(): int {
 | 
			
		||||
        return $this->startLine;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the file offset the comment started on.
 | 
			
		||||
     *
 | 
			
		||||
     * @return int File offset (or -1 if not available)
 | 
			
		||||
     */
 | 
			
		||||
    public function getStartFilePos(): int {
 | 
			
		||||
        return $this->startFilePos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the token offset the comment started on.
 | 
			
		||||
     *
 | 
			
		||||
     * @return int Token offset (or -1 if not available)
 | 
			
		||||
     */
 | 
			
		||||
    public function getStartTokenPos(): int {
 | 
			
		||||
        return $this->startTokenPos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the line number the comment ends on.
 | 
			
		||||
     *
 | 
			
		||||
     * @return int Line number (or -1 if not available)
 | 
			
		||||
     * @phpstan-return -1|positive-int
 | 
			
		||||
     */
 | 
			
		||||
    public function getEndLine(): int {
 | 
			
		||||
        return $this->endLine;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the file offset the comment ends on.
 | 
			
		||||
     *
 | 
			
		||||
     * @return int File offset (or -1 if not available)
 | 
			
		||||
     */
 | 
			
		||||
    public function getEndFilePos(): int {
 | 
			
		||||
        return $this->endFilePos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the token offset the comment ends on.
 | 
			
		||||
     *
 | 
			
		||||
     * @return int Token offset (or -1 if not available)
 | 
			
		||||
     */
 | 
			
		||||
    public function getEndTokenPos(): int {
 | 
			
		||||
        return $this->endTokenPos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the comment text.
 | 
			
		||||
     *
 | 
			
		||||
     * @return string The comment text (including comment delimiters like /*)
 | 
			
		||||
     */
 | 
			
		||||
    public function __toString(): string {
 | 
			
		||||
        return $this->text;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the reformatted comment text.
 | 
			
		||||
     *
 | 
			
		||||
     * "Reformatted" here means that we try to clean up the whitespace at the
 | 
			
		||||
     * starts of the lines. This is necessary because we receive the comments
 | 
			
		||||
     * without leading whitespace on the first line, but with leading whitespace
 | 
			
		||||
     * on all subsequent lines.
 | 
			
		||||
     *
 | 
			
		||||
     * Additionally, this normalizes CRLF newlines to LF newlines.
 | 
			
		||||
     */
 | 
			
		||||
    public function getReformattedText(): string {
 | 
			
		||||
        $text = str_replace("\r\n", "\n", $this->text);
 | 
			
		||||
        $newlinePos = strpos($text, "\n");
 | 
			
		||||
        if (false === $newlinePos) {
 | 
			
		||||
            // Single line comments don't need further processing
 | 
			
		||||
            return $text;
 | 
			
		||||
        }
 | 
			
		||||
        if (preg_match('(^.*(?:\n\s+\*.*)+$)', $text)) {
 | 
			
		||||
            // Multi line comment of the type
 | 
			
		||||
            //
 | 
			
		||||
            //     /*
 | 
			
		||||
            //      * Some text.
 | 
			
		||||
            //      * Some more text.
 | 
			
		||||
            //      */
 | 
			
		||||
            //
 | 
			
		||||
            // is handled by replacing the whitespace sequences before the * by a single space
 | 
			
		||||
            return preg_replace('(^\s+\*)m', ' *', $text);
 | 
			
		||||
        }
 | 
			
		||||
        if (preg_match('(^/\*\*?\s*\n)', $text) && preg_match('(\n(\s*)\*/$)', $text, $matches)) {
 | 
			
		||||
            // Multi line comment of the type
 | 
			
		||||
            //
 | 
			
		||||
            //    /*
 | 
			
		||||
            //        Some text.
 | 
			
		||||
            //        Some more text.
 | 
			
		||||
            //    */
 | 
			
		||||
            //
 | 
			
		||||
            // is handled by removing the whitespace sequence on the line before the closing
 | 
			
		||||
            // */ on all lines. So if the last line is "    */", then "    " is removed at the
 | 
			
		||||
            // start of all lines.
 | 
			
		||||
            return preg_replace('(^' . preg_quote($matches[1]) . ')m', '', $text);
 | 
			
		||||
        }
 | 
			
		||||
        if (preg_match('(^/\*\*?\s*(?!\s))', $text, $matches)) {
 | 
			
		||||
            // Multi line comment of the type
 | 
			
		||||
            //
 | 
			
		||||
            //     /* Some text.
 | 
			
		||||
            //        Some more text.
 | 
			
		||||
            //          Indented text.
 | 
			
		||||
            //        Even more text. */
 | 
			
		||||
            //
 | 
			
		||||
            // is handled by removing the difference between the shortest whitespace prefix on all
 | 
			
		||||
            // lines and the length of the "/* " opening sequence.
 | 
			
		||||
            $prefixLen = $this->getShortestWhitespacePrefixLen(substr($text, $newlinePos + 1));
 | 
			
		||||
            $removeLen = $prefixLen - strlen($matches[0]);
 | 
			
		||||
            return preg_replace('(^\s{' . $removeLen . '})m', '', $text);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // No idea how to format this comment, so simply return as is
 | 
			
		||||
        return $text;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get length of shortest whitespace prefix (at the start of a line).
 | 
			
		||||
     *
 | 
			
		||||
     * If there is a line with no prefix whitespace, 0 is a valid return value.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $str String to check
 | 
			
		||||
     * @return int Length in characters. Tabs count as single characters.
 | 
			
		||||
     */
 | 
			
		||||
    private function getShortestWhitespacePrefixLen(string $str): int {
 | 
			
		||||
        $lines = explode("\n", $str);
 | 
			
		||||
        $shortestPrefixLen = \PHP_INT_MAX;
 | 
			
		||||
        foreach ($lines as $line) {
 | 
			
		||||
            preg_match('(^\s*)', $line, $matches);
 | 
			
		||||
            $prefixLen = strlen($matches[0]);
 | 
			
		||||
            if ($prefixLen < $shortestPrefixLen) {
 | 
			
		||||
                $shortestPrefixLen = $prefixLen;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $shortestPrefixLen;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return array{nodeType:string, text:mixed, line:mixed, filePos:mixed}
 | 
			
		||||
     */
 | 
			
		||||
    public function jsonSerialize(): array {
 | 
			
		||||
        // Technically not a node, but we make it look like one anyway
 | 
			
		||||
        $type = $this instanceof Comment\Doc ? 'Comment_Doc' : 'Comment';
 | 
			
		||||
        return [
 | 
			
		||||
            'nodeType' => $type,
 | 
			
		||||
            'text' => $this->text,
 | 
			
		||||
            // TODO: Rename these to include "start".
 | 
			
		||||
            'line' => $this->startLine,
 | 
			
		||||
            'filePos' => $this->startFilePos,
 | 
			
		||||
            'tokenPos' => $this->startTokenPos,
 | 
			
		||||
            'endLine' => $this->endLine,
 | 
			
		||||
            'endFilePos' => $this->endFilePos,
 | 
			
		||||
            'endTokenPos' => $this->endTokenPos,
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Comment;
 | 
			
		||||
 | 
			
		||||
class Doc extends \PhpParser\Comment {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/ConstExprEvaluationException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/ConstExprEvaluationException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
class ConstExprEvaluationException extends \Exception {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										237
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/ConstExprEvaluator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/ConstExprEvaluator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,237 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Node\Expr;
 | 
			
		||||
use PhpParser\Node\Scalar;
 | 
			
		||||
 | 
			
		||||
use function array_merge;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Evaluates constant expressions.
 | 
			
		||||
 *
 | 
			
		||||
 * This evaluator is able to evaluate all constant expressions (as defined by PHP), which can be
 | 
			
		||||
 * evaluated without further context. If a subexpression is not of this type, a user-provided
 | 
			
		||||
 * fallback evaluator is invoked. To support all constant expressions that are also supported by
 | 
			
		||||
 * PHP (and not already handled by this class), the fallback evaluator must be able to handle the
 | 
			
		||||
 * following node types:
 | 
			
		||||
 *
 | 
			
		||||
 *  * All Scalar\MagicConst\* nodes.
 | 
			
		||||
 *  * Expr\ConstFetch nodes. Only null/false/true are already handled by this class.
 | 
			
		||||
 *  * Expr\ClassConstFetch nodes.
 | 
			
		||||
 *
 | 
			
		||||
 * The fallback evaluator should throw ConstExprEvaluationException for nodes it cannot evaluate.
 | 
			
		||||
 *
 | 
			
		||||
 * The evaluation is dependent on runtime configuration in two respects: Firstly, floating
 | 
			
		||||
 * point to string conversions are affected by the precision ini setting. Secondly, they are also
 | 
			
		||||
 * affected by the LC_NUMERIC locale.
 | 
			
		||||
 */
 | 
			
		||||
class ConstExprEvaluator {
 | 
			
		||||
    /** @var callable|null */
 | 
			
		||||
    private $fallbackEvaluator;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a constant expression evaluator.
 | 
			
		||||
     *
 | 
			
		||||
     * The provided fallback evaluator is invoked whenever a subexpression cannot be evaluated. See
 | 
			
		||||
     * class doc comment for more information.
 | 
			
		||||
     *
 | 
			
		||||
     * @param callable|null $fallbackEvaluator To call if subexpression cannot be evaluated
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(?callable $fallbackEvaluator = null) {
 | 
			
		||||
        $this->fallbackEvaluator = $fallbackEvaluator ?? function (Expr $expr) {
 | 
			
		||||
            throw new ConstExprEvaluationException(
 | 
			
		||||
                "Expression of type {$expr->getType()} cannot be evaluated"
 | 
			
		||||
            );
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Silently evaluates a constant expression into a PHP value.
 | 
			
		||||
     *
 | 
			
		||||
     * Thrown Errors, warnings or notices will be converted into a ConstExprEvaluationException.
 | 
			
		||||
     * The original source of the exception is available through getPrevious().
 | 
			
		||||
     *
 | 
			
		||||
     * If some part of the expression cannot be evaluated, the fallback evaluator passed to the
 | 
			
		||||
     * constructor will be invoked. By default, if no fallback is provided, an exception of type
 | 
			
		||||
     * ConstExprEvaluationException is thrown.
 | 
			
		||||
     *
 | 
			
		||||
     * See class doc comment for caveats and limitations.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Expr $expr Constant expression to evaluate
 | 
			
		||||
     * @return mixed Result of evaluation
 | 
			
		||||
     *
 | 
			
		||||
     * @throws ConstExprEvaluationException if the expression cannot be evaluated or an error occurred
 | 
			
		||||
     */
 | 
			
		||||
    public function evaluateSilently(Expr $expr) {
 | 
			
		||||
        set_error_handler(function ($num, $str, $file, $line) {
 | 
			
		||||
            throw new \ErrorException($str, 0, $num, $file, $line);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            return $this->evaluate($expr);
 | 
			
		||||
        } catch (\Throwable $e) {
 | 
			
		||||
            if (!$e instanceof ConstExprEvaluationException) {
 | 
			
		||||
                $e = new ConstExprEvaluationException(
 | 
			
		||||
                    "An error occurred during constant expression evaluation", 0, $e);
 | 
			
		||||
            }
 | 
			
		||||
            throw $e;
 | 
			
		||||
        } finally {
 | 
			
		||||
            restore_error_handler();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Directly evaluates a constant expression into a PHP value.
 | 
			
		||||
     *
 | 
			
		||||
     * May generate Error exceptions, warnings or notices. Use evaluateSilently() to convert these
 | 
			
		||||
     * into a ConstExprEvaluationException.
 | 
			
		||||
     *
 | 
			
		||||
     * If some part of the expression cannot be evaluated, the fallback evaluator passed to the
 | 
			
		||||
     * constructor will be invoked. By default, if no fallback is provided, an exception of type
 | 
			
		||||
     * ConstExprEvaluationException is thrown.
 | 
			
		||||
     *
 | 
			
		||||
     * See class doc comment for caveats and limitations.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Expr $expr Constant expression to evaluate
 | 
			
		||||
     * @return mixed Result of evaluation
 | 
			
		||||
     *
 | 
			
		||||
     * @throws ConstExprEvaluationException if the expression cannot be evaluated
 | 
			
		||||
     */
 | 
			
		||||
    public function evaluateDirectly(Expr $expr) {
 | 
			
		||||
        return $this->evaluate($expr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @return mixed */
 | 
			
		||||
    private function evaluate(Expr $expr) {
 | 
			
		||||
        if ($expr instanceof Scalar\Int_
 | 
			
		||||
            || $expr instanceof Scalar\Float_
 | 
			
		||||
            || $expr instanceof Scalar\String_
 | 
			
		||||
        ) {
 | 
			
		||||
            return $expr->value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($expr instanceof Expr\Array_) {
 | 
			
		||||
            return $this->evaluateArray($expr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Unary operators
 | 
			
		||||
        if ($expr instanceof Expr\UnaryPlus) {
 | 
			
		||||
            return +$this->evaluate($expr->expr);
 | 
			
		||||
        }
 | 
			
		||||
        if ($expr instanceof Expr\UnaryMinus) {
 | 
			
		||||
            return -$this->evaluate($expr->expr);
 | 
			
		||||
        }
 | 
			
		||||
        if ($expr instanceof Expr\BooleanNot) {
 | 
			
		||||
            return !$this->evaluate($expr->expr);
 | 
			
		||||
        }
 | 
			
		||||
        if ($expr instanceof Expr\BitwiseNot) {
 | 
			
		||||
            return ~$this->evaluate($expr->expr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($expr instanceof Expr\BinaryOp) {
 | 
			
		||||
            return $this->evaluateBinaryOp($expr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($expr instanceof Expr\Ternary) {
 | 
			
		||||
            return $this->evaluateTernary($expr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($expr instanceof Expr\ArrayDimFetch && null !== $expr->dim) {
 | 
			
		||||
            return $this->evaluate($expr->var)[$this->evaluate($expr->dim)];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($expr instanceof Expr\ConstFetch) {
 | 
			
		||||
            return $this->evaluateConstFetch($expr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ($this->fallbackEvaluator)($expr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function evaluateArray(Expr\Array_ $expr): array {
 | 
			
		||||
        $array = [];
 | 
			
		||||
        foreach ($expr->items as $item) {
 | 
			
		||||
            if (null !== $item->key) {
 | 
			
		||||
                $array[$this->evaluate($item->key)] = $this->evaluate($item->value);
 | 
			
		||||
            } elseif ($item->unpack) {
 | 
			
		||||
                $array = array_merge($array, $this->evaluate($item->value));
 | 
			
		||||
            } else {
 | 
			
		||||
                $array[] = $this->evaluate($item->value);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @return mixed */
 | 
			
		||||
    private function evaluateTernary(Expr\Ternary $expr) {
 | 
			
		||||
        if (null === $expr->if) {
 | 
			
		||||
            return $this->evaluate($expr->cond) ?: $this->evaluate($expr->else);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->evaluate($expr->cond)
 | 
			
		||||
            ? $this->evaluate($expr->if)
 | 
			
		||||
            : $this->evaluate($expr->else);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @return mixed */
 | 
			
		||||
    private function evaluateBinaryOp(Expr\BinaryOp $expr) {
 | 
			
		||||
        if ($expr instanceof Expr\BinaryOp\Coalesce
 | 
			
		||||
            && $expr->left instanceof Expr\ArrayDimFetch
 | 
			
		||||
        ) {
 | 
			
		||||
            // This needs to be special cased to respect BP_VAR_IS fetch semantics
 | 
			
		||||
            return $this->evaluate($expr->left->var)[$this->evaluate($expr->left->dim)]
 | 
			
		||||
                ?? $this->evaluate($expr->right);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // The evaluate() calls are repeated in each branch, because some of the operators are
 | 
			
		||||
        // short-circuiting and evaluating the RHS in advance may be illegal in that case
 | 
			
		||||
        $l = $expr->left;
 | 
			
		||||
        $r = $expr->right;
 | 
			
		||||
        switch ($expr->getOperatorSigil()) {
 | 
			
		||||
            case '&':   return $this->evaluate($l) &   $this->evaluate($r);
 | 
			
		||||
            case '|':   return $this->evaluate($l) |   $this->evaluate($r);
 | 
			
		||||
            case '^':   return $this->evaluate($l) ^   $this->evaluate($r);
 | 
			
		||||
            case '&&':  return $this->evaluate($l) &&  $this->evaluate($r);
 | 
			
		||||
            case '||':  return $this->evaluate($l) ||  $this->evaluate($r);
 | 
			
		||||
            case '??':  return $this->evaluate($l) ??  $this->evaluate($r);
 | 
			
		||||
            case '.':   return $this->evaluate($l) .   $this->evaluate($r);
 | 
			
		||||
            case '/':   return $this->evaluate($l) /   $this->evaluate($r);
 | 
			
		||||
            case '==':  return $this->evaluate($l) ==  $this->evaluate($r);
 | 
			
		||||
            case '>':   return $this->evaluate($l) >   $this->evaluate($r);
 | 
			
		||||
            case '>=':  return $this->evaluate($l) >=  $this->evaluate($r);
 | 
			
		||||
            case '===': return $this->evaluate($l) === $this->evaluate($r);
 | 
			
		||||
            case 'and': return $this->evaluate($l) and $this->evaluate($r);
 | 
			
		||||
            case 'or':  return $this->evaluate($l) or  $this->evaluate($r);
 | 
			
		||||
            case 'xor': return $this->evaluate($l) xor $this->evaluate($r);
 | 
			
		||||
            case '-':   return $this->evaluate($l) -   $this->evaluate($r);
 | 
			
		||||
            case '%':   return $this->evaluate($l) %   $this->evaluate($r);
 | 
			
		||||
            case '*':   return $this->evaluate($l) *   $this->evaluate($r);
 | 
			
		||||
            case '!=':  return $this->evaluate($l) !=  $this->evaluate($r);
 | 
			
		||||
            case '!==': return $this->evaluate($l) !== $this->evaluate($r);
 | 
			
		||||
            case '+':   return $this->evaluate($l) +   $this->evaluate($r);
 | 
			
		||||
            case '**':  return $this->evaluate($l) **  $this->evaluate($r);
 | 
			
		||||
            case '<<':  return $this->evaluate($l) <<  $this->evaluate($r);
 | 
			
		||||
            case '>>':  return $this->evaluate($l) >>  $this->evaluate($r);
 | 
			
		||||
            case '<':   return $this->evaluate($l) <   $this->evaluate($r);
 | 
			
		||||
            case '<=':  return $this->evaluate($l) <=  $this->evaluate($r);
 | 
			
		||||
            case '<=>': return $this->evaluate($l) <=> $this->evaluate($r);
 | 
			
		||||
            case '|>':
 | 
			
		||||
                $lval = $this->evaluate($l);
 | 
			
		||||
                return $this->evaluate($r)($lval);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new \Exception('Should not happen');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @return mixed */
 | 
			
		||||
    private function evaluateConstFetch(Expr\ConstFetch $expr) {
 | 
			
		||||
        $name = $expr->name->toLowerString();
 | 
			
		||||
        switch ($name) {
 | 
			
		||||
            case 'null': return null;
 | 
			
		||||
            case 'false': return false;
 | 
			
		||||
            case 'true': return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ($this->fallbackEvaluator)($expr);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										173
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Error.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Error.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,173 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
class Error extends \RuntimeException {
 | 
			
		||||
    protected string $rawMessage;
 | 
			
		||||
    /** @var array<string, mixed> */
 | 
			
		||||
    protected array $attributes;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates an Exception signifying a parse error.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $message Error message
 | 
			
		||||
     * @param array<string, mixed> $attributes Attributes of node/token where error occurred
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(string $message, array $attributes = []) {
 | 
			
		||||
        $this->rawMessage = $message;
 | 
			
		||||
        $this->attributes = $attributes;
 | 
			
		||||
        $this->updateMessage();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the error message
 | 
			
		||||
     *
 | 
			
		||||
     * @return string Error message
 | 
			
		||||
     */
 | 
			
		||||
    public function getRawMessage(): string {
 | 
			
		||||
        return $this->rawMessage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the line the error starts in.
 | 
			
		||||
     *
 | 
			
		||||
     * @return int Error start line
 | 
			
		||||
     * @phpstan-return -1|positive-int
 | 
			
		||||
     */
 | 
			
		||||
    public function getStartLine(): int {
 | 
			
		||||
        return $this->attributes['startLine'] ?? -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the line the error ends in.
 | 
			
		||||
     *
 | 
			
		||||
     * @return int Error end line
 | 
			
		||||
     * @phpstan-return -1|positive-int
 | 
			
		||||
     */
 | 
			
		||||
    public function getEndLine(): int {
 | 
			
		||||
        return $this->attributes['endLine'] ?? -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the attributes of the node/token the error occurred at.
 | 
			
		||||
     *
 | 
			
		||||
     * @return array<string, mixed>
 | 
			
		||||
     */
 | 
			
		||||
    public function getAttributes(): array {
 | 
			
		||||
        return $this->attributes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the attributes of the node/token the error occurred at.
 | 
			
		||||
     *
 | 
			
		||||
     * @param array<string, mixed> $attributes
 | 
			
		||||
     */
 | 
			
		||||
    public function setAttributes(array $attributes): void {
 | 
			
		||||
        $this->attributes = $attributes;
 | 
			
		||||
        $this->updateMessage();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the line of the PHP file the error occurred in.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $message Error message
 | 
			
		||||
     */
 | 
			
		||||
    public function setRawMessage(string $message): void {
 | 
			
		||||
        $this->rawMessage = $message;
 | 
			
		||||
        $this->updateMessage();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the line the error starts in.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $line Error start line
 | 
			
		||||
     */
 | 
			
		||||
    public function setStartLine(int $line): void {
 | 
			
		||||
        $this->attributes['startLine'] = $line;
 | 
			
		||||
        $this->updateMessage();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns whether the error has start and end column information.
 | 
			
		||||
     *
 | 
			
		||||
     * For column information enable the startFilePos and endFilePos in the lexer options.
 | 
			
		||||
     */
 | 
			
		||||
    public function hasColumnInfo(): bool {
 | 
			
		||||
        return isset($this->attributes['startFilePos'], $this->attributes['endFilePos']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the start column (1-based) into the line where the error started.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $code Source code of the file
 | 
			
		||||
     */
 | 
			
		||||
    public function getStartColumn(string $code): int {
 | 
			
		||||
        if (!$this->hasColumnInfo()) {
 | 
			
		||||
            throw new \RuntimeException('Error does not have column information');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->toColumn($code, $this->attributes['startFilePos']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the end column (1-based) into the line where the error ended.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $code Source code of the file
 | 
			
		||||
     */
 | 
			
		||||
    public function getEndColumn(string $code): int {
 | 
			
		||||
        if (!$this->hasColumnInfo()) {
 | 
			
		||||
            throw new \RuntimeException('Error does not have column information');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->toColumn($code, $this->attributes['endFilePos']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Formats message including line and column information.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $code Source code associated with the error, for calculation of the columns
 | 
			
		||||
     *
 | 
			
		||||
     * @return string Formatted message
 | 
			
		||||
     */
 | 
			
		||||
    public function getMessageWithColumnInfo(string $code): string {
 | 
			
		||||
        return sprintf(
 | 
			
		||||
            '%s from %d:%d to %d:%d', $this->getRawMessage(),
 | 
			
		||||
            $this->getStartLine(), $this->getStartColumn($code),
 | 
			
		||||
            $this->getEndLine(), $this->getEndColumn($code)
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Converts a file offset into a column.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $code Source code that $pos indexes into
 | 
			
		||||
     * @param int $pos 0-based position in $code
 | 
			
		||||
     *
 | 
			
		||||
     * @return int 1-based column (relative to start of line)
 | 
			
		||||
     */
 | 
			
		||||
    private function toColumn(string $code, int $pos): int {
 | 
			
		||||
        if ($pos > strlen($code)) {
 | 
			
		||||
            throw new \RuntimeException('Invalid position information');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $lineStartPos = strrpos($code, "\n", $pos - strlen($code));
 | 
			
		||||
        if (false === $lineStartPos) {
 | 
			
		||||
            $lineStartPos = -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $pos - $lineStartPos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates the exception message after a change to rawMessage or rawLine.
 | 
			
		||||
     */
 | 
			
		||||
    protected function updateMessage(): void {
 | 
			
		||||
        $this->message = $this->rawMessage;
 | 
			
		||||
 | 
			
		||||
        if (-1 === $this->getStartLine()) {
 | 
			
		||||
            $this->message .= ' on unknown line';
 | 
			
		||||
        } else {
 | 
			
		||||
            $this->message .= ' on line ' . $this->getStartLine();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
interface ErrorHandler {
 | 
			
		||||
    /**
 | 
			
		||||
     * Handle an error generated during lexing, parsing or some other operation.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Error $error The error that needs to be handled
 | 
			
		||||
     */
 | 
			
		||||
    public function handleError(Error $error): void;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Collecting.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Collecting.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\ErrorHandler;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Error;
 | 
			
		||||
use PhpParser\ErrorHandler;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Error handler that collects all errors into an array.
 | 
			
		||||
 *
 | 
			
		||||
 * This allows graceful handling of errors.
 | 
			
		||||
 */
 | 
			
		||||
class Collecting implements ErrorHandler {
 | 
			
		||||
    /** @var Error[] Collected errors */
 | 
			
		||||
    private array $errors = [];
 | 
			
		||||
 | 
			
		||||
    public function handleError(Error $error): void {
 | 
			
		||||
        $this->errors[] = $error;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get collected errors.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Error[]
 | 
			
		||||
     */
 | 
			
		||||
    public function getErrors(): array {
 | 
			
		||||
        return $this->errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check whether there are any errors.
 | 
			
		||||
     */
 | 
			
		||||
    public function hasErrors(): bool {
 | 
			
		||||
        return !empty($this->errors);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reset/clear collected errors.
 | 
			
		||||
     */
 | 
			
		||||
    public function clearErrors(): void {
 | 
			
		||||
        $this->errors = [];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\ErrorHandler;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Error;
 | 
			
		||||
use PhpParser\ErrorHandler;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Error handler that handles all errors by throwing them.
 | 
			
		||||
 *
 | 
			
		||||
 * This is the default strategy used by all components.
 | 
			
		||||
 */
 | 
			
		||||
class Throwing implements ErrorHandler {
 | 
			
		||||
    public function handleError(Error $error): void {
 | 
			
		||||
        throw $error;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Internal/DiffElem.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Internal/DiffElem.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Internal;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 */
 | 
			
		||||
class DiffElem {
 | 
			
		||||
    public const TYPE_KEEP = 0;
 | 
			
		||||
    public const TYPE_REMOVE = 1;
 | 
			
		||||
    public const TYPE_ADD = 2;
 | 
			
		||||
    public const TYPE_REPLACE = 3;
 | 
			
		||||
 | 
			
		||||
    /** @var int One of the TYPE_* constants */
 | 
			
		||||
    public int $type;
 | 
			
		||||
    /** @var mixed Is null for add operations */
 | 
			
		||||
    public $old;
 | 
			
		||||
    /** @var mixed Is null for remove operations */
 | 
			
		||||
    public $new;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param int $type One of the TYPE_* constants
 | 
			
		||||
     * @param mixed $old Is null for add operations
 | 
			
		||||
     * @param mixed $new Is null for remove operations
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(int $type, $old, $new) {
 | 
			
		||||
        $this->type = $type;
 | 
			
		||||
        $this->old = $old;
 | 
			
		||||
        $this->new = $new;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										178
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,178 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Internal;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implements the Myers diff algorithm.
 | 
			
		||||
 *
 | 
			
		||||
 * Myers, Eugene W. "An O (ND) difference algorithm and its variations."
 | 
			
		||||
 * Algorithmica 1.1 (1986): 251-266.
 | 
			
		||||
 *
 | 
			
		||||
 * @template T
 | 
			
		||||
 * @internal
 | 
			
		||||
 */
 | 
			
		||||
class Differ {
 | 
			
		||||
    /** @var callable(T, T): bool */
 | 
			
		||||
    private $isEqual;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create differ over the given equality relation.
 | 
			
		||||
     *
 | 
			
		||||
     * @param callable(T, T): bool $isEqual Equality relation
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(callable $isEqual) {
 | 
			
		||||
        $this->isEqual = $isEqual;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Calculate diff (edit script) from $old to $new.
 | 
			
		||||
     *
 | 
			
		||||
     * @param T[] $old Original array
 | 
			
		||||
     * @param T[] $new New array
 | 
			
		||||
     *
 | 
			
		||||
     * @return DiffElem[] Diff (edit script)
 | 
			
		||||
     */
 | 
			
		||||
    public function diff(array $old, array $new): array {
 | 
			
		||||
        $old = \array_values($old);
 | 
			
		||||
        $new = \array_values($new);
 | 
			
		||||
        list($trace, $x, $y) = $this->calculateTrace($old, $new);
 | 
			
		||||
        return $this->extractDiff($trace, $x, $y, $old, $new);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Calculate diff, including "replace" operations.
 | 
			
		||||
     *
 | 
			
		||||
     * If a sequence of remove operations is followed by the same number of add operations, these
 | 
			
		||||
     * will be coalesced into replace operations.
 | 
			
		||||
     *
 | 
			
		||||
     * @param T[] $old Original array
 | 
			
		||||
     * @param T[] $new New array
 | 
			
		||||
     *
 | 
			
		||||
     * @return DiffElem[] Diff (edit script), including replace operations
 | 
			
		||||
     */
 | 
			
		||||
    public function diffWithReplacements(array $old, array $new): array {
 | 
			
		||||
        return $this->coalesceReplacements($this->diff($old, $new));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param T[] $old
 | 
			
		||||
     * @param T[] $new
 | 
			
		||||
     * @return array{array<int, array<int, int>>, int, int}
 | 
			
		||||
     */
 | 
			
		||||
    private function calculateTrace(array $old, array $new): array {
 | 
			
		||||
        $n = \count($old);
 | 
			
		||||
        $m = \count($new);
 | 
			
		||||
        $max = $n + $m;
 | 
			
		||||
        $v = [1 => 0];
 | 
			
		||||
        $trace = [];
 | 
			
		||||
        for ($d = 0; $d <= $max; $d++) {
 | 
			
		||||
            $trace[] = $v;
 | 
			
		||||
            for ($k = -$d; $k <= $d; $k += 2) {
 | 
			
		||||
                if ($k === -$d || ($k !== $d && $v[$k - 1] < $v[$k + 1])) {
 | 
			
		||||
                    $x = $v[$k + 1];
 | 
			
		||||
                } else {
 | 
			
		||||
                    $x = $v[$k - 1] + 1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                $y = $x - $k;
 | 
			
		||||
                while ($x < $n && $y < $m && ($this->isEqual)($old[$x], $new[$y])) {
 | 
			
		||||
                    $x++;
 | 
			
		||||
                    $y++;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                $v[$k] = $x;
 | 
			
		||||
                if ($x >= $n && $y >= $m) {
 | 
			
		||||
                    return [$trace, $x, $y];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        throw new \Exception('Should not happen');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param array<int, array<int, int>> $trace
 | 
			
		||||
     * @param T[] $old
 | 
			
		||||
     * @param T[] $new
 | 
			
		||||
     * @return DiffElem[]
 | 
			
		||||
     */
 | 
			
		||||
    private function extractDiff(array $trace, int $x, int $y, array $old, array $new): array {
 | 
			
		||||
        $result = [];
 | 
			
		||||
        for ($d = \count($trace) - 1; $d >= 0; $d--) {
 | 
			
		||||
            $v = $trace[$d];
 | 
			
		||||
            $k = $x - $y;
 | 
			
		||||
 | 
			
		||||
            if ($k === -$d || ($k !== $d && $v[$k - 1] < $v[$k + 1])) {
 | 
			
		||||
                $prevK = $k + 1;
 | 
			
		||||
            } else {
 | 
			
		||||
                $prevK = $k - 1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $prevX = $v[$prevK];
 | 
			
		||||
            $prevY = $prevX - $prevK;
 | 
			
		||||
 | 
			
		||||
            while ($x > $prevX && $y > $prevY) {
 | 
			
		||||
                $result[] = new DiffElem(DiffElem::TYPE_KEEP, $old[$x - 1], $new[$y - 1]);
 | 
			
		||||
                $x--;
 | 
			
		||||
                $y--;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($d === 0) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            while ($x > $prevX) {
 | 
			
		||||
                $result[] = new DiffElem(DiffElem::TYPE_REMOVE, $old[$x - 1], null);
 | 
			
		||||
                $x--;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            while ($y > $prevY) {
 | 
			
		||||
                $result[] = new DiffElem(DiffElem::TYPE_ADD, null, $new[$y - 1]);
 | 
			
		||||
                $y--;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return array_reverse($result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Coalesce equal-length sequences of remove+add into a replace operation.
 | 
			
		||||
     *
 | 
			
		||||
     * @param DiffElem[] $diff
 | 
			
		||||
     * @return DiffElem[]
 | 
			
		||||
     */
 | 
			
		||||
    private function coalesceReplacements(array $diff): array {
 | 
			
		||||
        $newDiff = [];
 | 
			
		||||
        $c = \count($diff);
 | 
			
		||||
        for ($i = 0; $i < $c; $i++) {
 | 
			
		||||
            $diffType = $diff[$i]->type;
 | 
			
		||||
            if ($diffType !== DiffElem::TYPE_REMOVE) {
 | 
			
		||||
                $newDiff[] = $diff[$i];
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $j = $i;
 | 
			
		||||
            while ($j < $c && $diff[$j]->type === DiffElem::TYPE_REMOVE) {
 | 
			
		||||
                $j++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $k = $j;
 | 
			
		||||
            while ($k < $c && $diff[$k]->type === DiffElem::TYPE_ADD) {
 | 
			
		||||
                $k++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($j - $i === $k - $j) {
 | 
			
		||||
                $len = $j - $i;
 | 
			
		||||
                for ($n = 0; $n < $len; $n++) {
 | 
			
		||||
                    $newDiff[] = new DiffElem(
 | 
			
		||||
                        DiffElem::TYPE_REPLACE, $diff[$i + $n]->old, $diff[$j + $n]->new
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                for (; $i < $k; $i++) {
 | 
			
		||||
                    $newDiff[] = $diff[$i];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            $i = $k - 1;
 | 
			
		||||
        }
 | 
			
		||||
        return $newDiff;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Internal;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\Node\Expr;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This node is used internally by the format-preserving pretty printer to print anonymous classes.
 | 
			
		||||
 *
 | 
			
		||||
 * The normal anonymous class structure violates assumptions about the order of token offsets.
 | 
			
		||||
 * Namely, the constructor arguments are part of the Expr\New_ node and follow the class node, even
 | 
			
		||||
 * though they are actually interleaved with them. This special node type is used temporarily to
 | 
			
		||||
 * restore a sane token offset order.
 | 
			
		||||
 *
 | 
			
		||||
 * @internal
 | 
			
		||||
 */
 | 
			
		||||
class PrintableNewAnonClassNode extends Expr {
 | 
			
		||||
    /** @var Node\AttributeGroup[] PHP attribute groups */
 | 
			
		||||
    public array $attrGroups;
 | 
			
		||||
    /** @var int Modifiers */
 | 
			
		||||
    public int $flags;
 | 
			
		||||
    /** @var (Node\Arg|Node\VariadicPlaceholder)[] Arguments */
 | 
			
		||||
    public array $args;
 | 
			
		||||
    /** @var null|Node\Name Name of extended class */
 | 
			
		||||
    public ?Node\Name $extends;
 | 
			
		||||
    /** @var Node\Name[] Names of implemented interfaces */
 | 
			
		||||
    public array $implements;
 | 
			
		||||
    /** @var Node\Stmt[] Statements */
 | 
			
		||||
    public array $stmts;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param Node\AttributeGroup[] $attrGroups PHP attribute groups
 | 
			
		||||
     * @param (Node\Arg|Node\VariadicPlaceholder)[] $args Arguments
 | 
			
		||||
     * @param Node\Name|null $extends Name of extended class
 | 
			
		||||
     * @param Node\Name[] $implements Names of implemented interfaces
 | 
			
		||||
     * @param Node\Stmt[] $stmts Statements
 | 
			
		||||
     * @param array<string, mixed> $attributes Attributes
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        array $attrGroups, int $flags, array $args, ?Node\Name $extends, array $implements,
 | 
			
		||||
        array $stmts, array $attributes
 | 
			
		||||
    ) {
 | 
			
		||||
        parent::__construct($attributes);
 | 
			
		||||
        $this->attrGroups = $attrGroups;
 | 
			
		||||
        $this->flags = $flags;
 | 
			
		||||
        $this->args = $args;
 | 
			
		||||
        $this->extends = $extends;
 | 
			
		||||
        $this->implements = $implements;
 | 
			
		||||
        $this->stmts = $stmts;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function fromNewNode(Expr\New_ $newNode): self {
 | 
			
		||||
        $class = $newNode->class;
 | 
			
		||||
        assert($class instanceof Node\Stmt\Class_);
 | 
			
		||||
        // We don't assert that $class->name is null here, to allow consumers to assign unique names
 | 
			
		||||
        // to anonymous classes for their own purposes. We simplify ignore the name here.
 | 
			
		||||
        return new self(
 | 
			
		||||
            $class->attrGroups, $class->flags, $newNode->args, $class->extends, $class->implements,
 | 
			
		||||
            $class->stmts, $newNode->getAttributes()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getType(): string {
 | 
			
		||||
        return 'Expr_PrintableNewAnonClass';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getSubNodeNames(): array {
 | 
			
		||||
        return ['attrGroups', 'flags', 'args', 'extends', 'implements', 'stmts'];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										237
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenPolyfill.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenPolyfill.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,237 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Internal;
 | 
			
		||||
 | 
			
		||||
if (\PHP_VERSION_ID >= 80000) {
 | 
			
		||||
    class TokenPolyfill extends \PhpToken {
 | 
			
		||||
    }
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is a polyfill for the PhpToken class introduced in PHP 8.0. We do not actually polyfill
 | 
			
		||||
 * PhpToken, because composer might end up picking a different polyfill implementation, which does
 | 
			
		||||
 * not meet our requirements.
 | 
			
		||||
 *
 | 
			
		||||
 * @internal
 | 
			
		||||
 */
 | 
			
		||||
class TokenPolyfill {
 | 
			
		||||
    /** @var int The ID of the token. Either a T_* constant of a character code < 256. */
 | 
			
		||||
    public int $id;
 | 
			
		||||
    /** @var string The textual content of the token. */
 | 
			
		||||
    public string $text;
 | 
			
		||||
    /** @var int The 1-based starting line of the token (or -1 if unknown). */
 | 
			
		||||
    public int $line;
 | 
			
		||||
    /** @var int The 0-based starting position of the token (or -1 if unknown). */
 | 
			
		||||
    public int $pos;
 | 
			
		||||
 | 
			
		||||
    /** @var array<int, bool> Tokens ignored by the PHP parser. */
 | 
			
		||||
    private const IGNORABLE_TOKENS = [
 | 
			
		||||
        \T_WHITESPACE => true,
 | 
			
		||||
        \T_COMMENT => true,
 | 
			
		||||
        \T_DOC_COMMENT => true,
 | 
			
		||||
        \T_OPEN_TAG => true,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    /** @var array<int, bool> Tokens that may be part of a T_NAME_* identifier. */
 | 
			
		||||
    private static array $identifierTokens;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a Token with the given ID and text, as well optional line and position information.
 | 
			
		||||
     */
 | 
			
		||||
    final public function __construct(int $id, string $text, int $line = -1, int $pos = -1) {
 | 
			
		||||
        $this->id = $id;
 | 
			
		||||
        $this->text = $text;
 | 
			
		||||
        $this->line = $line;
 | 
			
		||||
        $this->pos = $pos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the name of the token. For single-char tokens this will be the token character.
 | 
			
		||||
     * Otherwise it will be a T_* style name, or null if the token ID is unknown.
 | 
			
		||||
     */
 | 
			
		||||
    public function getTokenName(): ?string {
 | 
			
		||||
        if ($this->id < 256) {
 | 
			
		||||
            return \chr($this->id);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $name = token_name($this->id);
 | 
			
		||||
        return $name === 'UNKNOWN' ? null : $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check whether the token is of the given kind. The kind may be either an integer that matches
 | 
			
		||||
     * the token ID, a string that matches the token text, or an array of integers/strings. In the
 | 
			
		||||
     * latter case, the function returns true if any of the kinds in the array match.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int|string|(int|string)[] $kind
 | 
			
		||||
     */
 | 
			
		||||
    public function is($kind): bool {
 | 
			
		||||
        if (\is_int($kind)) {
 | 
			
		||||
            return $this->id === $kind;
 | 
			
		||||
        }
 | 
			
		||||
        if (\is_string($kind)) {
 | 
			
		||||
            return $this->text === $kind;
 | 
			
		||||
        }
 | 
			
		||||
        if (\is_array($kind)) {
 | 
			
		||||
            foreach ($kind as $entry) {
 | 
			
		||||
                if (\is_int($entry)) {
 | 
			
		||||
                    if ($this->id === $entry) {
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                } elseif (\is_string($entry)) {
 | 
			
		||||
                    if ($this->text === $entry) {
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    throw new \TypeError(
 | 
			
		||||
                        'Argument #1 ($kind) must only have elements of type string|int, ' .
 | 
			
		||||
                        gettype($entry) . ' given');
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        throw new \TypeError(
 | 
			
		||||
            'Argument #1 ($kind) must be of type string|int|array, ' .gettype($kind) . ' given');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check whether this token would be ignored by the PHP parser. Returns true for T_WHITESPACE,
 | 
			
		||||
     * T_COMMENT, T_DOC_COMMENT and T_OPEN_TAG, and false for everything else.
 | 
			
		||||
     */
 | 
			
		||||
    public function isIgnorable(): bool {
 | 
			
		||||
        return isset(self::IGNORABLE_TOKENS[$this->id]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return the textual content of the token.
 | 
			
		||||
     */
 | 
			
		||||
    public function __toString(): string {
 | 
			
		||||
        return $this->text;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Tokenize the given source code and return an array of tokens.
 | 
			
		||||
     *
 | 
			
		||||
     * This performs certain canonicalizations to match the PHP 8.0 token format:
 | 
			
		||||
     *  * Bad characters are represented using T_BAD_CHARACTER rather than omitted.
 | 
			
		||||
     *  * T_COMMENT does not include trailing newlines, instead the newline is part of a following
 | 
			
		||||
     *    T_WHITESPACE token.
 | 
			
		||||
     *  * Namespaced names are represented using T_NAME_* tokens.
 | 
			
		||||
     *
 | 
			
		||||
     * @return static[]
 | 
			
		||||
     */
 | 
			
		||||
    public static function tokenize(string $code, int $flags = 0): array {
 | 
			
		||||
        self::init();
 | 
			
		||||
 | 
			
		||||
        $tokens = [];
 | 
			
		||||
        $line = 1;
 | 
			
		||||
        $pos = 0;
 | 
			
		||||
        $origTokens = \token_get_all($code, $flags);
 | 
			
		||||
 | 
			
		||||
        $numTokens = \count($origTokens);
 | 
			
		||||
        for ($i = 0; $i < $numTokens; $i++) {
 | 
			
		||||
            $token = $origTokens[$i];
 | 
			
		||||
            if (\is_string($token)) {
 | 
			
		||||
                if (\strlen($token) === 2) {
 | 
			
		||||
                    // b" and B" are tokenized as single-char tokens, even though they aren't.
 | 
			
		||||
                    $tokens[] = new static(\ord('"'), $token, $line, $pos);
 | 
			
		||||
                    $pos += 2;
 | 
			
		||||
                } else {
 | 
			
		||||
                    $tokens[] = new static(\ord($token), $token, $line, $pos);
 | 
			
		||||
                    $pos++;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                $id = $token[0];
 | 
			
		||||
                $text = $token[1];
 | 
			
		||||
 | 
			
		||||
                // Emulate PHP 8.0 comment format, which does not include trailing whitespace anymore.
 | 
			
		||||
                if ($id === \T_COMMENT && \substr($text, 0, 2) !== '/*' &&
 | 
			
		||||
                    \preg_match('/(\r\n|\n|\r)$/D', $text, $matches)
 | 
			
		||||
                ) {
 | 
			
		||||
                    $trailingNewline = $matches[0];
 | 
			
		||||
                    $text = \substr($text, 0, -\strlen($trailingNewline));
 | 
			
		||||
                    $tokens[] = new static($id, $text, $line, $pos);
 | 
			
		||||
                    $pos += \strlen($text);
 | 
			
		||||
 | 
			
		||||
                    if ($i + 1 < $numTokens && $origTokens[$i + 1][0] === \T_WHITESPACE) {
 | 
			
		||||
                        // Move trailing newline into following T_WHITESPACE token, if it already exists.
 | 
			
		||||
                        $origTokens[$i + 1][1] = $trailingNewline . $origTokens[$i + 1][1];
 | 
			
		||||
                        $origTokens[$i + 1][2]--;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        // Otherwise, we need to create a new T_WHITESPACE token.
 | 
			
		||||
                        $tokens[] = new static(\T_WHITESPACE, $trailingNewline, $line, $pos);
 | 
			
		||||
                        $line++;
 | 
			
		||||
                        $pos += \strlen($trailingNewline);
 | 
			
		||||
                    }
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Emulate PHP 8.0 T_NAME_* tokens, by combining sequences of T_NS_SEPARATOR and
 | 
			
		||||
                // T_STRING into a single token.
 | 
			
		||||
                if (($id === \T_NS_SEPARATOR || isset(self::$identifierTokens[$id]))) {
 | 
			
		||||
                    $newText = $text;
 | 
			
		||||
                    $lastWasSeparator = $id === \T_NS_SEPARATOR;
 | 
			
		||||
                    for ($j = $i + 1; $j < $numTokens; $j++) {
 | 
			
		||||
                        if ($lastWasSeparator) {
 | 
			
		||||
                            if (!isset(self::$identifierTokens[$origTokens[$j][0]])) {
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                            $lastWasSeparator = false;
 | 
			
		||||
                        } else {
 | 
			
		||||
                            if ($origTokens[$j][0] !== \T_NS_SEPARATOR) {
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                            $lastWasSeparator = true;
 | 
			
		||||
                        }
 | 
			
		||||
                        $newText .= $origTokens[$j][1];
 | 
			
		||||
                    }
 | 
			
		||||
                    if ($lastWasSeparator) {
 | 
			
		||||
                        // Trailing separator is not part of the name.
 | 
			
		||||
                        $j--;
 | 
			
		||||
                        $newText = \substr($newText, 0, -1);
 | 
			
		||||
                    }
 | 
			
		||||
                    if ($j > $i + 1) {
 | 
			
		||||
                        if ($id === \T_NS_SEPARATOR) {
 | 
			
		||||
                            $id = \T_NAME_FULLY_QUALIFIED;
 | 
			
		||||
                        } elseif ($id === \T_NAMESPACE) {
 | 
			
		||||
                            $id = \T_NAME_RELATIVE;
 | 
			
		||||
                        } else {
 | 
			
		||||
                            $id = \T_NAME_QUALIFIED;
 | 
			
		||||
                        }
 | 
			
		||||
                        $tokens[] = new static($id, $newText, $line, $pos);
 | 
			
		||||
                        $pos += \strlen($newText);
 | 
			
		||||
                        $i = $j - 1;
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                $tokens[] = new static($id, $text, $line, $pos);
 | 
			
		||||
                $line += \substr_count($text, "\n");
 | 
			
		||||
                $pos += \strlen($text);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Initialize private static state needed by tokenize(). */
 | 
			
		||||
    private static function init(): void {
 | 
			
		||||
        if (isset(self::$identifierTokens)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Based on semi_reserved production.
 | 
			
		||||
        self::$identifierTokens = \array_fill_keys([
 | 
			
		||||
            \T_STRING,
 | 
			
		||||
            \T_STATIC, \T_ABSTRACT, \T_FINAL, \T_PRIVATE, \T_PROTECTED, \T_PUBLIC, \T_READONLY,
 | 
			
		||||
            \T_INCLUDE, \T_INCLUDE_ONCE, \T_EVAL, \T_REQUIRE, \T_REQUIRE_ONCE, \T_LOGICAL_OR, \T_LOGICAL_XOR, \T_LOGICAL_AND,
 | 
			
		||||
            \T_INSTANCEOF, \T_NEW, \T_CLONE, \T_EXIT, \T_IF, \T_ELSEIF, \T_ELSE, \T_ENDIF, \T_ECHO, \T_DO, \T_WHILE,
 | 
			
		||||
            \T_ENDWHILE, \T_FOR, \T_ENDFOR, \T_FOREACH, \T_ENDFOREACH, \T_DECLARE, \T_ENDDECLARE, \T_AS, \T_TRY, \T_CATCH,
 | 
			
		||||
            \T_FINALLY, \T_THROW, \T_USE, \T_INSTEADOF, \T_GLOBAL, \T_VAR, \T_UNSET, \T_ISSET, \T_EMPTY, \T_CONTINUE, \T_GOTO,
 | 
			
		||||
            \T_FUNCTION, \T_CONST, \T_RETURN, \T_PRINT, \T_YIELD, \T_LIST, \T_SWITCH, \T_ENDSWITCH, \T_CASE, \T_DEFAULT,
 | 
			
		||||
            \T_BREAK, \T_ARRAY, \T_CALLABLE, \T_EXTENDS, \T_IMPLEMENTS, \T_NAMESPACE, \T_TRAIT, \T_INTERFACE, \T_CLASS,
 | 
			
		||||
            \T_CLASS_C, \T_TRAIT_C, \T_FUNC_C, \T_METHOD_C, \T_LINE, \T_FILE, \T_DIR, \T_NS_C, \T_HALT_COMPILER, \T_FN,
 | 
			
		||||
            \T_MATCH,
 | 
			
		||||
        ], true);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										282
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										282
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,282 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Internal;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Token;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Provides operations on token streams, for use by pretty printer.
 | 
			
		||||
 *
 | 
			
		||||
 * @internal
 | 
			
		||||
 */
 | 
			
		||||
class TokenStream {
 | 
			
		||||
    /** @var Token[] Tokens (in PhpToken::tokenize() format) */
 | 
			
		||||
    private array $tokens;
 | 
			
		||||
    /** @var int[] Map from position to indentation */
 | 
			
		||||
    private array $indentMap;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create token stream instance.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Token[] $tokens Tokens in PhpToken::tokenize() format
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(array $tokens, int $tabWidth) {
 | 
			
		||||
        $this->tokens = $tokens;
 | 
			
		||||
        $this->indentMap = $this->calcIndentMap($tabWidth);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Whether the given position is immediately surrounded by parenthesis.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $startPos Start position
 | 
			
		||||
     * @param int $endPos End position
 | 
			
		||||
     */
 | 
			
		||||
    public function haveParens(int $startPos, int $endPos): bool {
 | 
			
		||||
        return $this->haveTokenImmediatelyBefore($startPos, '(')
 | 
			
		||||
            && $this->haveTokenImmediatelyAfter($endPos, ')');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Whether the given position is immediately surrounded by braces.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $startPos Start position
 | 
			
		||||
     * @param int $endPos End position
 | 
			
		||||
     */
 | 
			
		||||
    public function haveBraces(int $startPos, int $endPos): bool {
 | 
			
		||||
        return ($this->haveTokenImmediatelyBefore($startPos, '{')
 | 
			
		||||
                || $this->haveTokenImmediatelyBefore($startPos, T_CURLY_OPEN))
 | 
			
		||||
            && $this->haveTokenImmediatelyAfter($endPos, '}');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check whether the position is directly preceded by a certain token type.
 | 
			
		||||
     *
 | 
			
		||||
     * During this check whitespace and comments are skipped.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $pos Position before which the token should occur
 | 
			
		||||
     * @param int|string $expectedTokenType Token to check for
 | 
			
		||||
     *
 | 
			
		||||
     * @return bool Whether the expected token was found
 | 
			
		||||
     */
 | 
			
		||||
    public function haveTokenImmediatelyBefore(int $pos, $expectedTokenType): bool {
 | 
			
		||||
        $tokens = $this->tokens;
 | 
			
		||||
        $pos--;
 | 
			
		||||
        for (; $pos >= 0; $pos--) {
 | 
			
		||||
            $token = $tokens[$pos];
 | 
			
		||||
            if ($token->is($expectedTokenType)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            if (!$token->isIgnorable()) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check whether the position is directly followed by a certain token type.
 | 
			
		||||
     *
 | 
			
		||||
     * During this check whitespace and comments are skipped.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $pos Position after which the token should occur
 | 
			
		||||
     * @param int|string $expectedTokenType Token to check for
 | 
			
		||||
     *
 | 
			
		||||
     * @return bool Whether the expected token was found
 | 
			
		||||
     */
 | 
			
		||||
    public function haveTokenImmediatelyAfter(int $pos, $expectedTokenType): bool {
 | 
			
		||||
        $tokens = $this->tokens;
 | 
			
		||||
        $pos++;
 | 
			
		||||
        for ($c = \count($tokens); $pos < $c; $pos++) {
 | 
			
		||||
            $token = $tokens[$pos];
 | 
			
		||||
            if ($token->is($expectedTokenType)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            if (!$token->isIgnorable()) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @param int|string|(int|string)[] $skipTokenType */
 | 
			
		||||
    public function skipLeft(int $pos, $skipTokenType): int {
 | 
			
		||||
        $tokens = $this->tokens;
 | 
			
		||||
 | 
			
		||||
        $pos = $this->skipLeftWhitespace($pos);
 | 
			
		||||
        if ($skipTokenType === \T_WHITESPACE) {
 | 
			
		||||
            return $pos;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!$tokens[$pos]->is($skipTokenType)) {
 | 
			
		||||
            // Shouldn't happen. The skip token MUST be there
 | 
			
		||||
            throw new \Exception('Encountered unexpected token');
 | 
			
		||||
        }
 | 
			
		||||
        $pos--;
 | 
			
		||||
 | 
			
		||||
        return $this->skipLeftWhitespace($pos);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @param int|string|(int|string)[] $skipTokenType */
 | 
			
		||||
    public function skipRight(int $pos, $skipTokenType): int {
 | 
			
		||||
        $tokens = $this->tokens;
 | 
			
		||||
 | 
			
		||||
        $pos = $this->skipRightWhitespace($pos);
 | 
			
		||||
        if ($skipTokenType === \T_WHITESPACE) {
 | 
			
		||||
            return $pos;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!$tokens[$pos]->is($skipTokenType)) {
 | 
			
		||||
            // Shouldn't happen. The skip token MUST be there
 | 
			
		||||
            throw new \Exception('Encountered unexpected token');
 | 
			
		||||
        }
 | 
			
		||||
        $pos++;
 | 
			
		||||
 | 
			
		||||
        return $this->skipRightWhitespace($pos);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return first non-whitespace token position smaller or equal to passed position.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $pos Token position
 | 
			
		||||
     * @return int Non-whitespace token position
 | 
			
		||||
     */
 | 
			
		||||
    public function skipLeftWhitespace(int $pos): int {
 | 
			
		||||
        $tokens = $this->tokens;
 | 
			
		||||
        for (; $pos >= 0; $pos--) {
 | 
			
		||||
            if (!$tokens[$pos]->isIgnorable()) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $pos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return first non-whitespace position greater or equal to passed position.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $pos Token position
 | 
			
		||||
     * @return int Non-whitespace token position
 | 
			
		||||
     */
 | 
			
		||||
    public function skipRightWhitespace(int $pos): int {
 | 
			
		||||
        $tokens = $this->tokens;
 | 
			
		||||
        for ($count = \count($tokens); $pos < $count; $pos++) {
 | 
			
		||||
            if (!$tokens[$pos]->isIgnorable()) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $pos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @param int|string|(int|string)[] $findTokenType */
 | 
			
		||||
    public function findRight(int $pos, $findTokenType): int {
 | 
			
		||||
        $tokens = $this->tokens;
 | 
			
		||||
        for ($count = \count($tokens); $pos < $count; $pos++) {
 | 
			
		||||
            if ($tokens[$pos]->is($findTokenType)) {
 | 
			
		||||
                return $pos;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Whether the given position range contains a certain token type.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $startPos Starting position (inclusive)
 | 
			
		||||
     * @param int $endPos Ending position (exclusive)
 | 
			
		||||
     * @param int|string $tokenType Token type to look for
 | 
			
		||||
     * @return bool Whether the token occurs in the given range
 | 
			
		||||
     */
 | 
			
		||||
    public function haveTokenInRange(int $startPos, int $endPos, $tokenType): bool {
 | 
			
		||||
        $tokens = $this->tokens;
 | 
			
		||||
        for ($pos = $startPos; $pos < $endPos; $pos++) {
 | 
			
		||||
            if ($tokens[$pos]->is($tokenType)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function haveTagInRange(int $startPos, int $endPos): bool {
 | 
			
		||||
        return $this->haveTokenInRange($startPos, $endPos, \T_OPEN_TAG)
 | 
			
		||||
            || $this->haveTokenInRange($startPos, $endPos, \T_CLOSE_TAG);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get indentation before token position.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $pos Token position
 | 
			
		||||
     *
 | 
			
		||||
     * @return int Indentation depth (in spaces)
 | 
			
		||||
     */
 | 
			
		||||
    public function getIndentationBefore(int $pos): int {
 | 
			
		||||
        return $this->indentMap[$pos];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the code corresponding to a token offset range, optionally adjusted for indentation.
 | 
			
		||||
     *
 | 
			
		||||
     * @param int $from Token start position (inclusive)
 | 
			
		||||
     * @param int $to Token end position (exclusive)
 | 
			
		||||
     * @param int $indent By how much the code should be indented (can be negative as well)
 | 
			
		||||
     *
 | 
			
		||||
     * @return string Code corresponding to token range, adjusted for indentation
 | 
			
		||||
     */
 | 
			
		||||
    public function getTokenCode(int $from, int $to, int $indent): string {
 | 
			
		||||
        $tokens = $this->tokens;
 | 
			
		||||
        $result = '';
 | 
			
		||||
        for ($pos = $from; $pos < $to; $pos++) {
 | 
			
		||||
            $token = $tokens[$pos];
 | 
			
		||||
            $id = $token->id;
 | 
			
		||||
            $text = $token->text;
 | 
			
		||||
            if ($id === \T_CONSTANT_ENCAPSED_STRING || $id === \T_ENCAPSED_AND_WHITESPACE) {
 | 
			
		||||
                $result .= $text;
 | 
			
		||||
            } else {
 | 
			
		||||
                // TODO Handle non-space indentation
 | 
			
		||||
                if ($indent < 0) {
 | 
			
		||||
                    $result .= str_replace("\n" . str_repeat(" ", -$indent), "\n", $text);
 | 
			
		||||
                } elseif ($indent > 0) {
 | 
			
		||||
                    $result .= str_replace("\n", "\n" . str_repeat(" ", $indent), $text);
 | 
			
		||||
                } else {
 | 
			
		||||
                    $result .= $text;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Precalculate the indentation at every token position.
 | 
			
		||||
     *
 | 
			
		||||
     * @return int[] Token position to indentation map
 | 
			
		||||
     */
 | 
			
		||||
    private function calcIndentMap(int $tabWidth): array {
 | 
			
		||||
        $indentMap = [];
 | 
			
		||||
        $indent = 0;
 | 
			
		||||
        foreach ($this->tokens as $i => $token) {
 | 
			
		||||
            $indentMap[] = $indent;
 | 
			
		||||
 | 
			
		||||
            if ($token->id === \T_WHITESPACE) {
 | 
			
		||||
                $content = $token->text;
 | 
			
		||||
                $newlinePos = \strrpos($content, "\n");
 | 
			
		||||
                if (false !== $newlinePos) {
 | 
			
		||||
                    $indent = $this->getIndent(\substr($content, $newlinePos + 1), $tabWidth);
 | 
			
		||||
                } elseif ($i === 1 && $this->tokens[0]->id === \T_OPEN_TAG &&
 | 
			
		||||
                          $this->tokens[0]->text[\strlen($this->tokens[0]->text) - 1] === "\n") {
 | 
			
		||||
                    // Special case: Newline at the end of opening tag followed by whitespace.
 | 
			
		||||
                    $indent = $this->getIndent($content, $tabWidth);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Add a sentinel for one past end of the file
 | 
			
		||||
        $indentMap[] = $indent;
 | 
			
		||||
 | 
			
		||||
        return $indentMap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function getIndent(string $ws, int $tabWidth): int {
 | 
			
		||||
        $spaces = \substr_count($ws, " ");
 | 
			
		||||
        $tabs = \substr_count($ws, "\t");
 | 
			
		||||
        assert(\strlen($ws) === $spaces + $tabs);
 | 
			
		||||
        return $spaces + $tabs * $tabWidth;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										108
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
class JsonDecoder {
 | 
			
		||||
    /** @var \ReflectionClass<Node>[] Node type to reflection class map */
 | 
			
		||||
    private array $reflectionClassCache;
 | 
			
		||||
 | 
			
		||||
    /** @return mixed */
 | 
			
		||||
    public function decode(string $json) {
 | 
			
		||||
        $value = json_decode($json, true);
 | 
			
		||||
        if (json_last_error()) {
 | 
			
		||||
            throw new \RuntimeException('JSON decoding error: ' . json_last_error_msg());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->decodeRecursive($value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param mixed $value
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    private function decodeRecursive($value) {
 | 
			
		||||
        if (\is_array($value)) {
 | 
			
		||||
            if (isset($value['nodeType'])) {
 | 
			
		||||
                if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc') {
 | 
			
		||||
                    return $this->decodeComment($value);
 | 
			
		||||
                }
 | 
			
		||||
                return $this->decodeNode($value);
 | 
			
		||||
            }
 | 
			
		||||
            return $this->decodeArray($value);
 | 
			
		||||
        }
 | 
			
		||||
        return $value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function decodeArray(array $array): array {
 | 
			
		||||
        $decodedArray = [];
 | 
			
		||||
        foreach ($array as $key => $value) {
 | 
			
		||||
            $decodedArray[$key] = $this->decodeRecursive($value);
 | 
			
		||||
        }
 | 
			
		||||
        return $decodedArray;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function decodeNode(array $value): Node {
 | 
			
		||||
        $nodeType = $value['nodeType'];
 | 
			
		||||
        if (!\is_string($nodeType)) {
 | 
			
		||||
            throw new \RuntimeException('Node type must be a string');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $reflectionClass = $this->reflectionClassFromNodeType($nodeType);
 | 
			
		||||
        $node = $reflectionClass->newInstanceWithoutConstructor();
 | 
			
		||||
 | 
			
		||||
        if (isset($value['attributes'])) {
 | 
			
		||||
            if (!\is_array($value['attributes'])) {
 | 
			
		||||
                throw new \RuntimeException('Attributes must be an array');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $node->setAttributes($this->decodeArray($value['attributes']));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($value as $name => $subNode) {
 | 
			
		||||
            if ($name === 'nodeType' || $name === 'attributes') {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $node->$name = $this->decodeRecursive($subNode);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $node;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function decodeComment(array $value): Comment {
 | 
			
		||||
        $className = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class;
 | 
			
		||||
        if (!isset($value['text'])) {
 | 
			
		||||
            throw new \RuntimeException('Comment must have text');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new $className(
 | 
			
		||||
            $value['text'],
 | 
			
		||||
            $value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1,
 | 
			
		||||
            $value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @return \ReflectionClass<Node> */
 | 
			
		||||
    private function reflectionClassFromNodeType(string $nodeType): \ReflectionClass {
 | 
			
		||||
        if (!isset($this->reflectionClassCache[$nodeType])) {
 | 
			
		||||
            $className = $this->classNameFromNodeType($nodeType);
 | 
			
		||||
            $this->reflectionClassCache[$nodeType] = new \ReflectionClass($className);
 | 
			
		||||
        }
 | 
			
		||||
        return $this->reflectionClassCache[$nodeType];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @return class-string<Node> */
 | 
			
		||||
    private function classNameFromNodeType(string $nodeType): string {
 | 
			
		||||
        $className = 'PhpParser\\Node\\' . strtr($nodeType, '_', '\\');
 | 
			
		||||
        if (class_exists($className)) {
 | 
			
		||||
            return $className;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $className .= '_';
 | 
			
		||||
        if (class_exists($className)) {
 | 
			
		||||
            return $className;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new \RuntimeException("Unknown node type \"$nodeType\"");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
require __DIR__ . '/compatibility_tokens.php';
 | 
			
		||||
 | 
			
		||||
class Lexer {
 | 
			
		||||
    /**
 | 
			
		||||
     * Tokenize the provided source code.
 | 
			
		||||
     *
 | 
			
		||||
     * The token array is in the same format as provided by the PhpToken::tokenize() method in
 | 
			
		||||
     * PHP 8.0. The tokens are instances of PhpParser\Token, to abstract over a polyfill
 | 
			
		||||
     * implementation in earlier PHP version.
 | 
			
		||||
     *
 | 
			
		||||
     * The token array is terminated by a sentinel token with token ID 0.
 | 
			
		||||
     * The token array does not discard any tokens (i.e. whitespace and comments are included).
 | 
			
		||||
     * The token position attributes are against this token array.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $code The source code to tokenize.
 | 
			
		||||
     * @param ErrorHandler|null $errorHandler Error handler to use for lexing errors. Defaults to
 | 
			
		||||
     *                                        ErrorHandler\Throwing.
 | 
			
		||||
     * @return Token[] Tokens
 | 
			
		||||
     */
 | 
			
		||||
    public function tokenize(string $code, ?ErrorHandler $errorHandler = null): array {
 | 
			
		||||
        if (null === $errorHandler) {
 | 
			
		||||
            $errorHandler = new ErrorHandler\Throwing();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $scream = ini_set('xdebug.scream', '0');
 | 
			
		||||
 | 
			
		||||
        $tokens = @Token::tokenize($code);
 | 
			
		||||
        $this->postprocessTokens($tokens, $errorHandler);
 | 
			
		||||
 | 
			
		||||
        if (false !== $scream) {
 | 
			
		||||
            ini_set('xdebug.scream', $scream);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function handleInvalidCharacter(Token $token, ErrorHandler $errorHandler): void {
 | 
			
		||||
        $chr = $token->text;
 | 
			
		||||
        if ($chr === "\0") {
 | 
			
		||||
            // PHP cuts error message after null byte, so need special case
 | 
			
		||||
            $errorMsg = 'Unexpected null byte';
 | 
			
		||||
        } else {
 | 
			
		||||
            $errorMsg = sprintf(
 | 
			
		||||
                'Unexpected character "%s" (ASCII %d)', $chr, ord($chr)
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $errorHandler->handleError(new Error($errorMsg, [
 | 
			
		||||
            'startLine' => $token->line,
 | 
			
		||||
            'endLine' => $token->line,
 | 
			
		||||
            'startFilePos' => $token->pos,
 | 
			
		||||
            'endFilePos' => $token->pos,
 | 
			
		||||
        ]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function isUnterminatedComment(Token $token): bool {
 | 
			
		||||
        return $token->is([\T_COMMENT, \T_DOC_COMMENT])
 | 
			
		||||
            && substr($token->text, 0, 2) === '/*'
 | 
			
		||||
            && substr($token->text, -2) !== '*/';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param list<Token> $tokens
 | 
			
		||||
     */
 | 
			
		||||
    protected function postprocessTokens(array &$tokens, ErrorHandler $errorHandler): void {
 | 
			
		||||
        // This function reports errors (bad characters and unterminated comments) in the token
 | 
			
		||||
        // array, and performs certain canonicalizations:
 | 
			
		||||
        //  * Use PHP 8.1 T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG and
 | 
			
		||||
        //    T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG tokens used to disambiguate intersection types.
 | 
			
		||||
        //  * Add a sentinel token with ID 0.
 | 
			
		||||
 | 
			
		||||
        $numTokens = \count($tokens);
 | 
			
		||||
        if ($numTokens === 0) {
 | 
			
		||||
            // Empty input edge case: Just add the sentinel token.
 | 
			
		||||
            $tokens[] = new Token(0, "\0", 1, 0);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for ($i = 0; $i < $numTokens; $i++) {
 | 
			
		||||
            $token = $tokens[$i];
 | 
			
		||||
            if ($token->id === \T_BAD_CHARACTER) {
 | 
			
		||||
                $this->handleInvalidCharacter($token, $errorHandler);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($token->id === \ord('&')) {
 | 
			
		||||
                $next = $i + 1;
 | 
			
		||||
                while (isset($tokens[$next]) && $tokens[$next]->id === \T_WHITESPACE) {
 | 
			
		||||
                    $next++;
 | 
			
		||||
                }
 | 
			
		||||
                $followedByVarOrVarArg = isset($tokens[$next]) &&
 | 
			
		||||
                    $tokens[$next]->is([\T_VARIABLE, \T_ELLIPSIS]);
 | 
			
		||||
                $token->id = $followedByVarOrVarArg
 | 
			
		||||
                    ? \T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG
 | 
			
		||||
                    : \T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check for unterminated comment
 | 
			
		||||
        $lastToken = $tokens[$numTokens - 1];
 | 
			
		||||
        if ($this->isUnterminatedComment($lastToken)) {
 | 
			
		||||
            $errorHandler->handleError(new Error('Unterminated comment', [
 | 
			
		||||
                'startLine' => $lastToken->line,
 | 
			
		||||
                'endLine' => $lastToken->getEndLine(),
 | 
			
		||||
                'startFilePos' => $lastToken->pos,
 | 
			
		||||
                'endFilePos' => $lastToken->getEndPos(),
 | 
			
		||||
            ]));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Add sentinel token.
 | 
			
		||||
        $tokens[] = new Token(0, "\0", $lastToken->getEndLine(), $lastToken->getEndPos());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										230
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,230 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Error;
 | 
			
		||||
use PhpParser\ErrorHandler;
 | 
			
		||||
use PhpParser\Lexer;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\AsymmetricVisibilityTokenEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\AttributeEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\EnumTokenEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\ExplicitOctalEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\MatchTokenEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\NullsafeTokenEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\PipeOperatorEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\PropertyTokenEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\ReadonlyFunctionTokenEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\ReadonlyTokenEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\ReverseEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\TokenEmulator;
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\VoidCastEmulator;
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
use PhpParser\Token;
 | 
			
		||||
 | 
			
		||||
class Emulative extends Lexer {
 | 
			
		||||
    /** @var array{int, string, string}[] Patches used to reverse changes introduced in the code */
 | 
			
		||||
    private array $patches = [];
 | 
			
		||||
 | 
			
		||||
    /** @var list<TokenEmulator> */
 | 
			
		||||
    private array $emulators = [];
 | 
			
		||||
 | 
			
		||||
    private PhpVersion $targetPhpVersion;
 | 
			
		||||
 | 
			
		||||
    private PhpVersion $hostPhpVersion;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param PhpVersion|null $phpVersion PHP version to emulate. Defaults to newest supported.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(?PhpVersion $phpVersion = null) {
 | 
			
		||||
        $this->targetPhpVersion = $phpVersion ?? PhpVersion::getNewestSupported();
 | 
			
		||||
        $this->hostPhpVersion = PhpVersion::getHostVersion();
 | 
			
		||||
 | 
			
		||||
        $emulators = [
 | 
			
		||||
            new MatchTokenEmulator(),
 | 
			
		||||
            new NullsafeTokenEmulator(),
 | 
			
		||||
            new AttributeEmulator(),
 | 
			
		||||
            new EnumTokenEmulator(),
 | 
			
		||||
            new ReadonlyTokenEmulator(),
 | 
			
		||||
            new ExplicitOctalEmulator(),
 | 
			
		||||
            new ReadonlyFunctionTokenEmulator(),
 | 
			
		||||
            new PropertyTokenEmulator(),
 | 
			
		||||
            new AsymmetricVisibilityTokenEmulator(),
 | 
			
		||||
            new PipeOperatorEmulator(),
 | 
			
		||||
            new VoidCastEmulator(),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        // Collect emulators that are relevant for the PHP version we're running
 | 
			
		||||
        // and the PHP version we're targeting for emulation.
 | 
			
		||||
        foreach ($emulators as $emulator) {
 | 
			
		||||
            $emulatorPhpVersion = $emulator->getPhpVersion();
 | 
			
		||||
            if ($this->isForwardEmulationNeeded($emulatorPhpVersion)) {
 | 
			
		||||
                $this->emulators[] = $emulator;
 | 
			
		||||
            } elseif ($this->isReverseEmulationNeeded($emulatorPhpVersion)) {
 | 
			
		||||
                $this->emulators[] = new ReverseEmulator($emulator);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function tokenize(string $code, ?ErrorHandler $errorHandler = null): array {
 | 
			
		||||
        $emulators = array_filter($this->emulators, function ($emulator) use ($code) {
 | 
			
		||||
            return $emulator->isEmulationNeeded($code);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (empty($emulators)) {
 | 
			
		||||
            // Nothing to emulate, yay
 | 
			
		||||
            return parent::tokenize($code, $errorHandler);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($errorHandler === null) {
 | 
			
		||||
            $errorHandler = new ErrorHandler\Throwing();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->patches = [];
 | 
			
		||||
        foreach ($emulators as $emulator) {
 | 
			
		||||
            $code = $emulator->preprocessCode($code, $this->patches);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $collector = new ErrorHandler\Collecting();
 | 
			
		||||
        $tokens = parent::tokenize($code, $collector);
 | 
			
		||||
        $this->sortPatches();
 | 
			
		||||
        $tokens = $this->fixupTokens($tokens);
 | 
			
		||||
 | 
			
		||||
        $errors = $collector->getErrors();
 | 
			
		||||
        if (!empty($errors)) {
 | 
			
		||||
            $this->fixupErrors($errors);
 | 
			
		||||
            foreach ($errors as $error) {
 | 
			
		||||
                $errorHandler->handleError($error);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($emulators as $emulator) {
 | 
			
		||||
            $tokens = $emulator->emulate($code, $tokens);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function isForwardEmulationNeeded(PhpVersion $emulatorPhpVersion): bool {
 | 
			
		||||
        return $this->hostPhpVersion->older($emulatorPhpVersion)
 | 
			
		||||
            && $this->targetPhpVersion->newerOrEqual($emulatorPhpVersion);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function isReverseEmulationNeeded(PhpVersion $emulatorPhpVersion): bool {
 | 
			
		||||
        return $this->hostPhpVersion->newerOrEqual($emulatorPhpVersion)
 | 
			
		||||
            && $this->targetPhpVersion->older($emulatorPhpVersion);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function sortPatches(): void {
 | 
			
		||||
        // Patches may be contributed by different emulators.
 | 
			
		||||
        // Make sure they are sorted by increasing patch position.
 | 
			
		||||
        usort($this->patches, function ($p1, $p2) {
 | 
			
		||||
            return $p1[0] <=> $p2[0];
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param list<Token> $tokens
 | 
			
		||||
     * @return list<Token>
 | 
			
		||||
     */
 | 
			
		||||
    private function fixupTokens(array $tokens): array {
 | 
			
		||||
        if (\count($this->patches) === 0) {
 | 
			
		||||
            return $tokens;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Load first patch
 | 
			
		||||
        $patchIdx = 0;
 | 
			
		||||
        list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];
 | 
			
		||||
 | 
			
		||||
        // We use a manual loop over the tokens, because we modify the array on the fly
 | 
			
		||||
        $posDelta = 0;
 | 
			
		||||
        $lineDelta = 0;
 | 
			
		||||
        for ($i = 0, $c = \count($tokens); $i < $c; $i++) {
 | 
			
		||||
            $token = $tokens[$i];
 | 
			
		||||
            $pos = $token->pos;
 | 
			
		||||
            $token->pos += $posDelta;
 | 
			
		||||
            $token->line += $lineDelta;
 | 
			
		||||
            $localPosDelta = 0;
 | 
			
		||||
            $len = \strlen($token->text);
 | 
			
		||||
            while ($patchPos >= $pos && $patchPos < $pos + $len) {
 | 
			
		||||
                $patchTextLen = \strlen($patchText);
 | 
			
		||||
                if ($patchType === 'remove') {
 | 
			
		||||
                    if ($patchPos === $pos && $patchTextLen === $len) {
 | 
			
		||||
                        // Remove token entirely
 | 
			
		||||
                        array_splice($tokens, $i, 1, []);
 | 
			
		||||
                        $i--;
 | 
			
		||||
                        $c--;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        // Remove from token string
 | 
			
		||||
                        $token->text = substr_replace(
 | 
			
		||||
                            $token->text, '', $patchPos - $pos + $localPosDelta, $patchTextLen
 | 
			
		||||
                        );
 | 
			
		||||
                        $localPosDelta -= $patchTextLen;
 | 
			
		||||
                    }
 | 
			
		||||
                    $lineDelta -= \substr_count($patchText, "\n");
 | 
			
		||||
                } elseif ($patchType === 'add') {
 | 
			
		||||
                    // Insert into the token string
 | 
			
		||||
                    $token->text = substr_replace(
 | 
			
		||||
                        $token->text, $patchText, $patchPos - $pos + $localPosDelta, 0
 | 
			
		||||
                    );
 | 
			
		||||
                    $localPosDelta += $patchTextLen;
 | 
			
		||||
                    $lineDelta += \substr_count($patchText, "\n");
 | 
			
		||||
                } elseif ($patchType === 'replace') {
 | 
			
		||||
                    // Replace inside the token string
 | 
			
		||||
                    $token->text = substr_replace(
 | 
			
		||||
                        $token->text, $patchText, $patchPos - $pos + $localPosDelta, $patchTextLen
 | 
			
		||||
                    );
 | 
			
		||||
                } else {
 | 
			
		||||
                    assert(false);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Fetch the next patch
 | 
			
		||||
                $patchIdx++;
 | 
			
		||||
                if ($patchIdx >= \count($this->patches)) {
 | 
			
		||||
                    // No more patches. However, we still need to adjust position.
 | 
			
		||||
                    $patchPos = \PHP_INT_MAX;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $posDelta += $localPosDelta;
 | 
			
		||||
        }
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Fixup line and position information in errors.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Error[] $errors
 | 
			
		||||
     */
 | 
			
		||||
    private function fixupErrors(array $errors): void {
 | 
			
		||||
        foreach ($errors as $error) {
 | 
			
		||||
            $attrs = $error->getAttributes();
 | 
			
		||||
 | 
			
		||||
            $posDelta = 0;
 | 
			
		||||
            $lineDelta = 0;
 | 
			
		||||
            foreach ($this->patches as $patch) {
 | 
			
		||||
                list($patchPos, $patchType, $patchText) = $patch;
 | 
			
		||||
                if ($patchPos >= $attrs['startFilePos']) {
 | 
			
		||||
                    // No longer relevant
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if ($patchType === 'add') {
 | 
			
		||||
                    $posDelta += strlen($patchText);
 | 
			
		||||
                    $lineDelta += substr_count($patchText, "\n");
 | 
			
		||||
                } elseif ($patchType === 'remove') {
 | 
			
		||||
                    $posDelta -= strlen($patchText);
 | 
			
		||||
                    $lineDelta -= substr_count($patchText, "\n");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $attrs['startFilePos'] += $posDelta;
 | 
			
		||||
            $attrs['endFilePos'] += $posDelta;
 | 
			
		||||
            $attrs['startLine'] += $lineDelta;
 | 
			
		||||
            $attrs['endLine'] += $lineDelta;
 | 
			
		||||
            $error->setAttributes($attrs);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,93 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
use PhpParser\Token;
 | 
			
		||||
 | 
			
		||||
final class AsymmetricVisibilityTokenEmulator extends TokenEmulator {
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return PhpVersion::fromComponents(8, 4);
 | 
			
		||||
    }
 | 
			
		||||
    public function isEmulationNeeded(string $code): bool {
 | 
			
		||||
        $code = strtolower($code);
 | 
			
		||||
        return strpos($code, 'public(set)') !== false ||
 | 
			
		||||
            strpos($code, 'protected(set)') !== false ||
 | 
			
		||||
            strpos($code, 'private(set)') !== false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function emulate(string $code, array $tokens): array {
 | 
			
		||||
        $map = [
 | 
			
		||||
            \T_PUBLIC => \T_PUBLIC_SET,
 | 
			
		||||
            \T_PROTECTED => \T_PROTECTED_SET,
 | 
			
		||||
            \T_PRIVATE => \T_PRIVATE_SET,
 | 
			
		||||
        ];
 | 
			
		||||
        for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
 | 
			
		||||
            $token = $tokens[$i];
 | 
			
		||||
            if (isset($map[$token->id]) && $i + 3 < $c && $tokens[$i + 1]->text === '(' &&
 | 
			
		||||
                $tokens[$i + 2]->id === \T_STRING && \strtolower($tokens[$i + 2]->text) === 'set' &&
 | 
			
		||||
                $tokens[$i + 3]->text === ')' &&
 | 
			
		||||
                $this->isKeywordContext($tokens, $i)
 | 
			
		||||
            ) {
 | 
			
		||||
                array_splice($tokens, $i, 4, [
 | 
			
		||||
                    new Token(
 | 
			
		||||
                        $map[$token->id], $token->text . '(' . $tokens[$i + 2]->text . ')',
 | 
			
		||||
                        $token->line, $token->pos),
 | 
			
		||||
                ]);
 | 
			
		||||
                $c -= 3;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function reverseEmulate(string $code, array $tokens): array {
 | 
			
		||||
        $reverseMap = [
 | 
			
		||||
            \T_PUBLIC_SET => \T_PUBLIC,
 | 
			
		||||
            \T_PROTECTED_SET => \T_PROTECTED,
 | 
			
		||||
            \T_PRIVATE_SET => \T_PRIVATE,
 | 
			
		||||
        ];
 | 
			
		||||
        for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
 | 
			
		||||
            $token = $tokens[$i];
 | 
			
		||||
            if (isset($reverseMap[$token->id]) &&
 | 
			
		||||
                \preg_match('/(public|protected|private)\((set)\)/i', $token->text, $matches)
 | 
			
		||||
            ) {
 | 
			
		||||
                [, $modifier, $set] = $matches;
 | 
			
		||||
                $modifierLen = \strlen($modifier);
 | 
			
		||||
                array_splice($tokens, $i, 1, [
 | 
			
		||||
                    new Token($reverseMap[$token->id], $modifier, $token->line, $token->pos),
 | 
			
		||||
                    new Token(\ord('('), '(', $token->line, $token->pos + $modifierLen),
 | 
			
		||||
                    new Token(\T_STRING, $set, $token->line, $token->pos + $modifierLen + 1),
 | 
			
		||||
                    new Token(\ord(')'), ')', $token->line, $token->pos + $modifierLen + 4),
 | 
			
		||||
                ]);
 | 
			
		||||
                $i += 3;
 | 
			
		||||
                $c += 3;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @param Token[] $tokens */
 | 
			
		||||
    protected function isKeywordContext(array $tokens, int $pos): bool {
 | 
			
		||||
        $prevToken = $this->getPreviousNonSpaceToken($tokens, $pos);
 | 
			
		||||
        if ($prevToken === null) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return $prevToken->id !== \T_OBJECT_OPERATOR
 | 
			
		||||
            && $prevToken->id !== \T_NULLSAFE_OBJECT_OPERATOR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @param Token[] $tokens */
 | 
			
		||||
    private function getPreviousNonSpaceToken(array $tokens, int $start): ?Token {
 | 
			
		||||
        for ($i = $start - 1; $i >= 0; --$i) {
 | 
			
		||||
            if ($tokens[$i]->id === T_WHITESPACE) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $tokens[$i];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
use PhpParser\Token;
 | 
			
		||||
 | 
			
		||||
final class AttributeEmulator extends TokenEmulator {
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return PhpVersion::fromComponents(8, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isEmulationNeeded(string $code): bool {
 | 
			
		||||
        return strpos($code, '#[') !== false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function emulate(string $code, array $tokens): array {
 | 
			
		||||
        // We need to manually iterate and manage a count because we'll change
 | 
			
		||||
        // the tokens array on the way.
 | 
			
		||||
        for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
 | 
			
		||||
            $token = $tokens[$i];
 | 
			
		||||
            if ($token->text === '#' && isset($tokens[$i + 1]) && $tokens[$i + 1]->text === '[') {
 | 
			
		||||
                array_splice($tokens, $i, 2, [
 | 
			
		||||
                    new Token(\T_ATTRIBUTE, '#[', $token->line, $token->pos),
 | 
			
		||||
                ]);
 | 
			
		||||
                $c--;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function reverseEmulate(string $code, array $tokens): array {
 | 
			
		||||
        // TODO
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function preprocessCode(string $code, array &$patches): string {
 | 
			
		||||
        $pos = 0;
 | 
			
		||||
        while (false !== $pos = strpos($code, '#[', $pos)) {
 | 
			
		||||
            // Replace #[ with %[
 | 
			
		||||
            $code[$pos] = '%';
 | 
			
		||||
            $patches[] = [$pos, 'replace', '#'];
 | 
			
		||||
            $pos += 2;
 | 
			
		||||
        }
 | 
			
		||||
        return $code;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
 | 
			
		||||
final class EnumTokenEmulator extends KeywordEmulator {
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return PhpVersion::fromComponents(8, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getKeywordString(): string {
 | 
			
		||||
        return 'enum';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getKeywordToken(): int {
 | 
			
		||||
        return \T_ENUM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function isKeywordContext(array $tokens, int $pos): bool {
 | 
			
		||||
        return parent::isKeywordContext($tokens, $pos)
 | 
			
		||||
            && isset($tokens[$pos + 2])
 | 
			
		||||
            && $tokens[$pos + 1]->id === \T_WHITESPACE
 | 
			
		||||
            && $tokens[$pos + 2]->id === \T_STRING;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
use PhpParser\Token;
 | 
			
		||||
 | 
			
		||||
class ExplicitOctalEmulator extends TokenEmulator {
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return PhpVersion::fromComponents(8, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isEmulationNeeded(string $code): bool {
 | 
			
		||||
        return strpos($code, '0o') !== false || strpos($code, '0O') !== false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function emulate(string $code, array $tokens): array {
 | 
			
		||||
        for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
 | 
			
		||||
            $token = $tokens[$i];
 | 
			
		||||
            if ($token->id == \T_LNUMBER && $token->text === '0' &&
 | 
			
		||||
                isset($tokens[$i + 1]) && $tokens[$i + 1]->id == \T_STRING &&
 | 
			
		||||
                preg_match('/[oO][0-7]+(?:_[0-7]+)*/', $tokens[$i + 1]->text)
 | 
			
		||||
            ) {
 | 
			
		||||
                $tokenKind = $this->resolveIntegerOrFloatToken($tokens[$i + 1]->text);
 | 
			
		||||
                array_splice($tokens, $i, 2, [
 | 
			
		||||
                    new Token($tokenKind, '0' . $tokens[$i + 1]->text, $token->line, $token->pos),
 | 
			
		||||
                ]);
 | 
			
		||||
                $c--;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function resolveIntegerOrFloatToken(string $str): int {
 | 
			
		||||
        $str = substr($str, 1);
 | 
			
		||||
        $str = str_replace('_', '', $str);
 | 
			
		||||
        $num = octdec($str);
 | 
			
		||||
        return is_float($num) ? \T_DNUMBER : \T_LNUMBER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function reverseEmulate(string $code, array $tokens): array {
 | 
			
		||||
        // Explicit octals were not legal code previously, don't bother.
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Token;
 | 
			
		||||
 | 
			
		||||
abstract class KeywordEmulator extends TokenEmulator {
 | 
			
		||||
    abstract public function getKeywordString(): string;
 | 
			
		||||
    abstract public function getKeywordToken(): int;
 | 
			
		||||
 | 
			
		||||
    public function isEmulationNeeded(string $code): bool {
 | 
			
		||||
        return strpos(strtolower($code), $this->getKeywordString()) !== false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @param Token[] $tokens */
 | 
			
		||||
    protected function isKeywordContext(array $tokens, int $pos): bool {
 | 
			
		||||
        $prevToken = $this->getPreviousNonSpaceToken($tokens, $pos);
 | 
			
		||||
        if ($prevToken === null) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return $prevToken->id !== \T_OBJECT_OPERATOR
 | 
			
		||||
            && $prevToken->id !== \T_NULLSAFE_OBJECT_OPERATOR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function emulate(string $code, array $tokens): array {
 | 
			
		||||
        $keywordString = $this->getKeywordString();
 | 
			
		||||
        foreach ($tokens as $i => $token) {
 | 
			
		||||
            if ($token->id === T_STRING && strtolower($token->text) === $keywordString
 | 
			
		||||
                    && $this->isKeywordContext($tokens, $i)) {
 | 
			
		||||
                $token->id = $this->getKeywordToken();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @param Token[] $tokens */
 | 
			
		||||
    private function getPreviousNonSpaceToken(array $tokens, int $start): ?Token {
 | 
			
		||||
        for ($i = $start - 1; $i >= 0; --$i) {
 | 
			
		||||
            if ($tokens[$i]->id === T_WHITESPACE) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return $tokens[$i];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function reverseEmulate(string $code, array $tokens): array {
 | 
			
		||||
        $keywordToken = $this->getKeywordToken();
 | 
			
		||||
        foreach ($tokens as $token) {
 | 
			
		||||
            if ($token->id === $keywordToken) {
 | 
			
		||||
                $token->id = \T_STRING;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
 | 
			
		||||
final class MatchTokenEmulator extends KeywordEmulator {
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return PhpVersion::fromComponents(8, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getKeywordString(): string {
 | 
			
		||||
        return 'match';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getKeywordToken(): int {
 | 
			
		||||
        return \T_MATCH;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
use PhpParser\Token;
 | 
			
		||||
 | 
			
		||||
final class NullsafeTokenEmulator extends TokenEmulator {
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return PhpVersion::fromComponents(8, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isEmulationNeeded(string $code): bool {
 | 
			
		||||
        return strpos($code, '?->') !== false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function emulate(string $code, array $tokens): array {
 | 
			
		||||
        // We need to manually iterate and manage a count because we'll change
 | 
			
		||||
        // the tokens array on the way
 | 
			
		||||
        for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
 | 
			
		||||
            $token = $tokens[$i];
 | 
			
		||||
            if ($token->text === '?' && isset($tokens[$i + 1]) && $tokens[$i + 1]->id === \T_OBJECT_OPERATOR) {
 | 
			
		||||
                array_splice($tokens, $i, 2, [
 | 
			
		||||
                    new Token(\T_NULLSAFE_OBJECT_OPERATOR, '?->', $token->line, $token->pos),
 | 
			
		||||
                ]);
 | 
			
		||||
                $c--;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Handle ?-> inside encapsed string.
 | 
			
		||||
            if ($token->id === \T_ENCAPSED_AND_WHITESPACE && isset($tokens[$i - 1])
 | 
			
		||||
                && $tokens[$i - 1]->id === \T_VARIABLE
 | 
			
		||||
                && preg_match('/^\?->([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)/', $token->text, $matches)
 | 
			
		||||
            ) {
 | 
			
		||||
                $replacement = [
 | 
			
		||||
                    new Token(\T_NULLSAFE_OBJECT_OPERATOR, '?->', $token->line, $token->pos),
 | 
			
		||||
                    new Token(\T_STRING, $matches[1], $token->line, $token->pos + 3),
 | 
			
		||||
                ];
 | 
			
		||||
                $matchLen = \strlen($matches[0]);
 | 
			
		||||
                if ($matchLen !== \strlen($token->text)) {
 | 
			
		||||
                    $replacement[] = new Token(
 | 
			
		||||
                        \T_ENCAPSED_AND_WHITESPACE,
 | 
			
		||||
                        \substr($token->text, $matchLen),
 | 
			
		||||
                        $token->line, $token->pos + $matchLen
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                array_splice($tokens, $i, 1, $replacement);
 | 
			
		||||
                $c += \count($replacement) - 1;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function reverseEmulate(string $code, array $tokens): array {
 | 
			
		||||
        // ?-> was not valid code previously, don't bother.
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/PipeOperatorEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/PipeOperatorEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Lexer\TokenEmulator\TokenEmulator;
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
use PhpParser\Token;
 | 
			
		||||
 | 
			
		||||
class PipeOperatorEmulator extends TokenEmulator {
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return PhpVersion::fromComponents(8, 5);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isEmulationNeeded(string $code): bool {
 | 
			
		||||
        return \strpos($code, '|>') !== false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function emulate(string $code, array $tokens): array {
 | 
			
		||||
        for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
 | 
			
		||||
            $token = $tokens[$i];
 | 
			
		||||
            if ($token->text === '|' && isset($tokens[$i + 1]) && $tokens[$i + 1]->text === '>') {
 | 
			
		||||
                array_splice($tokens, $i, 2, [
 | 
			
		||||
                    new Token(\T_PIPE, '|>', $token->line, $token->pos),
 | 
			
		||||
                ]);
 | 
			
		||||
                $c--;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function reverseEmulate(string $code, array $tokens): array {
 | 
			
		||||
        for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
 | 
			
		||||
            $token = $tokens[$i];
 | 
			
		||||
            if ($token->id === \T_PIPE) {
 | 
			
		||||
                array_splice($tokens, $i, 1, [
 | 
			
		||||
                    new Token(\ord('|'), '|', $token->line, $token->pos),
 | 
			
		||||
                    new Token(\ord('>'), '>', $token->line, $token->pos + 1),
 | 
			
		||||
                ]);
 | 
			
		||||
                $i++;
 | 
			
		||||
                $c++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
 | 
			
		||||
final class PropertyTokenEmulator extends KeywordEmulator {
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return PhpVersion::fromComponents(8, 4);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getKeywordString(): string {
 | 
			
		||||
        return '__property__';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getKeywordToken(): int {
 | 
			
		||||
        return \T_PROPERTY_C;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,31 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * In PHP 8.1, "readonly(" was special cased in the lexer in order to support functions with
 | 
			
		||||
 * name readonly. In PHP 8.2, this may conflict with readonly properties having a DNF type. For
 | 
			
		||||
 * this reason, PHP 8.2 instead treats this as T_READONLY and then handles it specially in the
 | 
			
		||||
 * parser. This emulator only exists to handle this special case, which is skipped by the
 | 
			
		||||
 * PHP 8.1 ReadonlyTokenEmulator.
 | 
			
		||||
 */
 | 
			
		||||
class ReadonlyFunctionTokenEmulator extends KeywordEmulator {
 | 
			
		||||
    public function getKeywordString(): string {
 | 
			
		||||
        return 'readonly';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getKeywordToken(): int {
 | 
			
		||||
        return \T_READONLY;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return PhpVersion::fromComponents(8, 2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function reverseEmulate(string $code, array $tokens): array {
 | 
			
		||||
        // Don't bother
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
 | 
			
		||||
final class ReadonlyTokenEmulator extends KeywordEmulator {
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return PhpVersion::fromComponents(8, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getKeywordString(): string {
 | 
			
		||||
        return 'readonly';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getKeywordToken(): int {
 | 
			
		||||
        return \T_READONLY;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function isKeywordContext(array $tokens, int $pos): bool {
 | 
			
		||||
        if (!parent::isKeywordContext($tokens, $pos)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        // Support "function readonly("
 | 
			
		||||
        return !(isset($tokens[$pos + 1]) &&
 | 
			
		||||
                 ($tokens[$pos + 1]->text === '(' ||
 | 
			
		||||
                  ($tokens[$pos + 1]->id === \T_WHITESPACE &&
 | 
			
		||||
                   isset($tokens[$pos + 2]) &&
 | 
			
		||||
                   $tokens[$pos + 2]->text === '(')));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reverses emulation direction of the inner emulator.
 | 
			
		||||
 */
 | 
			
		||||
final class ReverseEmulator extends TokenEmulator {
 | 
			
		||||
    /** @var TokenEmulator Inner emulator */
 | 
			
		||||
    private TokenEmulator $emulator;
 | 
			
		||||
 | 
			
		||||
    public function __construct(TokenEmulator $emulator) {
 | 
			
		||||
        $this->emulator = $emulator;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return $this->emulator->getPhpVersion();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isEmulationNeeded(string $code): bool {
 | 
			
		||||
        return $this->emulator->isEmulationNeeded($code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function emulate(string $code, array $tokens): array {
 | 
			
		||||
        return $this->emulator->reverseEmulate($code, $tokens);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function reverseEmulate(string $code, array $tokens): array {
 | 
			
		||||
        return $this->emulator->emulate($code, $tokens);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function preprocessCode(string $code, array &$patches): string {
 | 
			
		||||
        return $code;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
use PhpParser\Token;
 | 
			
		||||
 | 
			
		||||
/** @internal */
 | 
			
		||||
abstract class TokenEmulator {
 | 
			
		||||
    abstract public function getPhpVersion(): PhpVersion;
 | 
			
		||||
 | 
			
		||||
    abstract public function isEmulationNeeded(string $code): bool;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param Token[] $tokens Original tokens
 | 
			
		||||
     * @return Token[] Modified Tokens
 | 
			
		||||
     */
 | 
			
		||||
    abstract public function emulate(string $code, array $tokens): array;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param Token[] $tokens Original tokens
 | 
			
		||||
     * @return Token[] Modified Tokens
 | 
			
		||||
     */
 | 
			
		||||
    abstract public function reverseEmulate(string $code, array $tokens): array;
 | 
			
		||||
 | 
			
		||||
    /** @param array{int, string, string}[] $patches */
 | 
			
		||||
    public function preprocessCode(string $code, array &$patches): string {
 | 
			
		||||
        return $code;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										98
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/VoidCastEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/VoidCastEmulator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Lexer\TokenEmulator;
 | 
			
		||||
 | 
			
		||||
use PhpParser\PhpVersion;
 | 
			
		||||
use PhpParser\Token;
 | 
			
		||||
 | 
			
		||||
class VoidCastEmulator extends TokenEmulator {
 | 
			
		||||
    public function getPhpVersion(): PhpVersion {
 | 
			
		||||
        return PhpVersion::fromComponents(8, 5);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isEmulationNeeded(string $code): bool {
 | 
			
		||||
        return (bool)\preg_match('/\([ \t]*void[ \t]*\)/i', $code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function emulate(string $code, array $tokens): array {
 | 
			
		||||
        for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
 | 
			
		||||
            $token = $tokens[$i];
 | 
			
		||||
            if ($token->text !== '(') {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $numTokens = 1;
 | 
			
		||||
            $text = '(';
 | 
			
		||||
            $j = $i + 1;
 | 
			
		||||
            if ($j < $c && $tokens[$j]->id === \T_WHITESPACE && preg_match('/[ \t]+/', $tokens[$j]->text)) {
 | 
			
		||||
                $text .= $tokens[$j]->text;
 | 
			
		||||
                $numTokens++;
 | 
			
		||||
                $j++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($j >= $c || $tokens[$j]->id !== \T_STRING || \strtolower($tokens[$j]->text) !== 'void') {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $text .= $tokens[$j]->text;
 | 
			
		||||
            $numTokens++;
 | 
			
		||||
            $k = $j + 1;
 | 
			
		||||
            if ($k < $c && $tokens[$k]->id === \T_WHITESPACE && preg_match('/[ \t]+/', $tokens[$k]->text)) {
 | 
			
		||||
                $text .= $tokens[$k]->text;
 | 
			
		||||
                $numTokens++;
 | 
			
		||||
                $k++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($k >= $c || $tokens[$k]->text !== ')') {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $text .= ')';
 | 
			
		||||
            $numTokens++;
 | 
			
		||||
            array_splice($tokens, $i, $numTokens, [
 | 
			
		||||
                new Token(\T_VOID_CAST, $text, $token->line, $token->pos),
 | 
			
		||||
            ]);
 | 
			
		||||
            $c -= $numTokens - 1;
 | 
			
		||||
        }
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function reverseEmulate(string $code, array $tokens): array {
 | 
			
		||||
        for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
 | 
			
		||||
            $token = $tokens[$i];
 | 
			
		||||
            if ($token->id !== \T_VOID_CAST) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!preg_match('/^\(([ \t]*)(void)([ \t]*)\)$/i', $token->text, $match)) {
 | 
			
		||||
                throw new \LogicException('Unexpected T_VOID_CAST contents');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $newTokens = [];
 | 
			
		||||
            $pos = $token->pos;
 | 
			
		||||
 | 
			
		||||
            $newTokens[] = new Token(\ord('('), '(', $token->line, $pos);
 | 
			
		||||
            $pos++;
 | 
			
		||||
 | 
			
		||||
            if ($match[1] !== '') {
 | 
			
		||||
                $newTokens[] = new Token(\T_WHITESPACE, $match[1], $token->line, $pos);
 | 
			
		||||
                $pos += \strlen($match[1]);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $newTokens[] = new Token(\T_STRING, $match[2], $token->line, $pos);
 | 
			
		||||
            $pos += \strlen($match[2]);
 | 
			
		||||
 | 
			
		||||
            if ($match[3] !== '') {
 | 
			
		||||
                $newTokens[] = new Token(\T_WHITESPACE, $match[3], $token->line, $pos);
 | 
			
		||||
                $pos += \strlen($match[3]);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $newTokens[] = new Token(\ord(')'), ')', $token->line, $pos);
 | 
			
		||||
 | 
			
		||||
            array_splice($tokens, $i, 1, $newTokens);
 | 
			
		||||
            $i += \count($newTokens) - 1;
 | 
			
		||||
            $c += \count($newTokens) - 1;
 | 
			
		||||
        }
 | 
			
		||||
        return $tokens;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										85
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Modifiers.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Modifiers.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Modifiers used (as a bit mask) by various flags subnodes, for example on classes, functions,
 | 
			
		||||
 * properties and constants.
 | 
			
		||||
 */
 | 
			
		||||
final class Modifiers {
 | 
			
		||||
    public const PUBLIC    =  1;
 | 
			
		||||
    public const PROTECTED =  2;
 | 
			
		||||
    public const PRIVATE   =  4;
 | 
			
		||||
    public const STATIC    =  8;
 | 
			
		||||
    public const ABSTRACT  = 16;
 | 
			
		||||
    public const FINAL     = 32;
 | 
			
		||||
    public const READONLY  = 64;
 | 
			
		||||
    public const PUBLIC_SET = 128;
 | 
			
		||||
    public const PROTECTED_SET = 256;
 | 
			
		||||
    public const PRIVATE_SET = 512;
 | 
			
		||||
 | 
			
		||||
    public const VISIBILITY_MASK = self::PUBLIC | self::PROTECTED | self::PRIVATE;
 | 
			
		||||
 | 
			
		||||
    public const VISIBILITY_SET_MASK = self::PUBLIC_SET | self::PROTECTED_SET | self::PRIVATE_SET;
 | 
			
		||||
 | 
			
		||||
    private const TO_STRING_MAP = [
 | 
			
		||||
        self::PUBLIC  => 'public',
 | 
			
		||||
        self::PROTECTED => 'protected',
 | 
			
		||||
        self::PRIVATE => 'private',
 | 
			
		||||
        self::STATIC  => 'static',
 | 
			
		||||
        self::ABSTRACT => 'abstract',
 | 
			
		||||
        self::FINAL  => 'final',
 | 
			
		||||
        self::READONLY  => 'readonly',
 | 
			
		||||
        self::PUBLIC_SET => 'public(set)',
 | 
			
		||||
        self::PROTECTED_SET => 'protected(set)',
 | 
			
		||||
        self::PRIVATE_SET => 'private(set)',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    public static function toString(int $modifier): string {
 | 
			
		||||
        if (!isset(self::TO_STRING_MAP[$modifier])) {
 | 
			
		||||
            throw new \InvalidArgumentException("Unknown modifier $modifier");
 | 
			
		||||
        }
 | 
			
		||||
        return self::TO_STRING_MAP[$modifier];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static function isValidModifier(int $modifier): bool {
 | 
			
		||||
        $isPow2 = ($modifier & ($modifier - 1)) == 0 && $modifier != 0;
 | 
			
		||||
        return $isPow2 && $modifier <= self::PRIVATE_SET;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @internal
 | 
			
		||||
     */
 | 
			
		||||
    public static function verifyClassModifier(int $a, int $b): void {
 | 
			
		||||
        assert(self::isValidModifier($b));
 | 
			
		||||
        if (($a & $b) != 0) {
 | 
			
		||||
            throw new Error(
 | 
			
		||||
                'Multiple ' . self::toString($b) . ' modifiers are not allowed');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($a & 48 && $b & 48) {
 | 
			
		||||
            throw new Error('Cannot use the final modifier on an abstract class');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @internal
 | 
			
		||||
     */
 | 
			
		||||
    public static function verifyModifier(int $a, int $b): void {
 | 
			
		||||
        assert(self::isValidModifier($b));
 | 
			
		||||
        if (($a & Modifiers::VISIBILITY_MASK && $b & Modifiers::VISIBILITY_MASK) ||
 | 
			
		||||
            ($a & Modifiers::VISIBILITY_SET_MASK && $b & Modifiers::VISIBILITY_SET_MASK)
 | 
			
		||||
        ) {
 | 
			
		||||
            throw new Error('Multiple access type modifiers are not allowed');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (($a & $b) != 0) {
 | 
			
		||||
            throw new Error(
 | 
			
		||||
                'Multiple ' . self::toString($b) . ' modifiers are not allowed');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($a & 48 && $b & 48) {
 | 
			
		||||
            throw new Error('Cannot use the final modifier on an abstract class member');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										284
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/NameContext.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										284
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/NameContext.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,284 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Node\Name;
 | 
			
		||||
use PhpParser\Node\Name\FullyQualified;
 | 
			
		||||
use PhpParser\Node\Stmt;
 | 
			
		||||
 | 
			
		||||
class NameContext {
 | 
			
		||||
    /** @var null|Name Current namespace */
 | 
			
		||||
    protected ?Name $namespace;
 | 
			
		||||
 | 
			
		||||
    /** @var Name[][] Map of format [aliasType => [aliasName => originalName]] */
 | 
			
		||||
    protected array $aliases = [];
 | 
			
		||||
 | 
			
		||||
    /** @var Name[][] Same as $aliases but preserving original case */
 | 
			
		||||
    protected array $origAliases = [];
 | 
			
		||||
 | 
			
		||||
    /** @var ErrorHandler Error handler */
 | 
			
		||||
    protected ErrorHandler $errorHandler;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a name context.
 | 
			
		||||
     *
 | 
			
		||||
     * @param ErrorHandler $errorHandler Error handling used to report errors
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(ErrorHandler $errorHandler) {
 | 
			
		||||
        $this->errorHandler = $errorHandler;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Start a new namespace.
 | 
			
		||||
     *
 | 
			
		||||
     * This also resets the alias table.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Name|null $namespace Null is the global namespace
 | 
			
		||||
     */
 | 
			
		||||
    public function startNamespace(?Name $namespace = null): void {
 | 
			
		||||
        $this->namespace = $namespace;
 | 
			
		||||
        $this->origAliases = $this->aliases = [
 | 
			
		||||
            Stmt\Use_::TYPE_NORMAL   => [],
 | 
			
		||||
            Stmt\Use_::TYPE_FUNCTION => [],
 | 
			
		||||
            Stmt\Use_::TYPE_CONSTANT => [],
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add an alias / import.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Name $name Original name
 | 
			
		||||
     * @param string $aliasName Aliased name
 | 
			
		||||
     * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
 | 
			
		||||
     * @param array<string, mixed> $errorAttrs Attributes to use to report an error
 | 
			
		||||
     */
 | 
			
		||||
    public function addAlias(Name $name, string $aliasName, int $type, array $errorAttrs = []): void {
 | 
			
		||||
        // Constant names are case sensitive, everything else case insensitive
 | 
			
		||||
        if ($type === Stmt\Use_::TYPE_CONSTANT) {
 | 
			
		||||
            $aliasLookupName = $aliasName;
 | 
			
		||||
        } else {
 | 
			
		||||
            $aliasLookupName = strtolower($aliasName);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isset($this->aliases[$type][$aliasLookupName])) {
 | 
			
		||||
            $typeStringMap = [
 | 
			
		||||
                Stmt\Use_::TYPE_NORMAL   => '',
 | 
			
		||||
                Stmt\Use_::TYPE_FUNCTION => 'function ',
 | 
			
		||||
                Stmt\Use_::TYPE_CONSTANT => 'const ',
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            $this->errorHandler->handleError(new Error(
 | 
			
		||||
                sprintf(
 | 
			
		||||
                    'Cannot use %s%s as %s because the name is already in use',
 | 
			
		||||
                    $typeStringMap[$type], $name, $aliasName
 | 
			
		||||
                ),
 | 
			
		||||
                $errorAttrs
 | 
			
		||||
            ));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->aliases[$type][$aliasLookupName] = $name;
 | 
			
		||||
        $this->origAliases[$type][$aliasName] = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get current namespace.
 | 
			
		||||
     *
 | 
			
		||||
     * @return null|Name Namespace (or null if global namespace)
 | 
			
		||||
     */
 | 
			
		||||
    public function getNamespace(): ?Name {
 | 
			
		||||
        return $this->namespace;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get resolved name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Name $name Name to resolve
 | 
			
		||||
     * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_{FUNCTION|CONSTANT}
 | 
			
		||||
     *
 | 
			
		||||
     * @return null|Name Resolved name, or null if static resolution is not possible
 | 
			
		||||
     */
 | 
			
		||||
    public function getResolvedName(Name $name, int $type): ?Name {
 | 
			
		||||
        // don't resolve special class names
 | 
			
		||||
        if ($type === Stmt\Use_::TYPE_NORMAL && $name->isSpecialClassName()) {
 | 
			
		||||
            if (!$name->isUnqualified()) {
 | 
			
		||||
                $this->errorHandler->handleError(new Error(
 | 
			
		||||
                    sprintf("'\\%s' is an invalid class name", $name->toString()),
 | 
			
		||||
                    $name->getAttributes()
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
            return $name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // fully qualified names are already resolved
 | 
			
		||||
        if ($name->isFullyQualified()) {
 | 
			
		||||
            return $name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Try to resolve aliases
 | 
			
		||||
        if (null !== $resolvedName = $this->resolveAlias($name, $type)) {
 | 
			
		||||
            return $resolvedName;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($type !== Stmt\Use_::TYPE_NORMAL && $name->isUnqualified()) {
 | 
			
		||||
            if (null === $this->namespace) {
 | 
			
		||||
                // outside of a namespace unaliased unqualified is same as fully qualified
 | 
			
		||||
                return new FullyQualified($name, $name->getAttributes());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Cannot resolve statically
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // if no alias exists prepend current namespace
 | 
			
		||||
        return FullyQualified::concat($this->namespace, $name, $name->getAttributes());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get resolved class name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Name $name Class ame to resolve
 | 
			
		||||
     *
 | 
			
		||||
     * @return Name Resolved name
 | 
			
		||||
     */
 | 
			
		||||
    public function getResolvedClassName(Name $name): Name {
 | 
			
		||||
        return $this->getResolvedName($name, Stmt\Use_::TYPE_NORMAL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get possible ways of writing a fully qualified name (e.g., by making use of aliases).
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Fully-qualified name (without leading namespace separator)
 | 
			
		||||
     * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
 | 
			
		||||
     *
 | 
			
		||||
     * @return Name[] Possible representations of the name
 | 
			
		||||
     */
 | 
			
		||||
    public function getPossibleNames(string $name, int $type): array {
 | 
			
		||||
        $lcName = strtolower($name);
 | 
			
		||||
 | 
			
		||||
        if ($type === Stmt\Use_::TYPE_NORMAL) {
 | 
			
		||||
            // self, parent and static must always be unqualified
 | 
			
		||||
            if ($lcName === "self" || $lcName === "parent" || $lcName === "static") {
 | 
			
		||||
                return [new Name($name)];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Collect possible ways to write this name, starting with the fully-qualified name
 | 
			
		||||
        $possibleNames = [new FullyQualified($name)];
 | 
			
		||||
 | 
			
		||||
        if (null !== $nsRelativeName = $this->getNamespaceRelativeName($name, $lcName, $type)) {
 | 
			
		||||
            // Make sure there is no alias that makes the normally namespace-relative name
 | 
			
		||||
            // into something else
 | 
			
		||||
            if (null === $this->resolveAlias($nsRelativeName, $type)) {
 | 
			
		||||
                $possibleNames[] = $nsRelativeName;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check for relevant namespace use statements
 | 
			
		||||
        foreach ($this->origAliases[Stmt\Use_::TYPE_NORMAL] as $alias => $orig) {
 | 
			
		||||
            $lcOrig = $orig->toLowerString();
 | 
			
		||||
            if (0 === strpos($lcName, $lcOrig . '\\')) {
 | 
			
		||||
                $possibleNames[] = new Name($alias . substr($name, strlen($lcOrig)));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check for relevant type-specific use statements
 | 
			
		||||
        foreach ($this->origAliases[$type] as $alias => $orig) {
 | 
			
		||||
            if ($type === Stmt\Use_::TYPE_CONSTANT) {
 | 
			
		||||
                // Constants are complicated-sensitive
 | 
			
		||||
                $normalizedOrig = $this->normalizeConstName($orig->toString());
 | 
			
		||||
                if ($normalizedOrig === $this->normalizeConstName($name)) {
 | 
			
		||||
                    $possibleNames[] = new Name($alias);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // Everything else is case-insensitive
 | 
			
		||||
                if ($orig->toLowerString() === $lcName) {
 | 
			
		||||
                    $possibleNames[] = new Name($alias);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $possibleNames;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get shortest representation of this fully-qualified name.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name Fully-qualified name (without leading namespace separator)
 | 
			
		||||
     * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_*
 | 
			
		||||
     *
 | 
			
		||||
     * @return Name Shortest representation
 | 
			
		||||
     */
 | 
			
		||||
    public function getShortName(string $name, int $type): Name {
 | 
			
		||||
        $possibleNames = $this->getPossibleNames($name, $type);
 | 
			
		||||
 | 
			
		||||
        // Find shortest name
 | 
			
		||||
        $shortestName = null;
 | 
			
		||||
        $shortestLength = \INF;
 | 
			
		||||
        foreach ($possibleNames as $possibleName) {
 | 
			
		||||
            $length = strlen($possibleName->toCodeString());
 | 
			
		||||
            if ($length < $shortestLength) {
 | 
			
		||||
                $shortestName = $possibleName;
 | 
			
		||||
                $shortestLength = $length;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $shortestName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function resolveAlias(Name $name, int $type): ?FullyQualified {
 | 
			
		||||
        $firstPart = $name->getFirst();
 | 
			
		||||
 | 
			
		||||
        if ($name->isQualified()) {
 | 
			
		||||
            // resolve aliases for qualified names, always against class alias table
 | 
			
		||||
            $checkName = strtolower($firstPart);
 | 
			
		||||
            if (isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName])) {
 | 
			
		||||
                $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName];
 | 
			
		||||
                return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes());
 | 
			
		||||
            }
 | 
			
		||||
        } elseif ($name->isUnqualified()) {
 | 
			
		||||
            // constant aliases are case-sensitive, function aliases case-insensitive
 | 
			
		||||
            $checkName = $type === Stmt\Use_::TYPE_CONSTANT ? $firstPart : strtolower($firstPart);
 | 
			
		||||
            if (isset($this->aliases[$type][$checkName])) {
 | 
			
		||||
                // resolve unqualified aliases
 | 
			
		||||
                return new FullyQualified($this->aliases[$type][$checkName], $name->getAttributes());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // No applicable aliases
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function getNamespaceRelativeName(string $name, string $lcName, int $type): ?Name {
 | 
			
		||||
        if (null === $this->namespace) {
 | 
			
		||||
            return new Name($name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($type === Stmt\Use_::TYPE_CONSTANT) {
 | 
			
		||||
            // The constants true/false/null always resolve to the global symbols, even inside a
 | 
			
		||||
            // namespace, so they may be used without qualification
 | 
			
		||||
            if ($lcName === "true" || $lcName === "false" || $lcName === "null") {
 | 
			
		||||
                return new Name($name);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $namespacePrefix = strtolower($this->namespace . '\\');
 | 
			
		||||
        if (0 === strpos($lcName, $namespacePrefix)) {
 | 
			
		||||
            return new Name(substr($name, strlen($namespacePrefix)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function normalizeConstName(string $name): string {
 | 
			
		||||
        $nsSep = strrpos($name, '\\');
 | 
			
		||||
        if (false === $nsSep) {
 | 
			
		||||
            return $name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Constants have case-insensitive namespace and case-sensitive short-name
 | 
			
		||||
        $ns = substr($name, 0, $nsSep);
 | 
			
		||||
        $shortName = substr($name, $nsSep + 1);
 | 
			
		||||
        return strtolower($ns) . '\\' . $shortName;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										150
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Node.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Node.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser;
 | 
			
		||||
 | 
			
		||||
interface Node {
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the type of the node.
 | 
			
		||||
     *
 | 
			
		||||
     * @psalm-return non-empty-string
 | 
			
		||||
     * @return string Type of the node
 | 
			
		||||
     */
 | 
			
		||||
    public function getType(): string;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the names of the sub nodes.
 | 
			
		||||
     *
 | 
			
		||||
     * @return string[] Names of sub nodes
 | 
			
		||||
     */
 | 
			
		||||
    public function getSubNodeNames(): array;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets line the node started in (alias of getStartLine).
 | 
			
		||||
     *
 | 
			
		||||
     * @return int Start line (or -1 if not available)
 | 
			
		||||
     * @phpstan-return -1|positive-int
 | 
			
		||||
     *
 | 
			
		||||
     * @deprecated Use getStartLine() instead
 | 
			
		||||
     */
 | 
			
		||||
    public function getLine(): int;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets line the node started in.
 | 
			
		||||
     *
 | 
			
		||||
     * Requires the 'startLine' attribute to be enabled in the lexer (enabled by default).
 | 
			
		||||
     *
 | 
			
		||||
     * @return int Start line (or -1 if not available)
 | 
			
		||||
     * @phpstan-return -1|positive-int
 | 
			
		||||
     */
 | 
			
		||||
    public function getStartLine(): int;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the line the node ended in.
 | 
			
		||||
     *
 | 
			
		||||
     * Requires the 'endLine' attribute to be enabled in the lexer (enabled by default).
 | 
			
		||||
     *
 | 
			
		||||
     * @return int End line (or -1 if not available)
 | 
			
		||||
     * @phpstan-return -1|positive-int
 | 
			
		||||
     */
 | 
			
		||||
    public function getEndLine(): int;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the token offset of the first token that is part of this node.
 | 
			
		||||
     *
 | 
			
		||||
     * The offset is an index into the array returned by Lexer::getTokens().
 | 
			
		||||
     *
 | 
			
		||||
     * Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default).
 | 
			
		||||
     *
 | 
			
		||||
     * @return int Token start position (or -1 if not available)
 | 
			
		||||
     */
 | 
			
		||||
    public function getStartTokenPos(): int;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the token offset of the last token that is part of this node.
 | 
			
		||||
     *
 | 
			
		||||
     * The offset is an index into the array returned by Lexer::getTokens().
 | 
			
		||||
     *
 | 
			
		||||
     * Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default).
 | 
			
		||||
     *
 | 
			
		||||
     * @return int Token end position (or -1 if not available)
 | 
			
		||||
     */
 | 
			
		||||
    public function getEndTokenPos(): int;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the file offset of the first character that is part of this node.
 | 
			
		||||
     *
 | 
			
		||||
     * Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default).
 | 
			
		||||
     *
 | 
			
		||||
     * @return int File start position (or -1 if not available)
 | 
			
		||||
     */
 | 
			
		||||
    public function getStartFilePos(): int;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the file offset of the last character that is part of this node.
 | 
			
		||||
     *
 | 
			
		||||
     * Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default).
 | 
			
		||||
     *
 | 
			
		||||
     * @return int File end position (or -1 if not available)
 | 
			
		||||
     */
 | 
			
		||||
    public function getEndFilePos(): int;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets all comments directly preceding this node.
 | 
			
		||||
     *
 | 
			
		||||
     * The comments are also available through the "comments" attribute.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Comment[]
 | 
			
		||||
     */
 | 
			
		||||
    public function getComments(): array;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the doc comment of the node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return null|Comment\Doc Doc comment object or null
 | 
			
		||||
     */
 | 
			
		||||
    public function getDocComment(): ?Comment\Doc;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the doc comment of the node.
 | 
			
		||||
     *
 | 
			
		||||
     * This will either replace an existing doc comment or add it to the comments array.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Comment\Doc $docComment Doc comment to set
 | 
			
		||||
     */
 | 
			
		||||
    public function setDocComment(Comment\Doc $docComment): void;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets an attribute on a node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $value
 | 
			
		||||
     */
 | 
			
		||||
    public function setAttribute(string $key, $value): void;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns whether an attribute exists.
 | 
			
		||||
     */
 | 
			
		||||
    public function hasAttribute(string $key): bool;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the value of an attribute.
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $default
 | 
			
		||||
     *
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function getAttribute(string $key, $default = null);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns all the attributes of this node.
 | 
			
		||||
     *
 | 
			
		||||
     * @return array<string, mixed>
 | 
			
		||||
     */
 | 
			
		||||
    public function getAttributes(): array;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Replaces all the attributes of this node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param array<string, mixed> $attributes
 | 
			
		||||
     */
 | 
			
		||||
    public function setAttributes(array $attributes): void;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Node/Arg.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Node/Arg.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Node;
 | 
			
		||||
 | 
			
		||||
use PhpParser\NodeAbstract;
 | 
			
		||||
 | 
			
		||||
class Arg extends NodeAbstract {
 | 
			
		||||
    /** @var Identifier|null Parameter name (for named parameters) */
 | 
			
		||||
    public ?Identifier $name;
 | 
			
		||||
    /** @var Expr Value to pass */
 | 
			
		||||
    public Expr $value;
 | 
			
		||||
    /** @var bool Whether to pass by ref */
 | 
			
		||||
    public bool $byRef;
 | 
			
		||||
    /** @var bool Whether to unpack the argument */
 | 
			
		||||
    public bool $unpack;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a function call argument node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Expr $value Value to pass
 | 
			
		||||
     * @param bool $byRef Whether to pass by ref
 | 
			
		||||
     * @param bool $unpack Whether to unpack the argument
 | 
			
		||||
     * @param array<string, mixed> $attributes Additional attributes
 | 
			
		||||
     * @param Identifier|null $name Parameter name (for named parameters)
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        Expr $value, bool $byRef = false, bool $unpack = false, array $attributes = [],
 | 
			
		||||
        ?Identifier $name = null
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->attributes = $attributes;
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
        $this->value = $value;
 | 
			
		||||
        $this->byRef = $byRef;
 | 
			
		||||
        $this->unpack = $unpack;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getSubNodeNames(): array {
 | 
			
		||||
        return ['name', 'value', 'byRef', 'unpack'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getType(): string {
 | 
			
		||||
        return 'Arg';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Node/ArrayItem.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Node/ArrayItem.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Node;
 | 
			
		||||
 | 
			
		||||
use PhpParser\NodeAbstract;
 | 
			
		||||
 | 
			
		||||
class ArrayItem extends NodeAbstract {
 | 
			
		||||
    /** @var null|Expr Key */
 | 
			
		||||
    public ?Expr $key;
 | 
			
		||||
    /** @var Expr Value */
 | 
			
		||||
    public Expr $value;
 | 
			
		||||
    /** @var bool Whether to assign by reference */
 | 
			
		||||
    public bool $byRef;
 | 
			
		||||
    /** @var bool Whether to unpack the argument */
 | 
			
		||||
    public bool $unpack;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs an array item node.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Expr $value Value
 | 
			
		||||
     * @param null|Expr $key Key
 | 
			
		||||
     * @param bool $byRef Whether to assign by reference
 | 
			
		||||
     * @param array<string, mixed> $attributes Additional attributes
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Expr $value, ?Expr $key = null, bool $byRef = false, array $attributes = [], bool $unpack = false) {
 | 
			
		||||
        $this->attributes = $attributes;
 | 
			
		||||
        $this->key = $key;
 | 
			
		||||
        $this->value = $value;
 | 
			
		||||
        $this->byRef = $byRef;
 | 
			
		||||
        $this->unpack = $unpack;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getSubNodeNames(): array {
 | 
			
		||||
        return ['key', 'value', 'byRef', 'unpack'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getType(): string {
 | 
			
		||||
        return 'ArrayItem';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// @deprecated compatibility alias
 | 
			
		||||
class_alias(ArrayItem::class, Expr\ArrayItem::class);
 | 
			
		||||
							
								
								
									
										33
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Node/Attribute.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Node/Attribute.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Node;
 | 
			
		||||
 | 
			
		||||
use PhpParser\Node;
 | 
			
		||||
use PhpParser\NodeAbstract;
 | 
			
		||||
 | 
			
		||||
class Attribute extends NodeAbstract {
 | 
			
		||||
    /** @var Name Attribute name */
 | 
			
		||||
    public Name $name;
 | 
			
		||||
 | 
			
		||||
    /** @var list<Arg> Attribute arguments */
 | 
			
		||||
    public array $args;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param Node\Name $name Attribute name
 | 
			
		||||
     * @param list<Arg> $args Attribute arguments
 | 
			
		||||
     * @param array<string, mixed> $attributes Additional node attributes
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Name $name, array $args = [], array $attributes = []) {
 | 
			
		||||
        $this->attributes = $attributes;
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
        $this->args = $args;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getSubNodeNames(): array {
 | 
			
		||||
        return ['name', 'args'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getType(): string {
 | 
			
		||||
        return 'Attribute';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Node/AttributeGroup.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								qwen/php/vendor/nikic/php-parser/lib/PhpParser/Node/AttributeGroup.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace PhpParser\Node;
 | 
			
		||||
 | 
			
		||||
use PhpParser\NodeAbstract;
 | 
			
		||||
 | 
			
		||||
class AttributeGroup extends NodeAbstract {
 | 
			
		||||
    /** @var Attribute[] Attributes */
 | 
			
		||||
    public array $attrs;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param Attribute[] $attrs PHP attributes
 | 
			
		||||
     * @param array<string, mixed> $attributes Additional node attributes
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(array $attrs, array $attributes = []) {
 | 
			
		||||
        $this->attributes = $attributes;
 | 
			
		||||
        $this->attrs = $attrs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getSubNodeNames(): array {
 | 
			
		||||
        return ['attrs'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getType(): string {
 | 
			
		||||
        return 'AttributeGroup';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user