diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 027f1fd2..433d71ae 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -50,6 +50,8 @@ body: label: Версия DLE options: - "20.0" + - "19.x" + - "18.x" - "17.x" - "16.x" validations: diff --git a/.github/workflows/composer-update.yml b/.github/workflows/composer-update.yml index aef37f45..8f8b6e0a 100644 --- a/.github/workflows/composer-update.yml +++ b/.github/workflows/composer-update.yml @@ -31,7 +31,9 @@ jobs: coverage: none - name: Run composer update - run: composer update --no-dev --no-interaction --prefer-dist --no-progress + run: | + rm -rf vendor + composer update --no-dev --no-interaction --prefer-dist --no-progress - name: Open PR if lock file changed uses: peter-evans/create-pull-request@v8 diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml index 171991c8..1ba19bd3 100644 --- a/.github/workflows/openapi.yml +++ b/.github/workflows/openapi.yml @@ -32,7 +32,9 @@ jobs: coverage: none - name: Install dependencies - run: composer install --no-dev --no-interaction --prefer-dist --no-progress + run: | + rm -rf vendor + composer install --no-dev --no-interaction --prefer-dist --no-progress - name: Generate openapi.yaml run: composer openapi diff --git a/apidata/openapi.yaml b/apidata/openapi.yaml index dfc858c3..297be1a4 100644 --- a/apidata/openapi.yaml +++ b/apidata/openapi.yaml @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md openapi: 3.0.0 info: title: 'DLE API' @@ -3614,3621 +3613,3 @@ tags: - name: System description: Служебные -||||||| -======= -openapi: 3.0.0 -info: - title: 'DLE API' - description: 'Неофициальное REST API для DataLife Engine 20.0. Поверхность: /api/v2. Ресурсы: Authorization: Bearer . Выдача: POST /oauth/token с credential_type=api_key|auth|oauth_client или grant_type. Discovery: /.well-known/oauth-authorization-server. Identity: GET /me и /oauth/userinfo. Проверка сырого ключа: GET /key/check.' - version: 200.1.0 -servers: - - - url: '{apiBase}' - description: 'Базовый URL API (подставьте свой хост, напр. https://example.com/api/v2)' - variables: - apiBase: - default: /api/v2 - description: 'Путь или полный URL до /api/v2' - - - url: /api/v2 - description: 'Относительный путь по умолчанию' -paths: - /oauth/token: - post: - tags: - - OAuth - summary: 'Выдача AuthToken (credential_type или grant_type)' - description: 'Предпочтительно credential_type=api_key|auth|oauth_client. Альтернатива: grant_type=client_credentials|password|authorization_code|refresh_token. В DEMO_MODE при успехе — authorized без access_token.' - operationId: oauthToken - requestBody: - description: 'Параметры credential_type или OAuth2 grant' - required: true - content: - application/json: - schema: - properties: - credential_type: - description: 'Предпочтительный способ выдачи AuthToken' - type: string - enum: [api_key, auth, oauth_client] - grant_type: - type: string - enum: [client_credentials, authorization_code, refresh_token, password] - api_key: - description: credential_type=api_key - type: string - client_id: - type: string - client_secret: - type: string - scope: - type: string - code: - type: string - redirect_uri: - type: string - code_verifier: - type: string - refresh_token: - type: string - username: - description: 'Логин или email (auth / password)' - type: string - password: - type: string - type: object - example: - credential_type: api_key - api_key: your_api_key - responses: - '200': - description: 'Токен выдан или DEMO_MODE authorized' - content: - application/json: - schema: - properties: - access_token: { type: string, nullable: true } - token_type: { type: string, example: Bearer } - expires_in: { type: integer } - refresh_token: { type: string } - demo_mode: { type: boolean } - authorized: { type: boolean } - message: { type: string } - type: object - example: - access_token: … - token_type: Bearer - expires_in: 3600 - refresh_token: … - '400': - description: 'Ошибка grant / credential' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: [] - /.well-known/oauth-authorization-server: - get: - tags: - - OAuth - summary: 'OAuth AS discovery (без Bearer)' - operationId: oauthDiscovery - responses: - '200': - description: 'Метаданные AS' - content: - application/json: - schema: - properties: - issuer: { type: string } - authorization_endpoint: { type: string } - token_endpoint: { type: string } - revocation_endpoint: { type: string } - userinfo_endpoint: { type: string } - response_types_supported: { type: array, items: { type: string } } - grant_types_supported: { type: array, items: { type: string } } - code_challenge_methods_supported: { type: array, items: { type: string } } - token_endpoint_auth_methods_supported: { type: array, items: { type: string } } - credential_types_supported: { type: array, items: { type: string } } - type: object - security: [] - /me: - get: - tags: - - Me - summary: 'Субъект AuthToken (identity без CRUD-масок ПДн)' - operationId: me - responses: - '200': - description: Identity - content: - application/json: - schema: - properties: - sub: { type: string, nullable: true } - user_id: { type: integer } - name: { type: string, nullable: true } - email: { type: string, nullable: true } - user_group: { type: integer, nullable: true } - user: { type: object, nullable: true, additionalProperties: true } - api_key_id: { type: integer } - access_level: { type: object, nullable: true, additionalProperties: true } - client_id: { type: string, nullable: true } - auth_via: { type: string, example: access_token } - type: object - '401': - $ref: '#/components/responses/Unauthorized' - security: - - - bearerAuth: [] - /key/check: - get: - tags: - - Me - summary: 'Проверка сырого API-ключа' - description: 'Принимает Authorization: Bearer , возвращает ключ, scopes и payload `me`. `validTo = null` означает бессрочный ключ.' - operationId: keyCheck - responses: - '200': - description: 'Ключ валиден' - content: - application/json: - schema: - properties: - apiKey: { properties: { key: { type: string }, validFrom: { type: string, format: date-time, nullable: true }, validTo: { description: 'null = ключ бессрочный', type: string, format: date-time, nullable: true }, accessLevel: { type: object, nullable: true, additionalProperties: true } }, type: object } - scopes: { type: object, additionalProperties: { properties: { read: { type: boolean }, write: { type: boolean }, edit: { type: boolean }, delete: { type: boolean } }, type: object } } - me: { type: object, additionalProperties: true } - type: object - '401': - $ref: '#/components/responses/Unauthorized' - security: - - - rawApiKeyBearer: [] - /oauth/userinfo: - get: - tags: - - OAuth - summary: 'OIDC-совместимый userinfo (тот же payload, что /me)' - operationId: oauthUserinfo - responses: - '200': - description: Identity - content: - application/json: - schema: - properties: - sub: { type: string, nullable: true } - user_id: { type: integer } - name: { type: string, nullable: true } - email: { type: string, nullable: true } - user_group: { type: integer, nullable: true } - user: { type: object, nullable: true, additionalProperties: true } - api_key_id: { type: integer } - access_level: { type: object, nullable: true, additionalProperties: true } - client_id: { type: string, nullable: true } - auth_via: { type: string } - type: object - '401': - $ref: '#/components/responses/Unauthorized' - security: - - - bearerAuth: [] - /oauth/revoke: - post: - tags: - - OAuth - summary: 'Отзыв токена' - operationId: oauthRevoke - requestBody: - required: true - content: - application/json: - schema: - required: - - token - properties: - token: - description: 'Access или refresh token' - type: string - type: object - responses: - '200': - description: Отозван - content: - application/json: - schema: - properties: - revoked: { type: boolean, example: true } - type: object - example: - revoked: true - security: [] - /post/: - get: - tags: - - Post - summary: 'Список новостей (фильтры как у /table/post/ + legacy headers)' - description: 'Query-параметры колонок схемы; xf[name]=value для доп. полей; ! и % префиксы значений. Legacy: HTTP-заголовки с именами колонок (BC). category — virtual FK csv + post_extras_cats.' - operationId: listPosts - parameters: - - - name: limit - in: query - schema: - type: integer - default: 20 - - - name: offset - in: query - schema: - type: integer - default: 0 - - - name: orderby - in: query - description: 'Колонка сортировки' - schema: - type: string - - - name: sort - in: query - schema: - type: string - default: DESC - enum: - - ASC - - DESC - - - name: category - in: query - description: 'Virtual FK csv → category.id (FIND_IN_SET + post_extras_cats). !negate, %LIKE' - schema: - type: string - - - name: approve - in: query - schema: - type: string - - - name: xf - in: query - description: 'Доп. поля: xf[field]=value (pad-LIKE по xfields). Пример: xf[title]=foo' - style: form - explode: true - schema: - type: object - additionalProperties: - type: string - responses: - '200': - description: OK - content: - application/json: - schema: - properties: - data: { type: array, items: { $ref: '#/components/schemas/Post' } } - count: { type: integer } - type: object - '401': - $ref: '#/components/responses/Unauthorized' - security: - - - bearerAuth: [] - post: - tags: - - Post - summary: 'Создание новости (sugar → prepare post)' - operationId: createPost - requestBody: - description: 'Новость + optional nested children' - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Post' - responses: - '201': - description: Создано - content: - application/json: - schema: - properties: - id: { type: integer } - type: object - example: - id: 1 - '401': - $ref: '#/components/responses/Unauthorized' - '422': - description: 'Ошибка создания' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - '/post/{id}': - get: - tags: - - Post - summary: 'Новость по id' - operationId: getPost - parameters: - - - name: id - in: path - required: true - schema: - type: integer - responses: - '200': - description: OK - content: - application/json: - schema: - properties: - data: { $ref: '#/components/schemas/Post' } - type: object - '401': - $ref: '#/components/responses/Unauthorized' - '404': - description: 'Не найдено' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - '/table/{name}': - get: - tags: - - Table - summary: 'Список записей таблицы с фильтрами' - description: 'Любая таблица SchemaRegistry. Фильтры = query-параметры колонок. Virtual FK (RelationMap): csv→FIND_IN_SET, one→=. Операторы: !negate, %LIKE. Пример: /table/banners/?category=1&approve=1. xf[name] если есть колонка xfields.' - operationId: listTableRows - parameters: - - - name: name - in: path - description: 'Логическое имя таблицы SchemaRegistry (banners, post, category, …)' - required: true - schema: - description: 'Логическое имя таблицы SchemaRegistry' - type: string - - - name: limit - in: query - schema: - type: integer - default: 20 - - - name: offset - in: query - schema: - type: integer - default: 0 - - - name: orderby - in: query - description: 'Колонка сортировки (из схемы)' - schema: - type: string - - - name: sort - in: query - schema: - type: string - default: DESC - enum: - - ASC - - DESC - - - name: xf - in: query - description: 'Доп. поля (если у таблицы есть xfields): xf[field]=value. Пример: xf[title]=foo' - style: form - explode: true - schema: - type: object - additionalProperties: - type: string - responses: - '200': - description: OK - content: - application/json: - schema: - properties: - data: { type: array, items: { $ref: '#/components/schemas/TableRow' } } - count: { type: integer } - table: { type: string } - type: object - '401': - $ref: '#/components/responses/Unauthorized' - '404': - description: 'Неизвестная таблица' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - '422': - description: 'Неизвестная колонка / ошибка фильтра' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - post: - tags: - - Table - summary: 'Создание записи (Fluent prepare)' - operationId: createTableRow - parameters: - - - name: name - in: path - description: 'Логическое имя таблицы SchemaRegistry' - required: true - schema: - description: 'Логическое имя таблицы SchemaRegistry' - type: string - requestBody: - description: 'Колонки выбранной таблицы (+ optional nested children). Схема = oneOf TableRow.' - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/TableRow' - responses: - '201': - description: Создано - content: - application/json: - schema: - properties: - id: { type: integer } - table: { type: string } - type: object - example: - id: 1 - table: banners - '401': - $ref: '#/components/responses/Unauthorized' - '422': - description: 'Ошибка создания' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - '/table/{name}/{id}': - get: - tags: - - Table - summary: 'Запись по скалярному PK' - operationId: getTableRow - parameters: - - - name: name - in: path - required: true - schema: - description: 'Логическое имя таблицы SchemaRegistry' - type: string - - - name: id - in: path - description: 'Значение первичного ключа' - required: true - schema: - type: string - responses: - '200': - description: OK - content: - application/json: - schema: - properties: - data: { $ref: '#/components/schemas/TableRow' } - table: { type: string } - type: object - '400': - description: 'Составной PK не поддерживается через /{id}' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - description: 'Не найдено' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - put: - tags: - - Table - summary: 'Обновление записи по скалярному PK' - operationId: updateTableRow - parameters: - - - name: name - in: path - required: true - schema: - description: 'Логическое имя таблицы SchemaRegistry' - type: string - - - name: id - in: path - required: true - schema: - type: string - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/TableRow' - responses: - '200': - description: Обновлено - content: - application/json: - schema: - properties: - id: { type: string } - table: { type: string } - updated: { type: boolean, example: true } - type: object - example: - id: '1' - table: banners - updated: true - '400': - description: 'Составной PK не поддерживается' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - description: 'Не найдено' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - '422': - description: 'Ошибка обновления' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - delete: - tags: - - Table - summary: 'Удаление записи по скалярному PK' - operationId: deleteTableRow - parameters: - - - name: name - in: path - required: true - schema: - description: 'Логическое имя таблицы SchemaRegistry' - type: string - - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: Удалено - content: - application/json: - schema: - properties: - id: { type: string } - table: { type: string } - deleted: { type: boolean, example: true } - type: object - example: - id: '1' - table: banners - deleted: true - '400': - description: 'Составной PK не поддерживается' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - description: 'Не найдено' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - /user/: - post: - tags: - - User - summary: 'Создание пользователя' - operationId: createUser - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Users' - responses: - '201': - description: Создано - content: - application/json: - schema: - properties: - id: { type: integer } - type: object - example: - id: 1 - '401': - $ref: '#/components/responses/Unauthorized' - '422': - description: 'Ошибка создания' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - /usergroup/: - post: - tags: - - User - summary: 'Создание группы пользователей' - operationId: createUsergroup - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Usergroups' - responses: - '201': - description: Создано - content: - application/json: - schema: - properties: - id: { type: integer } - type: object - example: - id: 1 - '401': - $ref: '#/components/responses/Unauthorized' - '422': - description: 'Ошибка создания' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - /plugin/: - post: - tags: - - Plugin - summary: 'Регистрация плагина' - operationId: createPlugin - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Plugins' - responses: - '201': - description: Создано - content: - application/json: - schema: - properties: - id: { type: integer } - type: object - example: - id: 1 - '401': - $ref: '#/components/responses/Unauthorized' - '422': - description: 'Ошибка создания' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - /upload/: - post: - tags: - - Upload - summary: 'Загрузка файла (multipart)' - operationId: uploadFile - requestBody: - required: true - content: - multipart/form-data: - schema: - required: - - file - properties: - file: - type: string - format: binary - subdir: - type: string - example: files - type: object - responses: - '201': - description: Загружено - content: - application/json: - schema: - type: object - additionalProperties: true - example: - url: /uploads/files/… - name: file.jpg - '401': - $ref: '#/components/responses/Unauthorized' - '422': - description: 'Ошибка загрузки' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - /conversations/: - get: - tags: - - System - summary: 'Список переписок' - operationId: listConversations - responses: - '200': - description: OK - content: - application/json: - schema: - properties: - data: { type: array, items: { $ref: '#/components/schemas/Conversations' } } - type: object - '401': - $ref: '#/components/responses/Unauthorized' - security: - - - bearerAuth: [] - '/xfields/{scope}/': - get: - tags: - - Xfield - summary: 'Каталог доп. полей' - operationId: listXfields - parameters: - - - name: scope - in: path - required: true - schema: - type: string - enum: - - post - - user - responses: - '200': - description: 'OK (post → PostXfieldsCatalog, user → UserXfieldsCatalog)' - content: - application/json: - schema: - properties: - data: { oneOf: [{ $ref: '#/components/schemas/PostXfieldsCatalog' }, { $ref: '#/components/schemas/UserXfieldsCatalog' }] } - scope: { type: string, enum: [post, user] } - type: object - '401': - $ref: '#/components/responses/Unauthorized' - security: - - - bearerAuth: [] - post: - tags: - - Xfield - summary: 'Создать определение поля (typed validation)' - operationId: createXfield - parameters: - - - name: scope - in: path - required: true - schema: - type: string - enum: - - post - - user - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/PostXfieldField' - responses: - '201': - description: Создано - content: - application/json: - schema: - properties: - name: { type: string } - scope: { type: string } - data: { $ref: '#/components/schemas/PostXfieldField' } - type: object - '401': - $ref: '#/components/responses/Unauthorized' - '422': - description: 'validation + details.fields' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - '/xfields/{scope}/encode': - post: - tags: - - Xfield - summary: 'Сериализация значений в формат post.xfields / users.xfields (аналог forPost)' - description: 'Body: {fields:{name:value}} или {name,value}. Ответ: raw + parsed.' - operationId: encodeXfields - parameters: - - - name: scope - in: path - required: true - schema: - type: string - enum: - - post - - user - requestBody: - required: true - content: - application/json: - schema: - type: object - additionalProperties: true - responses: - '200': - description: OK - content: - application/json: - schema: - properties: - raw: { type: string } - parsed: { type: object, additionalProperties: true } - type: object - '401': - $ref: '#/components/responses/Unauthorized' - '422': - description: 'Неизвестное поле / validation' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - '/xfields/{scope}/{name}': - get: - tags: - - Xfield - summary: 'Определение одного поля' - operationId: getXfield - parameters: - - - name: scope - in: path - required: true - schema: - type: string - enum: - - post - - user - - - name: name - in: path - required: true - schema: - type: string - - - name: as - in: query - description: 'Projection по типу (image, text, …)' - schema: - type: string - responses: - '200': - description: OK - content: - application/json: - schema: - properties: - data: { $ref: '#/components/schemas/PostXfieldField' } - scope: { type: string } - type: object - '401': - $ref: '#/components/responses/Unauthorized' - '404': - description: 'Не найдено' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - '422': - description: 'Тип не совпадает с ?as=' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - put: - tags: - - Xfield - summary: 'Заменить определение поля' - operationId: replaceXfield - parameters: - - - name: scope - in: path - required: true - schema: - type: string - enum: - - post - - user - - - name: name - in: path - required: true - schema: - type: string - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/PostXfieldField' - responses: - '200': - description: Обновлено - content: - application/json: - schema: - properties: - name: { type: string } - updated: { type: boolean, example: true } - data: { $ref: '#/components/schemas/PostXfieldField' } - type: object - example: - name: myfield - updated: true - '401': - $ref: '#/components/responses/Unauthorized' - '422': - description: 'validation + details.fields' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - delete: - tags: - - Xfield - summary: 'Удалить определение поля' - operationId: deleteXfield - parameters: - - - name: scope - in: path - required: true - schema: - type: string - enum: - - post - - user - - - name: name - in: path - required: true - schema: - type: string - responses: - '200': - description: Удалено - content: - application/json: - schema: - properties: - name: { type: string, example: myfield } - deleted: { type: boolean, example: true } - type: object - example: - name: myfield - deleted: true - '401': - $ref: '#/components/responses/Unauthorized' - '404': - description: 'Поле не найдено' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - '422': - description: 'Ошибка удаления' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - security: - - - bearerAuth: [] - /health: - get: - tags: - - System - summary: 'Проверка API (без Bearer)' - operationId: health - responses: - '200': - description: OK - content: - application/json: - schema: - properties: - version: { type: string, example: 200.1.0 } - api: { type: string, example: v2 } - auth: { type: string, example: Bearer } - type: object - example: - version: 200.1.0 - api: v2 - auth: Bearer - security: [] -components: - schemas: - ApiError: - description: 'Единый JSON-формат ошибки API v2: error, message, details?' - required: - - error - - message - properties: - error: - description: 'Код ошибки' - type: string - example: unauthorized - message: - description: 'Человекочитаемое сообщение' - type: string - example: 'Требуется Authorization: Bearer ' - details: - description: 'Доп. детали (validation и т.п.)' - type: object - nullable: true - additionalProperties: true - type: object - example: - error: unauthorized - message: 'Требуется Authorization: Bearer ' - AdminLogs: - description: 'Схема таблицы `admin_logs`.' - properties: - id: - description: 'Первичный ключ (admin_logs.id)' - type: integer - name: - description: 'Имя (admin_logs.name)' - type: string - date: - description: 'Дата/время (admin_logs.date)' - type: integer - ip: - description: 'IP-адрес (admin_logs.ip)' - type: string - action: - description: 'Колонка admin_logs.action' - type: integer - extras: - description: 'Колонка admin_logs.extras' - type: string - type: object - AdminSections: - description: 'Схема таблицы `admin_sections`.' - properties: - id: - description: 'Первичный ключ (admin_sections.id)' - type: integer - name: - description: 'Имя (admin_sections.name)' - type: string - title: - description: 'Заголовок (admin_sections.title)' - type: string - descr: - description: 'Описание (admin_sections.descr)' - type: string - icon: - description: 'Колонка admin_sections.icon' - type: string - allow_groups: - description: 'CSV id или all (таблица admin_sections.allow_groups)' - type: string - type: object - Banned: - description: 'Схема таблицы `banned`.' - properties: - id: - description: 'Первичный ключ (banned.id)' - type: integer - users_id: - description: 'Колонка banned.users_id' - type: integer - descr: - description: 'Описание (banned.descr)' - type: string - date: - description: 'Дата/время (banned.date)' - type: string - days: - description: 'Колонка banned.days' - type: integer - ip: - description: 'IP-адрес (banned.ip)' - type: string - banned_from: - description: 'Колонка banned.banned_from' - type: string - type: object - BannersLogs: - description: 'Схема таблицы `banners_logs`.' - properties: - id: - description: 'Первичный ключ (banners_logs.id)' - type: integer - bid: - description: 'Колонка banners_logs.bid' - type: integer - click: - description: 'Колонка banners_logs.click' - type: integer - ip: - description: 'IP-адрес (banners_logs.ip)' - type: string - type: object - BannersRubrics: - description: 'Схема таблицы `banners_rubrics`.' - properties: - id: - description: 'Первичный ключ (banners_rubrics.id)' - type: integer - parentid: - description: 'Колонка banners_rubrics.parentid' - type: integer - title: - description: 'Заголовок (banners_rubrics.title)' - type: string - description: - description: 'Колонка banners_rubrics.description' - type: string - type: object - Banners: - description: 'Схема таблицы `banners`.' - properties: - id: - description: 'Первичный ключ (banners.id)' - type: integer - banner_tag: - description: 'Колонка banners.banner_tag' - type: string - descr: - description: 'Описание (banners.descr)' - type: string - code: - description: 'Колонка banners.code' - type: string - approve: - description: 'Одобрено (0/1) (banners.approve)' - type: integer - short_place: - description: 'Колонка banners.short_place' - type: integer - bstick: - description: 'Колонка banners.bstick' - type: integer - main: - description: 'Колонка banners.main' - type: integer - category: - description: 'CSV id категорий (virtual FK csv → category.id)' - type: string - x-dle-ref: category.id - x-dle-kind: csv - grouplevel: - description: 'CSV групп или all (virtual FK csv_or_all → usergroups.id)' - type: string - x-dle-ref: usergroups.id - x-dle-kind: csv_or_all - rubric: - description: 'Virtual FK one → banners_rubrics.id' - type: integer - x-dle-ref: banners_rubrics.id - x-dle-kind: one - start: - description: 'Колонка banners.start' - type: string - end: - description: 'Колонка banners.end' - type: string - fpage: - description: 'Колонка banners.fpage' - type: integer - innews: - description: 'Колонка banners.innews' - type: integer - devicelevel: - description: 'Колонка banners.devicelevel' - type: string - allow_views: - description: 'Колонка banners.allow_views' - type: integer - max_views: - description: 'Колонка banners.max_views' - type: integer - allow_counts: - description: 'Колонка banners.allow_counts' - type: integer - max_counts: - description: 'Колонка banners.max_counts' - type: integer - views: - description: 'Колонка banners.views' - type: integer - clicks: - description: 'Колонка banners.clicks' - type: integer - comments_place: - description: 'Колонка banners.comments_place' - type: integer - allowed_country: - description: 'Колонка banners.allowed_country' - type: string - not_allowed_country: - description: 'Колонка banners.not_allowed_country' - type: string - type: object - Category: - description: 'Схема таблицы `category`.' - properties: - id: - description: 'Первичный ключ (category.id)' - type: integer - parentid: - description: 'Колонка category.parentid' - type: integer - posi: - description: 'Колонка category.posi' - type: integer - name: - description: 'Имя (category.name)' - type: string - alt_name: - description: 'ЧПУ-имя (category.alt_name)' - type: string - icon: - description: 'Колонка category.icon' - type: string - skin: - description: 'Колонка category.skin' - type: string - descr: - description: 'Описание (category.descr)' - type: string - keywords: - description: 'Ключевые слова (category.keywords)' - type: string - news_sort: - description: 'Колонка category.news_sort' - type: string - news_msort: - description: 'Колонка category.news_msort' - type: string - news_number: - description: 'Колонка category.news_number' - type: integer - short_tpl: - description: 'Колонка category.short_tpl' - type: string - full_tpl: - description: 'Колонка category.full_tpl' - type: string - metatitle: - description: 'Колонка category.metatitle' - type: string - show_sub: - description: 'Колонка category.show_sub' - type: integer - allow_rss: - description: 'Колонка category.allow_rss' - type: integer - fulldescr: - description: 'Колонка category.fulldescr' - type: string - disable_search: - description: 'Колонка category.disable_search' - type: integer - disable_main: - description: 'Колонка category.disable_main' - type: integer - disable_rating: - description: 'Колонка category.disable_rating' - type: integer - disable_comments: - description: 'CSV id или all (таблица category.disable_comments)' - type: integer - enable_dzen: - description: 'Колонка category.enable_dzen' - type: integer - active: - description: 'Колонка category.active' - type: integer - rating_type: - description: 'Колонка category.rating_type' - type: integer - schema_org: - description: 'Колонка category.schema_org' - type: integer - disable_index: - description: 'Колонка category.disable_index' - type: integer - type: object - CommentRatingLog: - description: 'Схема таблицы `comment_rating_log`.' - properties: - id: - description: 'Первичный ключ (comment_rating_log.id)' - type: integer - c_id: - description: 'ID комментария (comment_rating_log.c_id)' - type: integer - member: - description: 'Колонка comment_rating_log.member' - type: string - ip: - description: 'IP-адрес (comment_rating_log.ip)' - type: string - rating: - description: 'Колонка comment_rating_log.rating' - type: integer - type: object - CommentsFiles: - description: 'Схема таблицы `comments_files`.' - properties: - id: - description: 'Первичный ключ (comments_files.id)' - type: integer - c_id: - description: 'ID комментария (comments_files.c_id)' - type: integer - author: - description: 'Колонка comments_files.author' - type: string - date: - description: 'Дата/время (comments_files.date)' - type: string - name: - description: 'Имя (comments_files.name)' - type: string - driver: - description: 'Колонка comments_files.driver' - type: integer - type: object - Comments: - description: 'Схема таблицы `comments`.' - properties: - id: - description: 'Первичный ключ (comments.id)' - type: integer - post_id: - description: 'ID новости (comments.post_id)' - type: integer - user_id: - description: 'ID пользователя (comments.user_id)' - type: integer - date: - description: 'Дата/время (comments.date)' - type: string - autor: - description: 'Автор (имя пользователя) (comments.autor)' - type: string - email: - description: 'E-mail (comments.email)' - type: string - text: - description: 'Колонка comments.text' - type: string - ip: - description: 'IP-адрес (comments.ip)' - type: string - is_register: - description: 'Колонка comments.is_register' - type: integer - approve: - description: 'Одобрено (0/1) (comments.approve)' - type: integer - rating: - description: 'Колонка comments.rating' - type: integer - vote_num: - description: 'Колонка comments.vote_num' - type: integer - parent: - description: 'ID родителя (comments.parent)' - type: integer - type: object - Complaint: - description: 'Схема таблицы `complaint`.' - properties: - id: - description: 'Первичный ключ (complaint.id)' - type: integer - p_id: - description: 'Колонка complaint.p_id' - type: integer - c_id: - description: 'ID комментария (complaint.c_id)' - type: integer - n_id: - description: 'Колонка complaint.n_id' - type: integer - text: - description: 'Колонка complaint.text' - type: string - from: - description: 'Колонка complaint.from' - type: string - to: - description: 'Колонка complaint.to' - type: string - date: - description: 'Дата/время (complaint.date)' - type: integer - email: - description: 'E-mail (complaint.email)' - type: string - type: object - ConversationReads: - description: 'Схема таблицы `conversation_reads`.' - properties: - user_id: - description: 'ID пользователя (conversation_reads.user_id)' - type: integer - conversation_id: - description: 'Колонка conversation_reads.conversation_id' - type: integer - last_read_at: - description: 'Колонка conversation_reads.last_read_at' - type: integer - type: object - ConversationUsers: - description: 'Схема таблицы `conversation_users`.' - properties: - user_id: - description: 'ID пользователя (conversation_users.user_id)' - type: integer - conversation_id: - description: 'Колонка conversation_users.conversation_id' - type: integer - type: object - ConversationsMessages: - description: 'Схема таблицы `conversations_messages`.' - properties: - id: - description: 'Первичный ключ (conversations_messages.id)' - type: integer - conversation_id: - description: 'Колонка conversations_messages.conversation_id' - type: integer - sender_id: - description: 'Колонка conversations_messages.sender_id' - type: integer - content: - description: 'Колонка conversations_messages.content' - type: string - created_at: - description: 'Колонка conversations_messages.created_at' - type: integer - type: object - Conversations: - description: 'Схема таблицы `conversations`.' - properties: - id: - description: 'Первичный ключ (conversations.id)' - type: integer - subject: - description: 'Колонка conversations.subject' - type: string - created_at: - description: 'Колонка conversations.created_at' - type: integer - updated_at: - description: 'Колонка conversations.updated_at' - type: integer - sender_id: - description: 'Колонка conversations.sender_id' - type: integer - recipient_id: - description: 'Колонка conversations.recipient_id' - type: integer - type: object - DownloadsLog: - description: 'Схема таблицы `downloads_log`.' - properties: - id: - description: 'Первичный ключ (downloads_log.id)' - type: integer - user_id: - description: 'ID пользователя (downloads_log.user_id)' - type: integer - ip: - description: 'IP-адрес (downloads_log.ip)' - type: string - file_id: - description: 'Колонка downloads_log.file_id' - type: integer - date: - description: 'Дата/время (downloads_log.date)' - type: integer - type: object - Email: - description: 'Схема таблицы `email`.' - properties: - id: - description: 'Первичный ключ (email.id)' - type: integer - name: - description: 'Имя (email.name)' - type: string - template: - description: 'Колонка email.template' - type: string - use_html: - description: 'Колонка email.use_html' - type: integer - type: object - Files: - description: 'Схема таблицы `files`.' - properties: - id: - description: 'Первичный ключ (files.id)' - type: integer - news_id: - description: 'ID новости (files.news_id)' - type: integer - name: - description: 'Имя (files.name)' - type: string - onserver: - description: 'Колонка files.onserver' - type: string - author: - description: 'Колонка files.author' - type: string - date: - description: 'Дата/время (files.date)' - type: string - dcount: - description: 'Колонка files.dcount' - type: integer - size: - description: 'Колонка files.size' - type: integer - checksum: - description: 'Колонка files.checksum' - type: string - driver: - description: 'Колонка files.driver' - type: integer - is_public: - description: 'Колонка files.is_public' - type: integer - type: object - Flood: - description: 'Схема таблицы `flood`.' - properties: - f_id: - description: 'Колонка flood.f_id' - type: integer - ip: - description: 'IP-адрес (flood.ip)' - type: string - id: - description: 'Первичный ключ (flood.id)' - type: string - flag: - description: 'Колонка flood.flag' - type: integer - type: object - IgnoreList: - description: 'Схема таблицы `ignore_list`.' - properties: - id: - description: 'Первичный ключ (ignore_list.id)' - type: integer - user: - description: 'Колонка ignore_list.user' - type: integer - user_from: - description: 'Колонка ignore_list.user_from' - type: string - type: object - Images: - description: 'Схема таблицы `images`.' - properties: - id: - description: 'Первичный ключ (images.id)' - type: integer - images: - description: 'Колонка images.images' - type: string - news_id: - description: 'ID новости (images.news_id)' - type: integer - author: - description: 'Колонка images.author' - type: string - date: - description: 'Дата/время (images.date)' - type: string - type: object - Links: - description: 'Схема таблицы `links`.' - properties: - id: - description: 'Первичный ключ (links.id)' - type: integer - word: - description: 'Колонка links.word' - type: string - link: - description: 'Колонка links.link' - type: string - only_one: - description: 'Колонка links.only_one' - type: integer - replacearea: - description: 'Колонка links.replacearea' - type: integer - rcount: - description: 'Колонка links.rcount' - type: integer - targetblank: - description: 'Колонка links.targetblank' - type: integer - title: - description: 'Заголовок (links.title)' - type: string - enabled: - description: 'Колонка links.enabled' - type: integer - type: object - LoginLog: - description: 'Схема таблицы `login_log`.' - properties: - id: - description: 'Первичный ключ (login_log.id)' - type: integer - ip: - description: 'IP-адрес (login_log.ip)' - type: string - count: - description: 'Колонка login_log.count' - type: integer - date: - description: 'Дата/время (login_log.date)' - type: integer - type: object - Logs: - description: 'Схема таблицы `logs`.' - properties: - id: - description: 'Первичный ключ (logs.id)' - type: integer - news_id: - description: 'ID новости (logs.news_id)' - type: integer - member: - description: 'Колонка logs.member' - type: string - ip: - description: 'IP-адрес (logs.ip)' - type: string - rating: - description: 'Колонка logs.rating' - type: integer - type: object - Lostdb: - description: 'Схема таблицы `lostdb`.' - properties: - id: - description: 'Первичный ключ (lostdb.id)' - type: integer - lostname: - description: 'Колонка lostdb.lostname' - type: integer - lostid: - description: 'Колонка lostdb.lostid' - type: string - type: object - MailLog: - description: 'Схема таблицы `mail_log`.' - properties: - id: - description: 'Первичный ключ (mail_log.id)' - type: integer - user_id: - description: 'ID пользователя (mail_log.user_id)' - type: integer - mail: - description: 'Колонка mail_log.mail' - type: string - hash: - description: 'Колонка mail_log.hash' - type: string - type: object - Metatags: - description: 'Схема таблицы `metatags`.' - properties: - id: - description: 'Первичный ключ (metatags.id)' - type: integer - url: - description: 'Колонка metatags.url' - type: string - title: - description: 'Заголовок (metatags.title)' - type: string - description: - description: 'Колонка metatags.description' - type: string - keywords: - description: 'Ключевые слова (metatags.keywords)' - type: string - page_title: - description: 'Колонка metatags.page_title' - type: string - page_description: - description: 'Колонка metatags.page_description' - type: string - robots: - description: 'Колонка metatags.robots' - type: string - enabled: - description: 'Колонка metatags.enabled' - type: integer - type: object - NewsletterTemplateCategories: - description: 'Схема таблицы `newsletter_template_categories`.' - properties: - id: - description: 'Первичный ключ (newsletter_template_categories.id)' - type: integer - title: - description: 'Заголовок (newsletter_template_categories.title)' - type: string - locked: - description: 'Колонка newsletter_template_categories.locked' - type: integer - sort_order: - description: 'Колонка newsletter_template_categories.sort_order' - type: integer - created_at: - description: 'Колонка newsletter_template_categories.created_at' - type: integer - created_by: - description: 'Колонка newsletter_template_categories.created_by' - type: integer - type: object - NewsletterTemplateItems: - description: 'Схема таблицы `newsletter_template_items`.' - properties: - id: - description: 'Первичный ключ (newsletter_template_items.id)' - type: integer - category_id: - description: 'ID категории шаблона (newsletter_template_items.category_id)' - type: integer - nullable: true - title: - description: 'Заголовок (newsletter_template_items.title)' - type: string - content: - description: 'Колонка newsletter_template_items.content' - type: string - locked: - description: 'Колонка newsletter_template_items.locked' - type: integer - sort_order: - description: 'Колонка newsletter_template_items.sort_order' - type: integer - created_at: - description: 'Колонка newsletter_template_items.created_at' - type: integer - created_by: - description: 'Колонка newsletter_template_items.created_by' - type: integer - type: object - Notice: - description: 'Схема таблицы `notice`.' - properties: - id: - description: 'Первичный ключ (notice.id)' - type: integer - user_id: - description: 'ID пользователя (notice.user_id)' - type: integer - notice: - description: 'Колонка notice.notice' - type: string - type: object - PluginsFiles: - description: 'Схема таблицы `plugins_files`.' - properties: - id: - description: 'Первичный ключ (plugins_files.id)' - type: integer - plugin_id: - description: 'Колонка plugins_files.plugin_id' - type: integer - file: - description: 'Колонка plugins_files.file' - type: string - action: - description: 'Колонка plugins_files.action' - type: string - searchcode: - description: 'Колонка plugins_files.searchcode' - type: string - replacecode: - description: 'Колонка plugins_files.replacecode' - type: string - active: - description: 'Колонка plugins_files.active' - type: integer - searchcount: - description: 'Колонка plugins_files.searchcount' - type: integer - replacecount: - description: 'Колонка plugins_files.replacecount' - type: integer - filedisable: - description: 'Колонка plugins_files.filedisable' - type: integer - filedleversion: - description: 'Колонка plugins_files.filedleversion' - type: string - fileversioncompare: - description: 'Колонка plugins_files.fileversioncompare' - type: string - type: object - PluginsLogs: - description: 'Схема таблицы `plugins_logs`.' - properties: - id: - description: 'Первичный ключ (plugins_logs.id)' - type: integer - plugin_id: - description: 'Колонка plugins_logs.plugin_id' - type: integer - area: - description: 'Колонка plugins_logs.area' - type: string - error: - description: 'Колонка plugins_logs.error' - type: string - type: - description: 'Колонка plugins_logs.type' - type: string - action_id: - description: 'Колонка plugins_logs.action_id' - type: integer - type: object - Plugins: - description: 'Схема таблицы `plugins`.' - properties: - id: - description: 'Первичный ключ (plugins.id)' - type: integer - name: - description: 'Имя (plugins.name)' - type: string - description: - description: 'Колонка plugins.description' - type: string - icon: - description: 'Колонка plugins.icon' - type: string - version: - description: 'Колонка plugins.version' - type: string - dleversion: - description: 'Колонка plugins.dleversion' - type: string - versioncompare: - description: 'Колонка plugins.versioncompare' - type: string - active: - description: 'Колонка plugins.active' - type: integer - mysqlinstall: - description: 'Колонка plugins.mysqlinstall' - type: string - mysqlupgrade: - description: 'Колонка plugins.mysqlupgrade' - type: string - mysqlenable: - description: 'Колонка plugins.mysqlenable' - type: string - mysqldisable: - description: 'Колонка plugins.mysqldisable' - type: string - mysqldelete: - description: 'Колонка plugins.mysqldelete' - type: string - filedelete: - description: 'Колонка plugins.filedelete' - type: integer - filelist: - description: 'Колонка plugins.filelist' - type: string - upgradeurl: - description: 'Колонка plugins.upgradeurl' - type: string - needplugin: - description: 'Колонка plugins.needplugin' - type: string - phpinstall: - description: 'Колонка plugins.phpinstall' - type: string - phpupgrade: - description: 'Колонка plugins.phpupgrade' - type: string - phpenable: - description: 'Колонка plugins.phpenable' - type: string - phpdisable: - description: 'Колонка plugins.phpdisable' - type: string - phpdelete: - description: 'Колонка plugins.phpdelete' - type: string - notice: - description: 'Колонка plugins.notice' - type: string - mnotice: - description: 'Колонка plugins.mnotice' - type: integer - posi: - description: 'Колонка plugins.posi' - type: integer - type: object - PollLog: - description: 'Схема таблицы `poll_log`.' - properties: - id: - description: 'Первичный ключ (poll_log.id)' - type: integer - news_id: - description: 'ID новости (poll_log.news_id)' - type: integer - member: - description: 'Колонка poll_log.member' - type: string - type: object - Poll: - description: 'Схема таблицы `poll`.' - properties: - id: - description: 'Первичный ключ (poll.id)' - type: integer - news_id: - description: 'ID новости (poll.news_id)' - type: integer - title: - description: 'Заголовок (poll.title)' - type: string - frage: - description: 'Колонка poll.frage' - type: string - body: - description: 'Колонка poll.body' - type: string - votes: - description: 'Колонка poll.votes' - type: integer - multiple: - description: 'Колонка poll.multiple' - type: integer - answer: - description: 'Колонка poll.answer' - type: string - closed: - description: 'Колонка poll.closed' - type: integer - date_closed: - description: 'Колонка poll.date_closed' - type: string - type: object - PostExtrasCats: - description: 'Схема таблицы `post_extras_cats`.' - properties: - id: - description: 'Первичный ключ (post_extras_cats.id)' - type: integer - news_id: - description: 'ID новости (post_extras_cats.news_id)' - type: integer - cat_id: - description: 'Колонка post_extras_cats.cat_id' - type: integer - type: object - PostExtras: - description: 'Схема таблицы `post_extras`.' - properties: - eid: - description: 'Колонка post_extras.eid' - type: integer - news_id: - description: 'ID новости (post_extras.news_id)' - type: integer - news_read: - description: 'Колонка post_extras.news_read' - type: integer - allow_rate: - description: 'Колонка post_extras.allow_rate' - type: integer - rating: - description: 'Колонка post_extras.rating' - type: integer - vote_num: - description: 'Колонка post_extras.vote_num' - type: integer - votes: - description: 'Колонка post_extras.votes' - type: integer - view_edit: - description: 'Колонка post_extras.view_edit' - type: integer - disable_index: - description: 'Колонка post_extras.disable_index' - type: integer - related_ids: - description: 'Колонка post_extras.related_ids' - type: string - access: - description: 'CSV id или all (таблица post_extras.access)' - type: string - editdate: - description: 'Колонка post_extras.editdate' - type: integer - editor: - description: 'Колонка post_extras.editor' - type: string - reason: - description: 'Колонка post_extras.reason' - type: string - user_id: - description: 'ID пользователя (post_extras.user_id)' - type: integer - disable_search: - description: 'Колонка post_extras.disable_search' - type: integer - need_pass: - description: 'Колонка post_extras.need_pass' - type: integer - allow_rss: - description: 'Колонка post_extras.allow_rss' - type: integer - allow_rss_dzen: - description: 'Колонка post_extras.allow_rss_dzen' - type: integer - edited_now: - description: 'Колонка post_extras.edited_now' - type: string - allowed_country: - description: 'Колонка post_extras.allowed_country' - type: string - not_allowed_country: - description: 'Колонка post_extras.not_allowed_country' - type: string - type: object - PostLog: - description: 'Схема таблицы `post_log`.' - properties: - id: - description: 'Первичный ключ (post_log.id)' - type: integer - news_id: - description: 'ID новости (post_log.news_id)' - type: integer - expires: - description: 'Колонка post_log.expires' - type: string - action: - description: 'Колонка post_log.action' - type: integer - move_cat: - description: 'Колонка post_log.move_cat' - type: string - type: object - PostPass: - description: 'Схема таблицы `post_pass`.' - properties: - id: - description: 'Первичный ключ (post_pass.id)' - type: integer - news_id: - description: 'ID новости (post_pass.news_id)' - type: integer - password: - description: 'Хеш пароля (post_pass.password)' - type: string - type: object - Post: - description: 'Схема таблицы `post`.' - properties: - id: - description: 'Первичный ключ (post.id)' - type: integer - autor: - description: 'Автор (имя пользователя) (post.autor)' - type: string - date: - description: 'Дата/время (post.date)' - type: string - short_story: - description: 'Краткое описание (post.short_story)' - type: string - full_story: - description: 'Полный текст (post.full_story)' - type: string - xfields: - description: 'Доп. поля (xfields) (post.xfields)' - type: string - title: - description: 'Заголовок (post.title)' - type: string - descr: - description: 'Описание (post.descr)' - type: string - keywords: - description: 'Ключевые слова (post.keywords)' - type: string - category: - description: 'CSV id категорий (virtual FK csv → category.id)' - type: string - x-dle-ref: category.id - x-dle-kind: csv - alt_name: - description: 'ЧПУ-имя (post.alt_name)' - type: string - comm_num: - description: 'Колонка post.comm_num' - type: integer - allow_comm: - description: 'Колонка post.allow_comm' - type: integer - allow_main: - description: 'Колонка post.allow_main' - type: integer - approve: - description: 'Одобрено (0/1) (post.approve)' - type: integer - fixed: - description: 'Колонка post.fixed' - type: integer - allow_br: - description: 'Колонка post.allow_br' - type: integer - symbol: - description: 'Колонка post.symbol' - type: string - tags: - description: 'Колонка post.tags' - type: string - metatitle: - description: 'Колонка post.metatitle' - type: string - type: object - Question: - description: 'Схема таблицы `question`.' - properties: - id: - description: 'Первичный ключ (question.id)' - type: integer - question: - description: 'Колонка question.question' - type: string - answer: - description: 'Колонка question.answer' - type: string - type: object - ReadLog: - description: 'Схема таблицы `read_log`.' - properties: - id: - description: 'Первичный ключ (read_log.id)' - type: integer - news_id: - description: 'ID новости (read_log.news_id)' - type: integer - ip: - description: 'IP-адрес (read_log.ip)' - type: string - type: object - Redirects: - description: 'Схема таблицы `redirects`.' - properties: - id: - description: 'Первичный ключ (redirects.id)' - type: integer - from: - description: 'Колонка redirects.from' - type: string - to: - description: 'Колонка redirects.to' - type: string - enabled: - description: 'Колонка redirects.enabled' - type: integer - type: object - Rss: - description: 'Схема таблицы `rss`.' - properties: - id: - description: 'Первичный ключ (rss.id)' - type: integer - url: - description: 'Колонка rss.url' - type: string - description: - description: 'Колонка rss.description' - type: string - allow_main: - description: 'Колонка rss.allow_main' - type: integer - allow_rating: - description: 'Колонка rss.allow_rating' - type: integer - allow_comm: - description: 'Колонка rss.allow_comm' - type: integer - text_type: - description: 'Колонка rss.text_type' - type: integer - date: - description: 'Дата/время (rss.date)' - type: integer - search: - description: 'Колонка rss.search' - type: string - max_news: - description: 'Колонка rss.max_news' - type: integer - cookie: - description: 'Колонка rss.cookie' - type: string - category: - description: 'CSV id или all (таблица rss.category)' - type: string - lastdate: - description: 'Колонка rss.lastdate' - type: integer - allow_source: - description: 'Колонка rss.allow_source' - type: integer - type: object - Rssinform: - description: 'Схема таблицы `rssinform`.' - properties: - id: - description: 'Первичный ключ (rssinform.id)' - type: integer - tag: - description: 'Колонка rssinform.tag' - type: string - descr: - description: 'Описание (rssinform.descr)' - type: string - category: - description: 'CSV id или all (таблица rssinform.category)' - type: string - url: - description: 'Колонка rssinform.url' - type: string - template: - description: 'Колонка rssinform.template' - type: string - news_max: - description: 'Колонка rssinform.news_max' - type: integer - tmax: - description: 'Колонка rssinform.tmax' - type: integer - dmax: - description: 'Колонка rssinform.dmax' - type: integer - approve: - description: 'Одобрено (0/1) (rssinform.approve)' - type: integer - rss_date_format: - description: 'Колонка rssinform.rss_date_format' - type: string - type: object - Sendlog: - description: 'Схема таблицы `sendlog`.' - properties: - id: - description: 'Первичный ключ (sendlog.id)' - type: integer - user: - description: 'Колонка sendlog.user' - type: string - date: - description: 'Дата/время (sendlog.date)' - type: integer - flag: - description: 'Колонка sendlog.flag' - type: integer - type: object - SocialLogin: - description: 'Схема таблицы `social_login`.' - properties: - id: - description: 'Первичный ключ (social_login.id)' - type: integer - sid: - description: 'Колонка social_login.sid' - type: string - uid: - description: 'Колонка social_login.uid' - type: integer - password: - description: 'Хеш пароля (social_login.password)' - type: string - provider: - description: 'Колонка social_login.provider' - type: string - wait: - description: 'Колонка social_login.wait' - type: integer - waitlogin: - description: 'Колонка social_login.waitlogin' - type: integer - type: object - SpamLog: - description: 'Схема таблицы `spam_log`.' - properties: - id: - description: 'Первичный ключ (spam_log.id)' - type: integer - ip: - description: 'IP-адрес (spam_log.ip)' - type: string - is_spammer: - description: 'Колонка spam_log.is_spammer' - type: integer - email: - description: 'E-mail (spam_log.email)' - type: string - date: - description: 'Дата/время (spam_log.date)' - type: integer - type: object - StaticFiles: - description: 'Схема таблицы `static_files`.' - properties: - id: - description: 'Первичный ключ (static_files.id)' - type: integer - static_id: - description: 'Колонка static_files.static_id' - type: integer - author: - description: 'Колонка static_files.author' - type: string - date: - description: 'Дата/время (static_files.date)' - type: string - name: - description: 'Имя (static_files.name)' - type: string - onserver: - description: 'Колонка static_files.onserver' - type: string - dcount: - description: 'Колонка static_files.dcount' - type: integer - size: - description: 'Колонка static_files.size' - type: integer - checksum: - description: 'Колонка static_files.checksum' - type: string - driver: - description: 'Колонка static_files.driver' - type: integer - is_public: - description: 'Колонка static_files.is_public' - type: integer - type: object - Static: - description: 'Схема таблицы `static`.' - properties: - id: - description: 'Первичный ключ (static.id)' - type: integer - name: - description: 'Имя (static.name)' - type: string - descr: - description: 'Описание (static.descr)' - type: string - template: - description: 'Колонка static.template' - type: string - allow_br: - description: 'Колонка static.allow_br' - type: integer - allow_template: - description: 'Колонка static.allow_template' - type: integer - grouplevel: - description: 'CSV id или all (таблица static.grouplevel)' - type: string - tpl: - description: 'Колонка static.tpl' - type: string - metadescr: - description: 'Колонка static.metadescr' - type: string - metakeys: - description: 'Колонка static.metakeys' - type: string - views: - description: 'Колонка static.views' - type: integer - template_folder: - description: 'Колонка static.template_folder' - type: string - date: - description: 'Дата/время (static.date)' - type: integer - metatitle: - description: 'Колонка static.metatitle' - type: string - allow_count: - description: 'Колонка static.allow_count' - type: integer - sitemap: - description: 'Колонка static.sitemap' - type: integer - disable_index: - description: 'Колонка static.disable_index' - type: integer - disable_search: - description: 'Колонка static.disable_search' - type: integer - password: - description: 'Хеш пароля (static.password)' - type: string - type: object - Storage: - description: 'Схема таблицы `storage`.' - properties: - id: - description: 'Первичный ключ (storage.id)' - type: integer - name: - description: 'Имя (storage.name)' - type: integer - type: - description: 'Колонка storage.type' - type: integer - accesstype: - description: 'Колонка storage.accesstype' - type: string - connect_url: - description: 'Колонка storage.connect_url' - type: string - connect_port: - description: 'Колонка storage.connect_port' - type: integer - username: - description: 'Колонка storage.username' - type: string - password: - description: 'Хеш пароля (storage.password)' - type: string - path: - description: 'Колонка storage.path' - type: string - http_url: - description: 'Колонка storage.http_url' - type: string - client_key: - description: 'Колонка storage.client_key' - type: string - secret_key: - description: 'Колонка storage.secret_key' - type: string - bucket: - description: 'Колонка storage.bucket' - type: string - region: - description: 'Колонка storage.region' - type: string - default_storage: - description: 'Колонка storage.default_storage' - type: integer - enabled: - description: 'Колонка storage.enabled' - type: integer - posi: - description: 'Колонка storage.posi' - type: integer - type: object - Subscribe: - description: 'Схема таблицы `subscribe`.' - properties: - id: - description: 'Первичный ключ (subscribe.id)' - type: integer - user_id: - description: 'ID пользователя (subscribe.user_id)' - type: integer - name: - description: 'Имя (subscribe.name)' - type: string - email: - description: 'E-mail (subscribe.email)' - type: string - news_id: - description: 'ID новости (subscribe.news_id)' - type: integer - hash: - description: 'Колонка subscribe.hash' - type: string - type: object - TableRow: - description: 'Тело записи: выберите схему по логическому имени таблицы в path {name} (SchemaRegistry).' - oneOf: - - - $ref: '#/components/schemas/AdminLogs' - - - $ref: '#/components/schemas/AdminSections' - - - $ref: '#/components/schemas/Banned' - - - $ref: '#/components/schemas/Banners' - - - $ref: '#/components/schemas/BannersLogs' - - - $ref: '#/components/schemas/BannersRubrics' - - - $ref: '#/components/schemas/Category' - - - $ref: '#/components/schemas/CommentRatingLog' - - - $ref: '#/components/schemas/Comments' - - - $ref: '#/components/schemas/CommentsFiles' - - - $ref: '#/components/schemas/Complaint' - - - $ref: '#/components/schemas/ConversationReads' - - - $ref: '#/components/schemas/ConversationUsers' - - - $ref: '#/components/schemas/Conversations' - - - $ref: '#/components/schemas/ConversationsMessages' - - - $ref: '#/components/schemas/DownloadsLog' - - - $ref: '#/components/schemas/Email' - - - $ref: '#/components/schemas/Files' - - - $ref: '#/components/schemas/Flood' - - - $ref: '#/components/schemas/IgnoreList' - - - $ref: '#/components/schemas/Images' - - - $ref: '#/components/schemas/Links' - - - $ref: '#/components/schemas/LoginLog' - - - $ref: '#/components/schemas/Logs' - - - $ref: '#/components/schemas/Lostdb' - - - $ref: '#/components/schemas/MailLog' - - - $ref: '#/components/schemas/Metatags' - - - $ref: '#/components/schemas/NewsletterTemplateCategories' - - - $ref: '#/components/schemas/NewsletterTemplateItems' - - - $ref: '#/components/schemas/Notice' - - - $ref: '#/components/schemas/Plugins' - - - $ref: '#/components/schemas/PluginsFiles' - - - $ref: '#/components/schemas/PluginsLogs' - - - $ref: '#/components/schemas/Poll' - - - $ref: '#/components/schemas/PollLog' - - - $ref: '#/components/schemas/Post' - - - $ref: '#/components/schemas/PostExtras' - - - $ref: '#/components/schemas/PostExtrasCats' - - - $ref: '#/components/schemas/PostLog' - - - $ref: '#/components/schemas/PostPass' - - - $ref: '#/components/schemas/Question' - - - $ref: '#/components/schemas/ReadLog' - - - $ref: '#/components/schemas/Redirects' - - - $ref: '#/components/schemas/Rss' - - - $ref: '#/components/schemas/Rssinform' - - - $ref: '#/components/schemas/Sendlog' - - - $ref: '#/components/schemas/SocialLogin' - - - $ref: '#/components/schemas/SpamLog' - - - $ref: '#/components/schemas/Static' - - - $ref: '#/components/schemas/StaticFiles' - - - $ref: '#/components/schemas/Storage' - - - $ref: '#/components/schemas/Subscribe' - - - $ref: '#/components/schemas/Tags' - - - $ref: '#/components/schemas/Twofactor' - - - $ref: '#/components/schemas/Usergroups' - - - $ref: '#/components/schemas/Users' - - - $ref: '#/components/schemas/UsersDelete' - - - $ref: '#/components/schemas/Views' - - - $ref: '#/components/schemas/Vote' - - - $ref: '#/components/schemas/VoteResult' - - - $ref: '#/components/schemas/Xfsearch' - Tags: - description: 'Схема таблицы `tags`.' - properties: - id: - description: 'Первичный ключ (tags.id)' - type: integer - news_id: - description: 'ID новости (tags.news_id)' - type: integer - tag: - description: 'Колонка tags.tag' - type: string - type: object - Twofactor: - description: 'Схема таблицы `twofactor`.' - properties: - id: - description: 'Первичный ключ (twofactor.id)' - type: integer - user_id: - description: 'ID пользователя (twofactor.user_id)' - type: integer - pin: - description: 'Колонка twofactor.pin' - type: string - attempt: - description: 'Колонка twofactor.attempt' - type: integer - date: - description: 'Дата/время (twofactor.date)' - type: integer - type: object - Usergroups: - description: 'Схема таблицы `usergroups`.' - properties: - id: - description: 'Первичный ключ (usergroups.id)' - type: integer - group_name: - description: 'Колонка usergroups.group_name' - type: string - allow_cats: - description: 'Колонка usergroups.allow_cats' - type: string - allow_adds: - description: 'Колонка usergroups.allow_adds' - type: integer - cat_add: - description: 'Колонка usergroups.cat_add' - type: string - allow_admin: - description: 'Колонка usergroups.allow_admin' - type: integer - allow_addc: - description: 'Колонка usergroups.allow_addc' - type: integer - allow_editc: - description: 'Колонка usergroups.allow_editc' - type: integer - allow_delc: - description: 'Колонка usergroups.allow_delc' - type: integer - edit_allc: - description: 'Колонка usergroups.edit_allc' - type: integer - del_allc: - description: 'Колонка usergroups.del_allc' - type: integer - moderation: - description: 'Колонка usergroups.moderation' - type: integer - allow_all_edit: - description: 'Колонка usergroups.allow_all_edit' - type: integer - allow_edit: - description: 'Колонка usergroups.allow_edit' - type: integer - allow_pm: - description: 'Колонка usergroups.allow_pm' - type: integer - max_pm: - description: 'Колонка usergroups.max_pm' - type: integer - max_foto: - description: 'Колонка usergroups.max_foto' - type: string - allow_files: - description: 'Колонка usergroups.allow_files' - type: integer - allow_hide: - description: 'Колонка usergroups.allow_hide' - type: integer - allow_short: - description: 'Колонка usergroups.allow_short' - type: integer - time_limit: - description: 'Колонка usergroups.time_limit' - type: integer - rid: - description: 'Колонка usergroups.rid' - type: integer - allow_fixed: - description: 'Колонка usergroups.allow_fixed' - type: integer - allow_feed: - description: 'Колонка usergroups.allow_feed' - type: integer - allow_search: - description: 'Колонка usergroups.allow_search' - type: integer - allow_poll: - description: 'Колонка usergroups.allow_poll' - type: integer - allow_main: - description: 'Колонка usergroups.allow_main' - type: integer - captcha: - description: 'Колонка usergroups.captcha' - type: integer - icon: - description: 'Колонка usergroups.icon' - type: string - allow_modc: - description: 'Колонка usergroups.allow_modc' - type: integer - allow_rating: - description: 'Колонка usergroups.allow_rating' - type: integer - allow_offline: - description: 'Колонка usergroups.allow_offline' - type: integer - allow_image_upload: - description: 'Колонка usergroups.allow_image_upload' - type: integer - allow_file_upload: - description: 'Колонка usergroups.allow_file_upload' - type: integer - allow_signature: - description: 'Колонка usergroups.allow_signature' - type: integer - allow_url: - description: 'Колонка usergroups.allow_url' - type: integer - news_sec_code: - description: 'Колонка usergroups.news_sec_code' - type: integer - allow_image: - description: 'Колонка usergroups.allow_image' - type: integer - max_signature: - description: 'Колонка usergroups.max_signature' - type: integer - max_info: - description: 'Колонка usergroups.max_info' - type: integer - admin_addnews: - description: 'Колонка usergroups.admin_addnews' - type: integer - admin_editnews: - description: 'Колонка usergroups.admin_editnews' - type: integer - admin_comments: - description: 'Колонка usergroups.admin_comments' - type: integer - admin_categories: - description: 'Колонка usergroups.admin_categories' - type: integer - admin_editusers: - description: 'Колонка usergroups.admin_editusers' - type: integer - admin_wordfilter: - description: 'Колонка usergroups.admin_wordfilter' - type: integer - admin_xfields: - description: 'Колонка usergroups.admin_xfields' - type: integer - admin_userfields: - description: 'Колонка usergroups.admin_userfields' - type: integer - admin_static: - description: 'Колонка usergroups.admin_static' - type: integer - admin_editvote: - description: 'Колонка usergroups.admin_editvote' - type: integer - admin_newsletter: - description: 'Колонка usergroups.admin_newsletter' - type: integer - admin_blockip: - description: 'Колонка usergroups.admin_blockip' - type: integer - admin_banners: - description: 'Колонка usergroups.admin_banners' - type: integer - admin_rss: - description: 'Колонка usergroups.admin_rss' - type: integer - admin_iptools: - description: 'Колонка usergroups.admin_iptools' - type: integer - admin_rssinform: - description: 'Колонка usergroups.admin_rssinform' - type: integer - admin_googlemap: - description: 'Колонка usergroups.admin_googlemap' - type: integer - allow_html: - description: 'Колонка usergroups.allow_html' - type: integer - group_prefix: - description: 'Колонка usergroups.group_prefix' - type: string - group_suffix: - description: 'Колонка usergroups.group_suffix' - type: string - allow_subscribe: - description: 'Колонка usergroups.allow_subscribe' - type: integer - allow_image_size: - description: 'Колонка usergroups.allow_image_size' - type: integer - cat_allow_addnews: - description: 'Колонка usergroups.cat_allow_addnews' - type: string - flood_news: - description: 'Колонка usergroups.flood_news' - type: integer - max_day_news: - description: 'Колонка usergroups.max_day_news' - type: integer - force_leech: - description: 'Колонка usergroups.force_leech' - type: integer - edit_limit: - description: 'Колонка usergroups.edit_limit' - type: integer - captcha_pm: - description: 'Колонка usergroups.captcha_pm' - type: integer - max_pm_day: - description: 'Колонка usergroups.max_pm_day' - type: integer - max_mail_day: - description: 'Колонка usergroups.max_mail_day' - type: integer - admin_tagscloud: - description: 'Колонка usergroups.admin_tagscloud' - type: integer - allow_vote: - description: 'Колонка usergroups.allow_vote' - type: integer - admin_complaint: - description: 'Колонка usergroups.admin_complaint' - type: integer - news_question: - description: 'Колонка usergroups.news_question' - type: integer - comments_question: - description: 'Колонка usergroups.comments_question' - type: integer - max_comment_day: - description: 'Колонка usergroups.max_comment_day' - type: integer - max_images: - description: 'Колонка usergroups.max_images' - type: integer - max_files: - description: 'Колонка usergroups.max_files' - type: integer - disable_news_captcha: - description: 'Колонка usergroups.disable_news_captcha' - type: integer - disable_comments_captcha: - description: 'Колонка usergroups.disable_comments_captcha' - type: integer - pm_question: - description: 'Колонка usergroups.pm_question' - type: integer - captcha_feedback: - description: 'Колонка usergroups.captcha_feedback' - type: integer - feedback_question: - description: 'Колонка usergroups.feedback_question' - type: integer - files_type: - description: 'Колонка usergroups.files_type' - type: string - max_file_size: - description: 'Колонка usergroups.max_file_size' - type: integer - files_max_speed: - description: 'Колонка usergroups.files_max_speed' - type: integer - spamfilter: - description: 'Колонка usergroups.spamfilter' - type: integer - allow_comments_rating: - description: 'Колонка usergroups.allow_comments_rating' - type: integer - max_edit_days: - description: 'Колонка usergroups.max_edit_days' - type: integer - spampmfilter: - description: 'Колонка usergroups.spampmfilter' - type: integer - force_reg: - description: 'Колонка usergroups.force_reg' - type: integer - force_reg_days: - description: 'Колонка usergroups.force_reg_days' - type: integer - force_reg_group: - description: 'Колонка usergroups.force_reg_group' - type: integer - force_news: - description: 'Колонка usergroups.force_news' - type: integer - force_news_count: - description: 'Колонка usergroups.force_news_count' - type: integer - force_news_group: - description: 'Колонка usergroups.force_news_group' - type: integer - force_comments: - description: 'Колонка usergroups.force_comments' - type: integer - force_comments_count: - description: 'Колонка usergroups.force_comments_count' - type: integer - force_comments_group: - description: 'Колонка usergroups.force_comments_group' - type: integer - force_rating: - description: 'Колонка usergroups.force_rating' - type: integer - force_rating_count: - description: 'Колонка usergroups.force_rating_count' - type: integer - force_rating_group: - description: 'Колонка usergroups.force_rating_group' - type: integer - not_allow_cats: - description: 'Колонка usergroups.not_allow_cats' - type: string - allow_up_image: - description: 'Колонка usergroups.allow_up_image' - type: integer - allow_up_watermark: - description: 'Колонка usergroups.allow_up_watermark' - type: integer - allow_up_thumb: - description: 'Колонка usergroups.allow_up_thumb' - type: integer - up_count_image: - description: 'Колонка usergroups.up_count_image' - type: integer - up_image_side: - description: 'Колонка usergroups.up_image_side' - type: string - up_image_size: - description: 'Колонка usergroups.up_image_size' - type: integer - up_thumb_size: - description: 'Колонка usergroups.up_thumb_size' - type: string - allow_mail_files: - description: 'Колонка usergroups.allow_mail_files' - type: integer - max_mail_files: - description: 'Колонка usergroups.max_mail_files' - type: integer - max_mail_allfiles: - description: 'Колонка usergroups.max_mail_allfiles' - type: integer - mail_files_type: - description: 'Колонка usergroups.mail_files_type' - type: string - video_comments: - description: 'Колонка usergroups.video_comments' - type: integer - media_comments: - description: 'Колонка usergroups.media_comments' - type: integer - min_image_side: - description: 'Колонка usergroups.min_image_side' - type: string - allow_public_file_upload: - description: 'Колонка usergroups.allow_public_file_upload' - type: integer - force_comments_rating: - description: 'Колонка usergroups.force_comments_rating' - type: integer - force_comments_rating_count: - description: 'Колонка usergroups.force_comments_rating_count' - type: integer - force_comments_rating_group: - description: 'Колонка usergroups.force_comments_rating_group' - type: integer - max_downloads: - description: 'Колонка usergroups.max_downloads' - type: integer - admin_links: - description: 'Колонка usergroups.admin_links' - type: integer - admin_meta: - description: 'Колонка usergroups.admin_meta' - type: integer - admin_redirects: - description: 'Колонка usergroups.admin_redirects' - type: integer - allow_change_storage: - description: 'Колонка usergroups.allow_change_storage' - type: integer - self_delete: - description: 'Колонка usergroups.self_delete' - type: integer - allow_complaint_news: - description: 'Колонка usergroups.allow_complaint_news' - type: integer - allow_complaint_comments: - description: 'Колонка usergroups.allow_complaint_comments' - type: integer - allow_complaint_orfo: - description: 'Колонка usergroups.allow_complaint_orfo' - type: integer - flood_time: - description: 'Колонка usergroups.flood_time' - type: integer - max_c_negative: - description: 'Колонка usergroups.max_c_negative' - type: integer - max_n_negative: - description: 'Колонка usergroups.max_n_negative' - type: integer - rating_n_day: - description: 'Колонка usergroups.rating_n_day' - type: integer - rating_c_day: - description: 'Колонка usergroups.rating_c_day' - type: integer - allow_rating_change: - description: 'Колонка usergroups.allow_rating_change' - type: integer - allow_crating_change: - description: 'Колонка usergroups.allow_crating_change' - type: integer - type: object - UsersDelete: - description: 'Схема таблицы `users_delete`.' - properties: - id: - description: 'Первичный ключ (users_delete.id)' - type: integer - user_id: - description: 'ID пользователя (users_delete.user_id)' - type: integer - type: object - Users: - description: 'Схема таблицы `users`.' - properties: - email: - description: 'E-mail (users.email)' - type: string - password: - description: 'Хеш пароля (users.password)' - type: string - name: - description: 'Имя (users.name)' - type: string - user_id: - description: 'ID пользователя (users.user_id)' - type: integer - news_num: - description: 'Колонка users.news_num' - type: integer - comm_num: - description: 'Колонка users.comm_num' - type: integer - user_group: - description: 'ID группы (users.user_group)' - type: integer - lastdate: - description: 'Колонка users.lastdate' - type: string - reg_date: - description: 'Колонка users.reg_date' - type: string - banned: - description: 'Колонка users.banned' - type: string - allow_mail: - description: 'Колонка users.allow_mail' - type: integer - info: - description: 'Колонка users.info' - type: string - signature: - description: 'Колонка users.signature' - type: string - foto: - description: 'Колонка users.foto' - type: string - fullname: - description: 'Колонка users.fullname' - type: string - land: - description: 'Колонка users.land' - type: string - favorites: - description: 'Колонка users.favorites' - type: string - pm_all: - description: 'Колонка users.pm_all' - type: integer - pm_unread: - description: 'Колонка users.pm_unread' - type: integer - time_limit: - description: 'Колонка users.time_limit' - type: string - xfields: - description: 'Доп. поля (xfields) (users.xfields)' - type: string - allowed_ip: - description: 'Колонка users.allowed_ip' - type: string - hash: - description: 'Колонка users.hash' - type: string - logged_ip: - description: 'Колонка users.logged_ip' - type: string - restricted: - description: 'Колонка users.restricted' - type: integer - restricted_days: - description: 'Колонка users.restricted_days' - type: integer - restricted_date: - description: 'Колонка users.restricted_date' - type: string - timezone: - description: 'Колонка users.timezone' - type: string - news_subscribe: - description: 'Колонка users.news_subscribe' - type: integer - comments_reply_subscribe: - description: 'Колонка users.comments_reply_subscribe' - type: integer - twofactor_auth: - description: 'Колонка users.twofactor_auth' - type: integer - cat_add: - description: 'Колонка users.cat_add' - type: string - cat_allow_addnews: - description: 'Колонка users.cat_allow_addnews' - type: string - twofactor_secret: - description: 'Колонка users.twofactor_secret' - type: string - type: object - Views: - description: 'Схема таблицы `views`.' - properties: - id: - description: 'Первичный ключ (views.id)' - type: integer - news_id: - description: 'ID новости (views.news_id)' - type: integer - type: object - VoteResult: - description: 'Схема таблицы `vote_result`.' - properties: - id: - description: 'Первичный ключ (vote_result.id)' - type: integer - ip: - description: 'IP-адрес (vote_result.ip)' - type: string - name: - description: 'Имя (vote_result.name)' - type: string - vote_id: - description: 'Колонка vote_result.vote_id' - type: integer - answer: - description: 'Колонка vote_result.answer' - type: integer - type: object - Vote: - description: 'Схема таблицы `vote`.' - properties: - id: - description: 'Первичный ключ (vote.id)' - type: integer - category: - description: 'CSV id или all (таблица vote.category)' - type: string - vote_num: - description: 'Колонка vote.vote_num' - type: integer - date: - description: 'Дата/время (vote.date)' - type: integer - title: - description: 'Заголовок (vote.title)' - type: string - body: - description: 'Колонка vote.body' - type: string - approve: - description: 'Одобрено (0/1) (vote.approve)' - type: integer - start: - description: 'Колонка vote.start' - type: string - end: - description: 'Колонка vote.end' - type: string - grouplevel: - description: 'CSV id или all (таблица vote.grouplevel)' - type: string - type: object - Xfsearch: - description: 'Схема таблицы `xfsearch`.' - properties: - id: - description: 'Первичный ключ (xfsearch.id)' - type: integer - news_id: - description: 'ID новости (xfsearch.news_id)' - type: integer - tagname: - description: 'Колонка xfsearch.tagname' - type: string - tagvalue: - description: 'Колонка xfsearch.tagvalue' - type: string - type: object - PostXfieldField: - description: 'Описание одного доп. поля новости (xfields.json → fields.*).' - properties: - name: - type: string - description: - type: string - hint: - type: string - group: - type: string - category: - type: string - allow_add_usergroups: - type: string - allow_view_usergroups: - type: string - type: - type: string - enum: - - text - - textarea - - htmljs - - select - - image - - imagegalery - - video - - audio - - file - - yesorno - - datetime - min: - type: string - max: - type: string - storage: - type: string - max_files: - type: string - max_size: - type: string - image_sizes: - type: string - image_size: - type: string - image_side: - type: string - image_max_size: - type: string - thumb_size: - type: string - thumb_side: - type: string - max_images: - type: string - files_ext: - type: string - file_max_size: - type: string - condition: - type: string - date_format: - type: string - date_view_format: - type: string - select_separator: - type: string - links_separator: - type: string - not_required: - type: integer - default: - description: 'Для select — варианты через \n' - type: string - allow_multi: - type: integer - use_as_links: - type: integer - use_editor: - type: integer - safe_mode: - type: integer - make_watermark: - type: integer - make_thumb: - type: integer - use_opengraph: - type: string - is_public: - type: string - date_local: - type: string - date_declension: - type: string - allow_in_news: - type: integer - lazy_load: - type: string - type: object - PostXfieldGroup: - description: 'Группа доп. полей новости (xfields.json → groups.*).' - properties: - title: - description: 'Заголовок группы' - type: string - description: - description: 'Описание группы' - type: string - type: object - PostXfieldsCatalog: - description: 'Каталог доп. полей новостей (xfields.json).' - properties: - fields: - description: 'Карта полей: имя → определение' - type: object - additionalProperties: - $ref: '#/components/schemas/PostXfieldField' - groups: - description: 'Карта групп: имя → определение' - type: object - additionalProperties: - $ref: '#/components/schemas/PostXfieldGroup' - type: object - UserXfieldField: - description: 'Описание доп. поля профиля (userxfields.json → fields.*).' - properties: - name: - description: 'Системное имя поля' - type: string - description: - description: 'Заголовок поля' - type: string - type: - description: 'Тип поля' - type: string - condition: - description: 'Условие отображения' - type: string - safe_mode: - description: 'Безопасный режим (0/1)' - type: integer - registration: - description: 'Показывать при регистрации (0/1)' - type: integer - allow_change: - description: 'Разрешить изменение (0/1)' - type: integer - private: - description: 'Приватное поле (0/1)' - type: integer - type: object - UserXfieldsCatalog: - description: 'Каталог доп. полей профиля (userxfields.json).' - properties: - fields: - description: 'Карта полей: имя → определение' - type: object - additionalProperties: - $ref: '#/components/schemas/UserXfieldField' - type: object - responses: - Unauthorized: - description: 'Нет Authorization: Bearer или AuthToken недействителен/просрочен' - content: - application/json: - schema: - $ref: '#/components/schemas/ApiError' - examples: - missing: - summary: 'Нет Bearer' - value: - error: unauthorized - message: 'Требуется Authorization: Bearer ' - invalid: - summary: 'Неверный или просроченный token' - value: - error: unauthorized - message: 'Недействительный или просроченный AuthToken' - securitySchemes: - bearerAuth: - type: http - description: 'Access token из POST /oauth/token (credential_type или grant_type). Сырой API-ключ на ресурсах не принимается.' - bearerFormat: AuthToken - scheme: bearer - rawApiKeyBearer: - type: http - description: 'Сырой API-ключ только для GET /key/check. Формат: Authorization: Bearer .' - bearerFormat: 'API Key' - scheme: bearer -tags: - - - name: OAuth - description: 'Выдача и отзыв токенов, discovery, userinfo' - - - name: Me - description: 'Субъект AuthToken и проверка сырого API-ключа' - - - name: Table - description: 'Универсальный CRUD по SchemaRegistry: GET/POST /table/{name}/, GET/PUT/DELETE /table/{name}/{id}' - - - name: Post - description: Новости - - - name: User - description: 'Пользователи и группы' - - - name: Plugin - description: Плагины - - - name: Upload - description: 'Загрузка файлов' - - - name: Xfield - description: 'Каталог доп. полей (xfields.json / userxfields.json)' - - - name: System - description: Служебные ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Http/V2/Controller/MeController.php b/upload/api/src/Http/V2/Controller/MeController.php index 416f67c8..ba071f2e 100644 --- a/upload/api/src/Http/V2/Controller/MeController.php +++ b/upload/api/src/Http/V2/Controller/MeController.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md payloadBuilder->fromRequest($request)); - } - -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Http/V2/Controller/OauthController.php b/upload/api/src/Http/V2/Controller/OauthController.php index fbe3f241..57949318 100644 --- a/upload/api/src/Http/V2/Controller/OauthController.php +++ b/upload/api/src/Http/V2/Controller/OauthController.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md getQueryParams(), (array) $request->getParsedBody()); - $cred = (string) ($params['credential_type'] ?? ''); - $grant = (string) ($params['grant_type'] ?? ''); - - if($cred !== '') { - $result = match ($cred) { - 'api_key' => $this->tokens->issueByApiKey( - (string) ($params['api_key'] ?? ''), - (string) ($params['scope'] ?? ''), - ), - 'auth' => $this->tokens->issueByAuth( - (string) ($params['username'] ?? ''), - (string) ($params['password'] ?? ''), - (string) ($params['scope'] ?? ''), - ), - 'oauth_client' => $this->tokens->issueByOauthClient( - (string) ($params['client_id'] ?? ''), - (string) ($params['client_secret'] ?? ''), - (string) ($params['scope'] ?? ''), - ), - default => ['error' => 'unsupported_credential_type', 'message' => __('Неподдерживаемый credential_type')], - }; - } else { - $result = match ($grant) { - 'client_credentials' => $this->tokens->issueByOauthClient( - (string) ($params['client_id'] ?? ''), - (string) ($params['client_secret'] ?? ''), - (string) ($params['scope'] ?? ''), - ), - 'authorization_code' => $this->tokens->issueAuthorizationCode( - (string) ($params['client_id'] ?? ''), - (string) ($params['client_secret'] ?? ''), - (string) ($params['code'] ?? ''), - (string) ($params['redirect_uri'] ?? ''), - (string) ($params['code_verifier'] ?? ''), - ), - 'refresh_token' => $this->tokens->refresh((string) ($params['refresh_token'] ?? '')), - 'password' => $this->tokens->issuePassword( - (string) ($params['client_id'] ?? ''), - (string) ($params['client_secret'] ?? ''), - (string) ($params['username'] ?? ''), - (string) ($params['password'] ?? ''), - (string) ($params['scope'] ?? ''), - ), - default => ['error' => 'unsupported_grant_type', 'message' => __('Укажите credential_type или grant_type')], - }; - } - - $status = isset($result['error']) ? 400 : 200; - - return JsonResponder::ok($result, $status); - } - - public function revoke(Request $request, Response $_response): Response { - $body = (array) $request->getParsedBody(); - $this->tokens->revoke((string) ($body['token'] ?? '')); - - return JsonResponder::ok(['revoked' => true]); - } - - public function authorize(Request $request, Response $response): Response { - $q = array_merge($request->getQueryParams(), (array) $request->getParsedBody()); - $clientId = (string) ($q['client_id'] ?? ''); - $redirect = (string) ($q['redirect_uri'] ?? ''); - $state = (string) ($q['state'] ?? ''); - $challenge = (string) ($q['code_challenge'] ?? ''); - $method = (string) ($q['code_challenge_method'] ?? 'S256'); - - global $is_logged, $member_id, $config; - $userId = 0; - if(!empty($is_logged) && is_array($member_id ?? null)) { - $userId = (int) ($member_id['user_id'] ?? 0); - } - - if($clientId === '' || $redirect === '') { - return JsonResponder::error('invalid_request', __('Нужны client_id и redirect_uri'), 400); - } - - $authErr = $this->tokens->validateAuthorizeRequest($clientId, $redirect); - if($authErr !== null) { - return JsonResponder::error($authErr['error'], $authErr['message'], 400); - } - - if($userId < 1) { - $return = (string) $request->getUri(); - if(session_status() === PHP_SESSION_ACTIVE || @session_start()) { - $_SESSION['dleapi_oauth_return'] = $return; - } - $login = rtrim((string) ($config['http_home_url'] ?? '/'), '/') . '/index.php?do=login'; - - return $response->withHeader('Location', $login)->withStatus(302); - } - - $sep = str_contains($redirect, '?') ? '&' : '?'; - if(DleApiConfig::isDemoMode()) { - $loc = $redirect . $sep . http_build_query(array_filter([ - 'error' => 'demo_mode', - 'error_description' => __('Авторизация пройдена, но сброшена в демо-режиме'), - 'authorized' => '1', - 'demo_mode' => '1', - 'state' => $state ?: null, - ])); - - return $response->withHeader('Location', $loc)->withStatus(302); - } - - $code = $this->tokens->createAuthCode($clientId, $userId, $redirect, (string) ($q['scope'] ?? ''), $challenge, $method); - $loc = $redirect . $sep . http_build_query(array_filter(['code' => $code, 'state' => $state ?: null])); - - return $response->withHeader('Location', $loc)->withStatus(302); - } - - public function discovery(Request $_request, Response $_response): Response { - $base = $this->apiBaseUrl(); - - return JsonResponder::ok([ - 'issuer' => $base, - 'authorization_endpoint' => $base . '/oauth/authorize', - 'token_endpoint' => $base . '/oauth/token', - 'revocation_endpoint' => $base . '/oauth/revoke', - 'userinfo_endpoint' => $base . '/oauth/userinfo', - 'response_types_supported' => ['code'], - 'grant_types_supported' => [ - 'authorization_code', - 'refresh_token', - 'client_credentials', - 'password', - ], - 'code_challenge_methods_supported' => ['S256', 'plain'], - 'token_endpoint_auth_methods_supported' => ['client_secret_post', 'client_secret_basic'], - 'credential_types_supported' => ['api_key', 'auth', 'oauth_client'], - ]); - } - - public function userinfo(Request $request, Response $_response): Response { - return (new MeController())->me($request, $_response); - } - - private function apiBaseUrl(): string { - global $config; - $host = rtrim((string) ($config['http_home_url'] ?? ''), '/'); - - return $host . '/api/v2'; - } - -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Http/V2/OAuth/TokenService.php b/upload/api/src/Http/V2/OAuth/TokenService.php index 28f5a6ae..4d66b0c5 100644 --- a/upload/api/src/Http/V2/OAuth/TokenService.php +++ b/upload/api/src/Http/V2/OAuth/TokenService.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md - */ - public function issueByApiKey(string $apiKey, string $scope = ''): array { - /** @var ApiKeyRepository $repo */ - $repo = $this->repo(ApiKey::class); - $key = $repo->findActiveByApi($apiKey); - if($key === null) { - return ['error' => 'invalid_client', 'message' => __('Неверный или неактивный API-ключ')]; - } - if(DleApiConfig::isDemoMode()) { - return DleApiConfig::demoAuthorizedResponse(); - } - - return $this->persistTokensForKey($key, $key->user_id, $scope); - } - - /** - * @return array - */ - public function issueByAuth(string $username, string $password, string $scope = ''): array { - $userId = (new DleUserPasswordVerifier())->verify($username, $password); - if($userId === null) { - return ['error' => 'invalid_grant', 'message' => __('Неверный логин или пароль')]; - } - $key = $this->resolveApiKeyForUser($userId); - if($key === null) { - return ['error' => 'access_denied', 'message' => __('Нет API-ключа пользователя и гостевого ключа')]; - } - if(DleApiConfig::isDemoMode()) { - return DleApiConfig::demoAuthorizedResponse(); - } - - return $this->persistTokensForKey($key, $userId, $scope); - } - - /** - * @return array - */ - public function issueByOauthClient(string $clientId, string $clientSecret, string $scope = ''): array { - $client = $this->findActiveClient($clientId); - if($client === null || !password_verify($clientSecret, $client->client_secret)) { - return ['error' => 'invalid_client', 'message' => __('Неверный client_id или client_secret')]; - } - if(!$this->clientAllowsGrant($client, 'client_credentials')) { - return ['error' => 'unauthorized_client', 'message' => __('Клиент не разрешает grant_type=client_credentials')]; - } - $key = $this->findActiveApiKey($client->api_key_id); - if($key === null) { - return ['error' => 'invalid_client', 'message' => __('API-ключ клиента неактивен')]; - } - if(DleApiConfig::isDemoMode()) { - return DleApiConfig::demoAuthorizedResponse(); - } - - return $this->persistTokens($client, $key, $key->user_id, $scope); - } - - /** - * @return array - */ - public function issueClientCredentials(string $clientId, string $clientSecret, string $scope = ''): array { - return $this->issueByOauthClient($clientId, $clientSecret, $scope); - } - - /** - * @return array - */ - public function issuePassword( - string $clientId, - string $clientSecret, - string $username, - string $password, - string $scope = '', - ): array { - if($clientId === '' && $clientSecret === '') { - return $this->issueByAuth($username, $password, $scope); - } - if($clientId === '' || $clientSecret === '') { - return ['error' => 'invalid_client', 'message' => __('Нужны оба: client_id и client_secret')]; - } - $client = $this->findActiveClient($clientId); - if($client === null || !password_verify($clientSecret, $client->client_secret)) { - return ['error' => 'invalid_client', 'message' => __('Неверный client_id или client_secret')]; - } - if(!$this->clientAllowsGrant($client, 'password')) { - return ['error' => 'unauthorized_client', 'message' => __('Клиент не разрешает grant_type=password')]; - } - $key = $this->findActiveApiKey($client->api_key_id); - if($key === null) { - return ['error' => 'invalid_client', 'message' => __('API-ключ клиента неактивен')]; - } - $userId = (new DleUserPasswordVerifier())->verify($username, $password); - if($userId === null) { - return ['error' => 'invalid_grant', 'message' => __('Неверный логин или пароль')]; - } - if(DleApiConfig::isDemoMode()) { - return DleApiConfig::demoAuthorizedResponse(); - } - - return $this->persistTokens($client, $key, $userId, $scope); - } - - /** - * @return array - */ - public function issueAuthorizationCode( - string $clientId, - string $clientSecret, - string $code, - string $redirectUri, - string $codeVerifier = '', - ): array { - $client = $this->findActiveClient($clientId); - if($client === null || !password_verify($clientSecret, $client->client_secret)) { - return ['error' => 'invalid_client', 'message' => __('Неверный client')]; - } - if(!$this->clientAllowsGrant($client, 'authorization_code')) { - return ['error' => 'unauthorized_client', 'message' => __('Клиент не разрешает grant_type=authorization_code')]; - } - /** @var OauthAuthCodeRepository $codes */ - $codes = $this->repo(OauthAuthCode::class); - $row = $codes->findValidByCode($code); - if($row === null || $row->client_id !== $clientId) { - return ['error' => 'invalid_grant', 'message' => __('Код недействителен')]; - } - if($redirectUri !== '' && (string) ($row->redirect_uri ?? '') !== $redirectUri) { - return ['error' => 'invalid_grant', 'message' => __('redirect_uri не совпадает')]; - } - $challenge = (string) ($row->code_challenge ?? ''); - if($challenge !== '') { - $method = (string) ($row->code_challenge_method ?? 'S256'); - $calc = $method === 'plain' - ? $codeVerifier - : rtrim(strtr(base64_encode(hash('sha256', $codeVerifier, true)), '+/', '-_'), '='); - if(!hash_equals($challenge, $calc)) { - return ['error' => 'invalid_grant', 'message' => __('Ошибка проверки PKCE')]; - } - } - if(DleApiConfig::isDemoMode()) { - return DleApiConfig::demoAuthorizedResponse(); - } - $codes->revokeEntity($row); - $key = $this->findActiveApiKey($client->api_key_id); - if($key === null) { - return ['error' => 'invalid_client', 'message' => __('API-ключ неактивен')]; - } - - return $this->persistTokens($client, $key, $row->user_id, (string) ($row->scopes ?? '')); - } - - /** - * @return array - */ - public function refresh(string $refreshToken): array { - /** @var OauthRefreshTokenRepository $refreshRepo */ - $refreshRepo = $this->repo(OauthRefreshToken::class); - $row = $refreshRepo->findValidByTokenId($refreshToken); - if($row === null) { - return ['error' => 'invalid_grant', 'message' => __('Refresh token недействителен')]; - } - /** @var OauthAccessTokenRepository $accessRepo */ - $accessRepo = $this->repo(OauthAccessToken::class); - $access = $accessRepo->findByTokenId($row->access_token_id); - if($access === null) { - return ['error' => 'invalid_grant', 'message' => __('Связанный access token не найден')]; - } - $client = $this->findActiveClient($access->client_id); - $key = $this->findActiveApiKey($access->api_key_id); - if($client === null || $key === null) { - return ['error' => 'invalid_client', 'message' => __('Клиент или ключ неактивен')]; - } - if(!$this->clientAllowsGrant($client, 'refresh_token')) { - return ['error' => 'unauthorized_client', 'message' => __('Клиент не разрешает grant_type=refresh_token')]; - } - if(DleApiConfig::isDemoMode()) { - return DleApiConfig::demoAuthorizedResponse(); - } - $refreshRepo->revokeEntity($row); - $accessRepo->revokeEntity($access); - - return $this->persistTokens($client, $key, $access->user_id, (string) ($access->scopes ?? '')); - } - - public function revoke(string $token): void { - /** @var OauthAccessTokenRepository $accessRepo */ - $accessRepo = $this->repo(OauthAccessToken::class); - $accessRepo->revokeByAccessOrTokenId($token); - /** @var OauthRefreshTokenRepository $refreshRepo */ - $refreshRepo = $this->repo(OauthRefreshToken::class); - $refreshRepo->revokeByTokenId($token); - } - - /** - * Только AuthToken (не сырой API-ключ). - * - * @return array{auth_via: 'access_token', token: array, key: array}|null - */ - public function validateAccessToken(string $bearer): ?array { - /** @var OauthAccessTokenRepository $accessRepo */ - $accessRepo = $this->repo(OauthAccessToken::class); - $row = $accessRepo->findValidByAccessToken($bearer); - if($row === null) { - return null; - } - $key = $this->findActiveApiKey($row->api_key_id); - if($key === null) { - return null; - } - - return [ - 'auth_via' => 'access_token', - 'token' => [ - 'token_id' => $row->token_id, - 'access_token' => $row->access_token, - 'client_id' => $row->client_id, - 'user_id' => $row->user_id, - 'api_key_id' => $row->api_key_id, - 'scopes' => $row->scopes, - ], - 'key' => ApiKeyRepository::toAuthArray($key), - ]; - } - - public function resolveApiKeyForUser(int $userId): ?ApiKey { - /** @var ApiKeyRepository $repo */ - $repo = $this->repo(ApiKey::class); - $key = $repo->findActiveByUserId($userId); - if($key !== null) { - return $key; - } - - return $repo->findActiveGuest(); - } - - /** - * Проверка client_id / redirect_uri / grant authorization_code до выдачи code. - * - * @return array{error: string, message: string}|null null — OK - */ - public function validateAuthorizeRequest(string $clientId, string $redirectUri): ?array { - $client = $this->findActiveClient($clientId); - if($client === null) { - return ['error' => 'invalid_client', 'message' => __('Неизвестный или неактивный client_id')]; - } - if(!$this->clientAllowsGrant($client, 'authorization_code')) { - return ['error' => 'unauthorized_client', 'message' => __('Клиент не разрешает grant_type=authorization_code')]; - } - $registered = (string) ($client->redirect_uri ?? ''); - if($registered === '') { - return ['error' => 'invalid_request', 'message' => __('У клиента не задан redirect_uri')]; - } - if($registered !== $redirectUri) { - return ['error' => 'invalid_request', 'message' => __('redirect_uri не совпадает с зарегистрированным у клиента')]; - } - - return null; - } - - public function createAuthCode( - string $clientId, - int $userId, - string $redirectUri, - string $scopes = '', - string $codeChallenge = '', - string $codeChallengeMethod = 'S256', - ): string { - $code = bin2hex(random_bytes(32)); - /** @var OauthAuthCodeRepository $codes */ - $codes = $this->repo(OauthAuthCode::class); - $codes->createCode( - $code, - $clientId, - $userId, - $scopes, - $redirectUri, - $codeChallenge, - $codeChallengeMethod, - new \DateTimeImmutable('+' . 600 . ' seconds'), - ); - - return $code; - } - - /** - * @return array{access_token: string, token_type: string, expires_in: int, refresh_token: string} - */ - private function persistTokens(OauthClient $client, ApiKey $key, int $userId, string $scopes): array { - return $this->persistTokensForKey($key, $userId, $scopes, $client->client_id); - } - - /** - * @return array{access_token: string, token_type: string, expires_in: int, refresh_token: string} - */ - private function persistTokensForKey(ApiKey $key, int $userId, string $scopes, string $clientId = ''): array { - $ttl = $this->tokenTtl(); - $tokenId = bin2hex(random_bytes(16)); - $accessToken = bin2hex(random_bytes(32)); - $refreshId = bin2hex(random_bytes(16)); - /** @var OauthAccessTokenRepository $accessRepo */ - $accessRepo = $this->repo(OauthAccessToken::class); - $accessRepo->createToken( - $tokenId, - $accessToken, - $clientId, - $userId, - $key->id(), - $scopes, - new \DateTimeImmutable('+' . $ttl . ' seconds'), - ); - /** @var OauthRefreshTokenRepository $refreshRepo */ - $refreshRepo = $this->repo(OauthRefreshToken::class); - $refreshRepo->createToken( - $refreshId, - $tokenId, - new \DateTimeImmutable('+' . (86400 * 30) . ' seconds'), - ); - - return [ - 'access_token' => $accessToken, - 'token_type' => 'Bearer', - 'expires_in' => $ttl, - 'refresh_token' => $refreshId, - ]; - } - - private function clientAllowsGrant(OauthClient $client, string $grant): bool { - $raw = $client->grant_types; - if($raw === '') { - return false; - } - - return in_array($grant, array_map('trim', explode(',', $raw)), true); - } - - private function findActiveClient(string $clientId): ?OauthClient { - /** @var OauthClientRepository $repo */ - $repo = $this->repo(OauthClient::class); - - return $repo->findActiveByClientId($clientId); - } - - private function findActiveApiKey(int $id): ?ApiKey { - /** @var ApiKeyRepository $repo */ - $repo = $this->repo(ApiKey::class); - - return $repo->findActive($id); - } - - /** - * @template T of object - * @param class-string $entity - * @return object - */ - private function repo(string $entity): object { - return Application::instance()->database()->repository($entity); - } - - private function tokenTtl(): int { - $cfg = DleApiConfig::all(); - if(isset($cfg['token_ttl'])) { - return max(60, (int) $cfg['token_ttl']); - } - - return 3600; - } - -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/OpenApi/Document.php b/upload/api/src/OpenApi/Document.php index 51f1e773..7ef50308 100644 --- a/upload/api/src/OpenApi/Document.php +++ b/upload/api/src/OpenApi/Document.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md . Выдача: POST /oauth/token с credential_type=api_key|auth|oauth_client или grant_type. Discovery: /.well-known/oauth-authorization-server. Identity: GET /me и /oauth/userinfo. Проверка сырого ключа: GET /key/check.', -)] -#[OA\Server( - url: '{apiBase}', - description: 'Базовый URL API (подставьте свой хост, напр. https://example.com/api/v2)', - variables: [ - new OA\ServerVariable( - serverVariable: 'apiBase', - default: '/api/v2', - description: 'Путь или полный URL до /api/v2', - ), - ], -)] -#[OA\Server(url: '/api/v2', description: 'Относительный путь по умолчанию')] -#[OA\SecurityScheme( - securityScheme: 'bearerAuth', - type: 'http', - scheme: 'bearer', - bearerFormat: 'AuthToken', - description: 'Access token из POST /oauth/token (credential_type или grant_type). Сырой API-ключ на ресурсах не принимается.', -)] -#[OA\SecurityScheme( - securityScheme: 'rawApiKeyBearer', - type: 'http', - scheme: 'bearer', - bearerFormat: 'API Key', - description: 'Сырой API-ключ только для GET /key/check. Формат: Authorization: Bearer .', -)] -#[OA\Tag(name: 'OAuth', description: 'Выдача и отзыв токенов, discovery, userinfo')] -#[OA\Tag(name: 'Me', description: 'Субъект AuthToken и проверка сырого API-ключа')] -#[OA\Tag(name: 'Table', description: 'Универсальный CRUD по SchemaRegistry: GET/POST /table/{name}/, GET/PUT/DELETE /table/{name}/{id}')] -#[OA\Tag(name: 'Post', description: 'Новости')] -#[OA\Tag(name: 'User', description: 'Пользователи и группы')] -#[OA\Tag(name: 'Plugin', description: 'Плагины')] -#[OA\Tag(name: 'Upload', description: 'Загрузка файлов')] -#[OA\Tag(name: 'Xfield', description: 'Каталог доп. полей (xfields.json / userxfields.json)')] -#[OA\Tag(name: 'System', description: 'Служебные')] -final class Document { - - #[OA\Post( - path: '/oauth/token', - operationId: 'oauthToken', - summary: 'Выдача AuthToken (credential_type или grant_type)', - description: 'Предпочтительно credential_type=api_key|auth|oauth_client. Альтернатива: grant_type=client_credentials|password|authorization_code|refresh_token. В DEMO_MODE при успехе — authorized без access_token.', - security: [], - tags: ['OAuth'], - )] - #[OA\RequestBody( - required: true, - description: 'Параметры credential_type или OAuth2 grant', - content: new OA\JsonContent( - properties: [ - new OA\Property( - property: 'credential_type', - type: 'string', - enum: ['api_key', 'auth', 'oauth_client'], - description: 'Предпочтительный способ выдачи AuthToken', - ), - new OA\Property( - property: 'grant_type', - type: 'string', - enum: ['client_credentials', 'authorization_code', 'refresh_token', 'password'], - ), - new OA\Property(property: 'api_key', type: 'string', description: 'credential_type=api_key'), - new OA\Property(property: 'client_id', type: 'string'), - new OA\Property(property: 'client_secret', type: 'string'), - new OA\Property(property: 'scope', type: 'string'), - new OA\Property(property: 'code', type: 'string'), - new OA\Property(property: 'redirect_uri', type: 'string'), - new OA\Property(property: 'code_verifier', type: 'string'), - new OA\Property(property: 'refresh_token', type: 'string'), - new OA\Property(property: 'username', type: 'string', description: 'Логин или email (auth / password)'), - new OA\Property(property: 'password', type: 'string'), - ], - example: [ - 'credential_type' => 'api_key', - 'api_key' => 'your_api_key', - ], - ), - )] - #[OA\Response( - response: 200, - description: 'Токен выдан или DEMO_MODE authorized', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'access_token', type: 'string', nullable: true), - new OA\Property(property: 'token_type', type: 'string', example: 'Bearer'), - new OA\Property(property: 'expires_in', type: 'integer'), - new OA\Property(property: 'refresh_token', type: 'string'), - new OA\Property(property: 'demo_mode', type: 'boolean'), - new OA\Property(property: 'authorized', type: 'boolean'), - new OA\Property(property: 'message', type: 'string'), - ], - example: [ - 'access_token' => '…', - 'token_type' => 'Bearer', - 'expires_in' => 3600, - 'refresh_token' => '…', - ], - ), - )] - #[OA\Response( - response: 400, - description: 'Ошибка grant / credential', - content: new OA\JsonContent(ref: ApiError::class), - )] - public function oauthToken(): void {} - - #[OA\Get( - path: '/.well-known/oauth-authorization-server', - operationId: 'oauthDiscovery', - summary: 'OAuth AS discovery (без Bearer)', - security: [], - tags: ['OAuth'], - )] - #[OA\Response( - response: 200, - description: 'Метаданные AS', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'issuer', type: 'string'), - new OA\Property(property: 'authorization_endpoint', type: 'string'), - new OA\Property(property: 'token_endpoint', type: 'string'), - new OA\Property(property: 'revocation_endpoint', type: 'string'), - new OA\Property(property: 'userinfo_endpoint', type: 'string'), - new OA\Property(property: 'response_types_supported', type: 'array', items: new OA\Items(type: 'string')), - new OA\Property(property: 'grant_types_supported', type: 'array', items: new OA\Items(type: 'string')), - new OA\Property(property: 'code_challenge_methods_supported', type: 'array', items: new OA\Items(type: 'string')), - new OA\Property(property: 'token_endpoint_auth_methods_supported', type: 'array', items: new OA\Items(type: 'string')), - new OA\Property(property: 'credential_types_supported', type: 'array', items: new OA\Items(type: 'string')), - ], - ), - )] - public function oauthDiscovery(): void {} - - #[OA\Get( - path: '/me', - operationId: 'me', - summary: 'Субъект AuthToken (identity без CRUD-масок ПДн)', - security: [['bearerAuth' => []]], - tags: ['Me'], - )] - #[OA\Response( - response: 200, - description: 'Identity', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'sub', type: 'string', nullable: true), - new OA\Property(property: 'user_id', type: 'integer'), - new OA\Property(property: 'name', type: 'string', nullable: true), - new OA\Property(property: 'email', type: 'string', nullable: true), - new OA\Property(property: 'user_group', type: 'integer', nullable: true), - new OA\Property(property: 'user', type: 'object', nullable: true, additionalProperties: true), - new OA\Property(property: 'api_key_id', type: 'integer'), - new OA\Property(property: 'access_level', type: 'object', nullable: true, additionalProperties: true), - new OA\Property(property: 'client_id', type: 'string', nullable: true), - new OA\Property(property: 'auth_via', type: 'string', example: 'access_token'), - ], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - public function me(): void {} - - #[OA\Get( - path: '/key/check', - operationId: 'keyCheck', - summary: 'Проверка сырого API-ключа', - description: 'Принимает Authorization: Bearer , возвращает ключ, scopes и payload `me`. `validTo = null` означает бессрочный ключ.', - security: [['rawApiKeyBearer' => []]], - tags: ['Me'], - )] - #[OA\Response( - response: 200, - description: 'Ключ валиден', - content: new OA\JsonContent( - properties: [ - new OA\Property( - property: 'apiKey', - type: 'object', - properties: [ - new OA\Property(property: 'key', type: 'string'), - new OA\Property(property: 'validFrom', type: 'string', format: 'date-time', nullable: true), - new OA\Property(property: 'validTo', type: 'string', format: 'date-time', nullable: true, description: 'null = ключ бессрочный'), - new OA\Property(property: 'accessLevel', type: 'object', nullable: true, additionalProperties: true), - ], - ), - new OA\Property( - property: 'scopes', - type: 'object', - additionalProperties: new OA\AdditionalProperties( - type: 'object', - properties: [ - new OA\Property(property: 'read', type: 'boolean'), - new OA\Property(property: 'write', type: 'boolean'), - new OA\Property(property: 'edit', type: 'boolean'), - new OA\Property(property: 'delete', type: 'boolean'), - ], - ), - ), - new OA\Property(property: 'me', type: 'object', additionalProperties: true), - ], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - public function keyCheck(): void {} - - #[OA\Get( - path: '/oauth/userinfo', - operationId: 'oauthUserinfo', - summary: 'OIDC-совместимый userinfo (тот же payload, что /me)', - security: [['bearerAuth' => []]], - tags: ['OAuth'], - )] - #[OA\Response( - response: 200, - description: 'Identity', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'sub', type: 'string', nullable: true), - new OA\Property(property: 'user_id', type: 'integer'), - new OA\Property(property: 'name', type: 'string', nullable: true), - new OA\Property(property: 'email', type: 'string', nullable: true), - new OA\Property(property: 'user_group', type: 'integer', nullable: true), - new OA\Property(property: 'user', type: 'object', nullable: true, additionalProperties: true), - new OA\Property(property: 'api_key_id', type: 'integer'), - new OA\Property(property: 'access_level', type: 'object', nullable: true, additionalProperties: true), - new OA\Property(property: 'client_id', type: 'string', nullable: true), - new OA\Property(property: 'auth_via', type: 'string'), - ], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - public function oauthUserinfo(): void {} - - #[OA\Post( - path: '/oauth/revoke', - operationId: 'oauthRevoke', - summary: 'Отзыв токена', - security: [], - tags: ['OAuth'], - )] - #[OA\RequestBody( - required: true, - content: new OA\JsonContent( - required: ['token'], - properties: [ - new OA\Property(property: 'token', type: 'string', description: 'Access или refresh token'), - ], - ), - )] - #[OA\Response( - response: 200, - description: 'Отозван', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'revoked', type: 'boolean', example: true), - ], - example: ['revoked' => true], - ), - )] - public function oauthRevoke(): void {} - - #[OA\Get( - path: '/post/', - operationId: 'listPosts', - summary: 'Список новостей (фильтры как у /table/post/ + legacy headers)', - description: 'Query-параметры колонок схемы; xf[name]=value для доп. полей; ! и % префиксы значений. Legacy: HTTP-заголовки с именами колонок (BC). category — virtual FK csv + post_extras_cats.', - security: [['bearerAuth' => []]], - tags: ['Post'], - )] - #[OA\QueryParameter(name: 'limit', schema: new OA\Schema(type: 'integer', default: 20))] - #[OA\QueryParameter(name: 'offset', schema: new OA\Schema(type: 'integer', default: 0))] - #[OA\QueryParameter(name: 'orderby', description: 'Колонка сортировки', schema: new OA\Schema(type: 'string'))] - #[OA\QueryParameter(name: 'sort', schema: new OA\Schema(type: 'string', enum: ['ASC', 'DESC'], default: 'DESC'))] - #[OA\QueryParameter(name: 'category', description: 'Virtual FK csv → category.id (FIND_IN_SET + post_extras_cats). !negate, %LIKE', schema: new OA\Schema(type: 'string'))] - #[OA\QueryParameter(name: 'approve', schema: new OA\Schema(type: 'string'))] - #[OA\QueryParameter( - name: 'xf', - description: 'Доп. поля: xf[field]=value (pad-LIKE по xfields). Пример: xf[title]=foo', - style: 'form', - explode: true, - schema: new OA\Schema(type: 'object', additionalProperties: new OA\AdditionalProperties(type: 'string')), - )] - #[OA\Response( - response: 200, - description: 'OK', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'data', type: 'array', items: new OA\Items(ref: PostSchema::class)), - new OA\Property(property: 'count', type: 'integer'), - ], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - public function listPosts(): void {} - - #[OA\Get( - path: '/post/{id}', - operationId: 'getPost', - summary: 'Новость по id', - security: [['bearerAuth' => []]], - tags: ['Post'], - )] - #[OA\PathParameter(name: 'id', required: true, schema: new OA\Schema(type: 'integer'))] - #[OA\Response( - response: 200, - description: 'OK', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'data', ref: PostSchema::class), - ], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 404, description: 'Не найдено', content: new OA\JsonContent(ref: ApiError::class))] - public function getPost(): void {} - - #[OA\Get( - path: '/table/{name}', - operationId: 'listTableRows', - summary: 'Список записей таблицы с фильтрами', - description: 'Любая таблица SchemaRegistry. Фильтры = query-параметры колонок. Virtual FK (RelationMap): csv→FIND_IN_SET, one→=. Операторы: !negate, %LIKE. Пример: /table/banners/?category=1&approve=1. xf[name] если есть колонка xfields.', - security: [['bearerAuth' => []]], - tags: ['Table'], - )] - #[OA\PathParameter( - name: 'name', - required: true, - description: 'Логическое имя таблицы SchemaRegistry (banners, post, category, …)', - schema: new OA\Schema(type: 'string', description: 'Логическое имя таблицы SchemaRegistry'), - )] - #[OA\QueryParameter(name: 'limit', schema: new OA\Schema(type: 'integer', default: 20))] - #[OA\QueryParameter(name: 'offset', schema: new OA\Schema(type: 'integer', default: 0))] - #[OA\QueryParameter(name: 'orderby', description: 'Колонка сортировки (из схемы)', schema: new OA\Schema(type: 'string'))] - #[OA\QueryParameter(name: 'sort', schema: new OA\Schema(type: 'string', enum: ['ASC', 'DESC'], default: 'DESC'))] - #[OA\QueryParameter( - name: 'xf', - description: 'Доп. поля (если у таблицы есть xfields): xf[field]=value. Пример: xf[title]=foo', - style: 'form', - explode: true, - schema: new OA\Schema(type: 'object', additionalProperties: new OA\AdditionalProperties(type: 'string')), - )] - #[OA\Response( - response: 200, - description: 'OK', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'data', type: 'array', items: new OA\Items(ref: TableRowUnion::class)), - new OA\Property(property: 'count', type: 'integer'), - new OA\Property(property: 'table', type: 'string'), - ], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 404, description: 'Неизвестная таблица', content: new OA\JsonContent(ref: ApiError::class))] - #[OA\Response(response: 422, description: 'Неизвестная колонка / ошибка фильтра', content: new OA\JsonContent(ref: ApiError::class))] - public function listTableRows(): void {} - - #[OA\Get( - path: '/table/{name}/{id}', - operationId: 'getTableRow', - summary: 'Запись по скалярному PK', - security: [['bearerAuth' => []]], - tags: ['Table'], - )] - #[OA\PathParameter( - name: 'name', - required: true, - schema: new OA\Schema(type: 'string', description: 'Логическое имя таблицы SchemaRegistry'), - )] - #[OA\PathParameter(name: 'id', required: true, description: 'Значение первичного ключа', schema: new OA\Schema(type: 'string'))] - #[OA\Response( - response: 200, - description: 'OK', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'data', ref: TableRowUnion::class), - new OA\Property(property: 'table', type: 'string'), - ], - ), - )] - #[OA\Response(response: 400, description: 'Составной PK не поддерживается через /{id}', content: new OA\JsonContent(ref: ApiError::class))] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 404, description: 'Не найдено', content: new OA\JsonContent(ref: ApiError::class))] - public function getTableRow(): void {} - - #[OA\Post( - path: '/table/{name}', - operationId: 'createTableRow', - summary: 'Создание записи (Fluent prepare)', - security: [['bearerAuth' => []]], - tags: ['Table'], - )] - #[OA\PathParameter( - name: 'name', - required: true, - description: 'Логическое имя таблицы SchemaRegistry', - schema: new OA\Schema(type: 'string', description: 'Логическое имя таблицы SchemaRegistry'), - )] - #[OA\RequestBody( - required: true, - description: 'Колонки выбранной таблицы (+ optional nested children). Схема = oneOf TableRow.', - content: [new OA\MediaType( - mediaType: 'application/json', - schema: new OA\Schema(ref: TableRowUnion::class), - )], - )] - #[OA\Response( - response: 201, - description: 'Создано', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'id', type: 'integer'), - new OA\Property(property: 'table', type: 'string'), - ], - example: ['id' => 1, 'table' => 'banners'], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 422, description: 'Ошибка создания', content: new OA\JsonContent(ref: ApiError::class))] - public function createTableRow(): void {} - - #[OA\Put( - path: '/table/{name}/{id}', - operationId: 'updateTableRow', - summary: 'Обновление записи по скалярному PK', - security: [['bearerAuth' => []]], - tags: ['Table'], - )] - #[OA\PathParameter( - name: 'name', - required: true, - schema: new OA\Schema(type: 'string', description: 'Логическое имя таблицы SchemaRegistry'), - )] - #[OA\PathParameter(name: 'id', required: true, schema: new OA\Schema(type: 'string'))] - #[OA\RequestBody( - required: true, - content: [new OA\MediaType( - mediaType: 'application/json', - schema: new OA\Schema(ref: TableRowUnion::class), - )], - )] - #[OA\Response( - response: 200, - description: 'Обновлено', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'id', type: 'string'), - new OA\Property(property: 'table', type: 'string'), - new OA\Property(property: 'updated', type: 'boolean', example: true), - ], - example: ['id' => '1', 'table' => 'banners', 'updated' => true], - ), - )] - #[OA\Response(response: 400, description: 'Составной PK не поддерживается', content: new OA\JsonContent(ref: ApiError::class))] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 404, description: 'Не найдено', content: new OA\JsonContent(ref: ApiError::class))] - #[OA\Response(response: 422, description: 'Ошибка обновления', content: new OA\JsonContent(ref: ApiError::class))] - public function updateTableRow(): void {} - - #[OA\Delete( - path: '/table/{name}/{id}', - operationId: 'deleteTableRow', - summary: 'Удаление записи по скалярному PK', - security: [['bearerAuth' => []]], - tags: ['Table'], - )] - #[OA\PathParameter( - name: 'name', - required: true, - schema: new OA\Schema(type: 'string', description: 'Логическое имя таблицы SchemaRegistry'), - )] - #[OA\PathParameter(name: 'id', required: true, schema: new OA\Schema(type: 'string'))] - #[OA\Response( - response: 200, - description: 'Удалено', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'id', type: 'string'), - new OA\Property(property: 'table', type: 'string'), - new OA\Property(property: 'deleted', type: 'boolean', example: true), - ], - example: ['id' => '1', 'table' => 'banners', 'deleted' => true], - ), - )] - #[OA\Response(response: 400, description: 'Составной PK не поддерживается', content: new OA\JsonContent(ref: ApiError::class))] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 404, description: 'Не найдено', content: new OA\JsonContent(ref: ApiError::class))] - public function deleteTableRow(): void {} - - #[OA\Post( - path: '/post/', - operationId: 'createPost', - summary: 'Создание новости (sugar → prepare post)', - security: [['bearerAuth' => []]], - tags: ['Post'], - )] - #[OA\RequestBody( - description: 'Новость + optional nested children', - required: true, - content: [new OA\MediaType( - mediaType: 'application/json', - schema: new OA\Schema(ref: PostSchema::class), - )], - )] - #[OA\Response( - response: 201, - description: 'Создано', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'id', type: 'integer'), - ], - example: ['id' => 1], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 422, description: 'Ошибка создания', content: new OA\JsonContent(ref: ApiError::class))] - public function createPost(): void {} - - #[OA\Post( - path: '/user/', - operationId: 'createUser', - summary: 'Создание пользователя', - security: [['bearerAuth' => []]], - tags: ['User'], - )] - #[OA\RequestBody( - required: true, - content: new OA\JsonContent(ref: UsersSchema::class), - )] - #[OA\Response( - response: 201, - description: 'Создано', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'id', type: 'integer'), - ], - example: ['id' => 1], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 422, description: 'Ошибка создания', content: new OA\JsonContent(ref: ApiError::class))] - public function createUser(): void {} - - #[OA\Post( - path: '/usergroup/', - operationId: 'createUsergroup', - summary: 'Создание группы пользователей', - security: [['bearerAuth' => []]], - tags: ['User'], - )] - #[OA\RequestBody( - required: true, - content: new OA\JsonContent(ref: UsergroupsSchema::class), - )] - #[OA\Response( - response: 201, - description: 'Создано', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'id', type: 'integer'), - ], - example: ['id' => 1], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 422, description: 'Ошибка создания', content: new OA\JsonContent(ref: ApiError::class))] - public function createUsergroup(): void {} - - #[OA\Post( - path: '/plugin/', - operationId: 'createPlugin', - summary: 'Регистрация плагина', - security: [['bearerAuth' => []]], - tags: ['Plugin'], - )] - #[OA\RequestBody( - required: true, - content: new OA\JsonContent(ref: PluginsSchema::class), - )] - #[OA\Response( - response: 201, - description: 'Создано', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'id', type: 'integer'), - ], - example: ['id' => 1], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 422, description: 'Ошибка создания', content: new OA\JsonContent(ref: ApiError::class))] - public function createPlugin(): void {} - - #[OA\Post( - path: '/upload/', - operationId: 'uploadFile', - summary: 'Загрузка файла (multipart)', - security: [['bearerAuth' => []]], - tags: ['Upload'], - )] - #[OA\RequestBody( - required: true, - content: [new OA\MediaType( - mediaType: 'multipart/form-data', - schema: new OA\Schema( - required: ['file'], - properties: [ - new OA\Property(property: 'file', type: 'string', format: 'binary'), - new OA\Property(property: 'subdir', type: 'string', example: 'files'), - ], - ), - )], - )] - #[OA\Response( - response: 201, - description: 'Загружено', - content: new OA\JsonContent( - type: 'object', - additionalProperties: true, - example: ['url' => '/uploads/files/…', 'name' => 'file.jpg'], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 422, description: 'Ошибка загрузки', content: new OA\JsonContent(ref: ApiError::class))] - public function uploadFile(): void {} - - #[OA\Get( - path: '/conversations/', - operationId: 'listConversations', - summary: 'Список переписок', - security: [['bearerAuth' => []]], - tags: ['System'], - )] - #[OA\Response( - response: 200, - description: 'OK', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'data', type: 'array', items: new OA\Items(ref: ConversationsSchema::class)), - ], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - public function listConversations(): void {} - - #[OA\Get( - path: '/xfields/{scope}/', - operationId: 'listXfields', - summary: 'Каталог доп. полей', - security: [['bearerAuth' => []]], - tags: ['Xfield'], - )] - #[OA\PathParameter(name: 'scope', required: true, schema: new OA\Schema(type: 'string', enum: ['post', 'user']))] - #[OA\Response( - response: 200, - description: 'OK (post → PostXfieldsCatalog, user → UserXfieldsCatalog)', - content: new OA\JsonContent( - properties: [ - new OA\Property( - property: 'data', - oneOf: [ - new OA\Schema(ref: PostXfieldsCatalog::class), - new OA\Schema(ref: UserXfieldsCatalog::class), - ], - ), - new OA\Property(property: 'scope', type: 'string', enum: ['post', 'user']), - ], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - public function listXfields(): void {} - - #[OA\Post( - path: '/xfields/{scope}/encode', - operationId: 'encodeXfields', - summary: 'Сериализация значений в формат post.xfields / users.xfields (аналог forPost)', - description: 'Body: {fields:{name:value}} или {name,value}. Ответ: raw + parsed.', - security: [['bearerAuth' => []]], - tags: ['Xfield'], - )] - #[OA\PathParameter(name: 'scope', required: true, schema: new OA\Schema(type: 'string', enum: ['post', 'user']))] - #[OA\RequestBody(required: true, content: new OA\JsonContent(type: 'object', additionalProperties: true))] - #[OA\Response( - response: 200, - description: 'OK', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'raw', type: 'string'), - new OA\Property(property: 'parsed', type: 'object', additionalProperties: true), - ], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 422, description: 'Неизвестное поле / validation', content: new OA\JsonContent(ref: ApiError::class))] - public function encodeXfields(): void {} - - #[OA\Get( - path: '/xfields/{scope}/{name}', - operationId: 'getXfield', - summary: 'Определение одного поля', - security: [['bearerAuth' => []]], - tags: ['Xfield'], - )] - #[OA\PathParameter(name: 'scope', required: true, schema: new OA\Schema(type: 'string', enum: ['post', 'user']))] - #[OA\PathParameter(name: 'name', required: true, schema: new OA\Schema(type: 'string'))] - #[OA\QueryParameter(name: 'as', description: 'Projection по типу (image, text, …)', schema: new OA\Schema(type: 'string'))] - #[OA\Response( - response: 200, - description: 'OK', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'data', ref: PostXfieldField::class), - new OA\Property(property: 'scope', type: 'string'), - ], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 404, description: 'Не найдено', content: new OA\JsonContent(ref: ApiError::class))] - #[OA\Response(response: 422, description: 'Тип не совпадает с ?as=', content: new OA\JsonContent(ref: ApiError::class))] - public function getXfield(): void {} - - #[OA\Post( - path: '/xfields/{scope}/', - operationId: 'createXfield', - summary: 'Создать определение поля (typed validation)', - security: [['bearerAuth' => []]], - tags: ['Xfield'], - )] - #[OA\PathParameter(name: 'scope', required: true, schema: new OA\Schema(type: 'string', enum: ['post', 'user']))] - #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: PostXfieldField::class))] - #[OA\Response( - response: 201, - description: 'Создано', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'name', type: 'string'), - new OA\Property(property: 'scope', type: 'string'), - new OA\Property(property: 'data', ref: PostXfieldField::class), - ], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 422, description: 'validation + details.fields', content: new OA\JsonContent(ref: ApiError::class))] - public function createXfield(): void {} - - #[OA\Put( - path: '/xfields/{scope}/{name}', - operationId: 'replaceXfield', - summary: 'Заменить определение поля', - security: [['bearerAuth' => []]], - tags: ['Xfield'], - )] - #[OA\PathParameter(name: 'scope', required: true, schema: new OA\Schema(type: 'string', enum: ['post', 'user']))] - #[OA\PathParameter(name: 'name', required: true, schema: new OA\Schema(type: 'string'))] - #[OA\RequestBody(required: true, content: new OA\JsonContent(ref: PostXfieldField::class))] - #[OA\Response( - response: 200, - description: 'Обновлено', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'name', type: 'string'), - new OA\Property(property: 'updated', type: 'boolean', example: true), - new OA\Property(property: 'data', ref: PostXfieldField::class), - ], - example: ['name' => 'myfield', 'updated' => true], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 422, description: 'validation + details.fields', content: new OA\JsonContent(ref: ApiError::class))] - public function replaceXfield(): void {} - - #[OA\Delete( - path: '/xfields/{scope}/{name}', - operationId: 'deleteXfield', - summary: 'Удалить определение поля', - security: [['bearerAuth' => []]], - tags: ['Xfield'], - )] - #[OA\PathParameter(name: 'scope', required: true, schema: new OA\Schema(type: 'string', enum: ['post', 'user']))] - #[OA\PathParameter(name: 'name', required: true, schema: new OA\Schema(type: 'string'))] - #[OA\Response( - response: 200, - description: 'Удалено', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'name', type: 'string', example: 'myfield'), - new OA\Property(property: 'deleted', type: 'boolean', example: true), - ], - example: ['name' => 'myfield', 'deleted' => true], - ), - )] - #[OA\Response(response: 401, ref: UnauthorizedResponse::class)] - #[OA\Response(response: 404, description: 'Поле не найдено', content: new OA\JsonContent(ref: ApiError::class))] - #[OA\Response(response: 422, description: 'Ошибка удаления', content: new OA\JsonContent(ref: ApiError::class))] - public function deleteXfield(): void {} - - #[OA\Get( - path: '/health', - operationId: 'health', - summary: 'Проверка API (без Bearer)', - security: [], - tags: ['System'], - )] - #[OA\Response( - response: 200, - description: 'OK', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'version', type: 'string', example: '200.1.0'), - new OA\Property(property: 'api', type: 'string', example: 'v2'), - new OA\Property(property: 'auth', type: 'string', example: 'Bearer'), - ], - example: ['version' => '200.1.0', 'api' => 'v2', 'auth' => 'Bearer'], - ), - )] - public function health(): void {} -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/AdminLogsSchema.php b/upload/api/src/Schema/AdminLogsSchema.php index badf1d0c..f7fd3cbd 100644 --- a/upload/api/src/Schema/AdminLogsSchema.php +++ b/upload/api/src/Schema/AdminLogsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'date' => 0, - 'ip' => '', - 'action' => 0, - 'extras' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/AdminSectionsSchema.php b/upload/api/src/Schema/AdminSectionsSchema.php index 4425f0d2..593ed05b 100644 --- a/upload/api/src/Schema/AdminSectionsSchema.php +++ b/upload/api/src/Schema/AdminSectionsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'title' => '', - 'descr' => '', - 'icon' => '', - 'allow_groups' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/BannedSchema.php b/upload/api/src/Schema/BannedSchema.php index b489528b..5ab41d05 100644 --- a/upload/api/src/Schema/BannedSchema.php +++ b/upload/api/src/Schema/BannedSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'descr' => '', - 'date' => '', - 'days' => 0, - 'ip' => '', - 'banned_from' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/BannersLogsSchema.php b/upload/api/src/Schema/BannersLogsSchema.php index 3fd0182a..11341ab8 100644 --- a/upload/api/src/Schema/BannersLogsSchema.php +++ b/upload/api/src/Schema/BannersLogsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'click' => 0, - 'ip' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/BannersRubricsSchema.php b/upload/api/src/Schema/BannersRubricsSchema.php index 8bf38126..11954dc5 100644 --- a/upload/api/src/Schema/BannersRubricsSchema.php +++ b/upload/api/src/Schema/BannersRubricsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'title' => '', - 'description' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/BannersSchema.php b/upload/api/src/Schema/BannersSchema.php index d2dcecb6..09e319c1 100644 --- a/upload/api/src/Schema/BannersSchema.php +++ b/upload/api/src/Schema/BannersSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 'category.id', 'dle-kind' => 'csv'], - )] - public string $category = ''; - #[OA\Property( - property: 'grouplevel', - type: 'string', - description: 'CSV групп или all (virtual FK csv_or_all → usergroups.id)', - x: ['dle-ref' => 'usergroups.id', 'dle-kind' => 'csv_or_all'], - )] - public string $grouplevel = 'all'; - #[OA\Property( - property: 'rubric', - type: 'integer', - description: 'Virtual FK one → banners_rubrics.id', - x: ['dle-ref' => 'banners_rubrics.id', 'dle-kind' => 'one'], - )] - public int $rubric = 0; - #[OA\Property( - property: 'start', - type: 'string', - description: 'Колонка banners.start', - )] - public string $start = ''; - #[OA\Property( - property: 'end', - type: 'string', - description: 'Колонка banners.end', - )] - public string $end = ''; - #[OA\Property( - property: 'fpage', - type: 'integer', - description: 'Колонка banners.fpage', - )] - public int $fpage = 0; - #[OA\Property( - property: 'innews', - type: 'integer', - description: 'Колонка banners.innews', - )] - public int $innews = 0; - #[OA\Property( - property: 'devicelevel', - type: 'string', - description: 'Колонка banners.devicelevel', - )] - public string $devicelevel = ''; - #[OA\Property( - property: 'allow_views', - type: 'integer', - description: 'Колонка banners.allow_views', - )] - public int $allow_views = 0; - #[OA\Property( - property: 'max_views', - type: 'integer', - description: 'Колонка banners.max_views', - )] - public int $max_views = 0; - #[OA\Property( - property: 'allow_counts', - type: 'integer', - description: 'Колонка banners.allow_counts', - )] - public int $allow_counts = 0; - #[OA\Property( - property: 'max_counts', - type: 'integer', - description: 'Колонка banners.max_counts', - )] - public int $max_counts = 0; - #[OA\Property( - property: 'views', - type: 'integer', - description: 'Колонка banners.views', - )] - public int $views = 0; - #[OA\Property( - property: 'clicks', - type: 'integer', - description: 'Колонка banners.clicks', - )] - public int $clicks = 0; - #[OA\Property( - property: 'comments_place', - type: 'integer', - description: 'Колонка banners.comments_place', - )] - public int $comments_place = 0; - #[OA\Property( - property: 'allowed_country', - type: 'string', - description: 'Колонка banners.allowed_country', - )] - public string $allowed_country = ''; - #[OA\Property( - property: 'not_allowed_country', - type: 'string', - description: 'Колонка banners.not_allowed_country', - )] - public string $not_allowed_country = ''; - - public function table(): string { - return 'banners'; - } - - protected function columnList(): array { - return [ - 'id', - 'banner_tag', - 'descr', - 'code', - 'approve', - 'short_place', - 'bstick', - 'main', - 'category', - 'grouplevel', - 'start', - 'end', - 'fpage', - 'innews', - 'devicelevel', - 'allow_views', - 'max_views', - 'allow_counts', - 'max_counts', - 'views', - 'clicks', - 'rubric', - 'comments_place', - 'allowed_country', - 'not_allowed_country', - ]; - } - - protected function defaultMap(): array { - return [ - 'banner_tag' => '', - 'descr' => '', - 'code' => '', - 'approve' => 0, - 'short_place' => 0, - 'bstick' => 0, - 'main' => 0, - 'category' => '', - 'grouplevel' => 'all', - 'start' => '', - 'end' => '', - 'fpage' => 0, - 'innews' => 0, - 'devicelevel' => '', - 'allow_views' => 0, - 'max_views' => 0, - 'allow_counts' => 0, - 'max_counts' => 0, - 'views' => 0, - 'clicks' => 0, - 'rubric' => 0, - 'comments_place' => 0, - 'allowed_country' => '', - 'not_allowed_country' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/CategorySchema.php b/upload/api/src/Schema/CategorySchema.php index f43efea9..c6bfbeb4 100644 --- a/upload/api/src/Schema/CategorySchema.php +++ b/upload/api/src/Schema/CategorySchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'posi' => 1, - 'name' => '', - 'alt_name' => '', - 'icon' => '', - 'skin' => '', - 'descr' => '', - 'keywords' => '', - 'news_sort' => '', - 'news_msort' => '', - 'news_number' => 0, - 'short_tpl' => '', - 'full_tpl' => '', - 'metatitle' => '', - 'show_sub' => 0, - 'allow_rss' => 1, - 'fulldescr' => '', - 'disable_search' => 0, - 'disable_main' => 0, - 'disable_rating' => 0, - 'disable_comments' => 0, - 'enable_dzen' => 1, - 'active' => 1, - 'rating_type' => -1, - 'schema_org' => 1, - 'disable_index' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/CommentRatingLogSchema.php b/upload/api/src/Schema/CommentRatingLogSchema.php index f4554bac..f64918f8 100644 --- a/upload/api/src/Schema/CommentRatingLogSchema.php +++ b/upload/api/src/Schema/CommentRatingLogSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'member' => '', - 'ip' => '', - 'rating' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/CommentsFilesSchema.php b/upload/api/src/Schema/CommentsFilesSchema.php index 7681bbfd..ce0ac4a7 100644 --- a/upload/api/src/Schema/CommentsFilesSchema.php +++ b/upload/api/src/Schema/CommentsFilesSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'author' => '', - 'date' => '', - 'name' => '', - 'driver' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/CommentsSchema.php b/upload/api/src/Schema/CommentsSchema.php index c3aec28f..cf6895b4 100644 --- a/upload/api/src/Schema/CommentsSchema.php +++ b/upload/api/src/Schema/CommentsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md attachChildEntity('comment_rating_log', $entity); } } -||||||| -======= - 0, - 'user_id' => 0, - 'date' => '2000-01-01 00:00:00', - 'autor' => '', - 'email' => '', - 'text' => '', - 'ip' => '', - 'is_register' => 0, - 'approve' => 1, - 'rating' => 0, - 'vote_num' => 0, - 'parent' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } - - public function withPostId(int $postId): static { - return $this->with('post_id', $postId); - } - - public function withUserId(int $userId): static { - return $this->with('user_id', $userId); - } - - public function withAutor(string $autor): static { - return $this->with('autor', $autor); - } - - public function withText(string $text): static { - return $this->with('text', $text); - } - - public function withParent(int $parentId): static { - return $this->with('parent', $parentId); - } - - public function withFilesEntity(CommentsFilesSchema $entity): static { - return $this->attachChildEntity('comments_files', $entity); - } - - public function withRatingEntity(CommentRatingLogSchema $entity): static { - return $this->attachChildEntity('comment_rating_log', $entity); - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/ComplaintSchema.php b/upload/api/src/Schema/ComplaintSchema.php index b49f6d56..dec618fe 100644 --- a/upload/api/src/Schema/ComplaintSchema.php +++ b/upload/api/src/Schema/ComplaintSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'c_id' => 0, - 'n_id' => 0, - 'text' => '', - 'from' => '', - 'to' => '', - 'date' => 0, - 'email' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/ConversationReadsSchema.php b/upload/api/src/Schema/ConversationReadsSchema.php index 3b5e21dd..42b2a2fc 100644 --- a/upload/api/src/Schema/ConversationReadsSchema.php +++ b/upload/api/src/Schema/ConversationReadsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - ]; - } - - public function primaryKey(): string|array { - return ['user_id', 'conversation_id']; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/ConversationUsersSchema.php b/upload/api/src/Schema/ConversationUsersSchema.php index 1dcd531d..ad777a5c 100644 --- a/upload/api/src/Schema/ConversationUsersSchema.php +++ b/upload/api/src/Schema/ConversationUsersSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md >>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/ConversationsMessagesSchema.php b/upload/api/src/Schema/ConversationsMessagesSchema.php index a6d6fbde..d69780b1 100644 --- a/upload/api/src/Schema/ConversationsMessagesSchema.php +++ b/upload/api/src/Schema/ConversationsMessagesSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'sender_id' => 0, - 'content' => '', - 'created_at' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/ConversationsSchema.php b/upload/api/src/Schema/ConversationsSchema.php index 2ec4a5ec..6eb98dbc 100644 --- a/upload/api/src/Schema/ConversationsSchema.php +++ b/upload/api/src/Schema/ConversationsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md attachChildEntity('conversation_reads', $entity); } } -||||||| -======= - '', - 'created_at' => 0, - 'updated_at' => 0, - 'sender_id' => 0, - 'recipient_id' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } - - public function withSenderId(int $senderId): static { - return $this->with('sender_id', $senderId); - } - - public function withRecipientId(int $recipientId): static { - return $this->with('recipient_id', $recipientId); - } - - public function withMessageEntity(ConversationsMessagesSchema $entity): static { - return $this->attachChildEntity('conversations_messages', $entity); - } - - public function withUsersEntity(ConversationUsersSchema $entity): static { - return $this->attachChildEntity('conversation_users', $entity); - } - - public function withReadsEntity(ConversationReadsSchema $entity): static { - return $this->attachChildEntity('conversation_reads', $entity); - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/DownloadsLogSchema.php b/upload/api/src/Schema/DownloadsLogSchema.php index 3b530f9f..5c70ee32 100644 --- a/upload/api/src/Schema/DownloadsLogSchema.php +++ b/upload/api/src/Schema/DownloadsLogSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'ip' => '', - 'file_id' => 0, - 'date' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/EmailSchema.php b/upload/api/src/Schema/EmailSchema.php index 0ab51fb2..b3a88e11 100644 --- a/upload/api/src/Schema/EmailSchema.php +++ b/upload/api/src/Schema/EmailSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'template' => '', - 'use_html' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/FilesSchema.php b/upload/api/src/Schema/FilesSchema.php index 6dbec704..5d1e106e 100644 --- a/upload/api/src/Schema/FilesSchema.php +++ b/upload/api/src/Schema/FilesSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md with('driver', $driver); } } -||||||| -======= - 0, - 'name' => '', - 'onserver' => '', - 'author' => '', - 'date' => '', - 'dcount' => 0, - 'size' => 0, - 'checksum' => '', - 'driver' => 0, - 'is_public' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } - - public function withName(string $name): static { - return $this->with('name', $name); - } - - public function withOnserver(string $onserver): static { - return $this->with('onserver', $onserver); - } - - public function withNewsId(int $newsId): static { - return $this->with('news_id', $newsId); - } - - public function withAuthor(string $author): static { - return $this->with('author', $author); - } - - public function withDriver(int $driver): static { - return $this->with('driver', $driver); - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/FloodSchema.php b/upload/api/src/Schema/FloodSchema.php index 24244158..7b6c6fa0 100644 --- a/upload/api/src/Schema/FloodSchema.php +++ b/upload/api/src/Schema/FloodSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'id' => '', - 'flag' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'f_id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/IgnoreListSchema.php b/upload/api/src/Schema/IgnoreListSchema.php index c8a6d59a..073217ff 100644 --- a/upload/api/src/Schema/IgnoreListSchema.php +++ b/upload/api/src/Schema/IgnoreListSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'user_from' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/ImagesSchema.php b/upload/api/src/Schema/ImagesSchema.php index cc27ac83..f751a946 100644 --- a/upload/api/src/Schema/ImagesSchema.php +++ b/upload/api/src/Schema/ImagesSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md with('date', $date); } } -||||||| -======= - '', - 'news_id' => 0, - 'author' => '', - 'date' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } - - public function withImages(string $images): static { - return $this->with('images', $images); - } - - public function withNewsId(int $newsId): static { - return $this->with('news_id', $newsId); - } - - public function withAuthor(string $author): static { - return $this->with('author', $author); - } - - public function withDate(string $date): static { - return $this->with('date', $date); - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/LinksSchema.php b/upload/api/src/Schema/LinksSchema.php index 427d15e8..65b269a7 100644 --- a/upload/api/src/Schema/LinksSchema.php +++ b/upload/api/src/Schema/LinksSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'link' => '', - 'only_one' => 0, - 'replacearea' => 1, - 'rcount' => 0, - 'targetblank' => 0, - 'title' => '', - 'enabled' => 1, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/LoginLogSchema.php b/upload/api/src/Schema/LoginLogSchema.php index ee3b2cd1..89537f6a 100644 --- a/upload/api/src/Schema/LoginLogSchema.php +++ b/upload/api/src/Schema/LoginLogSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'count' => 0, - 'date' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/LogsSchema.php b/upload/api/src/Schema/LogsSchema.php index 7b93b499..fa0d447e 100644 --- a/upload/api/src/Schema/LogsSchema.php +++ b/upload/api/src/Schema/LogsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'member' => '', - 'ip' => '', - 'rating' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/LostdbSchema.php b/upload/api/src/Schema/LostdbSchema.php index 30631f5f..dd3d4a43 100644 --- a/upload/api/src/Schema/LostdbSchema.php +++ b/upload/api/src/Schema/LostdbSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'lostid' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/MailLogSchema.php b/upload/api/src/Schema/MailLogSchema.php index 107c8525..854d2ad5 100644 --- a/upload/api/src/Schema/MailLogSchema.php +++ b/upload/api/src/Schema/MailLogSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'mail' => '', - 'hash' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/MetatagsSchema.php b/upload/api/src/Schema/MetatagsSchema.php index 22b6bce9..c6893376 100644 --- a/upload/api/src/Schema/MetatagsSchema.php +++ b/upload/api/src/Schema/MetatagsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'title' => '', - 'description' => '', - 'keywords' => '', - 'page_title' => '', - 'page_description' => '', - 'robots' => '', - 'enabled' => 1, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/NewsletterTemplateCategoriesSchema.php b/upload/api/src/Schema/NewsletterTemplateCategoriesSchema.php index bb9b85aa..b8855041 100644 --- a/upload/api/src/Schema/NewsletterTemplateCategoriesSchema.php +++ b/upload/api/src/Schema/NewsletterTemplateCategoriesSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'locked' => 0, - 'sort_order' => 0, - 'created_at' => 0, - 'created_by' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/NewsletterTemplateItemsSchema.php b/upload/api/src/Schema/NewsletterTemplateItemsSchema.php index 0ac16124..06683179 100644 --- a/upload/api/src/Schema/NewsletterTemplateItemsSchema.php +++ b/upload/api/src/Schema/NewsletterTemplateItemsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md null, - 'title' => '', - 'content' => '', - 'locked' => 0, - 'sort_order' => 0, - 'created_at' => 0, - 'created_by' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/NoticeSchema.php b/upload/api/src/Schema/NoticeSchema.php index 368e2f6c..aa5a82d4 100644 --- a/upload/api/src/Schema/NoticeSchema.php +++ b/upload/api/src/Schema/NoticeSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'notice' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/PluginsFilesSchema.php b/upload/api/src/Schema/PluginsFilesSchema.php index c9159d5f..b94a1df2 100644 --- a/upload/api/src/Schema/PluginsFilesSchema.php +++ b/upload/api/src/Schema/PluginsFilesSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'file' => '', - 'action' => '', - 'searchcode' => '', - 'replacecode' => '', - 'active' => 0, - 'searchcount' => 0, - 'replacecount' => 0, - 'filedisable' => 1, - 'filedleversion' => '', - 'fileversioncompare' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/PluginsLogsSchema.php b/upload/api/src/Schema/PluginsLogsSchema.php index d4d77105..9a99b00e 100644 --- a/upload/api/src/Schema/PluginsLogsSchema.php +++ b/upload/api/src/Schema/PluginsLogsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'area' => '', - 'error' => '', - 'type' => '', - 'action_id' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/PluginsSchema.php b/upload/api/src/Schema/PluginsSchema.php index e66e291f..c5f71d34 100644 --- a/upload/api/src/Schema/PluginsSchema.php +++ b/upload/api/src/Schema/PluginsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md attachChildEntity('plugins_files', $entity); } } -||||||| -======= - '', - 'description' => '', - 'icon' => '', - 'version' => '', - 'dleversion' => '', - 'versioncompare' => '', - 'active' => 0, - 'mysqlinstall' => '', - 'mysqlupgrade' => '', - 'mysqlenable' => '', - 'mysqldisable' => '', - 'mysqldelete' => '', - 'filedelete' => 0, - 'filelist' => '', - 'upgradeurl' => '', - 'needplugin' => '', - 'phpinstall' => '', - 'phpupgrade' => '', - 'phpenable' => '', - 'phpdisable' => '', - 'phpdelete' => '', - 'notice' => '', - 'mnotice' => 0, - 'posi' => 1, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } - - public function withName(string $name): static { - return $this->with('name', $name); - } - - public function withDescription(string $description): static { - return $this->with('description', $description); - } - - public function withVersion(string $version): static { - return $this->with('version', $version); - } - - public function withFilesEntity(PluginsFilesSchema $entity): static { - return $this->attachChildEntity('plugins_files', $entity); - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/PollLogSchema.php b/upload/api/src/Schema/PollLogSchema.php index 7ba097d6..e49cdc97 100644 --- a/upload/api/src/Schema/PollLogSchema.php +++ b/upload/api/src/Schema/PollLogSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'member' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/PollSchema.php b/upload/api/src/Schema/PollSchema.php index 19b16c32..81d2e0e5 100644 --- a/upload/api/src/Schema/PollSchema.php +++ b/upload/api/src/Schema/PollSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'title' => '', - 'frage' => '', - 'body' => '', - 'votes' => 0, - 'multiple' => 0, - 'answer' => '', - 'closed' => 0, - 'date_closed' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/PostExtrasCatsSchema.php b/upload/api/src/Schema/PostExtrasCatsSchema.php index 6dde150f..5b60778f 100644 --- a/upload/api/src/Schema/PostExtrasCatsSchema.php +++ b/upload/api/src/Schema/PostExtrasCatsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'cat_id' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/PostExtrasSchema.php b/upload/api/src/Schema/PostExtrasSchema.php index 2e3943d0..994c427a 100644 --- a/upload/api/src/Schema/PostExtrasSchema.php +++ b/upload/api/src/Schema/PostExtrasSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'news_read' => 0, - 'allow_rate' => 1, - 'rating' => 0, - 'vote_num' => 0, - 'votes' => 0, - 'view_edit' => 0, - 'disable_index' => 0, - 'related_ids' => '', - 'access' => '', - 'editdate' => 0, - 'editor' => '', - 'reason' => '', - 'user_id' => 0, - 'disable_search' => 0, - 'need_pass' => 0, - 'allow_rss' => 1, - 'allow_rss_dzen' => 1, - 'edited_now' => '', - 'allowed_country' => '', - 'not_allowed_country' => '', - ]; - } - - public function primaryKey(): string|array { - return 'eid'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/PostLogSchema.php b/upload/api/src/Schema/PostLogSchema.php index 7292ad97..02978776 100644 --- a/upload/api/src/Schema/PostLogSchema.php +++ b/upload/api/src/Schema/PostLogSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'expires' => '', - 'action' => 0, - 'move_cat' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/PostPassSchema.php b/upload/api/src/Schema/PostPassSchema.php index 7d7bbb03..05669657 100644 --- a/upload/api/src/Schema/PostPassSchema.php +++ b/upload/api/src/Schema/PostPassSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'password' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/PostSchema.php b/upload/api/src/Schema/PostSchema.php index d380a365..b1fb2dac 100644 --- a/upload/api/src/Schema/PostSchema.php +++ b/upload/api/src/Schema/PostSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 'category.id', 'dle-kind' => 'csv'], - )] - public string $category = ''; - #[OA\Property( - property: 'alt_name', - type: 'string', - description: 'ЧПУ-имя (post.alt_name)', - )] - public string $alt_name = ''; - #[OA\Property( - property: 'comm_num', - type: 'integer', - description: 'Колонка post.comm_num', - )] - public int $comm_num = 0; - #[OA\Property( - property: 'allow_comm', - type: 'integer', - description: 'Колонка post.allow_comm', - )] - public int $allow_comm = 1; - #[OA\Property( - property: 'allow_main', - type: 'integer', - description: 'Колонка post.allow_main', - )] - public int $allow_main = 1; - #[OA\Property( - property: 'approve', - type: 'integer', - description: 'Одобрено (0/1) (post.approve)', - )] - public int $approve = 0; - #[OA\Property( - property: 'fixed', - type: 'integer', - description: 'Колонка post.fixed', - )] - public int $fixed = 0; - #[OA\Property( - property: 'allow_br', - type: 'integer', - description: 'Колонка post.allow_br', - )] - public int $allow_br = 1; - #[OA\Property( - property: 'symbol', - type: 'string', - description: 'Колонка post.symbol', - )] - public string $symbol = ''; - #[OA\Property( - property: 'tags', - type: 'string', - description: 'Колонка post.tags', - )] - public string $tags = ''; - #[OA\Property( - property: 'metatitle', - type: 'string', - description: 'Колонка post.metatitle', - )] - public string $metatitle = ''; - - public function table(): string { - return 'post'; - } - - protected function columnList(): array { - return [ - 'id', - 'autor', - 'date', - 'short_story', - 'full_story', - 'xfields', - 'title', - 'descr', - 'keywords', - 'category', - 'alt_name', - 'comm_num', - 'allow_comm', - 'allow_main', - 'approve', - 'fixed', - 'allow_br', - 'symbol', - 'tags', - 'metatitle', - ]; - } - - protected function defaultMap(): array { - return [ - 'autor' => '', - 'date' => '2000-01-01 00:00:00', - 'short_story' => '', - 'full_story' => '', - 'xfields' => '', - 'title' => '', - 'descr' => '', - 'keywords' => '', - 'category' => '', - 'alt_name' => '', - 'comm_num' => 0, - 'allow_comm' => 1, - 'allow_main' => 1, - 'approve' => 0, - 'fixed' => 0, - 'allow_br' => 1, - 'symbol' => '', - 'tags' => '', - 'metatitle' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } - - /** @var array */ - private array $xfieldMap = []; - - public function withTitle(string $title): static { - return $this->with('title', $title); - } - - public function withShortStory(string $text): static { - return $this->with('short_story', $text); - } - - public function withFullStory(string $text): static { - return $this->with('full_story', $text); - } - - public function withAutor(string $autor): static { - return $this->with('autor', $autor); - } - - /** - * @param int|string|list $category - */ - public function withCategory(int|string|array $category): static { - [$csv, $ids] = self::normalizeCategoryIds($category); - $this->with('category', $csv); - $this->replaceExtrasCats($ids); - - return $this; - } - - /** - * @param int|string|list $category - */ - public function withExtrasCats(int|string|array $category): static { - return $this->withCategory($category); - } - - public function withExtras( - #[\JetBrains\PhpStorm\ExpectedValues(values: [ - 'news_read', 'allow_rate', 'rating', 'vote_num', 'votes', 'view_edit', 'disable_index', - 'related_ids', 'access', 'editdate', 'editor', 'reason', 'user_id', 'disable_search', - 'need_pass', 'allow_rss', 'allow_rss_dzen', 'edited_now', 'allowed_country', 'not_allowed_country', - ])] - string $attrName, - mixed $value, - ): static { - $this->extrasEntity()->with($attrName, $value); - - return $this; - } - - public function withExtrasEntity(PostExtrasSchema $entity): static { - $this->childEntities['post_extras'] = [$entity]; - - return $this; - } - - public function withPass( - #[\JetBrains\PhpStorm\ExpectedValues(values: ['password'])] - string $attrName, - mixed $value, - ): static { - $this->passEntity()->with($attrName, $value); - - return $this; - } - - public function withPassEntity(PostPassSchema $entity): static { - $this->childEntities['post_pass'] = [$entity]; - - return $this; - } - - public function withXfield(string $fieldName, mixed $value): static { - $this->xfieldMap[$fieldName] = $value; - - return $this; - } - - /** - * @param array $fields - */ - public function withXfields(array $fields): static { - $this->xfieldMap = array_merge($this->xfieldMap, $fields); - - return $this; - } - - public function withImagesEntity(ImagesSchema $entity): static { - return $this->attachChildEntity('images', $entity); - } - - public function withFilesEntity(FilesSchema $entity): static { - return $this->attachChildEntity('files', $entity); - } - - public function withCommentsEntity(CommentsSchema $entity): static { - return $this->attachChildEntity('comments', $entity); - } - - public function withPollEntity(PollSchema $entity): static { - return $this->attachChildEntity('poll', $entity); - } - - public function create(): static { - $this->flushXfields(); - - return parent::create(); - } - - public function save(): static { - $this->flushXfields(); - - return parent::save(); - } - - private function flushXfields(): void { - if($this->xfieldMap === []) { - return; - } - $this->with('xfields', \DleApi\Xfield\XfieldValueEncoder::encode($this->xfieldMap)); - } - - private function extrasEntity(): PostExtrasSchema { - if(!isset($this->childEntities['post_extras'][0]) || !$this->childEntities['post_extras'][0] instanceof PostExtrasSchema) { - $this->childEntities['post_extras'] = [new PostExtrasSchema()]; - } - - return $this->childEntities['post_extras'][0]; - } - - private function passEntity(): PostPassSchema { - if(!isset($this->childEntities['post_pass'][0]) || !$this->childEntities['post_pass'][0] instanceof PostPassSchema) { - $this->childEntities['post_pass'] = [new PostPassSchema()]; - } - - return $this->childEntities['post_pass'][0]; - } - - /** - * @param list $ids - */ - private function replaceExtrasCats(array $ids): void { - $this->childEntities['post_extras_cats'] = []; - foreach($ids as $id) { - if($id < 1) { - continue; - } - $cat = new PostExtrasCatsSchema(); - $cat->with('cat_id', $id); - $this->attachChildEntity('post_extras_cats', $cat); - } - } - - /** - * @param int|string|list $category - * @return array{0: string, 1: list} - */ - private static function normalizeCategoryIds(int|string|array $category): array { - if(is_array($category)) { - $ids = array_values(array_filter(array_map(static fn($v) => (int) $v, $category), static fn(int $v) => $v > 0)); - - return [implode(',', $ids), $ids]; - } - $csv = (string) $category; - $ids = array_values(array_filter(array_map(static fn($v) => (int) $v, explode(',', $csv)), static fn(int $v) => $v > 0)); - - return [$csv, $ids]; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/QuestionSchema.php b/upload/api/src/Schema/QuestionSchema.php index 374b679b..94bc824a 100644 --- a/upload/api/src/Schema/QuestionSchema.php +++ b/upload/api/src/Schema/QuestionSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'answer' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/ReadLogSchema.php b/upload/api/src/Schema/ReadLogSchema.php index 3b105711..4f2a9def 100644 --- a/upload/api/src/Schema/ReadLogSchema.php +++ b/upload/api/src/Schema/ReadLogSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'ip' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/RedirectsSchema.php b/upload/api/src/Schema/RedirectsSchema.php index a7b0a63a..56d166e3 100644 --- a/upload/api/src/Schema/RedirectsSchema.php +++ b/upload/api/src/Schema/RedirectsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'to' => '', - 'enabled' => 1, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/RssSchema.php b/upload/api/src/Schema/RssSchema.php index 120599dd..78c55fd4 100644 --- a/upload/api/src/Schema/RssSchema.php +++ b/upload/api/src/Schema/RssSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'description' => '', - 'allow_main' => 0, - 'allow_rating' => 0, - 'allow_comm' => 0, - 'text_type' => 0, - 'date' => 0, - 'search' => '', - 'max_news' => 0, - 'cookie' => '', - 'category' => '', - 'lastdate' => 0, - 'allow_source' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/RssinformSchema.php b/upload/api/src/Schema/RssinformSchema.php index a244a72d..37de0cc3 100644 --- a/upload/api/src/Schema/RssinformSchema.php +++ b/upload/api/src/Schema/RssinformSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'descr' => '', - 'category' => '', - 'url' => '', - 'template' => '', - 'news_max' => 0, - 'tmax' => 0, - 'dmax' => 0, - 'approve' => 1, - 'rss_date_format' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/SendlogSchema.php b/upload/api/src/Schema/SendlogSchema.php index a79481d5..0acbbb73 100644 --- a/upload/api/src/Schema/SendlogSchema.php +++ b/upload/api/src/Schema/SendlogSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'date' => 0, - 'flag' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/SocialLoginSchema.php b/upload/api/src/Schema/SocialLoginSchema.php index ae9a4039..739601af 100644 --- a/upload/api/src/Schema/SocialLoginSchema.php +++ b/upload/api/src/Schema/SocialLoginSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'uid' => 0, - 'password' => '', - 'provider' => '', - 'wait' => 0, - 'waitlogin' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/SpamLogSchema.php b/upload/api/src/Schema/SpamLogSchema.php index d893db18..43ad3198 100644 --- a/upload/api/src/Schema/SpamLogSchema.php +++ b/upload/api/src/Schema/SpamLogSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'is_spammer' => 0, - 'email' => '', - 'date' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/StaticFilesSchema.php b/upload/api/src/Schema/StaticFilesSchema.php index fe598a38..dc939429 100644 --- a/upload/api/src/Schema/StaticFilesSchema.php +++ b/upload/api/src/Schema/StaticFilesSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'author' => '', - 'date' => '', - 'name' => '', - 'onserver' => '', - 'dcount' => 0, - 'size' => 0, - 'checksum' => '', - 'driver' => 0, - 'is_public' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/StaticSchema.php b/upload/api/src/Schema/StaticSchema.php index dfcdd4d0..a642c330 100644 --- a/upload/api/src/Schema/StaticSchema.php +++ b/upload/api/src/Schema/StaticSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md with('metatitle', $metatitle); } } -||||||| -======= - '', - 'descr' => '', - 'template' => '', - 'allow_br' => 0, - 'allow_template' => 0, - 'grouplevel' => 'all', - 'tpl' => '', - 'metadescr' => '', - 'metakeys' => '', - 'views' => 0, - 'template_folder' => '', - 'date' => 0, - 'metatitle' => '', - 'allow_count' => 1, - 'sitemap' => 1, - 'disable_index' => 0, - 'disable_search' => 0, - 'password' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } - - public function withName(string $name): static { - return $this->with('name', $name); - } - - public function withDescr(string $descr): static { - return $this->with('descr', $descr); - } - - public function withTemplate(string $template): static { - return $this->with('template', $template); - } - - public function withPassword(string $password): static { - return $this->with('password', $password); - } - - public function withMetatitle(string $metatitle): static { - return $this->with('metatitle', $metatitle); - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/StorageSchema.php b/upload/api/src/Schema/StorageSchema.php index e4bf406b..8d89a3b3 100644 --- a/upload/api/src/Schema/StorageSchema.php +++ b/upload/api/src/Schema/StorageSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'type' => 0, - 'accesstype' => '', - 'connect_url' => '', - 'connect_port' => 0, - 'username' => '', - 'password' => '', - 'path' => '', - 'http_url' => '', - 'client_key' => '', - 'secret_key' => '', - 'bucket' => '', - 'region' => '', - 'default_storage' => 0, - 'enabled' => 1, - 'posi' => 1, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/SubscribeSchema.php b/upload/api/src/Schema/SubscribeSchema.php index a972a3eb..dcbae8db 100644 --- a/upload/api/src/Schema/SubscribeSchema.php +++ b/upload/api/src/Schema/SubscribeSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'name' => '', - 'email' => '', - 'news_id' => 0, - 'hash' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/TagsSchema.php b/upload/api/src/Schema/TagsSchema.php index 9e617a3b..15ac30b7 100644 --- a/upload/api/src/Schema/TagsSchema.php +++ b/upload/api/src/Schema/TagsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'tag' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/TwofactorSchema.php b/upload/api/src/Schema/TwofactorSchema.php index ceafaaac..365ca836 100644 --- a/upload/api/src/Schema/TwofactorSchema.php +++ b/upload/api/src/Schema/TwofactorSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'pin' => '', - 'attempt' => 0, - 'date' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/UsergroupsSchema.php b/upload/api/src/Schema/UsergroupsSchema.php index fe47f98b..061808dc 100644 --- a/upload/api/src/Schema/UsergroupsSchema.php +++ b/upload/api/src/Schema/UsergroupsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'allow_cats' => '', - 'allow_adds' => 1, - 'cat_add' => '', - 'allow_admin' => 0, - 'allow_addc' => 0, - 'allow_editc' => 0, - 'allow_delc' => 0, - 'edit_allc' => 0, - 'del_allc' => 0, - 'moderation' => 0, - 'allow_all_edit' => 0, - 'allow_edit' => 0, - 'allow_pm' => 0, - 'max_pm' => 0, - 'max_foto' => '', - 'allow_files' => 0, - 'allow_hide' => 1, - 'allow_short' => 0, - 'time_limit' => 0, - 'rid' => 0, - 'allow_fixed' => 0, - 'allow_feed' => 1, - 'allow_search' => 1, - 'allow_poll' => 1, - 'allow_main' => 1, - 'captcha' => 0, - 'icon' => '', - 'allow_modc' => 0, - 'allow_rating' => 1, - 'allow_offline' => 0, - 'allow_image_upload' => 0, - 'allow_file_upload' => 0, - 'allow_signature' => 0, - 'allow_url' => 1, - 'news_sec_code' => 1, - 'allow_image' => 0, - 'max_signature' => 0, - 'max_info' => 0, - 'admin_addnews' => 0, - 'admin_editnews' => 0, - 'admin_comments' => 0, - 'admin_categories' => 0, - 'admin_editusers' => 0, - 'admin_wordfilter' => 0, - 'admin_xfields' => 0, - 'admin_userfields' => 0, - 'admin_static' => 0, - 'admin_editvote' => 0, - 'admin_newsletter' => 0, - 'admin_blockip' => 0, - 'admin_banners' => 0, - 'admin_rss' => 0, - 'admin_iptools' => 0, - 'admin_rssinform' => 0, - 'admin_googlemap' => 0, - 'allow_html' => 1, - 'group_prefix' => '', - 'group_suffix' => '', - 'allow_subscribe' => 0, - 'allow_image_size' => 0, - 'cat_allow_addnews' => '', - 'flood_news' => 0, - 'max_day_news' => 0, - 'force_leech' => 0, - 'edit_limit' => 0, - 'captcha_pm' => 0, - 'max_pm_day' => 0, - 'max_mail_day' => 0, - 'admin_tagscloud' => 0, - 'allow_vote' => 0, - 'admin_complaint' => 0, - 'news_question' => 0, - 'comments_question' => 0, - 'max_comment_day' => 0, - 'max_images' => 0, - 'max_files' => 0, - 'disable_news_captcha' => 0, - 'disable_comments_captcha' => 0, - 'pm_question' => 0, - 'captcha_feedback' => 1, - 'feedback_question' => 0, - 'files_type' => '', - 'max_file_size' => 0, - 'files_max_speed' => 0, - 'spamfilter' => 2, - 'allow_comments_rating' => 1, - 'max_edit_days' => 0, - 'spampmfilter' => 0, - 'force_reg' => 0, - 'force_reg_days' => 0, - 'force_reg_group' => 4, - 'force_news' => 0, - 'force_news_count' => 0, - 'force_news_group' => 4, - 'force_comments' => 0, - 'force_comments_count' => 0, - 'force_comments_group' => 4, - 'force_rating' => 0, - 'force_rating_count' => 0, - 'force_rating_group' => 4, - 'not_allow_cats' => '', - 'allow_up_image' => 0, - 'allow_up_watermark' => 0, - 'allow_up_thumb' => 0, - 'up_count_image' => 0, - 'up_image_side' => '', - 'up_image_size' => 0, - 'up_thumb_size' => '', - 'allow_mail_files' => 0, - 'max_mail_files' => 0, - 'max_mail_allfiles' => 0, - 'mail_files_type' => '', - 'video_comments' => 0, - 'media_comments' => 0, - 'min_image_side' => '', - 'allow_public_file_upload' => 0, - 'force_comments_rating' => 0, - 'force_comments_rating_count' => 0, - 'force_comments_rating_group' => 0, - 'max_downloads' => 0, - 'admin_links' => 0, - 'admin_meta' => 0, - 'admin_redirects' => 0, - 'allow_change_storage' => 0, - 'self_delete' => 2, - 'allow_complaint_news' => 1, - 'allow_complaint_comments' => 1, - 'allow_complaint_orfo' => 1, - 'flood_time' => 0, - 'max_c_negative' => 0, - 'max_n_negative' => 0, - 'rating_n_day' => 0, - 'rating_c_day' => 0, - 'allow_rating_change' => 1, - 'allow_crating_change' => 1, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/UsersDeleteSchema.php b/upload/api/src/Schema/UsersDeleteSchema.php index 8d3b6cd7..7f254ec4 100644 --- a/upload/api/src/Schema/UsersDeleteSchema.php +++ b/upload/api/src/Schema/UsersDeleteSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/UsersSchema.php b/upload/api/src/Schema/UsersSchema.php index 44fd1b17..eefe6c49 100644 --- a/upload/api/src/Schema/UsersSchema.php +++ b/upload/api/src/Schema/UsersSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md with('user_group', $userGroup); } } -||||||| -======= - '', - 'password' => '', - 'name' => '', - 'news_num' => 0, - 'comm_num' => 0, - 'user_group' => 4, - 'lastdate' => '', - 'reg_date' => '', - 'banned' => '', - 'allow_mail' => 1, - 'info' => '', - 'signature' => '', - 'foto' => '', - 'fullname' => '', - 'land' => '', - 'favorites' => '', - 'pm_all' => 0, - 'pm_unread' => 0, - 'time_limit' => '', - 'xfields' => '', - 'allowed_ip' => '', - 'hash' => '', - 'logged_ip' => '', - 'restricted' => 0, - 'restricted_days' => 0, - 'restricted_date' => '', - 'timezone' => '', - 'news_subscribe' => 0, - 'comments_reply_subscribe' => 0, - 'twofactor_auth' => 0, - 'cat_add' => '', - 'cat_allow_addnews' => '', - 'twofactor_secret' => '', - ]; - } - - public function primaryKey(): string|array { - return 'user_id'; - } - - public function withName(string $name): static { - return $this->with('name', $name); - } - - public function withEmail(string $email): static { - return $this->with('email', $email); - } - - public function withPassword(string $password): static { - return $this->with('password', $password); - } - - public function withUsergroup(int $userGroup): static { - return $this->with('user_group', $userGroup); - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/ViewsSchema.php b/upload/api/src/Schema/ViewsSchema.php index 0ffdbeff..e6126875 100644 --- a/upload/api/src/Schema/ViewsSchema.php +++ b/upload/api/src/Schema/ViewsSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/VoteResultSchema.php b/upload/api/src/Schema/VoteResultSchema.php index 3fac14a8..70a4fb20 100644 --- a/upload/api/src/Schema/VoteResultSchema.php +++ b/upload/api/src/Schema/VoteResultSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'name' => '', - 'vote_id' => 0, - 'answer' => 0, - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/VoteSchema.php b/upload/api/src/Schema/VoteSchema.php index af12a09e..368103fd 100644 --- a/upload/api/src/Schema/VoteSchema.php +++ b/upload/api/src/Schema/VoteSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md '', - 'vote_num' => 0, - 'date' => 0, - 'title' => '', - 'body' => '', - 'approve' => 1, - 'start' => '', - 'end' => '', - 'grouplevel' => 'all', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Schema/XfsearchSchema.php b/upload/api/src/Schema/XfsearchSchema.php index 63c96783..e95f39e5 100644 --- a/upload/api/src/Schema/XfsearchSchema.php +++ b/upload/api/src/Schema/XfsearchSchema.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md 0, - 'tagname' => '', - 'tagvalue' => '', - ]; - } - - public function primaryKey(): string|array { - return 'id'; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/src/Sdk/Presenter/TablePresenter.php b/upload/api/src/Sdk/Presenter/TablePresenter.php index b155b45b..0810895a 100644 --- a/upload/api/src/Sdk/Presenter/TablePresenter.php +++ b/upload/api/src/Sdk/Presenter/TablePresenter.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md tableName; } } -||||||| -======= -tableName; - } -} ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/v2/routes.php b/upload/api/v2/routes.php index 389bddc2..413d240d 100644 --- a/upload/api/v2/routes.php +++ b/upload/api/v2/routes.php @@ -1,4 +1,3 @@ -<<<<<<< New base: Update README.md patch('/xfields/{scope}/{name}[/]', [$xf, 'patch']); $group->delete('/xfields/{scope}/{name}[/]', [$xf, 'delete']); })->add(new BearerAuthMiddleware()); -||||||| -======= -group('', function (RouteCollectorProxy $group) { - $oauth = new OauthController(); - $group->post('/oauth/token[/]', [$oauth, 'token']); - $group->post('/oauth/revoke[/]', [$oauth, 'revoke']); - $group->map(['GET', 'POST'], '/oauth/authorize[/]', [$oauth, 'authorize']); - $group->get('/.well-known/oauth-authorization-server[/]', [$oauth, 'discovery']); - $group->get('/health[/]', [new ResourceController(), 'health']); -}); - -$app->group('', function (RouteCollectorProxy $group) { - $group->get('/key/check[/]', [new ApiKeyCheckController(), 'check']); -})->add(new ApiKeyAuthMiddleware()); - -$app->group('', function (RouteCollectorProxy $group) { - $table = new TableCrudController(); - $resource = new ResourceController(); - $xf = new XfieldController(); - $up = new UploadController(); - $me = new MeController(); - $oauth = new OauthController(); - - $group->get('/me[/]', [$me, 'me']); - $group->get('/oauth/userinfo[/]', [$oauth, 'userinfo']); - - $group->get('/post[/]', [$resource, 'listPosts']); - $group->get('/post/{id}[/]', [$resource, 'getPost']); - $group->post('/post[/]', [$resource, 'createPost']); - $group->post('/user[/]', [$resource, 'createUser']); - $group->post('/usergroup[/]', [$resource, 'createUsergroup']); - $group->post('/plugin[/]', [$resource, 'createPlugin']); - $group->get('/conversations[/]', [$resource, 'conversations']); - - $group->get('/table/{name}[/]', [$table, 'list']); - $group->get('/table/{name}/{id}[/]', [$table, 'get']); - $group->post('/table/{name}[/]', [$table, 'create']); - $group->put('/table/{name}/{id}[/]', [$table, 'update']); - $group->delete('/table/{name}/{id}[/]', [$table, 'delete']); - - $group->post('/upload[/]', [$up, 'upload']); - - $group->get('/xfields/{scope}[/]', [$xf, 'list']); - $group->post('/xfields/{scope}/encode[/]', [$xf, 'encode']); - $group->get('/xfields/{scope}/{name}[/]', [$xf, 'get']); - $group->post('/xfields/{scope}[/]', [$xf, 'create']); - $group->put('/xfields/{scope}/{name}[/]', [$xf, 'put']); - $group->patch('/xfields/{scope}/{name}[/]', [$xf, 'patch']); - $group->delete('/xfields/{scope}/{name}[/]', [$xf, 'delete']); -})->add(new BearerAuthMiddleware()); ->>>>>>> Current commit: Начало обновления до api v2 diff --git a/upload/api/vendor/bin/generate-defuse-key b/upload/api/vendor/bin/generate-defuse-key new file mode 100755 index 00000000..2a4e979b --- /dev/null +++ b/upload/api/vendor/bin/generate-defuse-key @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/defuse/php-encryption/bin/generate-defuse-key'); + } +} + +return include __DIR__ . '/..'.'/defuse/php-encryption/bin/generate-defuse-key'; diff --git a/upload/api/vendor/bin/openapi b/upload/api/vendor/bin/openapi new file mode 100755 index 00000000..9f74b06f --- /dev/null +++ b/upload/api/vendor/bin/openapi @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/zircote/swagger-php/bin/openapi'); + } +} + +return include __DIR__ . '/..'.'/zircote/swagger-php/bin/openapi'; diff --git a/upload/api/vendor/bin/php-parse b/upload/api/vendor/bin/php-parse new file mode 100755 index 00000000..61566e60 --- /dev/null +++ b/upload/api/vendor/bin/php-parse @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse'); + } +} + +return include __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse'; diff --git a/upload/api/vendor/bin/yaml-lint b/upload/api/vendor/bin/yaml-lint new file mode 100755 index 00000000..388092f5 --- /dev/null +++ b/upload/api/vendor/bin/yaml-lint @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint'); + } +} + +return include __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint'; diff --git a/upload/api/vendor/composer/installed.php b/upload/api/vendor/composer/installed.php index dce31a7c..69c046ac 100644 --- a/upload/api/vendor/composer/installed.php +++ b/upload/api/vendor/composer/installed.php @@ -1,9 +1,9 @@ array( 'name' => 'devcraftclub/dle-api', - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'reference' => '141118597a4a291be0b1808cacf1b01b2a9eeb58', + 'pretty_version' => 'dev-dev/200.1.0', + 'version' => 'dev-dev/200.1.0', + 'reference' => 'df2e3843a142efbc8ae5b3725f03f4aec1d2902d', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -20,9 +20,9 @@ 'dev_requirement' => false, ), 'devcraftclub/dle-api' => array( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'reference' => '141118597a4a291be0b1808cacf1b01b2a9eeb58', + 'pretty_version' => 'dev-dev/200.1.0', + 'version' => 'dev-dev/200.1.0', + 'reference' => 'df2e3843a142efbc8ae5b3725f03f4aec1d2902d', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/upload/api/vendor/defuse/php-encryption/bin/generate-defuse-key b/upload/api/vendor/defuse/php-encryption/bin/generate-defuse-key new file mode 100755 index 00000000..24e31b5e --- /dev/null +++ b/upload/api/vendor/defuse/php-encryption/bin/generate-defuse-key @@ -0,0 +1,14 @@ +#!/usr/bin/env php +saveToAsciiSafeString(), "\n"; diff --git a/upload/api/vendor/defuse/php-encryption/dist/Makefile b/upload/api/vendor/defuse/php-encryption/dist/Makefile new file mode 100644 index 00000000..bffe6163 --- /dev/null +++ b/upload/api/vendor/defuse/php-encryption/dist/Makefile @@ -0,0 +1,39 @@ +# This builds defuse-crypto.phar. To run this Makefile, `box` and `composer` +# must be installed and in your $PATH. Run it from inside the dist/ directory. + +box := $(shell which box) +composer := $(shell which composer) +gitcommit := $(shell git rev-parse HEAD) + +.PHONY: all +all: build-phar + +.PHONY: sign-phar +sign-phar: + gpg -u DD2E507F7BDB1669 --armor --output defuse-crypto.phar.sig --detach-sig defuse-crypto.phar + +# ensure we run in clean tree. export git tree and run there. +.PHONY: build-phar +build-phar: + @echo "Creating .phar from revision $(shell git rev-parse HEAD)." + rm -rf worktree + install -d worktree + (cd $(CURDIR)/..; git archive HEAD) | tar -x -C worktree + $(MAKE) -f $(CURDIR)/Makefile -C worktree defuse-crypto.phar + mv worktree/*.phar . + rm -rf worktree + +.PHONY: clean +clean: + rm -vf defuse-crypto.phar defuse-crypto.phar.sig + +# Inside workdir/: + +defuse-crypto.phar: dist/box.json composer.lock + cp dist/box.json . + php $(box) compile -c box.json -v + +composer.lock: + $(composer) config autoloader-suffix $(gitcommit) + $(composer) install --no-dev + diff --git a/upload/api/vendor/defuse/php-encryption/dist/box.json b/upload/api/vendor/defuse/php-encryption/dist/box.json new file mode 100644 index 00000000..3c81e953 --- /dev/null +++ b/upload/api/vendor/defuse/php-encryption/dist/box.json @@ -0,0 +1,22 @@ +{ + "chmod": "0755", + "finder": [ + { + "in": "src", + "name": "*.php" + }, + { + "in": "vendor/composer", + "name": "*.php" + }, + { + "in": "vendor/paragonie", + "name": "*.php", + "exclude": "other" + } + ], + "main": "vendor/autoload.php", + "output": "defuse-crypto.phar", + "shebang": false, + "stub": true +} diff --git a/upload/api/vendor/defuse/php-encryption/dist/phar-testing-autoload.php b/upload/api/vendor/defuse/php-encryption/dist/phar-testing-autoload.php new file mode 100644 index 00000000..433395a7 --- /dev/null +++ b/upload/api/vendor/defuse/php-encryption/dist/phar-testing-autoload.php @@ -0,0 +1,4 @@ + diff --git a/upload/api/vendor/defuse/php-encryption/dist/signingkey-new.asc b/upload/api/vendor/defuse/php-encryption/dist/signingkey-new.asc new file mode 100644 index 00000000..7e3a4a1f --- /dev/null +++ b/upload/api/vendor/defuse/php-encryption/dist/signingkey-new.asc @@ -0,0 +1,53 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBF5V4TABEAC4G2BkHDaqbip3gj1oOqKh3V6LQa9QAd/f/hyhmR5hXpciPxf3 +NNHAxzoGAuB51f1YPJTNO59mGKHDuCFfr0pI94HDGoW4WgxqnUyqHBj2+/JhQPqO +lgDT0QDcfxmUd0wfZl/Ur+8SsaBYvfFWNmPaXHp9m4MMRtw9uZNIW6LlZ24JqmGy +/YUELUSH7P+uJ4HQEdixaqQ0VgIomRDI+5IwdJMtq4TSNazQm3nNmH9Em37cdi6J +NDfFRy2QxJDmuqlg8mkpS5TvrrNy/UJwIeXO9PuGaBODr8GAKWvhkpfGlxN+hWMY +01bOFnuEnOcuXw8BjPAKHqwOuGvinNmQ7lX1Rj3ssd31sTUimop0oNjOTZztpJBR +m6wO2/YGMjt+eL02NgBBDIsV837PeWuJmymTJDGQuBjZ3JWUfyT3AnkA8OU5vKjs +pM8AjIiuU7C8zQhUSHDnukTKWpBmMdOXeWNb5Ye6n60wJWzWFGlm+cYalPs+q3H8 +bxHxHEdFT0rUpxB05bc9zsZ3gGkc2NTNW/00a6gvTyX1UsBAeNgvVSHBHQGfow6o +ZKG+LnVxd+cl97ay6kP29eLypXffbXQ3hMXe9tUNBjAeiok9tssU70Epr9wTh/Fm +/iEbGc8VhS4TSk3c+3eS16rvlQ51FmAlmG6kAnN/ah+BiM4syPrWcJHIDQARAQAB +tG1kZWZ1c2UvcGhwLWVuY3J5cHRpb24gbWFpbnRhaW5lcnMgKGRlZnVzZS9waHAt +ZW5jcnlwdGlvbiByZWxlYXNlIHNpZ25pbmcga2V5KSA8cGhwLWVuY3J5cHRpb25A +ZGVmdXNlLmludmFsaWQ+iQJUBBMBCAA+FiEEbdbmdwKBWEb8hSWj3S5Qf3vbFmkF +Al5V4TACGwMFCQlmAYAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ3S5Qf3vb +FmnQ4Q//bHAwDI7CcTlDDktdRCP0YCRtb5zMa6vSqnZLi5aTqzmL1yQCAp1/JTwf +nlHn5xt60eKwfjIKj7Kj0n8WDFYnlOu30H5fNtFHis0xeS7GkH60tIE/pQUZILlB +Wcnx/ZPnlxccjtfSbnpelSPdvIoHVRNhh1ZYG/49kuuv8TMbMIi2FBAzGEatPoLN +f4wntoOKGvl8R2rPc2geapXTz++X+HJkddHCISR61obDRl9P0t9x+0M7gGSVMGfC +GC4wh3JB6/ha8l+DI+l88/64IKRG+M33bBwLGQ0RIhotHIy442gLJTm6TeoH8iUz +xCBwPYW+Ta1wZi17PIjHdTkNGBeEj/Hr5tTVV3oxrQVgHCymzasnz9IwcCCMwpKK +ZOMFl0+PT3TSBKLnUByvOB64YOjxU7t+sRf53Biz3yKzto5VdHGW64OG2vGFy/Xz +vI5RqU34wjtEHxWfz8y2GBnhD2TzEFCIIWPAX3TDG64NBSEBjhUraOmoVoaYJlP6 +rqxIQo4yhC+f5rnr2ZA48Hnrg0jEdVvN07FegoOnQQPpYBBkOrkTDWChn8oiXMfg +9bjv19zDOBVXl9EU+P8AhwTHz/pBKmhb97N9nYp/pbmejA+I0Kw1vZo7gaMxL938 +oQkdtWT70ZzcpcZfeKVXoZa/ddAmuxzNknZA8ZnjQ9Qhv7aNX2O5Ag0EXlXhMAEQ +AM8od4/85i7ZPmM6C1M4n4XcXeKsuZKHLvLLcRHFGkjVdXRSaxpbk2yDJiLnB9hX +GSJG2gUCT+yrimjQ71bJ4q9K2+mkVHVjdtCrCtoOYEIpMLzsRtqyAWotcVmdv8Zv +4IIjxfdxpTkj9gZmUfDIe6tbN2iBCAo1HArXq1qSdof3ui8SqdWeinkd7lZMesFm +dGQaAcHbmEakO5mRzljme8IBs3UY9j/zxEG1JbsHx9ua7CVwJ7lxi2SgSW6nF9k5 +CX5zbrDqlqSJNtDs+KbjCbI2eK+qe4qZWHPiw4bNBn6EWf97/4Os8w7Vrrpyd2eO +1JENwjlG6WG9mbJdIWWwakZ0CeH5LnJo6dV47KZbbbB6ncavaL+VpfbTCgdOGsCc +GcYUVl90/v5pPm2owx4Dg9hSfcp8fesQuq4b79NAcjF7meu5wgNdvFlfuXony+UC +W2wNi0mi9lzLD0n0j0GDzWyd3r7yXmPTL4LhrQu/pIcWIljKI3GUAQZqIYbGAO3G +7hEFT8rDWg2vKRtMag4iy5FvZFqR+7TwWJAcWnHJBZ95F9NzeYIFhp9a3hxbKXqD +xEnyGgzAszUycq29BApT4/4rDZQuXuOBd4lJp8tSzctLjvo7D3la+MWD6AlDkYT4 +bGKN9NfRCzYr2Zq3jOByAV3d5hGgyzdJlZSqXAGtbHHdABEBAAGJAjwEGAEIACYW +IQRt1uZ3AoFYRvyFJaPdLlB/e9sWaQUCXlXhMAIbDAUJCWYBgAAKCRDdLlB/e9sW +aSGfD/wPeq6lGu8ocHIkO74VPioJRKRXDVLsY02xKP64p0RHUGFTOqqB3A3UV0ue +tkizoUdfF5xkgJ18gbxXo8lotBq+Ita5hoYAfqJnTnucAPGovREJ+X1HfdK4pJqW +KNJElBz+fC4chqksiUAuH7IMImmy0/lA+LqZagzkQJU10MvmiFZ6kn+X5Mb4izRl +vAHo16eI4psApdT8Bs7mwAjgCHxS9Re46uOElB4Bx3iFPd/PEwHWnfr8x9TJZYKW +fsShG31+vfBRCfGtfKGxiAkp3EEM11lzbbfMcC3lai5iJQ/FmHgoIDeIG2Ebuk4w +/PYakSrpvkEYoMP31pVHDhzopVeURS2lpvQJ4CvTP5CVQtKrbuygow6GF8N/drCE +hdEx22pzW02ADS9fgzrlDztIOlOvC9a+epISIaEjfrc9dWhrw6chZEoWIil2MVQR +Sj0jZ8w/H7P88oHTOcFVel73ZEPg9eRUkqMnIn3DWUuqLI2SX/AtVnhdYHWTiOkq +knsGofWxUSu3RZR2ZElK9hjNKdVbGDzHGAYeJihieTKIOXpCf6Ix5B32tmFpfmBV +Q9YP3JLsRTxIMbXsJImand/r6fSjdmTpk2PovYPtE1HTJKaVHeagQdsrWw5LaJv0 +ZWuwJm0y0WJXcAEjwOHhBs0nvq2CXuZi2ZTPtY+DbsSFWhaN7g== +=Ysgx +-----END PGP PUBLIC KEY BLOCK----- diff --git a/upload/api/vendor/defuse/php-encryption/dist/signingkey-new.asc.sig b/upload/api/vendor/defuse/php-encryption/dist/signingkey-new.asc.sig new file mode 100644 index 00000000..56e1f3a0 Binary files /dev/null and b/upload/api/vendor/defuse/php-encryption/dist/signingkey-new.asc.sig differ diff --git a/upload/api/vendor/defuse/php-encryption/dist/signingkey.asc b/upload/api/vendor/defuse/php-encryption/dist/signingkey.asc new file mode 100644 index 00000000..63b6aa3d --- /dev/null +++ b/upload/api/vendor/defuse/php-encryption/dist/signingkey.asc @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2 + +mQINBFarvO4BEACdQBaLt6SUBx1cB5liUu1qo+YwVLh9bxTregQtmEREMdTVqXYt +e5b79uL4pQp2GlKHcEyRURS+6rIIruM0oh9ZYGTJYPAkCDzJxaU2awZeFbfBvpCm +iF66/O4ZJI4mlT8dFKmxBJxDhfeOR2UmmhDiEsJK9FxBKUzvo/dWrX2pBzf8Y122 +iIaVraSo+tymaf7vriaIf/NnSKhDw8dtQYGM4NMrxxsPTfbCF8XiboDgTkoD2A+6 +NpOJYxA4Veedsf2TP9YLhljH4m5yYlfjjqBzbBCPWuE6Hhy5Xze9mncgDr7LKenm +Ctf2NxW6y4O3RCI+9eLlBfFWB+KuGV87/b5daetX7NNLbjID8z2rqEa+d6wu5xA5 +Ta2uiVkAOEovr3XnkayZ9zth+Za7w7Ai0ln0N/LVMkM+Gu4z/pJv6HjmTGDM2wJb +fs+UOM0TFdg+N81Do67XT2M4o0MeHyUqsIiWpYa2Qf1PNmqTQNJnRk8uZZ9I96Nh +eCgNuCbhsQiYBMicox+xmuWAlGAfA06y0kCtmqGhiBGArdJlWvUqPqGiZ4Hln9z0 +FJmXDOh0Q/FIPxcDg8mKRRbx+lOP389PLsPpj4b2B/4PEgfpCCOwuKpLotATZxC1 +9JwFk0Y/cvUUkq4a+nAJBNtBbtRJkEesuuUnRq6XexmnE3uUucDcV0XCSwARAQAB +tCBUYXlsb3IgSG9ybmJ5IDx0YXlsb3JAZGVmdXNlLmNhPokCPQQTAQgAJwUCVqu8 +7gIbAwUJB4TOAAULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRA4XuBVoSkVOJbx +EACG0F9blPMAsK05EWyNnnS4mw25zPfbaqqEvYbquAeM0nBpRDm7sRn2MNR0AL4g +7XrtxE/4qYkdEl6f2wFCQeRhZgxE3w22llredzLme11Hic8hn4i7ysdIw0r9dMMR +kjgR5UcWpv8iU847czyK09PkKW2EaLRbX2qbA7rNU5qCFKeD4Sy4bBTteISeVsHo +Vr9o1/bRrMhgZ++ts8hYf0LmujIf5cxp+qcdKwCXSnS/gmmXaKRMCPv/Wdlq9bt6 +LX9jZB9lXBdGxcBJeFOsTG+QRDiVjg3d6i3o3TAKV87ALBI4v2ADEYtN8lviHo3/ +SovVKv6zrUsZHxhoGiLTiksNrYsKMmiMxdJCoOazmtUPnZ4UOtT8NdqMPoKvdoRz +f4rhZ+f5jSVD9OuX2PDmfyq21Rdiym7Vcgr+uTIFJ3ShRHjWb/ytCwoB2FeGY6+G +AKY58bTQvUIqEJvSov/+TAqZ4BfOuSdTLcHglV1OdUu2SFZvU2gmyVp0l5elGv5t +FyUlBJUkQT9MtvsdLOR7vQi8QapV+9LWpqwvaj9hyEJz848DQ2sdYTphUytFHv7H +k58DAtVhTrVjHyeefjiYtMl6vSAgTjy5LWAUpo5TfhdGrAi0Tdd/GD7amHoWoDy8 +EKXKq2xPLo3JOdkWYQUi5NErzEskfsSzpCOgyDJmGetWK7kCDQRWq7zuARAAu7/i +cm8cjgLhHEX/bgfwOT2hLOLSjjve0O8YFSuJO9XqIHXqmfVOrqWtfG0Mh4bwlfqc +MAvBfF5NSSPfAE4ftBAQ1e5jEv8hJeqICpq3IHTFX4etBs49NfNkyveQl/amVTu1 ++/O5J4CuIcsEf3y0Xuu38n7EB3SfMQCWLcOR1NyZoX3bI+CGRpOVVoFse3ljSWL4 +LhLVl0WiEMXULsussEoN+c6x9KCyAi/jFOrxrTrFC//sZesKj6KucoqKGfwMWrrv +IeRT9Ga8Wn5MJnQu0aWg+zVVYqTedXZLNLODgQIInFnXO0seBXy15yDok1y5bkx2 +sinKg4+mueYaGUpoUti0hM3J3yaC34i6Cwa8MQoLNw1JIS/oNtKjpMxyV10w8aoc +PHRK3n7UYp10mJHx7aM+lldSKvVS1NTQmI4vloNLwMp324H5ANDFAlRUz7mysVnu +DEEvigPSPxs5ZYENu/i7pCQC5qHfhrlBrQwTjhegr0pQPcumy2fO5SGC9l/5B7ev +bqQSZmDeWWoTvh2w2wl5/RWAsgZKx6rDtkCqYx7sSBY17uorrxP24LP4zhq7NxRV +nfdsLogbCFNVQ66u7qvq5zFccdFtg9h1HQWdS7wbnKSBGZoo5gl6js7GGtxfGbb0 +oQ9kp6eciF4U92r6POhVgbRe4CfPo50nqgZBddkAEQEAAYkCJQQYAQgADwUCVqu8 +7gIbDAUJB4TOAAAKCRA4XuBVoSkVOFJ8D/9J8IJ4XWUU3FYIaHJ3XeSoxDmTi7d5 +WmNdf1lmwz82MQjG4uw17oCbvQzmj4/a/CM1Ly4v0WwBhUf9aiNErD0ByHASFnuc +tlQBLVJdk0vRyD0fZakGg64qCA76hiySjMhlGHkQFyP2mDORc2GNu/OqFGm79pXT +ZUplXxd431E603/agM5xJrweutMMpP1nBFTSEMJvbMNzDVN8I1A1CH4zVmAVxOUk +sQ5L5rXW+KeXWyiMF24+l2CMnkQ2CxfHpkcpfPJs1Cbt+TIBSSofIqK8QJXrb/2f +Zpl/ftqW7Xe86rJFrB/Y/77LDWx10rqWEvfCqrBxrMj7ONAQfbKQF/IjAwDN17Wf +1K74rqKnRu+KHCyNM89s1iDbQC9kzZfzYt4AEOvAH/ZQDMZffzPSbnfkBerExFpa +93XMuiR66jiBsf9IXIQeydpJD4Ogl2sSUSxFEJxJ/bBSxPxC5w7/BVMA7Am1y8Zo +3hrpqnX2PBzxG7L0FZ6fYkfR3p8JS7vI6nByBf2IDv8W32wn43olPf+u6uobHLvt +ttapOjwPAhPDalRuxs9U6WSg06QJkT/0F8TFUPWpsFmKTl+G4Ty7PHWsjeeNHJCL +7/5RQboFY3k8Jy3/sIofABO6Un9LJivDuu9PxqA0IgvaS6Mja8JdCCk9Nyk4vHB7 +IEgAL/CYqrk38w== +=lmD7 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/upload/api/vendor/nikic/php-parser/bin/php-parse b/upload/api/vendor/nikic/php-parser/bin/php-parse new file mode 100755 index 00000000..1e7b2994 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/bin/php-parse @@ -0,0 +1,206 @@ +#!/usr/bin/env php +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, ' 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] " 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]; +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder.php new file mode 100644 index 00000000..d6aa124c --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder.php @@ -0,0 +1,12 @@ + */ + protected array $attributes = []; + /** @var list */ + protected array $constants = []; + + /** @var list */ + 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 + ); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Class_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Class_.php new file mode 100644 index 00000000..6f394315 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Class_.php @@ -0,0 +1,151 @@ + */ + protected array $implements = []; + protected int $flags = 0; + /** @var list */ + protected array $uses = []; + /** @var list */ + protected array $constants = []; + /** @var list */ + protected array $properties = []; + /** @var list */ + protected array $methods = []; + /** @var list */ + 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); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php new file mode 100644 index 00000000..488b7213 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php @@ -0,0 +1,50 @@ + */ + 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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php new file mode 100644 index 00000000..c766321b --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php @@ -0,0 +1,86 @@ + */ + protected array $attributes = []; + + /** @var list */ + 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 + ); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Enum_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Enum_.php new file mode 100644 index 00000000..c00df03f --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Enum_.php @@ -0,0 +1,116 @@ + */ + protected array $implements = []; + /** @var list */ + protected array $uses = []; + /** @var list */ + protected array $enumCases = []; + /** @var list */ + protected array $constants = []; + /** @var list */ + protected array $methods = []; + /** @var list */ + 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); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php new file mode 100644 index 00000000..ff79cb6b --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php @@ -0,0 +1,73 @@ +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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php new file mode 100644 index 00000000..48f5f693 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php @@ -0,0 +1,67 @@ + */ + protected array $stmts = []; + + /** @var list */ + 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); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php new file mode 100644 index 00000000..13dd3f7f --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php @@ -0,0 +1,94 @@ + */ + protected array $extends = []; + /** @var list */ + protected array $constants = []; + /** @var list */ + protected array $methods = []; + /** @var list */ + 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); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php new file mode 100644 index 00000000..8358dbe3 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php @@ -0,0 +1,147 @@ +|null */ + protected ?array $stmts = []; + + /** @var list */ + 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); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php new file mode 100644 index 00000000..80fe6f84 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php @@ -0,0 +1,45 @@ +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); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php new file mode 100644 index 00000000..324a32b0 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php @@ -0,0 +1,171 @@ + */ + 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 + ); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php new file mode 100644 index 00000000..c80fe481 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php @@ -0,0 +1,223 @@ + */ + protected array $attributes = []; + /** @var null|Identifier|Name|ComplexType */ + protected ?Node $type = null; + /** @var list */ + protected array $attributeGroups = []; + /** @var list */ + 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 + ); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php new file mode 100644 index 00000000..cf21c821 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php @@ -0,0 +1,65 @@ +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); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php new file mode 100644 index 00000000..fee09583 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php @@ -0,0 +1,145 @@ +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'); + } + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php new file mode 100644 index 00000000..ffa1bd5c --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php @@ -0,0 +1,83 @@ + */ + protected array $uses = []; + /** @var list */ + protected array $constants = []; + /** @var list */ + protected array $properties = []; + /** @var list */ + protected array $methods = []; + /** @var list */ + 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 + ); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php new file mode 100644 index 00000000..b82cf139 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php @@ -0,0 +1,49 @@ +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); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php new file mode 100644 index 00000000..07642f92 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php @@ -0,0 +1,375 @@ +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 + */ + 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'); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php new file mode 100644 index 00000000..f29a6915 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php @@ -0,0 +1,338 @@ +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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Comment.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Comment.php new file mode 100644 index 00000000..01b341e4 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Comment.php @@ -0,0 +1,209 @@ +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, + ]; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php new file mode 100644 index 00000000..bb3e9146 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php @@ -0,0 +1,6 @@ +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 '|>': return ($this->fallbackEvaluator)($expr); + } + + 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); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Error.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Error.php new file mode 100644 index 00000000..f81f0c42 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Error.php @@ -0,0 +1,173 @@ + */ + protected array $attributes; + + /** + * Creates an Exception signifying a parse error. + * + * @param string $message Error message + * @param array $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 + */ + public function getAttributes(): array { + return $this->attributes; + } + + /** + * Sets the attributes of the node/token the error occurred at. + * + * @param array $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(); + } + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php new file mode 100644 index 00000000..51ad730c --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php @@ -0,0 +1,12 @@ +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 = []; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php new file mode 100644 index 00000000..dff33dd0 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php @@ -0,0 +1,17 @@ +type = $type; + $this->old = $old; + $this->new = $new; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php new file mode 100644 index 00000000..253e1757 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php @@ -0,0 +1,178 @@ +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, 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> $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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php new file mode 100644 index 00000000..b30a99a1 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php @@ -0,0 +1,71 @@ + $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']; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenPolyfill.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenPolyfill.php new file mode 100644 index 00000000..36022d09 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenPolyfill.php @@ -0,0 +1,237 @@ += 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 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 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); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php new file mode 100644 index 00000000..cdbe2bdc --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php @@ -0,0 +1,282 @@ +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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php new file mode 100644 index 00000000..7be41426 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php @@ -0,0 +1,108 @@ +[] 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 */ + 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 */ + 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\""); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer.php new file mode 100644 index 00000000..5e2ece96 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer.php @@ -0,0 +1,116 @@ +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 $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()); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php new file mode 100644 index 00000000..442aa1fa --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php @@ -0,0 +1,232 @@ + */ + 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 FnTokenEmulator(), + 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 $tokens + * @return list + */ + 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); + } + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AsymmetricVisibilityTokenEmulator.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AsymmetricVisibilityTokenEmulator.php new file mode 100644 index 00000000..084bb75d --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AsymmetricVisibilityTokenEmulator.php @@ -0,0 +1,93 @@ + \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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php new file mode 100644 index 00000000..2c12f33a --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php @@ -0,0 +1,49 @@ +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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php new file mode 100644 index 00000000..5418f52c --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php @@ -0,0 +1,26 @@ +id === \T_WHITESPACE + && $tokens[$pos + 2]->id === \T_STRING; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php new file mode 100644 index 00000000..9cadf420 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php @@ -0,0 +1,45 @@ +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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php new file mode 100644 index 00000000..99ebb5c9 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php @@ -0,0 +1,20 @@ +getKeywordString()) !== false; + } + + /** @param Token[] $tokens */ + protected function isKeywordContext(array $tokens, int $pos): bool { + $prevToken = $this->getPreviousNonIgnorableToken($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 getPreviousNonIgnorableToken(array $tokens, int $start): ?Token { + for ($i = $start - 1; $i >= 0; --$i) { + $token = $tokens[$i]; + if ($token->id === T_WHITESPACE || $token->id == T_COMMENT || $token->id === T_DOC_COMMENT) { + continue; + } + + return $token; + } + + 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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php new file mode 100644 index 00000000..0fa5fbc2 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php @@ -0,0 +1,19 @@ +') !== 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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/PipeOperatorEmulator.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/PipeOperatorEmulator.php new file mode 100644 index 00000000..b5616923 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/PipeOperatorEmulator.php @@ -0,0 +1,45 @@ +') !== 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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php new file mode 100644 index 00000000..71b7fc23 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php @@ -0,0 +1,19 @@ +text === '(' || + ($tokens[$pos + 1]->id === \T_WHITESPACE && + isset($tokens[$pos + 2]) && + $tokens[$pos + 2]->text === '('))); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php new file mode 100644 index 00000000..851b5c4a --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php @@ -0,0 +1,37 @@ +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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php new file mode 100644 index 00000000..fec2f19f --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php @@ -0,0 +1,30 @@ +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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Modifiers.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Modifiers.php new file mode 100644 index 00000000..0f0f22d6 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Modifiers.php @@ -0,0 +1,85 @@ + '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'); + } + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NameContext.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NameContext.php new file mode 100644 index 00000000..2265ecce --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NameContext.php @@ -0,0 +1,284 @@ + [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 $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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node.php new file mode 100644 index 00000000..fd2a9b72 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node.php @@ -0,0 +1,150 @@ + + */ + public function getAttributes(): array; + + /** + * Replaces all the attributes of this node. + * + * @param array $attributes + */ + public function setAttributes(array $attributes): void; +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Arg.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Arg.php new file mode 100644 index 00000000..6680efac --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Arg.php @@ -0,0 +1,44 @@ + $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'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/ArrayItem.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/ArrayItem.php new file mode 100644 index 00000000..fa1cff52 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/ArrayItem.php @@ -0,0 +1,43 @@ + $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); diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Attribute.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Attribute.php new file mode 100644 index 00000000..9d892436 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Attribute.php @@ -0,0 +1,33 @@ + Attribute arguments */ + public array $args; + + /** + * @param Node\Name $name Attribute name + * @param list $args Attribute arguments + * @param array $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'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/AttributeGroup.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/AttributeGroup.php new file mode 100644 index 00000000..b9eb588d --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/AttributeGroup.php @@ -0,0 +1,27 @@ + $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'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/ClosureUse.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/ClosureUse.php new file mode 100644 index 00000000..e313280b --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/ClosureUse.php @@ -0,0 +1,36 @@ + $attributes Additional attributes + */ + public function __construct(Expr\Variable $var, bool $byRef = false, array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + $this->byRef = $byRef; + } + + public function getSubNodeNames(): array { + return ['var', 'byRef']; + } + + public function getType(): string { + return 'ClosureUse'; + } +} + +// @deprecated compatibility alias +class_alias(ClosureUse::class, Expr\ClosureUse::class); diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/ComplexType.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/ComplexType.php new file mode 100644 index 00000000..05a5e5ee --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/ComplexType.php @@ -0,0 +1,13 @@ + $attributes Additional attributes + */ + public function __construct($name, Expr $value, array $attributes = []) { + $this->attributes = $attributes; + $this->name = \is_string($name) ? new Identifier($name) : $name; + $this->value = $value; + } + + public function getSubNodeNames(): array { + return ['name', 'value']; + } + + public function getType(): string { + return 'Const'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/DeclareItem.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/DeclareItem.php new file mode 100644 index 00000000..55c1fe4f --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/DeclareItem.php @@ -0,0 +1,37 @@ +value pair node. + * + * @param string|Node\Identifier $key Key + * @param Node\Expr $value Value + * @param array $attributes Additional attributes + */ + public function __construct($key, Node\Expr $value, array $attributes = []) { + $this->attributes = $attributes; + $this->key = \is_string($key) ? new Node\Identifier($key) : $key; + $this->value = $value; + } + + public function getSubNodeNames(): array { + return ['key', 'value']; + } + + public function getType(): string { + return 'DeclareItem'; + } +} + +// @deprecated compatibility alias +class_alias(DeclareItem::class, Stmt\DeclareDeclare::class); diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php new file mode 100644 index 00000000..8b7dbb6c --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php @@ -0,0 +1,8 @@ + $attributes Additional attributes + */ + public function __construct(Expr $var, ?Expr $dim = null, array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + $this->dim = $dim; + } + + public function getSubNodeNames(): array { + return ['var', 'dim']; + } + + public function getType(): string { + return 'Expr_ArrayDimFetch'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php new file mode 100644 index 00000000..55ef1635 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php @@ -0,0 +1,15 @@ + $attributes Additional attributes + */ + public function __construct(array $items = [], array $attributes = []) { + $this->attributes = $attributes; + $this->items = $items; + } + + public function getSubNodeNames(): array { + return ['items']; + } + + public function getType(): string { + return 'Expr_Array'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php new file mode 100644 index 00000000..0e98ce9f --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php @@ -0,0 +1,84 @@ + false : Whether the closure is static + * 'byRef' => false : Whether to return by reference + * 'params' => array() : Parameters + * 'returnType' => null : Return type + * 'attrGroups' => array() : PHP attribute groups + * @param array $attributes Additional attributes + */ + public function __construct(array $subNodes, array $attributes = []) { + $this->attributes = $attributes; + $this->static = $subNodes['static'] ?? false; + $this->byRef = $subNodes['byRef'] ?? false; + $this->params = $subNodes['params'] ?? []; + $this->returnType = $subNodes['returnType'] ?? null; + $this->expr = $subNodes['expr']; + $this->attrGroups = $subNodes['attrGroups'] ?? []; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'static', 'byRef', 'params', 'returnType', 'expr']; + } + + public function returnsByRef(): bool { + return $this->byRef; + } + + public function getParams(): array { + return $this->params; + } + + public function getReturnType() { + return $this->returnType; + } + + public function getAttrGroups(): array { + return $this->attrGroups; + } + + /** + * @return Node\Stmt\Return_[] + */ + public function getStmts(): array { + return [new Node\Stmt\Return_($this->expr)]; + } + + public function getType(): string { + return 'Expr_ArrowFunction'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php new file mode 100644 index 00000000..dcbf84dd --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php @@ -0,0 +1,33 @@ + $attributes Additional attributes + */ + public function __construct(Expr $var, Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['var', 'expr']; + } + + public function getType(): string { + return 'Expr_Assign'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php new file mode 100644 index 00000000..5209a64b --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $var, Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['var', 'expr']; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php new file mode 100644 index 00000000..4f3623fb --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php @@ -0,0 +1,11 @@ + $attributes Additional attributes + */ + public function __construct(Expr $var, Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['var', 'expr']; + } + + public function getType(): string { + return 'Expr_AssignRef'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php new file mode 100644 index 00000000..1b92bd4f --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php @@ -0,0 +1,37 @@ + $attributes Additional attributes + */ + public function __construct(Expr $left, Expr $right, array $attributes = []) { + $this->attributes = $attributes; + $this->left = $left; + $this->right = $right; + } + + public function getSubNodeNames(): array { + return ['left', 'right']; + } + + /** + * Get the operator sigil for this binary operation. + * + * In the case there are multiple possible sigils for an operator, this method does not + * necessarily return the one used in the parsed code. + */ + abstract public function getOperatorSigil(): string; +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php new file mode 100644 index 00000000..5930c541 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php @@ -0,0 +1,15 @@ +'; + } + + public function getType(): string { + return 'Expr_BinaryOp_Greater'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php new file mode 100644 index 00000000..4d440b10 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php @@ -0,0 +1,15 @@ +='; + } + + public function getType(): string { + return 'Expr_BinaryOp_GreaterOrEqual'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php new file mode 100644 index 00000000..e25d17cd --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php @@ -0,0 +1,15 @@ +'; + } + + public function getType(): string { + return 'Expr_BinaryOp_Pipe'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Plus.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Plus.php new file mode 100644 index 00000000..fe34b84c --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Plus.php @@ -0,0 +1,15 @@ +>'; + } + + public function getType(): string { + return 'Expr_BinaryOp_ShiftRight'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php new file mode 100644 index 00000000..01e9b231 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php @@ -0,0 +1,15 @@ +'; + } + + public function getType(): string { + return 'Expr_BinaryOp_Spaceship'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php new file mode 100644 index 00000000..b7175a7a --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_BitwiseNot'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php new file mode 100644 index 00000000..c66d2332 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_BooleanNot'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/CallLike.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/CallLike.php new file mode 100644 index 00000000..86e781c1 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/CallLike.php @@ -0,0 +1,60 @@ + + */ + abstract public function getRawArgs(): array; + + /** + * Returns whether this call expression is actually a first class callable. + */ + public function isFirstClassCallable(): bool { + $rawArgs = $this->getRawArgs(); + return count($rawArgs) === 1 && current($rawArgs) instanceof VariadicPlaceholder; + } + + /** + * Assert that this is not a first-class callable and return only ordinary Args. + * + * @return Arg[] + */ + public function getArgs(): array { + assert(!$this->isFirstClassCallable()); + return $this->getRawArgs(); + } + + /** + * Retrieves a specific argument from the raw arguments. + * + * Returns the named argument that matches the given `$name`, or the + * positional (unnamed) argument that exists at the given `$position`, + * otherwise, returns `null` for first-class callables or if no match is found. + */ + public function getArg(string $name, int $position): ?Arg { + if ($this->isFirstClassCallable()) { + return null; + } + foreach ($this->getRawArgs() as $i => $arg) { + if ($arg->unpack) { + continue; + } + if ( + ($arg->name !== null && $arg->name->toString() === $name) + || ($arg->name === null && $i === $position) + ) { + return $arg; + } + } + return null; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php new file mode 100644 index 00000000..c2751de4 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php @@ -0,0 +1,25 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php new file mode 100644 index 00000000..471cb824 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php @@ -0,0 +1,11 @@ + $attributes Additional attributes + */ + public function __construct(Node $class, $name, array $attributes = []) { + $this->attributes = $attributes; + $this->class = $class; + $this->name = \is_string($name) ? new Identifier($name) : $name; + } + + public function getSubNodeNames(): array { + return ['class', 'name']; + } + + public function getType(): string { + return 'Expr_ClassConstFetch'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php new file mode 100644 index 00000000..d85bc9ab --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_Clone'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php new file mode 100644 index 00000000..0680446f --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php @@ -0,0 +1,86 @@ + false : Whether the closure is static + * 'byRef' => false : Whether to return by reference + * 'params' => array(): Parameters + * 'uses' => array(): use()s + * 'returnType' => null : Return type + * 'stmts' => array(): Statements + * 'attrGroups' => array(): PHP attributes groups + * @param array $attributes Additional attributes + */ + public function __construct(array $subNodes = [], array $attributes = []) { + $this->attributes = $attributes; + $this->static = $subNodes['static'] ?? false; + $this->byRef = $subNodes['byRef'] ?? false; + $this->params = $subNodes['params'] ?? []; + $this->uses = $subNodes['uses'] ?? []; + $this->returnType = $subNodes['returnType'] ?? null; + $this->stmts = $subNodes['stmts'] ?? []; + $this->attrGroups = $subNodes['attrGroups'] ?? []; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'static', 'byRef', 'params', 'uses', 'returnType', 'stmts']; + } + + public function returnsByRef(): bool { + return $this->byRef; + } + + public function getParams(): array { + return $this->params; + } + + public function getReturnType() { + return $this->returnType; + } + + /** @return Node\Stmt[] */ + public function getStmts(): array { + return $this->stmts; + } + + public function getAttrGroups(): array { + return $this->attrGroups; + } + + public function getType(): string { + return 'Expr_Closure'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php new file mode 100644 index 00000000..279aa26a --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php @@ -0,0 +1,15 @@ + $attributes Additional attributes + */ + public function __construct(Name $name, array $attributes = []) { + $this->attributes = $attributes; + $this->name = $name; + } + + public function getSubNodeNames(): array { + return ['name']; + } + + public function getType(): string { + return 'Expr_ConstFetch'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php new file mode 100644 index 00000000..d2f30506 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_Empty'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php new file mode 100644 index 00000000..43010ac4 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php @@ -0,0 +1,30 @@ + $attributes Additional attributes + */ + public function __construct(array $attributes = []) { + $this->attributes = $attributes; + } + + public function getSubNodeNames(): array { + return []; + } + + public function getType(): string { + return 'Expr_Error'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ErrorSuppress.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ErrorSuppress.php new file mode 100644 index 00000000..32625a23 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ErrorSuppress.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_ErrorSuppress'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php new file mode 100644 index 00000000..5120b1b4 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_Eval'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php new file mode 100644 index 00000000..cf002466 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php @@ -0,0 +1,33 @@ + $attributes Additional attributes + */ + public function __construct(?Expr $expr = null, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_Exit'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php new file mode 100644 index 00000000..0b85840d --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php @@ -0,0 +1,38 @@ + Arguments */ + public array $args; + + /** + * Constructs a function call node. + * + * @param Node\Name|Expr $name Function name + * @param array $args Arguments + * @param array $attributes Additional attributes + */ + public function __construct(Node $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 'Expr_FuncCall'; + } + + public function getRawArgs(): array { + return $this->args; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php new file mode 100644 index 00000000..e1187b19 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php @@ -0,0 +1,38 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, int $type, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + $this->type = $type; + } + + public function getSubNodeNames(): array { + return ['expr', 'type']; + } + + public function getType(): string { + return 'Expr_Include'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php new file mode 100644 index 00000000..a2783cb3 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php @@ -0,0 +1,35 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, Node $class, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + $this->class = $class; + } + + public function getSubNodeNames(): array { + return ['expr', 'class']; + } + + public function getType(): string { + return 'Expr_Instanceof'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php new file mode 100644 index 00000000..4f80fff7 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(array $vars, array $attributes = []) { + $this->attributes = $attributes; + $this->vars = $vars; + } + + public function getSubNodeNames(): array { + return ['vars']; + } + + public function getType(): string { + return 'Expr_Isset'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php new file mode 100644 index 00000000..496b7b38 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php @@ -0,0 +1,34 @@ + $attributes Additional attributes + */ + public function __construct(array $items, array $attributes = []) { + $this->attributes = $attributes; + $this->items = $items; + } + + public function getSubNodeNames(): array { + return ['items']; + } + + public function getType(): string { + return 'Expr_List'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Match_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Match_.php new file mode 100644 index 00000000..cd028a2d --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Match_.php @@ -0,0 +1,32 @@ + $attributes Additional attributes + */ + public function __construct(Node\Expr $cond, array $arms = [], array $attributes = []) { + $this->attributes = $attributes; + $this->cond = $cond; + $this->arms = $arms; + } + + public function getSubNodeNames(): array { + return ['cond', 'arms']; + } + + public function getType(): string { + return 'Expr_Match'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php new file mode 100644 index 00000000..2703c75d --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php @@ -0,0 +1,45 @@ + Arguments */ + public array $args; + + /** + * Constructs a function call node. + * + * @param Expr $var Variable holding object + * @param string|Identifier|Expr $name Method name + * @param array $args Arguments + * @param array $attributes Additional attributes + */ + public function __construct(Expr $var, $name, array $args = [], array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + $this->name = \is_string($name) ? new Identifier($name) : $name; + $this->args = $args; + } + + public function getSubNodeNames(): array { + return ['var', 'name', 'args']; + } + + public function getType(): string { + return 'Expr_MethodCall'; + } + + public function getRawArgs(): array { + return $this->args; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php new file mode 100644 index 00000000..eedaaa1e --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php @@ -0,0 +1,40 @@ + Arguments */ + public array $args; + + /** + * Constructs a function call node. + * + * @param Node\Name|Expr|Node\Stmt\Class_ $class Class name (or class node for anonymous classes) + * @param array $args Arguments + * @param array $attributes Additional attributes + */ + public function __construct(Node $class, array $args = [], array $attributes = []) { + $this->attributes = $attributes; + $this->class = $class; + $this->args = $args; + } + + public function getSubNodeNames(): array { + return ['class', 'args']; + } + + public function getType(): string { + return 'Expr_New'; + } + + public function getRawArgs(): array { + return $this->args; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafeMethodCall.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafeMethodCall.php new file mode 100644 index 00000000..a151f715 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafeMethodCall.php @@ -0,0 +1,45 @@ + Arguments */ + public array $args; + + /** + * Constructs a nullsafe method call node. + * + * @param Expr $var Variable holding object + * @param string|Identifier|Expr $name Method name + * @param array $args Arguments + * @param array $attributes Additional attributes + */ + public function __construct(Expr $var, $name, array $args = [], array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + $this->name = \is_string($name) ? new Identifier($name) : $name; + $this->args = $args; + } + + public function getSubNodeNames(): array { + return ['var', 'name', 'args']; + } + + public function getType(): string { + return 'Expr_NullsafeMethodCall'; + } + + public function getRawArgs(): array { + return $this->args; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafePropertyFetch.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafePropertyFetch.php new file mode 100644 index 00000000..6f73a16d --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafePropertyFetch.php @@ -0,0 +1,35 @@ + $attributes Additional attributes + */ + public function __construct(Expr $var, $name, array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + $this->name = \is_string($name) ? new Identifier($name) : $name; + } + + public function getSubNodeNames(): array { + return ['var', 'name']; + } + + public function getType(): string { + return 'Expr_NullsafePropertyFetch'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php new file mode 100644 index 00000000..3dca8fdc --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $var, array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + } + + public function getSubNodeNames(): array { + return ['var']; + } + + public function getType(): string { + return 'Expr_PostDec'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php new file mode 100644 index 00000000..bc990c30 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $var, array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + } + + public function getSubNodeNames(): array { + return ['var']; + } + + public function getType(): string { + return 'Expr_PostInc'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php new file mode 100644 index 00000000..2f168730 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $var, array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + } + + public function getSubNodeNames(): array { + return ['var']; + } + + public function getType(): string { + return 'Expr_PreDec'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php new file mode 100644 index 00000000..fd455f55 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $var, array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + } + + public function getSubNodeNames(): array { + return ['var']; + } + + public function getType(): string { + return 'Expr_PreInc'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php new file mode 100644 index 00000000..60574760 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_Print'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php new file mode 100644 index 00000000..8c416a8c --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php @@ -0,0 +1,35 @@ + $attributes Additional attributes + */ + public function __construct(Expr $var, $name, array $attributes = []) { + $this->attributes = $attributes; + $this->var = $var; + $this->name = \is_string($name) ? new Identifier($name) : $name; + } + + public function getSubNodeNames(): array { + return ['var', 'name']; + } + + public function getType(): string { + return 'Expr_PropertyFetch'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php new file mode 100644 index 00000000..e4003512 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php @@ -0,0 +1,30 @@ + $attributes Additional attributes + */ + public function __construct(array $parts, array $attributes = []) { + $this->attributes = $attributes; + $this->parts = $parts; + } + + public function getSubNodeNames(): array { + return ['parts']; + } + + public function getType(): string { + return 'Expr_ShellExec'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php new file mode 100644 index 00000000..707f34b6 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php @@ -0,0 +1,45 @@ + Arguments */ + public array $args; + + /** + * Constructs a static method call node. + * + * @param Node\Name|Expr $class Class name + * @param string|Identifier|Expr $name Method name + * @param array $args Arguments + * @param array $attributes Additional attributes + */ + public function __construct(Node $class, $name, array $args = [], array $attributes = []) { + $this->attributes = $attributes; + $this->class = $class; + $this->name = \is_string($name) ? new Identifier($name) : $name; + $this->args = $args; + } + + public function getSubNodeNames(): array { + return ['class', 'name', 'args']; + } + + public function getType(): string { + return 'Expr_StaticCall'; + } + + public function getRawArgs(): array { + return $this->args; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php new file mode 100644 index 00000000..4836a65b --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php @@ -0,0 +1,36 @@ + $attributes Additional attributes + */ + public function __construct(Node $class, $name, array $attributes = []) { + $this->attributes = $attributes; + $this->class = $class; + $this->name = \is_string($name) ? new VarLikeIdentifier($name) : $name; + } + + public function getSubNodeNames(): array { + return ['class', 'name']; + } + + public function getType(): string { + return 'Expr_StaticPropertyFetch'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php new file mode 100644 index 00000000..d4837e64 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php @@ -0,0 +1,37 @@ + $attributes Additional attributes + */ + public function __construct(Expr $cond, ?Expr $if, Expr $else, array $attributes = []) { + $this->attributes = $attributes; + $this->cond = $cond; + $this->if = $if; + $this->else = $else; + } + + public function getSubNodeNames(): array { + return ['cond', 'if', 'else']; + } + + public function getType(): string { + return 'Expr_Ternary'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Throw_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Throw_.php new file mode 100644 index 00000000..ee49f835 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Throw_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Node\Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_Throw'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php new file mode 100644 index 00000000..cd06f74b --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_UnaryMinus'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php new file mode 100644 index 00000000..1b44f7b3 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_UnaryPlus'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php new file mode 100644 index 00000000..bab74920 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct($name, array $attributes = []) { + $this->attributes = $attributes; + $this->name = $name; + } + + public function getSubNodeNames(): array { + return ['name']; + } + + public function getType(): string { + return 'Expr_Variable'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php new file mode 100644 index 00000000..5cff88f8 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Expr_YieldFrom'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php new file mode 100644 index 00000000..bd81e69b --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php @@ -0,0 +1,33 @@ + $attributes Additional attributes + */ + public function __construct(?Expr $value = null, ?Expr $key = null, array $attributes = []) { + $this->attributes = $attributes; + $this->key = $key; + $this->value = $value; + } + + public function getSubNodeNames(): array { + return ['key', 'value']; + } + + public function getType(): string { + return 'Expr_Yield'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php new file mode 100644 index 00000000..58f653a8 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php @@ -0,0 +1,40 @@ + */ + private static array $specialClassNames = [ + 'self' => true, + 'parent' => true, + 'static' => true, + ]; + + /** + * Constructs an identifier node. + * + * @param string $name Identifier as string + * @param array $attributes Additional attributes + */ + public function __construct(string $name, array $attributes = []) { + if ($name === '') { + throw new \InvalidArgumentException('Identifier name cannot be empty'); + } + + $this->attributes = $attributes; + $this->name = $name; + } + + public function getSubNodeNames(): array { + return ['name']; + } + + /** + * Get identifier as string. + * + * @psalm-return non-empty-string + * @return string Identifier as string. + */ + public function toString(): string { + return $this->name; + } + + /** + * Get lowercased identifier as string. + * + * @psalm-return non-empty-string&lowercase-string + * @return string Lowercased identifier as string + */ + public function toLowerString(): string { + return strtolower($this->name); + } + + /** + * Checks whether the identifier is a special class name (self, parent or static). + * + * @return bool Whether identifier is a special class name + */ + public function isSpecialClassName(): bool { + return isset(self::$specialClassNames[strtolower($this->name)]); + } + + /** + * Get identifier as string. + * + * @psalm-return non-empty-string + * @return string Identifier as string + */ + public function __toString(): string { + return $this->name; + } + + public function getType(): string { + return 'Identifier'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/InterpolatedStringPart.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/InterpolatedStringPart.php new file mode 100644 index 00000000..576dac46 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/InterpolatedStringPart.php @@ -0,0 +1,32 @@ + $attributes Additional attributes + */ + public function __construct(string $value, array $attributes = []) { + $this->attributes = $attributes; + $this->value = $value; + } + + public function getSubNodeNames(): array { + return ['value']; + } + + public function getType(): string { + return 'InterpolatedStringPart'; + } +} + +// @deprecated compatibility alias +class_alias(InterpolatedStringPart::class, Scalar\EncapsedStringPart::class); diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/IntersectionType.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/IntersectionType.php new file mode 100644 index 00000000..3b39cf10 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/IntersectionType.php @@ -0,0 +1,27 @@ + $attributes Additional attributes + */ + public function __construct(array $types, array $attributes = []) { + $this->attributes = $attributes; + $this->types = $types; + } + + public function getSubNodeNames(): array { + return ['types']; + } + + public function getType(): string { + return 'IntersectionType'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/MatchArm.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/MatchArm.php new file mode 100644 index 00000000..192216df --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/MatchArm.php @@ -0,0 +1,29 @@ + */ + public ?array $conds; + public Expr $body; + + /** + * @param null|list $conds + */ + public function __construct(?array $conds, Node\Expr $body, array $attributes = []) { + $this->conds = $conds; + $this->body = $body; + $this->attributes = $attributes; + } + + public function getSubNodeNames(): array { + return ['conds', 'body']; + } + + public function getType(): string { + return 'MatchArm'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php new file mode 100644 index 00000000..932080b5 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php @@ -0,0 +1,278 @@ + */ + private static array $specialClassNames = [ + 'self' => true, + 'parent' => true, + 'static' => true, + ]; + + /** + * Constructs a name node. + * + * @param string|string[]|self $name Name as string, part array or Name instance (copy ctor) + * @param array $attributes Additional attributes + */ + final public function __construct($name, array $attributes = []) { + $this->attributes = $attributes; + $this->name = self::prepareName($name); + } + + public function getSubNodeNames(): array { + return ['name']; + } + + /** + * Get parts of name (split by the namespace separator). + * + * @psalm-return non-empty-list + * @return string[] Parts of name + */ + public function getParts(): array { + return \explode('\\', $this->name); + } + + /** + * Gets the first part of the name, i.e. everything before the first namespace separator. + * + * @return string First part of the name + */ + public function getFirst(): string { + if (false !== $pos = \strpos($this->name, '\\')) { + return \substr($this->name, 0, $pos); + } + return $this->name; + } + + /** + * Gets the last part of the name, i.e. everything after the last namespace separator. + * + * @return string Last part of the name + */ + public function getLast(): string { + if (false !== $pos = \strrpos($this->name, '\\')) { + return \substr($this->name, $pos + 1); + } + return $this->name; + } + + /** + * Checks whether the name is unqualified. (E.g. Name) + * + * @return bool Whether the name is unqualified + */ + public function isUnqualified(): bool { + return false === \strpos($this->name, '\\'); + } + + /** + * Checks whether the name is qualified. (E.g. Name\Name) + * + * @return bool Whether the name is qualified + */ + public function isQualified(): bool { + return false !== \strpos($this->name, '\\'); + } + + /** + * Checks whether the name is fully qualified. (E.g. \Name) + * + * @return bool Whether the name is fully qualified + */ + public function isFullyQualified(): bool { + return false; + } + + /** + * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name) + * + * @return bool Whether the name is relative + */ + public function isRelative(): bool { + return false; + } + + /** + * Returns a string representation of the name itself, without taking the name type into + * account (e.g., not including a leading backslash for fully qualified names). + * + * @psalm-return non-empty-string + * @return string String representation + */ + public function toString(): string { + return $this->name; + } + + /** + * Returns a string representation of the name as it would occur in code (e.g., including + * leading backslash for fully qualified names. + * + * @psalm-return non-empty-string + * @return string String representation + */ + public function toCodeString(): string { + return $this->toString(); + } + + /** + * Returns lowercased string representation of the name, without taking the name type into + * account (e.g., no leading backslash for fully qualified names). + * + * @psalm-return non-empty-string&lowercase-string + * @return string Lowercased string representation + */ + public function toLowerString(): string { + return strtolower($this->name); + } + + /** + * Checks whether the identifier is a special class name (self, parent or static). + * + * @return bool Whether identifier is a special class name + */ + public function isSpecialClassName(): bool { + return isset(self::$specialClassNames[strtolower($this->name)]); + } + + /** + * Returns a string representation of the name by imploding the namespace parts with the + * namespace separator. + * + * @psalm-return non-empty-string + * @return string String representation + */ + public function __toString(): string { + return $this->name; + } + + /** + * Gets a slice of a name (similar to array_slice). + * + * This method returns a new instance of the same type as the original and with the same + * attributes. + * + * If the slice is empty, null is returned. The null value will be correctly handled in + * concatenations using concat(). + * + * Offset and length have the same meaning as in array_slice(). + * + * @param int $offset Offset to start the slice at (may be negative) + * @param int|null $length Length of the slice (may be negative) + * + * @return static|null Sliced name + */ + public function slice(int $offset, ?int $length = null) { + if ($offset === 1 && $length === null) { + // Short-circuit the common case. + if (false !== $pos = \strpos($this->name, '\\')) { + return new static(\substr($this->name, $pos + 1)); + } + return null; + } + + $parts = \explode('\\', $this->name); + $numParts = \count($parts); + + $realOffset = $offset < 0 ? $offset + $numParts : $offset; + if ($realOffset < 0 || $realOffset > $numParts) { + throw new \OutOfBoundsException(sprintf('Offset %d is out of bounds', $offset)); + } + + if (null === $length) { + $realLength = $numParts - $realOffset; + } else { + $realLength = $length < 0 ? $length + $numParts - $realOffset : $length; + if ($realLength < 0 || $realLength > $numParts - $realOffset) { + throw new \OutOfBoundsException(sprintf('Length %d is out of bounds', $length)); + } + } + + if ($realLength === 0) { + // Empty slice is represented as null + return null; + } + + return new static(array_slice($parts, $realOffset, $realLength), $this->attributes); + } + + /** + * Concatenate two names, yielding a new Name instance. + * + * The type of the generated instance depends on which class this method is called on, for + * example Name\FullyQualified::concat() will yield a Name\FullyQualified instance. + * + * If one of the arguments is null, a new instance of the other name will be returned. If both + * arguments are null, null will be returned. As such, writing + * Name::concat($namespace, $shortName) + * where $namespace is a Name node or null will work as expected. + * + * @param string|string[]|self|null $name1 The first name + * @param string|string[]|self|null $name2 The second name + * @param array $attributes Attributes to assign to concatenated name + * + * @return static|null Concatenated name + */ + public static function concat($name1, $name2, array $attributes = []) { + if (null === $name1 && null === $name2) { + return null; + } + if (null === $name1) { + return new static($name2, $attributes); + } + if (null === $name2) { + return new static($name1, $attributes); + } else { + return new static( + self::prepareName($name1) . '\\' . self::prepareName($name2), $attributes + ); + } + } + + /** + * Prepares a (string, array or Name node) name for use in name changing methods by converting + * it to a string. + * + * @param string|string[]|self $name Name to prepare + * + * @psalm-return non-empty-string + * @return string Prepared name + */ + private static function prepareName($name): string { + if (\is_string($name)) { + if ('' === $name) { + throw new \InvalidArgumentException('Name cannot be empty'); + } + + return $name; + } + if (\is_array($name)) { + if (empty($name)) { + throw new \InvalidArgumentException('Name cannot be empty'); + } + + return implode('\\', $name); + } + if ($name instanceof self) { + return $name->name; + } + + throw new \InvalidArgumentException( + 'Expected string, array of parts or Name instance' + ); + } + + public function getType(): string { + return 'Name'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php new file mode 100644 index 00000000..21183786 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php @@ -0,0 +1,49 @@ +toString(); + } + + public function getType(): string { + return 'Name_FullyQualified'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php new file mode 100644 index 00000000..0226a4e4 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php @@ -0,0 +1,49 @@ +toString(); + } + + public function getType(): string { + return 'Name_Relative'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php new file mode 100644 index 00000000..b99acd13 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(Node $type, array $attributes = []) { + $this->attributes = $attributes; + $this->type = $type; + } + + public function getSubNodeNames(): array { + return ['type']; + } + + public function getType(): string { + return 'NullableType'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php new file mode 100644 index 00000000..6cbb84c9 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php @@ -0,0 +1,123 @@ + $attributes Additional attributes + * @param int $flags Optional visibility flags + * @param list $attrGroups PHP attribute groups + * @param PropertyHook[] $hooks Property hooks for promoted properties + */ + public function __construct( + Expr $var, ?Expr $default = null, ?Node $type = null, + bool $byRef = false, bool $variadic = false, + array $attributes = [], + int $flags = 0, + array $attrGroups = [], + array $hooks = [] + ) { + $this->attributes = $attributes; + $this->type = $type; + $this->byRef = $byRef; + $this->variadic = $variadic; + $this->var = $var; + $this->default = $default; + $this->flags = $flags; + $this->attrGroups = $attrGroups; + $this->hooks = $hooks; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'flags', 'type', 'byRef', 'variadic', 'var', 'default', 'hooks']; + } + + public function getType(): string { + return 'Param'; + } + + /** + * Whether this parameter uses constructor property promotion. + */ + public function isPromoted(): bool { + return $this->flags !== 0 || $this->hooks !== []; + } + + public function isFinal(): bool { + return (bool) ($this->flags & Modifiers::FINAL); + } + + public function isPublic(): bool { + $public = (bool) ($this->flags & Modifiers::PUBLIC); + if ($public) { + return true; + } + + if (!$this->isPromoted()) { + return false; + } + + return ($this->flags & Modifiers::VISIBILITY_MASK) === 0; + } + + public function isProtected(): bool { + return (bool) ($this->flags & Modifiers::PROTECTED); + } + + public function isPrivate(): bool { + return (bool) ($this->flags & Modifiers::PRIVATE); + } + + public function isReadonly(): bool { + return (bool) ($this->flags & Modifiers::READONLY); + } + + /** + * Whether the promoted property has explicit public(set) visibility. + */ + public function isPublicSet(): bool { + return (bool) ($this->flags & Modifiers::PUBLIC_SET); + } + + /** + * Whether the promoted property has explicit protected(set) visibility. + */ + public function isProtectedSet(): bool { + return (bool) ($this->flags & Modifiers::PROTECTED_SET); + } + + /** + * Whether the promoted property has explicit private(set) visibility. + */ + public function isPrivateSet(): bool { + return (bool) ($this->flags & Modifiers::PRIVATE_SET); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/PropertyHook.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/PropertyHook.php new file mode 100644 index 00000000..349b9cef --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/PropertyHook.php @@ -0,0 +1,105 @@ + 0 : Flags + * 'byRef' => false : Whether hook returns by reference + * 'params' => array(): Parameters + * 'attrGroups' => array(): PHP attribute groups + * @param array $attributes Additional attributes + */ + public function __construct($name, $body, array $subNodes = [], array $attributes = []) { + $this->attributes = $attributes; + $this->name = \is_string($name) ? new Identifier($name) : $name; + $this->body = $body; + $this->flags = $subNodes['flags'] ?? 0; + $this->byRef = $subNodes['byRef'] ?? false; + $this->params = $subNodes['params'] ?? []; + $this->attrGroups = $subNodes['attrGroups'] ?? []; + } + + public function returnsByRef(): bool { + return $this->byRef; + } + + public function getParams(): array { + return $this->params; + } + + public function getReturnType() { + return null; + } + + /** + * Whether the property hook is final. + */ + public function isFinal(): bool { + return (bool) ($this->flags & Modifiers::FINAL); + } + + public function getStmts(): ?array { + if ($this->body instanceof Expr) { + $name = $this->name->toLowerString(); + if ($name === 'get') { + return [new Return_($this->body)]; + } + if ($name === 'set') { + if (!$this->hasAttribute('propertyName')) { + throw new \LogicException( + 'Can only use getStmts() on a "set" hook if the "propertyName" attribute is set'); + } + + $propName = $this->getAttribute('propertyName'); + $prop = new PropertyFetch(new Variable('this'), (string) $propName); + return [new Expression(new Assign($prop, $this->body))]; + } + throw new \LogicException('Unknown property hook "' . $name . '"'); + } + return $this->body; + } + + public function getAttrGroups(): array { + return $this->attrGroups; + } + + public function getType(): string { + return 'PropertyHook'; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'flags', 'byRef', 'name', 'params', 'body']; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/PropertyItem.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/PropertyItem.php new file mode 100644 index 00000000..101611e6 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/PropertyItem.php @@ -0,0 +1,37 @@ + $attributes Additional attributes + */ + public function __construct($name, ?Node\Expr $default = null, array $attributes = []) { + $this->attributes = $attributes; + $this->name = \is_string($name) ? new Node\VarLikeIdentifier($name) : $name; + $this->default = $default; + } + + public function getSubNodeNames(): array { + return ['name', 'default']; + } + + public function getType(): string { + return 'PropertyItem'; + } +} + +// @deprecated compatibility alias +class_alias(PropertyItem::class, Stmt\PropertyProperty::class); diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.php new file mode 100644 index 00000000..3df25721 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.php @@ -0,0 +1,6 @@ + $attributes Additional attributes + */ + public function __construct(float $value, array $attributes = []) { + $this->attributes = $attributes; + $this->value = $value; + } + + public function getSubNodeNames(): array { + return ['value']; + } + + /** + * @param mixed[] $attributes + */ + public static function fromString(string $str, array $attributes = []): Float_ { + $attributes['rawValue'] = $str; + $float = self::parse($str); + + return new Float_($float, $attributes); + } + + /** + * @internal + * + * Parses a DNUMBER token like PHP would. + * + * @param string $str A string number + * + * @return float The parsed number + */ + public static function parse(string $str): float { + $str = str_replace('_', '', $str); + + // Check whether this is one of the special integer notations. + if ('0' === $str[0]) { + // hex + if ('x' === $str[1] || 'X' === $str[1]) { + return hexdec($str); + } + + // bin + if ('b' === $str[1] || 'B' === $str[1]) { + return bindec($str); + } + + // oct, but only if the string does not contain any of '.eE'. + if (false === strpbrk($str, '.eE')) { + // substr($str, 0, strcspn($str, '89')) cuts the string at the first invalid digit + // (8 or 9) so that only the digits before that are used. + return octdec(substr($str, 0, strcspn($str, '89'))); + } + } + + // dec + return (float) $str; + } + + public function getType(): string { + return 'Scalar_Float'; + } +} + +// @deprecated compatibility alias +class_alias(Float_::class, DNumber::class); diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Int_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Int_.php new file mode 100644 index 00000000..bcc257a6 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Int_.php @@ -0,0 +1,82 @@ + $attributes Additional attributes + */ + public function __construct(int $value, array $attributes = []) { + $this->attributes = $attributes; + $this->value = $value; + } + + public function getSubNodeNames(): array { + return ['value']; + } + + /** + * Constructs an Int node from a string number literal. + * + * @param string $str String number literal (decimal, octal, hex or binary) + * @param array $attributes Additional attributes + * @param bool $allowInvalidOctal Whether to allow invalid octal numbers (PHP 5) + * + * @return Int_ The constructed LNumber, including kind attribute + */ + public static function fromString(string $str, array $attributes = [], bool $allowInvalidOctal = false): Int_ { + $attributes['rawValue'] = $str; + + $str = str_replace('_', '', $str); + + if ('0' !== $str[0] || '0' === $str) { + $attributes['kind'] = Int_::KIND_DEC; + return new Int_((int) $str, $attributes); + } + + if ('x' === $str[1] || 'X' === $str[1]) { + $attributes['kind'] = Int_::KIND_HEX; + return new Int_(hexdec($str), $attributes); + } + + if ('b' === $str[1] || 'B' === $str[1]) { + $attributes['kind'] = Int_::KIND_BIN; + return new Int_(bindec($str), $attributes); + } + + if (!$allowInvalidOctal && strpbrk($str, '89')) { + throw new Error('Invalid numeric literal', $attributes); + } + + // Strip optional explicit octal prefix. + if ('o' === $str[1] || 'O' === $str[1]) { + $str = substr($str, 2); + } + + // use intval instead of octdec to get proper cutting behavior with malformed numbers + $attributes['kind'] = Int_::KIND_OCT; + return new Int_(intval($str, 8), $attributes); + } + + public function getType(): string { + return 'Scalar_Int'; + } +} + +// @deprecated compatibility alias +class_alias(Int_::class, LNumber::class); diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/InterpolatedString.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/InterpolatedString.php new file mode 100644 index 00000000..9336dfe4 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/InterpolatedString.php @@ -0,0 +1,34 @@ + $attributes Additional attributes + */ + public function __construct(array $parts, array $attributes = []) { + $this->attributes = $attributes; + $this->parts = $parts; + } + + public function getSubNodeNames(): array { + return ['parts']; + } + + public function getType(): string { + return 'Scalar_InterpolatedString'; + } +} + +// @deprecated compatibility alias +class_alias(InterpolatedString::class, Encapsed::class); diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php new file mode 100644 index 00000000..868d78f8 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php @@ -0,0 +1,15 @@ + $attributes Additional attributes + */ + public function __construct(array $attributes = []) { + $this->attributes = $attributes; + } + + public function getSubNodeNames(): array { + return []; + } + + /** + * Get name of magic constant. + * + * @return string Name of magic constant + */ + abstract public function getName(): string; +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Class_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Class_.php new file mode 100644 index 00000000..732ed140 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Class_.php @@ -0,0 +1,15 @@ + Escaped character to its decoded value */ + protected static array $replacements = [ + '\\' => '\\', + '$' => '$', + 'n' => "\n", + 'r' => "\r", + 't' => "\t", + 'f' => "\f", + 'v' => "\v", + 'e' => "\x1B", + ]; + + /** + * Constructs a string scalar node. + * + * @param string $value Value of the string + * @param array $attributes Additional attributes + */ + public function __construct(string $value, array $attributes = []) { + $this->attributes = $attributes; + $this->value = $value; + } + + public function getSubNodeNames(): array { + return ['value']; + } + + /** + * @param array $attributes + * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes + */ + public static function fromString(string $str, array $attributes = [], bool $parseUnicodeEscape = true): self { + $attributes['kind'] = ($str[0] === "'" || ($str[1] === "'" && ($str[0] === 'b' || $str[0] === 'B'))) + ? Scalar\String_::KIND_SINGLE_QUOTED + : Scalar\String_::KIND_DOUBLE_QUOTED; + + $attributes['rawValue'] = $str; + + $string = self::parse($str, $parseUnicodeEscape); + + return new self($string, $attributes); + } + + /** + * @internal + * + * Parses a string token. + * + * @param string $str String token content + * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes + * + * @return string The parsed string + */ + public static function parse(string $str, bool $parseUnicodeEscape = true): string { + $bLength = 0; + if ('b' === $str[0] || 'B' === $str[0]) { + $bLength = 1; + } + + if ('\'' === $str[$bLength]) { + return str_replace( + ['\\\\', '\\\''], + ['\\', '\''], + substr($str, $bLength + 1, -1) + ); + } else { + return self::parseEscapeSequences( + substr($str, $bLength + 1, -1), '"', $parseUnicodeEscape + ); + } + } + + /** + * @internal + * + * Parses escape sequences in strings (all string types apart from single quoted). + * + * @param string $str String without quotes + * @param null|string $quote Quote type + * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes + * + * @return string String with escape sequences parsed + */ + public static function parseEscapeSequences(string $str, ?string $quote, bool $parseUnicodeEscape = true): string { + if (null !== $quote) { + $str = str_replace('\\' . $quote, $quote, $str); + } + + $extra = ''; + if ($parseUnicodeEscape) { + $extra = '|u\{([0-9a-fA-F]+)\}'; + } + + return preg_replace_callback( + '~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}' . $extra . ')~', + function ($matches) { + $str = $matches[1]; + + if (isset(self::$replacements[$str])) { + return self::$replacements[$str]; + } + if ('x' === $str[0] || 'X' === $str[0]) { + return chr(hexdec(substr($str, 1))); + } + if ('u' === $str[0]) { + $dec = hexdec($matches[2]); + // If it overflowed to float, treat as INT_MAX, it will throw an error anyway. + return self::codePointToUtf8(\is_int($dec) ? $dec : \PHP_INT_MAX); + } else { + return chr(octdec($str) & 255); + } + }, + $str + ); + } + + /** + * Converts a Unicode code point to its UTF-8 encoded representation. + * + * @param int $num Code point + * + * @return string UTF-8 representation of code point + */ + private static function codePointToUtf8(int $num): string { + if ($num <= 0x7F) { + return chr($num); + } + if ($num <= 0x7FF) { + return chr(($num >> 6) + 0xC0) . chr(($num & 0x3F) + 0x80); + } + if ($num <= 0xFFFF) { + return chr(($num >> 12) + 0xE0) . chr((($num >> 6) & 0x3F) + 0x80) . chr(($num & 0x3F) + 0x80); + } + if ($num <= 0x1FFFFF) { + return chr(($num >> 18) + 0xF0) . chr((($num >> 12) & 0x3F) + 0x80) + . chr((($num >> 6) & 0x3F) + 0x80) . chr(($num & 0x3F) + 0x80); + } + throw new Error('Invalid UTF-8 codepoint escape sequence: Codepoint too large'); + } + + public function getType(): string { + return 'Scalar_String'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/StaticVar.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/StaticVar.php new file mode 100644 index 00000000..517c0edd --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/StaticVar.php @@ -0,0 +1,39 @@ + $attributes Additional attributes + */ + public function __construct( + Expr\Variable $var, ?Node\Expr $default = null, array $attributes = [] + ) { + $this->attributes = $attributes; + $this->var = $var; + $this->default = $default; + } + + public function getSubNodeNames(): array { + return ['var', 'default']; + } + + public function getType(): string { + return 'StaticVar'; + } +} + +// @deprecated compatibility alias +class_alias(StaticVar::class, Stmt\StaticVar::class); diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php new file mode 100644 index 00000000..481d31a9 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php @@ -0,0 +1,8 @@ + $attributes Additional attributes + */ + public function __construct(array $stmts, array $attributes = []) { + $this->attributes = $attributes; + $this->stmts = $stmts; + } + + public function getType(): string { + return 'Stmt_Block'; + } + + public function getSubNodeNames(): array { + return ['stmts']; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php new file mode 100644 index 00000000..d2bcc5eb --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(?Node\Expr $num = null, array $attributes = []) { + $this->attributes = $attributes; + $this->num = $num; + } + + public function getSubNodeNames(): array { + return ['num']; + } + + public function getType(): string { + return 'Stmt_Break'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php new file mode 100644 index 00000000..a06ca183 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php @@ -0,0 +1,33 @@ + $attributes Additional attributes + */ + public function __construct(?Node\Expr $cond, array $stmts = [], array $attributes = []) { + $this->attributes = $attributes; + $this->cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames(): array { + return ['cond', 'stmts']; + } + + public function getType(): string { + return 'Stmt_Case'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php new file mode 100644 index 00000000..e8d39c9c --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php @@ -0,0 +1,40 @@ + $attributes Additional attributes + */ + public function __construct( + array $types, ?Expr\Variable $var = null, array $stmts = [], array $attributes = [] + ) { + $this->attributes = $attributes; + $this->types = $types; + $this->var = $var; + $this->stmts = $stmts; + } + + public function getSubNodeNames(): array { + return ['types', 'var', 'stmts']; + } + + public function getType(): string { + return 'Stmt_Catch'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php new file mode 100644 index 00000000..9bdce1f1 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php @@ -0,0 +1,77 @@ + $attributes Additional attributes + * @param list $attrGroups PHP attribute groups + * @param null|Node\Identifier|Node\Name|Node\ComplexType $type Type declaration + */ + public function __construct( + array $consts, + int $flags = 0, + array $attributes = [], + array $attrGroups = [], + ?Node $type = null + ) { + $this->attributes = $attributes; + $this->flags = $flags; + $this->consts = $consts; + $this->attrGroups = $attrGroups; + $this->type = $type; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'flags', 'type', 'consts']; + } + + /** + * Whether constant is explicitly or implicitly public. + */ + public function isPublic(): bool { + return ($this->flags & Modifiers::PUBLIC) !== 0 + || ($this->flags & Modifiers::VISIBILITY_MASK) === 0; + } + + /** + * Whether constant is protected. + */ + public function isProtected(): bool { + return (bool) ($this->flags & Modifiers::PROTECTED); + } + + /** + * Whether constant is private. + */ + public function isPrivate(): bool { + return (bool) ($this->flags & Modifiers::PRIVATE); + } + + /** + * Whether constant is final. + */ + public function isFinal(): bool { + return (bool) ($this->flags & Modifiers::FINAL); + } + + public function getType(): string { + return 'Stmt_ClassConst'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php new file mode 100644 index 00000000..e652177c --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php @@ -0,0 +1,109 @@ + + */ + public function getTraitUses(): array { + $traitUses = []; + foreach ($this->stmts as $stmt) { + if ($stmt instanceof TraitUse) { + $traitUses[] = $stmt; + } + } + return $traitUses; + } + + /** + * @return list + */ + public function getConstants(): array { + $constants = []; + foreach ($this->stmts as $stmt) { + if ($stmt instanceof ClassConst) { + $constants[] = $stmt; + } + } + return $constants; + } + + /** + * @return list + */ + public function getProperties(): array { + $properties = []; + foreach ($this->stmts as $stmt) { + if ($stmt instanceof Property) { + $properties[] = $stmt; + } + } + return $properties; + } + + /** + * Gets property with the given name defined directly in this class/interface/trait. + * + * @param string $name Name of the property + * + * @return Property|null Property node or null if the property does not exist + */ + public function getProperty(string $name): ?Property { + foreach ($this->stmts as $stmt) { + if ($stmt instanceof Property) { + foreach ($stmt->props as $prop) { + if ($prop instanceof PropertyItem && $name === $prop->name->toString()) { + return $stmt; + } + } + } + } + return null; + } + + /** + * Gets all methods defined directly in this class/interface/trait + * + * @return list + */ + public function getMethods(): array { + $methods = []; + foreach ($this->stmts as $stmt) { + if ($stmt instanceof ClassMethod) { + $methods[] = $stmt; + } + } + return $methods; + } + + /** + * Gets method with the given name defined directly in this class/interface/trait. + * + * @param string $name Name of the method (compared case-insensitively) + * + * @return ClassMethod|null Method node or null if the method does not exist + */ + public function getMethod(string $name): ?ClassMethod { + $lowerName = strtolower($name); + foreach ($this->stmts as $stmt) { + if ($stmt instanceof ClassMethod && $lowerName === $stmt->name->toLowerString()) { + return $stmt; + } + } + return null; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php new file mode 100644 index 00000000..59c0519e --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php @@ -0,0 +1,154 @@ + */ + private static array $magicNames = [ + '__construct' => true, + '__destruct' => true, + '__call' => true, + '__callstatic' => true, + '__get' => true, + '__set' => true, + '__isset' => true, + '__unset' => true, + '__sleep' => true, + '__wakeup' => true, + '__tostring' => true, + '__set_state' => true, + '__clone' => true, + '__invoke' => true, + '__debuginfo' => true, + '__serialize' => true, + '__unserialize' => true, + ]; + + /** + * Constructs a class method node. + * + * @param string|Node\Identifier $name Name + * @param array{ + * flags?: int, + * byRef?: bool, + * params?: Node\Param[], + * returnType?: null|Node\Identifier|Node\Name|Node\ComplexType, + * stmts?: Node\Stmt[]|null, + * attrGroups?: Node\AttributeGroup[], + * } $subNodes Array of the following optional subnodes: + * 'flags => 0 : Flags + * 'byRef' => false : Whether to return by reference + * 'params' => array() : Parameters + * 'returnType' => null : Return type + * 'stmts' => array() : Statements + * 'attrGroups' => array() : PHP attribute groups + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = [], array $attributes = []) { + $this->attributes = $attributes; + $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0; + $this->byRef = $subNodes['byRef'] ?? false; + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->params = $subNodes['params'] ?? []; + $this->returnType = $subNodes['returnType'] ?? null; + $this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : []; + $this->attrGroups = $subNodes['attrGroups'] ?? []; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'flags', 'byRef', 'name', 'params', 'returnType', 'stmts']; + } + + public function returnsByRef(): bool { + return $this->byRef; + } + + public function getParams(): array { + return $this->params; + } + + public function getReturnType() { + return $this->returnType; + } + + public function getStmts(): ?array { + return $this->stmts; + } + + public function getAttrGroups(): array { + return $this->attrGroups; + } + + /** + * Whether the method is explicitly or implicitly public. + */ + public function isPublic(): bool { + return ($this->flags & Modifiers::PUBLIC) !== 0 + || ($this->flags & Modifiers::VISIBILITY_MASK) === 0; + } + + /** + * Whether the method is protected. + */ + public function isProtected(): bool { + return (bool) ($this->flags & Modifiers::PROTECTED); + } + + /** + * Whether the method is private. + */ + public function isPrivate(): bool { + return (bool) ($this->flags & Modifiers::PRIVATE); + } + + /** + * Whether the method is abstract. + */ + public function isAbstract(): bool { + return (bool) ($this->flags & Modifiers::ABSTRACT); + } + + /** + * Whether the method is final. + */ + public function isFinal(): bool { + return (bool) ($this->flags & Modifiers::FINAL); + } + + /** + * Whether the method is static. + */ + public function isStatic(): bool { + return (bool) ($this->flags & Modifiers::STATIC); + } + + /** + * Whether the method is magic. + */ + public function isMagic(): bool { + return isset(self::$magicNames[$this->name->toLowerString()]); + } + + public function getType(): string { + return 'Stmt_ClassMethod'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php new file mode 100644 index 00000000..3f492b7b --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php @@ -0,0 +1,94 @@ + 0 : Flags + * 'extends' => null : Name of extended class + * 'implements' => array(): Names of implemented interfaces + * 'stmts' => array(): Statements + * 'attrGroups' => array(): PHP attribute groups + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = [], array $attributes = []) { + $this->attributes = $attributes; + $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0; + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->extends = $subNodes['extends'] ?? null; + $this->implements = $subNodes['implements'] ?? []; + $this->stmts = $subNodes['stmts'] ?? []; + $this->attrGroups = $subNodes['attrGroups'] ?? []; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'flags', 'name', 'extends', 'implements', 'stmts']; + } + + /** + * Whether the class is explicitly abstract. + */ + public function isAbstract(): bool { + return (bool) ($this->flags & Modifiers::ABSTRACT); + } + + /** + * Whether the class is final. + */ + public function isFinal(): bool { + return (bool) ($this->flags & Modifiers::FINAL); + } + + public function isReadonly(): bool { + return (bool) ($this->flags & Modifiers::READONLY); + } + + /** + * Whether the class is anonymous. + */ + public function isAnonymous(): bool { + return null === $this->name; + } + + public function getType(): string { + return 'Stmt_Class'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php new file mode 100644 index 00000000..c54d6780 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php @@ -0,0 +1,37 @@ + $attributes Additional attributes + * @param list $attrGroups PHP attribute groups + */ + public function __construct( + array $consts, + array $attributes = [], + array $attrGroups = [] + ) { + $this->attributes = $attributes; + $this->attrGroups = $attrGroups; + $this->consts = $consts; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'consts']; + } + + public function getType(): string { + return 'Stmt_Const'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php new file mode 100644 index 00000000..54e979dd --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(?Node\Expr $num = null, array $attributes = []) { + $this->attributes = $attributes; + $this->num = $num; + } + + public function getSubNodeNames(): array { + return ['num']; + } + + public function getType(): string { + return 'Stmt_Continue'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php new file mode 100644 index 00000000..c1861343 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php @@ -0,0 +1,17 @@ + $attributes Additional attributes + */ + public function __construct(array $declares, ?array $stmts = null, array $attributes = []) { + $this->attributes = $attributes; + $this->declares = $declares; + $this->stmts = $stmts; + } + + public function getSubNodeNames(): array { + return ['declares', 'stmts']; + } + + public function getType(): string { + return 'Stmt_Declare'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php new file mode 100644 index 00000000..61244428 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php @@ -0,0 +1,33 @@ + $attributes Additional attributes + */ + public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = []) { + $this->attributes = $attributes; + $this->cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames(): array { + return ['stmts', 'cond']; + } + + public function getType(): string { + return 'Stmt_Do'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php new file mode 100644 index 00000000..4d424523 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(array $exprs, array $attributes = []) { + $this->attributes = $attributes; + $this->exprs = $exprs; + } + + public function getSubNodeNames(): array { + return ['exprs']; + } + + public function getType(): string { + return 'Stmt_Echo'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php new file mode 100644 index 00000000..b26d59ce --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php @@ -0,0 +1,33 @@ + $attributes Additional attributes + */ + public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = []) { + $this->attributes = $attributes; + $this->cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames(): array { + return ['cond', 'stmts']; + } + + public function getType(): string { + return 'Stmt_ElseIf'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php new file mode 100644 index 00000000..3d2b066e --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(array $stmts = [], array $attributes = []) { + $this->attributes = $attributes; + $this->stmts = $stmts; + } + + public function getSubNodeNames(): array { + return ['stmts']; + } + + public function getType(): string { + return 'Stmt_Else'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.php new file mode 100644 index 00000000..c071a0af --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.php @@ -0,0 +1,36 @@ + $attrGroups PHP attribute groups + * @param array $attributes Additional attributes + */ + public function __construct($name, ?Node\Expr $expr = null, array $attrGroups = [], array $attributes = []) { + parent::__construct($attributes); + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->expr = $expr; + $this->attrGroups = $attrGroups; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'name', 'expr']; + } + + public function getType(): string { + return 'Stmt_EnumCase'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Enum_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Enum_.php new file mode 100644 index 00000000..7eea6a69 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Enum_.php @@ -0,0 +1,44 @@ + null : Scalar type + * 'implements' => array() : Names of implemented interfaces + * 'stmts' => array() : Statements + * 'attrGroups' => array() : PHP attribute groups + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = [], array $attributes = []) { + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->scalarType = $subNodes['scalarType'] ?? null; + $this->implements = $subNodes['implements'] ?? []; + $this->stmts = $subNodes['stmts'] ?? []; + $this->attrGroups = $subNodes['attrGroups'] ?? []; + + parent::__construct($attributes); + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'name', 'scalarType', 'implements', 'stmts']; + } + + public function getType(): string { + return 'Stmt_Enum'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php new file mode 100644 index 00000000..89751fa2 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php @@ -0,0 +1,32 @@ + $attributes Additional attributes + */ + public function __construct(Node\Expr $expr, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Stmt_Expression'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php new file mode 100644 index 00000000..69ecf253 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(array $stmts = [], array $attributes = []) { + $this->attributes = $attributes; + $this->stmts = $stmts; + } + + public function getSubNodeNames(): array { + return ['stmts']; + } + + public function getType(): string { + return 'Stmt_Finally'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php new file mode 100644 index 00000000..6f2fbb9e --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php @@ -0,0 +1,47 @@ + array(): Init expressions + * 'cond' => array(): Loop conditions + * 'loop' => array(): Loop expressions + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct(array $subNodes = [], array $attributes = []) { + $this->attributes = $attributes; + $this->init = $subNodes['init'] ?? []; + $this->cond = $subNodes['cond'] ?? []; + $this->loop = $subNodes['loop'] ?? []; + $this->stmts = $subNodes['stmts'] ?? []; + } + + public function getSubNodeNames(): array { + return ['init', 'cond', 'loop', 'stmts']; + } + + public function getType(): string { + return 'Stmt_For'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php new file mode 100644 index 00000000..c5d9a8b1 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php @@ -0,0 +1,50 @@ + null : Variable to assign key to + * 'byRef' => false : Whether to assign value by reference + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = [], array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + $this->keyVar = $subNodes['keyVar'] ?? null; + $this->byRef = $subNodes['byRef'] ?? false; + $this->valueVar = $valueVar; + $this->stmts = $subNodes['stmts'] ?? []; + } + + public function getSubNodeNames(): array { + return ['expr', 'keyVar', 'byRef', 'valueVar', 'stmts']; + } + + public function getType(): string { + return 'Stmt_Foreach'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php new file mode 100644 index 00000000..2111bab7 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php @@ -0,0 +1,81 @@ + false : Whether to return by reference + * 'params' => array(): Parameters + * 'returnType' => null : Return type + * 'stmts' => array(): Statements + * 'attrGroups' => array(): PHP attribute groups + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = [], array $attributes = []) { + $this->attributes = $attributes; + $this->byRef = $subNodes['byRef'] ?? false; + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->params = $subNodes['params'] ?? []; + $this->returnType = $subNodes['returnType'] ?? null; + $this->stmts = $subNodes['stmts'] ?? []; + $this->attrGroups = $subNodes['attrGroups'] ?? []; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'byRef', 'name', 'params', 'returnType', 'stmts']; + } + + public function returnsByRef(): bool { + return $this->byRef; + } + + public function getParams(): array { + return $this->params; + } + + public function getReturnType() { + return $this->returnType; + } + + public function getAttrGroups(): array { + return $this->attrGroups; + } + + /** @return Node\Stmt[] */ + public function getStmts(): array { + return $this->stmts; + } + + public function getType(): string { + return 'Stmt_Function'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php new file mode 100644 index 00000000..d3ab12fc --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(array $vars, array $attributes = []) { + $this->attributes = $attributes; + $this->vars = $vars; + } + + public function getSubNodeNames(): array { + return ['vars']; + } + + public function getType(): string { + return 'Stmt_Global'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php new file mode 100644 index 00000000..26a0d01e --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php @@ -0,0 +1,30 @@ + $attributes Additional attributes + */ + public function __construct($name, array $attributes = []) { + $this->attributes = $attributes; + $this->name = \is_string($name) ? new Identifier($name) : $name; + } + + public function getSubNodeNames(): array { + return ['name']; + } + + public function getType(): string { + return 'Stmt_Goto'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php new file mode 100644 index 00000000..0ec8e9d4 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php @@ -0,0 +1,41 @@ + $attributes Additional attributes + */ + public function __construct(Name $prefix, array $uses, int $type = Use_::TYPE_NORMAL, array $attributes = []) { + $this->attributes = $attributes; + $this->type = $type; + $this->prefix = $prefix; + $this->uses = $uses; + } + + public function getSubNodeNames(): array { + return ['type', 'prefix', 'uses']; + } + + public function getType(): string { + return 'Stmt_GroupUse'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php new file mode 100644 index 00000000..665bacde --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(string $remaining, array $attributes = []) { + $this->attributes = $attributes; + $this->remaining = $remaining; + } + + public function getSubNodeNames(): array { + return ['remaining']; + } + + public function getType(): string { + return 'Stmt_HaltCompiler'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php new file mode 100644 index 00000000..544390ff --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php @@ -0,0 +1,46 @@ + array(): Statements + * 'elseifs' => array(): Elseif clauses + * 'else' => null : Else clause + * @param array $attributes Additional attributes + */ + public function __construct(Node\Expr $cond, array $subNodes = [], array $attributes = []) { + $this->attributes = $attributes; + $this->cond = $cond; + $this->stmts = $subNodes['stmts'] ?? []; + $this->elseifs = $subNodes['elseifs'] ?? []; + $this->else = $subNodes['else'] ?? null; + } + + public function getSubNodeNames(): array { + return ['cond', 'stmts', 'elseifs', 'else']; + } + + public function getType(): string { + return 'Stmt_If'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php new file mode 100644 index 00000000..0515d020 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(string $value, array $attributes = []) { + $this->attributes = $attributes; + $this->value = $value; + } + + public function getSubNodeNames(): array { + return ['value']; + } + + public function getType(): string { + return 'Stmt_InlineHTML'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php new file mode 100644 index 00000000..9359064f --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php @@ -0,0 +1,40 @@ + array(): Name of extended interfaces + * 'stmts' => array(): Statements + * 'attrGroups' => array(): PHP attribute groups + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = [], array $attributes = []) { + $this->attributes = $attributes; + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->extends = $subNodes['extends'] ?? []; + $this->stmts = $subNodes['stmts'] ?? []; + $this->attrGroups = $subNodes['attrGroups'] ?? []; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'name', 'extends', 'stmts']; + } + + public function getType(): string { + return 'Stmt_Interface'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php new file mode 100644 index 00000000..658468d2 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php @@ -0,0 +1,30 @@ + $attributes Additional attributes + */ + public function __construct($name, array $attributes = []) { + $this->attributes = $attributes; + $this->name = \is_string($name) ? new Identifier($name) : $name; + } + + public function getSubNodeNames(): array { + return ['name']; + } + + public function getType(): string { + return 'Stmt_Label'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php new file mode 100644 index 00000000..f5b59ad6 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php @@ -0,0 +1,37 @@ + $attributes Additional attributes + */ + public function __construct(?Node\Name $name = null, ?array $stmts = [], array $attributes = []) { + $this->attributes = $attributes; + $this->name = $name; + $this->stmts = $stmts; + } + + public function getSubNodeNames(): array { + return ['name', 'stmts']; + } + + public function getType(): string { + return 'Stmt_Namespace'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php new file mode 100644 index 00000000..3acfa46f --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php @@ -0,0 +1,16 @@ + $attributes Additional attributes + * @param null|Identifier|Name|ComplexType $type Type declaration + * @param Node\AttributeGroup[] $attrGroups PHP attribute groups + * @param Node\PropertyHook[] $hooks Property hooks + */ + public function __construct(int $flags, array $props, array $attributes = [], ?Node $type = null, array $attrGroups = [], array $hooks = []) { + $this->attributes = $attributes; + $this->flags = $flags; + $this->props = $props; + $this->type = $type; + $this->attrGroups = $attrGroups; + $this->hooks = $hooks; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'flags', 'type', 'props', 'hooks']; + } + + /** + * Whether the property is explicitly or implicitly public. + */ + public function isPublic(): bool { + return ($this->flags & Modifiers::PUBLIC) !== 0 + || ($this->flags & Modifiers::VISIBILITY_MASK) === 0; + } + + /** + * Whether the property is protected. + */ + public function isProtected(): bool { + return (bool) ($this->flags & Modifiers::PROTECTED); + } + + /** + * Whether the property is private. + */ + public function isPrivate(): bool { + return (bool) ($this->flags & Modifiers::PRIVATE); + } + + /** + * Whether the property is static. + */ + public function isStatic(): bool { + return (bool) ($this->flags & Modifiers::STATIC); + } + + /** + * Whether the property is readonly. + */ + public function isReadonly(): bool { + return (bool) ($this->flags & Modifiers::READONLY); + } + + /** + * Whether the property is abstract. + */ + public function isAbstract(): bool { + return (bool) ($this->flags & Modifiers::ABSTRACT); + } + + /** + * Whether the property is final. + */ + public function isFinal(): bool { + return (bool) ($this->flags & Modifiers::FINAL); + } + + /** + * Whether the property has explicit public(set) visibility. + */ + public function isPublicSet(): bool { + return (bool) ($this->flags & Modifiers::PUBLIC_SET); + } + + /** + * Whether the property has explicit protected(set) visibility. + */ + public function isProtectedSet(): bool { + return (bool) ($this->flags & Modifiers::PROTECTED_SET); + } + + /** + * Whether the property has explicit private(set) visibility. + */ + public function isPrivateSet(): bool { + return (bool) ($this->flags & Modifiers::PRIVATE_SET); + } + + public function getType(): string { + return 'Stmt_Property'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php new file mode 100644 index 00000000..62556e70 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php @@ -0,0 +1,17 @@ + $attributes Additional attributes + */ + public function __construct(?Node\Expr $expr = null, array $attributes = []) { + $this->attributes = $attributes; + $this->expr = $expr; + } + + public function getSubNodeNames(): array { + return ['expr']; + } + + public function getType(): string { + return 'Stmt_Return'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php new file mode 100644 index 00000000..a3c5fa6e --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php @@ -0,0 +1,15 @@ + $attributes Additional attributes + */ + public function __construct(array $vars, array $attributes = []) { + $this->attributes = $attributes; + $this->vars = $vars; + } + + public function getSubNodeNames(): array { + return ['vars']; + } + + public function getType(): string { + return 'Stmt_Static'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php new file mode 100644 index 00000000..21e5efa5 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php @@ -0,0 +1,33 @@ + $attributes Additional attributes + */ + public function __construct(Node\Expr $cond, array $cases, array $attributes = []) { + $this->attributes = $attributes; + $this->cond = $cond; + $this->cases = $cases; + } + + public function getSubNodeNames(): array { + return ['cond', 'cases']; + } + + public function getType(): string { + return 'Stmt_Switch'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php new file mode 100644 index 00000000..7705a570 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php @@ -0,0 +1,33 @@ + $attributes Additional attributes + */ + public function __construct(array $traits, array $adaptations = [], array $attributes = []) { + $this->attributes = $attributes; + $this->traits = $traits; + $this->adaptations = $adaptations; + } + + public function getSubNodeNames(): array { + return ['traits', 'adaptations']; + } + + public function getType(): string { + return 'Stmt_TraitUse'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php new file mode 100644 index 00000000..987bc88e --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php @@ -0,0 +1,12 @@ + $attributes Additional attributes + */ + public function __construct(?Node\Name $trait, $method, ?int $newModifier, $newName, array $attributes = []) { + $this->attributes = $attributes; + $this->trait = $trait; + $this->method = \is_string($method) ? new Node\Identifier($method) : $method; + $this->newModifier = $newModifier; + $this->newName = \is_string($newName) ? new Node\Identifier($newName) : $newName; + } + + public function getSubNodeNames(): array { + return ['trait', 'method', 'newModifier', 'newName']; + } + + public function getType(): string { + return 'Stmt_TraitUseAdaptation_Alias'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php new file mode 100644 index 00000000..7bc40837 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php @@ -0,0 +1,33 @@ + $attributes Additional attributes + */ + public function __construct(Node\Name $trait, $method, array $insteadof, array $attributes = []) { + $this->attributes = $attributes; + $this->trait = $trait; + $this->method = \is_string($method) ? new Node\Identifier($method) : $method; + $this->insteadof = $insteadof; + } + + public function getSubNodeNames(): array { + return ['trait', 'method', 'insteadof']; + } + + public function getType(): string { + return 'Stmt_TraitUseAdaptation_Precedence'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php new file mode 100644 index 00000000..5f2b3307 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php @@ -0,0 +1,34 @@ + array(): Statements + * 'attrGroups' => array(): PHP attribute groups + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = [], array $attributes = []) { + $this->attributes = $attributes; + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->stmts = $subNodes['stmts'] ?? []; + $this->attrGroups = $subNodes['attrGroups'] ?? []; + } + + public function getSubNodeNames(): array { + return ['attrGroups', 'name', 'stmts']; + } + + public function getType(): string { + return 'Stmt_Trait'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php new file mode 100644 index 00000000..6414c46c --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php @@ -0,0 +1,37 @@ + $attributes Additional attributes + */ + public function __construct(array $stmts, array $catches, ?Finally_ $finally = null, array $attributes = []) { + $this->attributes = $attributes; + $this->stmts = $stmts; + $this->catches = $catches; + $this->finally = $finally; + } + + public function getSubNodeNames(): array { + return ['stmts', 'catches', 'finally']; + } + + public function getType(): string { + return 'Stmt_TryCatch'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php new file mode 100644 index 00000000..c211beb0 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php @@ -0,0 +1,29 @@ + $attributes Additional attributes + */ + public function __construct(array $vars, array $attributes = []) { + $this->attributes = $attributes; + $this->vars = $vars; + } + + public function getSubNodeNames(): array { + return ['vars']; + } + + public function getType(): string { + return 'Stmt_Unset'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php new file mode 100644 index 00000000..9e504f89 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php @@ -0,0 +1,17 @@ + $attributes Additional attributes + */ + public function __construct(array $uses, int $type = self::TYPE_NORMAL, array $attributes = []) { + $this->attributes = $attributes; + $this->type = $type; + $this->uses = $uses; + } + + public function getSubNodeNames(): array { + return ['type', 'uses']; + } + + public function getType(): string { + return 'Stmt_Use'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php new file mode 100644 index 00000000..2f7aed23 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php @@ -0,0 +1,33 @@ + $attributes Additional attributes + */ + public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = []) { + $this->attributes = $attributes; + $this->cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames(): array { + return ['cond', 'stmts']; + } + + public function getType(): string { + return 'Stmt_While'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/UnionType.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/UnionType.php new file mode 100644 index 00000000..bad88d2b --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/UnionType.php @@ -0,0 +1,27 @@ + $attributes Additional attributes + */ + public function __construct(array $types, array $attributes = []) { + $this->attributes = $attributes; + $this->types = $types; + } + + public function getSubNodeNames(): array { + return ['types']; + } + + public function getType(): string { + return 'UnionType'; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/UseItem.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/UseItem.php new file mode 100644 index 00000000..a7d9fc44 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/UseItem.php @@ -0,0 +1,55 @@ + $attributes Additional attributes + */ + public function __construct(Node\Name $name, $alias = null, int $type = Use_::TYPE_UNKNOWN, array $attributes = []) { + $this->attributes = $attributes; + $this->type = $type; + $this->name = $name; + $this->alias = \is_string($alias) ? new Identifier($alias) : $alias; + } + + public function getSubNodeNames(): array { + return ['type', 'name', 'alias']; + } + + /** + * Get alias. If not explicitly given this is the last component of the used name. + */ + public function getAlias(): Identifier { + if (null !== $this->alias) { + return $this->alias; + } + + return new Identifier($this->name->getLast()); + } + + public function getType(): string { + return 'UseItem'; + } +} + +// @deprecated compatibility alias +class_alias(UseItem::class, Stmt\UseUse::class); diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php new file mode 100644 index 00000000..9baa6fe0 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php @@ -0,0 +1,16 @@ + $attributes Additional attributes + */ + public function __construct(array $attributes = []) { + $this->attributes = $attributes; + } + + public function getType(): string { + return 'VariadicPlaceholder'; + } + + public function getSubNodeNames(): array { + return []; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeAbstract.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeAbstract.php new file mode 100644 index 00000000..a6a50aea --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeAbstract.php @@ -0,0 +1,181 @@ + Attributes */ + protected array $attributes; + + /** + * Creates a Node. + * + * @param array $attributes Array of attributes + */ + public function __construct(array $attributes = []) { + $this->attributes = $attributes; + } + + /** + * Gets line the node started in (alias of getStartLine). + * + * @return int Start line (or -1 if not available) + * @phpstan-return -1|positive-int + */ + public function getLine(): int { + return $this->attributes['startLine'] ?? -1; + } + + /** + * 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 { + return $this->attributes['startLine'] ?? -1; + } + + /** + * 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 { + return $this->attributes['endLine'] ?? -1; + } + + /** + * 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 { + return $this->attributes['startTokenPos'] ?? -1; + } + + /** + * 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 { + return $this->attributes['endTokenPos'] ?? -1; + } + + /** + * 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 { + return $this->attributes['startFilePos'] ?? -1; + } + + /** + * 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 { + return $this->attributes['endFilePos'] ?? -1; + } + + /** + * Gets all comments directly preceding this node. + * + * The comments are also available through the "comments" attribute. + * + * @return Comment[] + */ + public function getComments(): array { + return $this->attributes['comments'] ?? []; + } + + /** + * Gets the doc comment of the node. + * + * @return null|Comment\Doc Doc comment object or null + */ + public function getDocComment(): ?Comment\Doc { + $comments = $this->getComments(); + for ($i = count($comments) - 1; $i >= 0; $i--) { + $comment = $comments[$i]; + if ($comment instanceof Comment\Doc) { + return $comment; + } + } + + return null; + } + + /** + * 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 { + $comments = $this->getComments(); + for ($i = count($comments) - 1; $i >= 0; $i--) { + if ($comments[$i] instanceof Comment\Doc) { + // Replace existing doc comment. + $comments[$i] = $docComment; + $this->setAttribute('comments', $comments); + return; + } + } + + // Append new doc comment. + $comments[] = $docComment; + $this->setAttribute('comments', $comments); + } + + public function setAttribute(string $key, $value): void { + $this->attributes[$key] = $value; + } + + public function hasAttribute(string $key): bool { + return array_key_exists($key, $this->attributes); + } + + public function getAttribute(string $key, $default = null) { + if (array_key_exists($key, $this->attributes)) { + return $this->attributes[$key]; + } + + return $default; + } + + public function getAttributes(): array { + return $this->attributes; + } + + public function setAttributes(array $attributes): void { + $this->attributes = $attributes; + } + + /** + * @return array + */ + public function jsonSerialize(): array { + return ['nodeType' => $this->getType()] + get_object_vars($this); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php new file mode 100644 index 00000000..7d62d038 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php @@ -0,0 +1,299 @@ + true, + 'startLine' => true, + 'endLine' => true, + 'startFilePos' => true, + 'endFilePos' => true, + 'startTokenPos' => true, + 'endTokenPos' => true, + ]; + + /** + * Constructs a NodeDumper. + * + * Supported options: + * * bool dumpComments: Whether comments should be dumped. + * * bool dumpPositions: Whether line/offset information should be dumped. To dump offset + * information, the code needs to be passed to dump(). + * * bool dumpOtherAttributes: Whether non-comment, non-position attributes should be dumped. + * + * @param array $options Options (see description) + */ + public function __construct(array $options = []) { + $this->dumpComments = !empty($options['dumpComments']); + $this->dumpPositions = !empty($options['dumpPositions']); + $this->dumpOtherAttributes = !empty($options['dumpOtherAttributes']); + } + + /** + * Dumps a node or array. + * + * @param array|Node $node Node or array to dump + * @param string|null $code Code corresponding to dumped AST. This only needs to be passed if + * the dumpPositions option is enabled and the dumping of node offsets + * is desired. + * + * @return string Dumped value + */ + public function dump($node, ?string $code = null): string { + $this->code = $code; + $this->res = ''; + $this->nl = "\n"; + $this->dumpRecursive($node, false); + return $this->res; + } + + /** @param mixed $node */ + protected function dumpRecursive($node, bool $indent = true): void { + if ($indent) { + $this->nl .= " "; + } + if ($node instanceof Node) { + $this->res .= $node->getType(); + if ($this->dumpPositions && null !== $p = $this->dumpPosition($node)) { + $this->res .= $p; + } + $this->res .= '('; + + foreach ($node->getSubNodeNames() as $key) { + $this->res .= "$this->nl " . $key . ': '; + + $value = $node->$key; + if (\is_int($value)) { + if ('flags' === $key || 'newModifier' === $key) { + $this->res .= $this->dumpFlags($value); + continue; + } + if ('type' === $key && $node instanceof Include_) { + $this->res .= $this->dumpIncludeType($value); + continue; + } + if ('type' === $key + && ($node instanceof Use_ || $node instanceof UseItem || $node instanceof GroupUse)) { + $this->res .= $this->dumpUseType($value); + continue; + } + } + $this->dumpRecursive($value); + } + + if ($this->dumpComments && $comments = $node->getComments()) { + $this->res .= "$this->nl comments: "; + $this->dumpRecursive($comments); + } + + if ($this->dumpOtherAttributes) { + foreach ($node->getAttributes() as $key => $value) { + if (isset(self::IGNORE_ATTRIBUTES[$key])) { + continue; + } + + $this->res .= "$this->nl $key: "; + if (\is_int($value)) { + if ('kind' === $key) { + if ($node instanceof Int_) { + $this->res .= $this->dumpIntKind($value); + continue; + } + if ($node instanceof String_ || $node instanceof InterpolatedString) { + $this->res .= $this->dumpStringKind($value); + continue; + } + if ($node instanceof Array_) { + $this->res .= $this->dumpArrayKind($value); + continue; + } + if ($node instanceof List_) { + $this->res .= $this->dumpListKind($value); + continue; + } + } + } + $this->dumpRecursive($value); + } + } + $this->res .= "$this->nl)"; + } elseif (\is_array($node)) { + $this->res .= 'array('; + foreach ($node as $key => $value) { + $this->res .= "$this->nl " . $key . ': '; + $this->dumpRecursive($value); + } + $this->res .= "$this->nl)"; + } elseif ($node instanceof Comment) { + $this->res .= \str_replace("\n", $this->nl, $node->getReformattedText()); + } elseif (\is_string($node)) { + $this->res .= \str_replace("\n", $this->nl, $node); + } elseif (\is_int($node) || \is_float($node)) { + $this->res .= $node; + } elseif (null === $node) { + $this->res .= 'null'; + } elseif (false === $node) { + $this->res .= 'false'; + } elseif (true === $node) { + $this->res .= 'true'; + } else { + throw new \InvalidArgumentException('Can only dump nodes and arrays.'); + } + if ($indent) { + $this->nl = \substr($this->nl, 0, -4); + } + } + + protected function dumpFlags(int $flags): string { + $strs = []; + if ($flags & Modifiers::PUBLIC) { + $strs[] = 'PUBLIC'; + } + if ($flags & Modifiers::PROTECTED) { + $strs[] = 'PROTECTED'; + } + if ($flags & Modifiers::PRIVATE) { + $strs[] = 'PRIVATE'; + } + if ($flags & Modifiers::ABSTRACT) { + $strs[] = 'ABSTRACT'; + } + if ($flags & Modifiers::STATIC) { + $strs[] = 'STATIC'; + } + if ($flags & Modifiers::FINAL) { + $strs[] = 'FINAL'; + } + if ($flags & Modifiers::READONLY) { + $strs[] = 'READONLY'; + } + if ($flags & Modifiers::PUBLIC_SET) { + $strs[] = 'PUBLIC_SET'; + } + if ($flags & Modifiers::PROTECTED_SET) { + $strs[] = 'PROTECTED_SET'; + } + if ($flags & Modifiers::PRIVATE_SET) { + $strs[] = 'PRIVATE_SET'; + } + + if ($strs) { + return implode(' | ', $strs) . ' (' . $flags . ')'; + } else { + return (string) $flags; + } + } + + /** @param array $map */ + private function dumpEnum(int $value, array $map): string { + if (!isset($map[$value])) { + return (string) $value; + } + return $map[$value] . ' (' . $value . ')'; + } + + private function dumpIncludeType(int $type): string { + return $this->dumpEnum($type, [ + Include_::TYPE_INCLUDE => 'TYPE_INCLUDE', + Include_::TYPE_INCLUDE_ONCE => 'TYPE_INCLUDE_ONCE', + Include_::TYPE_REQUIRE => 'TYPE_REQUIRE', + Include_::TYPE_REQUIRE_ONCE => 'TYPE_REQUIRE_ONCE', + ]); + } + + private function dumpUseType(int $type): string { + return $this->dumpEnum($type, [ + Use_::TYPE_UNKNOWN => 'TYPE_UNKNOWN', + Use_::TYPE_NORMAL => 'TYPE_NORMAL', + Use_::TYPE_FUNCTION => 'TYPE_FUNCTION', + Use_::TYPE_CONSTANT => 'TYPE_CONSTANT', + ]); + } + + private function dumpIntKind(int $kind): string { + return $this->dumpEnum($kind, [ + Int_::KIND_BIN => 'KIND_BIN', + Int_::KIND_OCT => 'KIND_OCT', + Int_::KIND_DEC => 'KIND_DEC', + Int_::KIND_HEX => 'KIND_HEX', + ]); + } + + private function dumpStringKind(int $kind): string { + return $this->dumpEnum($kind, [ + String_::KIND_SINGLE_QUOTED => 'KIND_SINGLE_QUOTED', + String_::KIND_DOUBLE_QUOTED => 'KIND_DOUBLE_QUOTED', + String_::KIND_HEREDOC => 'KIND_HEREDOC', + String_::KIND_NOWDOC => 'KIND_NOWDOC', + ]); + } + + private function dumpArrayKind(int $kind): string { + return $this->dumpEnum($kind, [ + Array_::KIND_LONG => 'KIND_LONG', + Array_::KIND_SHORT => 'KIND_SHORT', + ]); + } + + private function dumpListKind(int $kind): string { + return $this->dumpEnum($kind, [ + List_::KIND_LIST => 'KIND_LIST', + List_::KIND_ARRAY => 'KIND_ARRAY', + ]); + } + + /** + * Dump node position, if possible. + * + * @param Node $node Node for which to dump position + * + * @return string|null Dump of position, or null if position information not available + */ + protected function dumpPosition(Node $node): ?string { + if (!$node->hasAttribute('startLine') || !$node->hasAttribute('endLine')) { + return null; + } + + $start = $node->getStartLine(); + $end = $node->getEndLine(); + if ($node->hasAttribute('startFilePos') && $node->hasAttribute('endFilePos') + && null !== $this->code + ) { + $start .= ':' . $this->toColumn($this->code, $node->getStartFilePos()); + $end .= ':' . $this->toColumn($this->code, $node->getEndFilePos()); + } + return "[$start - $end]"; + } + + // Copied from Error class + 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; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php new file mode 100644 index 00000000..96c84526 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php @@ -0,0 +1,90 @@ +traverse($nodes); + + return $visitor->getFoundNodes(); + } + + /** + * Find all nodes that are instances of a certain class. + + * @template TNode as Node + * + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param class-string $class Class name + * + * @return TNode[] Found nodes (all instances of $class) + */ + public function findInstanceOf($nodes, string $class): array { + return $this->find($nodes, function ($node) use ($class) { + return $node instanceof $class; + }); + } + + /** + * Find first node satisfying a filter callback. + * + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param callable $filter Filter callback: function(Node $node) : bool + * + * @return null|Node Found node (or null if none found) + */ + public function findFirst($nodes, callable $filter): ?Node { + if ($nodes === []) { + return null; + } + + if (!is_array($nodes)) { + $nodes = [$nodes]; + } + + $visitor = new FirstFindingVisitor($filter); + + $traverser = new NodeTraverser($visitor); + $traverser->traverse($nodes); + + return $visitor->getFoundNode(); + } + + /** + * Find first node that is an instance of a certain class. + * + * @template TNode as Node + * + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param class-string $class Class name + * + * @return null|TNode Found node, which is an instance of $class (or null if none found) + */ + public function findFirstInstanceOf($nodes, string $class): ?Node { + return $this->findFirst($nodes, function ($node) use ($class) { + return $node instanceof $class; + }); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php new file mode 100644 index 00000000..6a5c2ad7 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php @@ -0,0 +1,287 @@ + Visitors */ + protected array $visitors = []; + + /** @var bool Whether traversal should be stopped */ + protected bool $stopTraversal; + + /** + * Create a traverser with the given visitors. + * + * @param NodeVisitor ...$visitors Node visitors + */ + public function __construct(NodeVisitor ...$visitors) { + $this->visitors = $visitors; + } + + /** + * Adds a visitor. + * + * @param NodeVisitor $visitor Visitor to add + */ + public function addVisitor(NodeVisitor $visitor): void { + $this->visitors[] = $visitor; + } + + /** + * Removes an added visitor. + */ + public function removeVisitor(NodeVisitor $visitor): void { + $index = array_search($visitor, $this->visitors); + if ($index !== false) { + array_splice($this->visitors, $index, 1, []); + } + } + + /** + * Traverses an array of nodes using the registered visitors. + * + * @param Node[] $nodes Array of nodes + * + * @return Node[] Traversed array of nodes + */ + public function traverse(array $nodes): array { + $this->stopTraversal = false; + + foreach ($this->visitors as $visitor) { + if (null !== $return = $visitor->beforeTraverse($nodes)) { + $nodes = $return; + } + } + + $nodes = $this->traverseArray($nodes); + + for ($i = \count($this->visitors) - 1; $i >= 0; --$i) { + $visitor = $this->visitors[$i]; + if (null !== $return = $visitor->afterTraverse($nodes)) { + $nodes = $return; + } + } + + return $nodes; + } + + /** + * Recursively traverse a node. + * + * @param Node $node Node to traverse. + */ + protected function traverseNode(Node $node): void { + foreach ($node->getSubNodeNames() as $name) { + $subNode = $node->$name; + + if (\is_array($subNode)) { + $node->$name = $this->traverseArray($subNode); + if ($this->stopTraversal) { + break; + } + + continue; + } + + if (!$subNode instanceof Node) { + continue; + } + + $traverseChildren = true; + $visitorIndex = -1; + + foreach ($this->visitors as $visitorIndex => $visitor) { + $return = $visitor->enterNode($subNode); + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($subNode, $return); + $subNode = $node->$name = $return; + } elseif (NodeVisitor::DONT_TRAVERSE_CHILDREN === $return) { + $traverseChildren = false; + } elseif (NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) { + $traverseChildren = false; + break; + } elseif (NodeVisitor::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) { + $node->$name = null; + continue 2; + } else { + throw new \LogicException( + 'enterNode() returned invalid value of type ' . gettype($return) + ); + } + } + } + + if ($traverseChildren) { + $this->traverseNode($subNode); + if ($this->stopTraversal) { + break; + } + } + + for (; $visitorIndex >= 0; --$visitorIndex) { + $visitor = $this->visitors[$visitorIndex]; + $return = $visitor->leaveNode($subNode); + + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($subNode, $return); + $subNode = $node->$name = $return; + } elseif (NodeVisitor::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) { + $node->$name = null; + break; + } elseif (\is_array($return)) { + throw new \LogicException( + 'leaveNode() may only return an array ' . + 'if the parent structure is an array' + ); + } else { + throw new \LogicException( + 'leaveNode() returned invalid value of type ' . gettype($return) + ); + } + } + } + } + } + + /** + * Recursively traverse array (usually of nodes). + * + * @param Node[] $nodes Array to traverse + * + * @return Node[] Result of traversal (may be original array or changed one) + */ + protected function traverseArray(array $nodes): array { + $doNodes = []; + + foreach ($nodes as $i => $node) { + if (!$node instanceof Node) { + if (\is_array($node)) { + throw new \LogicException('Invalid node structure: Contains nested arrays'); + } + continue; + } + + $traverseChildren = true; + $visitorIndex = -1; + + foreach ($this->visitors as $visitorIndex => $visitor) { + $return = $visitor->enterNode($node); + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($node, $return); + $nodes[$i] = $node = $return; + } elseif (\is_array($return)) { + $doNodes[] = [$i, $return]; + continue 2; + } elseif (NodeVisitor::REMOVE_NODE === $return) { + $doNodes[] = [$i, []]; + continue 2; + } elseif (NodeVisitor::DONT_TRAVERSE_CHILDREN === $return) { + $traverseChildren = false; + } elseif (NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) { + $traverseChildren = false; + break; + } elseif (NodeVisitor::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) { + throw new \LogicException( + 'REPLACE_WITH_NULL can not be used if the parent structure is an array'); + } else { + throw new \LogicException( + 'enterNode() returned invalid value of type ' . gettype($return) + ); + } + } + } + + if ($traverseChildren) { + $this->traverseNode($node); + if ($this->stopTraversal) { + break; + } + } + + for (; $visitorIndex >= 0; --$visitorIndex) { + $visitor = $this->visitors[$visitorIndex]; + $return = $visitor->leaveNode($node); + + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($node, $return); + $nodes[$i] = $node = $return; + } elseif (\is_array($return)) { + $doNodes[] = [$i, $return]; + break; + } elseif (NodeVisitor::REMOVE_NODE === $return) { + $doNodes[] = [$i, []]; + break; + } elseif (NodeVisitor::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } elseif (NodeVisitor::REPLACE_WITH_NULL === $return) { + throw new \LogicException( + 'REPLACE_WITH_NULL can not be used if the parent structure is an array'); + } else { + throw new \LogicException( + 'leaveNode() returned invalid value of type ' . gettype($return) + ); + } + } + } + } + + if (!empty($doNodes)) { + while (list($i, $replace) = array_pop($doNodes)) { + array_splice($nodes, $i, 1, $replace); + } + } + + return $nodes; + } + + private function ensureReplacementReasonable(Node $old, Node $new): void { + if ($old instanceof Node\Stmt && $new instanceof Node\Expr) { + throw new \LogicException( + "Trying to replace statement ({$old->getType()}) " . + "with expression ({$new->getType()}). Are you missing a " . + "Stmt_Expression wrapper?" + ); + } + + if ($old instanceof Node\Expr && $new instanceof Node\Stmt) { + throw new \LogicException( + "Trying to replace expression ({$old->getType()}) " . + "with statement ({$new->getType()})" + ); + } + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php new file mode 100644 index 00000000..c3992b3d --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php @@ -0,0 +1,26 @@ + $node stays as-is + * * array (of Nodes) + * => The return value is merged into the parent array (at the position of the $node) + * * NodeVisitor::REMOVE_NODE + * => $node is removed from the parent array + * * NodeVisitor::REPLACE_WITH_NULL + * => $node is replaced with null + * * NodeVisitor::DONT_TRAVERSE_CHILDREN + * => Children of $node are not traversed. $node stays as-is + * * NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN + * => Further visitors for the current node are skipped, and its children are not + * traversed. $node stays as-is. + * * NodeVisitor::STOP_TRAVERSAL + * => Traversal is aborted. $node stays as-is + * * otherwise + * => $node is set to the return value + * + * @param Node $node Node + * + * @return null|int|Node|Node[] Replacement node (or special return value) + */ + public function enterNode(Node $node); + + /** + * Called when leaving a node. + * + * Return value semantics: + * * null + * => $node stays as-is + * * NodeVisitor::REMOVE_NODE + * => $node is removed from the parent array + * * NodeVisitor::REPLACE_WITH_NULL + * => $node is replaced with null + * * NodeVisitor::STOP_TRAVERSAL + * => Traversal is aborted. $node stays as-is + * * array (of Nodes) + * => The return value is merged into the parent array (at the position of the $node) + * * otherwise + * => $node is set to the return value + * + * @param Node $node Node + * + * @return null|int|Node|Node[] Replacement node (or special return value) + */ + public function leaveNode(Node $node); + + /** + * Called once after traversal. + * + * Return value semantics: + * * null: $nodes stays as-is + * * otherwise: $nodes is set to the return value + * + * @param Node[] $nodes Array of nodes + * + * @return null|Node[] Array of nodes + */ + public function afterTraverse(array $nodes); +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CloningVisitor.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CloningVisitor.php new file mode 100644 index 00000000..cba92499 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CloningVisitor.php @@ -0,0 +1,19 @@ +setAttribute('origNode', $origNode); + return $node; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php new file mode 100644 index 00000000..5e2aed31 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php @@ -0,0 +1,82 @@ + Token positions of comments */ + private array $commentPositions = []; + + /** + * Create a comment annotation visitor. + * + * @param Token[] $tokens Token array + */ + public function __construct(array $tokens) { + $this->tokens = $tokens; + + // Collect positions of comments. We use this to avoid traversing parts of the AST where + // there are no comments. + foreach ($tokens as $i => $token) { + if ($token->id === \T_COMMENT || $token->id === \T_DOC_COMMENT) { + $this->commentPositions[] = $i; + } + } + } + + public function enterNode(Node $node) { + $nextCommentPos = current($this->commentPositions); + if ($nextCommentPos === false) { + // No more comments. + return self::STOP_TRAVERSAL; + } + + $oldPos = $this->pos; + $this->pos = $pos = $node->getStartTokenPos(); + if ($nextCommentPos > $oldPos && $nextCommentPos < $pos) { + $comments = []; + while (--$pos >= $oldPos) { + $token = $this->tokens[$pos]; + if ($token->id === \T_DOC_COMMENT) { + $comments[] = new Comment\Doc( + $token->text, $token->line, $token->pos, $pos, + $token->getEndLine(), $token->getEndPos() - 1, $pos); + continue; + } + if ($token->id === \T_COMMENT) { + $comments[] = new Comment( + $token->text, $token->line, $token->pos, $pos, + $token->getEndLine(), $token->getEndPos() - 1, $pos); + continue; + } + if ($token->id !== \T_WHITESPACE) { + break; + } + } + if (!empty($comments)) { + $node->setAttribute('comments', array_reverse($comments)); + } + + do { + $nextCommentPos = next($this->commentPositions); + } while ($nextCommentPos !== false && $nextCommentPos < $this->pos); + } + + $endPos = $node->getEndTokenPos(); + if ($nextCommentPos > $endPos) { + // Skip children if there are no comments located inside this node. + $this->pos = $endPos; + return self::DONT_TRAVERSE_CHILDREN; + } + + return null; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php new file mode 100644 index 00000000..65a1bd3f --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php @@ -0,0 +1,47 @@ + Found nodes */ + protected array $foundNodes; + + public function __construct(callable $filterCallback) { + $this->filterCallback = $filterCallback; + } + + /** + * Get found nodes satisfying the filter callback. + * + * Nodes are returned in pre-order. + * + * @return list Found nodes + */ + public function getFoundNodes(): array { + return $this->foundNodes; + } + + public function beforeTraverse(array $nodes): ?array { + $this->foundNodes = []; + + return null; + } + + public function enterNode(Node $node) { + $filterCallback = $this->filterCallback; + if ($filterCallback($node)) { + $this->foundNodes[] = $node; + } + + return null; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php new file mode 100644 index 00000000..05deed59 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php @@ -0,0 +1,49 @@ +filterCallback = $filterCallback; + } + + /** + * Get found node satisfying the filter callback. + * + * Returns null if no node satisfies the filter callback. + * + * @return null|Node Found node (or null if not found) + */ + public function getFoundNode(): ?Node { + return $this->foundNode; + } + + public function beforeTraverse(array $nodes): ?array { + $this->foundNode = null; + + return null; + } + + public function enterNode(Node $node) { + $filterCallback = $this->filterCallback; + if ($filterCallback($node)) { + $this->foundNode = $node; + return NodeVisitor::STOP_TRAVERSAL; + } + + return null; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php new file mode 100644 index 00000000..e0066f2d --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php @@ -0,0 +1,269 @@ +nameContext = new NameContext($errorHandler ?? new ErrorHandler\Throwing()); + $this->preserveOriginalNames = $options['preserveOriginalNames'] ?? false; + $this->replaceNodes = $options['replaceNodes'] ?? true; + } + + /** + * Get name resolution context. + */ + public function getNameContext(): NameContext { + return $this->nameContext; + } + + public function beforeTraverse(array $nodes): ?array { + $this->nameContext->startNamespace(); + return null; + } + + public function enterNode(Node $node) { + if ($node instanceof Stmt\Namespace_) { + $this->nameContext->startNamespace($node->name); + } elseif ($node instanceof Stmt\Use_) { + foreach ($node->uses as $use) { + $this->addAlias($use, $node->type, null); + } + } elseif ($node instanceof Stmt\GroupUse) { + foreach ($node->uses as $use) { + $this->addAlias($use, $node->type, $node->prefix); + } + } elseif ($node instanceof Stmt\Class_) { + if (null !== $node->extends) { + $node->extends = $this->resolveClassName($node->extends); + } + + foreach ($node->implements as &$interface) { + $interface = $this->resolveClassName($interface); + } + + $this->resolveAttrGroups($node); + if (null !== $node->name) { + $this->addNamespacedName($node); + } else { + $node->namespacedName = null; + } + } elseif ($node instanceof Stmt\Interface_) { + foreach ($node->extends as &$interface) { + $interface = $this->resolveClassName($interface); + } + + $this->resolveAttrGroups($node); + $this->addNamespacedName($node); + } elseif ($node instanceof Stmt\Enum_) { + foreach ($node->implements as &$interface) { + $interface = $this->resolveClassName($interface); + } + + $this->resolveAttrGroups($node); + $this->addNamespacedName($node); + } elseif ($node instanceof Stmt\Trait_) { + $this->resolveAttrGroups($node); + $this->addNamespacedName($node); + } elseif ($node instanceof Stmt\Function_) { + $this->resolveSignature($node); + $this->resolveAttrGroups($node); + $this->addNamespacedName($node); + } elseif ($node instanceof Stmt\ClassMethod + || $node instanceof Expr\Closure + || $node instanceof Expr\ArrowFunction + ) { + $this->resolveSignature($node); + $this->resolveAttrGroups($node); + } elseif ($node instanceof Stmt\Property) { + if (null !== $node->type) { + $node->type = $this->resolveType($node->type); + } + $this->resolveAttrGroups($node); + } elseif ($node instanceof Node\PropertyHook) { + foreach ($node->params as $param) { + $param->type = $this->resolveType($param->type); + $this->resolveAttrGroups($param); + } + $this->resolveAttrGroups($node); + } elseif ($node instanceof Stmt\Const_) { + foreach ($node->consts as $const) { + $this->addNamespacedName($const); + } + $this->resolveAttrGroups($node); + } elseif ($node instanceof Stmt\ClassConst) { + if (null !== $node->type) { + $node->type = $this->resolveType($node->type); + } + $this->resolveAttrGroups($node); + } elseif ($node instanceof Stmt\EnumCase) { + $this->resolveAttrGroups($node); + } elseif ($node instanceof Expr\StaticCall + || $node instanceof Expr\StaticPropertyFetch + || $node instanceof Expr\ClassConstFetch + || $node instanceof Expr\New_ + || $node instanceof Expr\Instanceof_ + ) { + if ($node->class instanceof Name) { + $node->class = $this->resolveClassName($node->class); + } + } elseif ($node instanceof Stmt\Catch_) { + foreach ($node->types as &$type) { + $type = $this->resolveClassName($type); + } + } elseif ($node instanceof Expr\FuncCall) { + if ($node->name instanceof Name) { + $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_FUNCTION); + } + } elseif ($node instanceof Expr\ConstFetch) { + $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_CONSTANT); + } elseif ($node instanceof Stmt\TraitUse) { + foreach ($node->traits as &$trait) { + $trait = $this->resolveClassName($trait); + } + + foreach ($node->adaptations as $adaptation) { + if (null !== $adaptation->trait) { + $adaptation->trait = $this->resolveClassName($adaptation->trait); + } + + if ($adaptation instanceof Stmt\TraitUseAdaptation\Precedence) { + foreach ($adaptation->insteadof as &$insteadof) { + $insteadof = $this->resolveClassName($insteadof); + } + } + } + } + + return null; + } + + /** @param Stmt\Use_::TYPE_* $type */ + private function addAlias(Node\UseItem $use, int $type, ?Name $prefix = null): void { + // Add prefix for group uses + $name = $prefix ? Name::concat($prefix, $use->name) : $use->name; + // Type is determined either by individual element or whole use declaration + $type |= $use->type; + + $this->nameContext->addAlias( + $name, (string) $use->getAlias(), $type, $use->getAttributes() + ); + } + + /** @param Stmt\Function_|Stmt\ClassMethod|Expr\Closure|Expr\ArrowFunction $node */ + private function resolveSignature($node): void { + foreach ($node->params as $param) { + $param->type = $this->resolveType($param->type); + $this->resolveAttrGroups($param); + } + $node->returnType = $this->resolveType($node->returnType); + } + + /** + * @template T of Node\Identifier|Name|Node\ComplexType|null + * @param T $node + * @return T + */ + private function resolveType(?Node $node): ?Node { + if ($node instanceof Name) { + return $this->resolveClassName($node); + } + if ($node instanceof Node\NullableType) { + $node->type = $this->resolveType($node->type); + return $node; + } + if ($node instanceof Node\UnionType || $node instanceof Node\IntersectionType) { + foreach ($node->types as &$type) { + $type = $this->resolveType($type); + } + return $node; + } + return $node; + } + + /** + * Resolve name, according to name resolver options. + * + * @param Name $name Function or constant name to resolve + * @param Stmt\Use_::TYPE_* $type One of Stmt\Use_::TYPE_* + * + * @return Name Resolved name, or original name with attribute + */ + protected function resolveName(Name $name, int $type): Name { + if (!$this->replaceNodes) { + $resolvedName = $this->nameContext->getResolvedName($name, $type); + if (null !== $resolvedName) { + $name->setAttribute('resolvedName', $resolvedName); + } else { + $name->setAttribute('namespacedName', FullyQualified::concat( + $this->nameContext->getNamespace(), $name, $name->getAttributes())); + } + return $name; + } + + if ($this->preserveOriginalNames) { + // Save the original name + $originalName = $name; + $name = clone $originalName; + $name->setAttribute('originalName', $originalName); + } + + $resolvedName = $this->nameContext->getResolvedName($name, $type); + if (null !== $resolvedName) { + return $resolvedName; + } + + // unqualified names inside a namespace cannot be resolved at compile-time + // add the namespaced version of the name as an attribute + $name->setAttribute('namespacedName', FullyQualified::concat( + $this->nameContext->getNamespace(), $name, $name->getAttributes())); + return $name; + } + + protected function resolveClassName(Name $name): Name { + return $this->resolveName($name, Stmt\Use_::TYPE_NORMAL); + } + + protected function addNamespacedName(Node $node): void { + $node->namespacedName = Name::concat( + $this->nameContext->getNamespace(), (string) $node->name); + } + + protected function resolveAttrGroups(Node $node): void { + foreach ($node->attrGroups as $attrGroup) { + foreach ($attrGroup->attrs as $attr) { + $attr->name = $this->resolveClassName($attr->name); + } + } + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NodeConnectingVisitor.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NodeConnectingVisitor.php new file mode 100644 index 00000000..70e051e2 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NodeConnectingVisitor.php @@ -0,0 +1,73 @@ +$weakReferences=false on the child node, the parent node can be accessed through + * $node->getAttribute('parent'), the previous + * node can be accessed through $node->getAttribute('previous'), + * and the next node can be accessed through $node->getAttribute('next'). + * + * With $weakReferences=true attribute names are prefixed by "weak_", e.g. "weak_parent". + */ +final class NodeConnectingVisitor extends NodeVisitorAbstract { + /** + * @var Node[] + */ + private array $stack = []; + + /** + * @var ?Node + */ + private $previous; + + private bool $weakReferences; + + public function __construct(bool $weakReferences = false) { + $this->weakReferences = $weakReferences; + } + + public function beforeTraverse(array $nodes) { + $this->stack = []; + $this->previous = null; + } + + public function enterNode(Node $node) { + if (!empty($this->stack)) { + $parent = $this->stack[count($this->stack) - 1]; + if ($this->weakReferences) { + $node->setAttribute('weak_parent', \WeakReference::create($parent)); + } else { + $node->setAttribute('parent', $parent); + } + } + + if ($this->previous !== null) { + if ( + $this->weakReferences + ) { + if ($this->previous->getAttribute('weak_parent') === $node->getAttribute('weak_parent')) { + $node->setAttribute('weak_previous', \WeakReference::create($this->previous)); + $this->previous->setAttribute('weak_next', \WeakReference::create($node)); + } + } elseif ($this->previous->getAttribute('parent') === $node->getAttribute('parent')) { + $node->setAttribute('previous', $this->previous); + $this->previous->setAttribute('next', $node); + } + } + + $this->stack[] = $node; + } + + public function leaveNode(Node $node) { + $this->previous = $node; + + array_pop($this->stack); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/ParentConnectingVisitor.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/ParentConnectingVisitor.php new file mode 100644 index 00000000..abf6e37d --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/ParentConnectingVisitor.php @@ -0,0 +1,51 @@ +$weakReferences=false on the child node, the parent node can be accessed through + * $node->getAttribute('parent'). + * + * With $weakReferences=true the attribute name is "weak_parent" instead. + */ +final class ParentConnectingVisitor extends NodeVisitorAbstract { + /** + * @var Node[] + */ + private array $stack = []; + + private bool $weakReferences; + + public function __construct(bool $weakReferences = false) { + $this->weakReferences = $weakReferences; + } + + public function beforeTraverse(array $nodes) { + $this->stack = []; + } + + public function enterNode(Node $node) { + if (!empty($this->stack)) { + $parent = $this->stack[count($this->stack) - 1]; + if ($this->weakReferences) { + $node->setAttribute('weak_parent', \WeakReference::create($parent)); + } else { + $node->setAttribute('parent', $parent); + } + } + + $this->stack[] = $node; + } + + public function leaveNode(Node $node) { + array_pop($this->stack); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php new file mode 100644 index 00000000..6fb15cca --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php @@ -0,0 +1,24 @@ +'", + "T_IS_GREATER_OR_EQUAL", + "T_SL", + "T_SR", + "'+'", + "'-'", + "'.'", + "'*'", + "'/'", + "'%'", + "'!'", + "T_INSTANCEOF", + "'~'", + "T_INC", + "T_DEC", + "T_INT_CAST", + "T_DOUBLE_CAST", + "T_STRING_CAST", + "T_ARRAY_CAST", + "T_OBJECT_CAST", + "T_BOOL_CAST", + "T_UNSET_CAST", + "'@'", + "T_POW", + "'['", + "T_NEW", + "T_CLONE", + "T_EXIT", + "T_IF", + "T_ELSEIF", + "T_ELSE", + "T_ENDIF", + "T_LNUMBER", + "T_DNUMBER", + "T_STRING", + "T_STRING_VARNAME", + "T_VARIABLE", + "T_NUM_STRING", + "T_INLINE_HTML", + "T_ENCAPSED_AND_WHITESPACE", + "T_CONSTANT_ENCAPSED_STRING", + "T_ECHO", + "T_DO", + "T_WHILE", + "T_ENDWHILE", + "T_FOR", + "T_ENDFOR", + "T_FOREACH", + "T_ENDFOREACH", + "T_DECLARE", + "T_ENDDECLARE", + "T_AS", + "T_SWITCH", + "T_MATCH", + "T_ENDSWITCH", + "T_CASE", + "T_DEFAULT", + "T_BREAK", + "T_CONTINUE", + "T_GOTO", + "T_FUNCTION", + "T_FN", + "T_CONST", + "T_RETURN", + "T_TRY", + "T_CATCH", + "T_FINALLY", + "T_USE", + "T_INSTEADOF", + "T_GLOBAL", + "T_STATIC", + "T_ABSTRACT", + "T_FINAL", + "T_PRIVATE", + "T_PROTECTED", + "T_PUBLIC", + "T_READONLY", + "T_PUBLIC_SET", + "T_PROTECTED_SET", + "T_PRIVATE_SET", + "T_VAR", + "T_UNSET", + "T_ISSET", + "T_EMPTY", + "T_HALT_COMPILER", + "T_CLASS", + "T_TRAIT", + "T_INTERFACE", + "T_ENUM", + "T_EXTENDS", + "T_IMPLEMENTS", + "T_OBJECT_OPERATOR", + "T_NULLSAFE_OBJECT_OPERATOR", + "T_LIST", + "T_ARRAY", + "T_CALLABLE", + "T_CLASS_C", + "T_TRAIT_C", + "T_METHOD_C", + "T_FUNC_C", + "T_PROPERTY_C", + "T_LINE", + "T_FILE", + "T_START_HEREDOC", + "T_END_HEREDOC", + "T_DOLLAR_OPEN_CURLY_BRACES", + "T_CURLY_OPEN", + "T_PAAMAYIM_NEKUDOTAYIM", + "T_NAMESPACE", + "T_NS_C", + "T_DIR", + "T_NS_SEPARATOR", + "T_ELLIPSIS", + "T_NAME_FULLY_QUALIFIED", + "T_NAME_QUALIFIED", + "T_NAME_RELATIVE", + "T_ATTRIBUTE", + "';'", + "']'", + "'('", + "')'", + "'{'", + "'}'", + "'`'", + "'\"'", + "'$'" + ); + + protected array $tokenToSymbol = array( + 0, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 57, 171, 173, 172, 56, 173, 173, + 166, 167, 54, 51, 9, 52, 53, 55, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 32, 164, + 45, 17, 47, 31, 69, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 71, 173, 165, 37, 173, 170, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 168, 36, 169, 59, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 1, 2, 3, 4, + 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, + 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 33, 34, 35, 38, 39, 40, + 41, 42, 43, 44, 46, 48, 49, 50, 58, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 70, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163 + ); + + protected array $action = array( + 133, 134, 135, 575, 136, 137, 1049, 766, 767, 768, + 138, 41, 850, -341, 495, 1390,-32766,-32766,-32766, 1008, + 841, 1145, 1146, 1147, 1141, 1140, 1139, 1148, 1142, 1143, + 1144,-32766,-32766,-32766, -195, 760, 759,-32766, -194,-32766, + -32766,-32766,-32766,-32766,-32766,-32766,-32767,-32767,-32767,-32767, + -32767, 0,-32766, 3, 4, 769, 1145, 1146, 1147, 1141, + 1140, 1139, 1148, 1142, 1143, 1144, 388, 389, 448, 272, + 53, 391, 773, 774, 775, 776, 433, 5, 434, 571, + 337, 39, 254, 29, 298, 830, 777, 778, 779, 780, + 781, 782, 783, 784, 785, 786, 806, 576, 807, 808, + 809, 810, 798, 799, 353, 354, 801, 802, 787, 788, + 789, 791, 792, 793, 364, 833, 834, 835, 836, 837, + 577, -382, 306, -382, 794, 795, 578, 579, 244, 818, + 816, 817, 829, 813, 814, 1313, 38, 580, 581, 812, + 582, 583, 584, 585, 1325, 586, 587, 481, 482, -628, + 496, 1009, 815, 588, 589, 140, 139, -628, 133, 134, + 135, 575, 136, 137, 1085, 766, 767, 768, 138, 41, + -32766, -341, 1046, 1041, 1040, 1039, 1045, 1042, 1043, 1044, + -32766,-32766,-32766,-32767,-32767,-32767,-32767, 106, 107, 108, + 109, 110, -195, 760, 759, 1058, -194,-32766,-32766,-32766, + 149,-32766, 852,-32766,-32766,-32766,-32766,-32766,-32766,-32766, + 936, 303, 257, 769,-32766,-32766,-32766, 850,-32766, 297, + -32766,-32766,-32766,-32766,-32766, 1371, 1355, 272, 53, 391, + 773, 774, 775, 776, -625,-32766, 434,-32766,-32766,-32766, + -32766, 730, -625, 830, 777, 778, 779, 780, 781, 782, + 783, 784, 785, 786, 806, 576, 807, 808, 809, 810, + 798, 799, 353, 354, 801, 802, 787, 788, 789, 791, + 792, 793, 364, 833, 834, 835, 836, 837, 577, -579, + -275, 317, 794, 795, 578, 579, -577, 818, 816, 817, + 829, 813, 814, 957, 926, 580, 581, 812, 582, 583, + 584, 585, 144, 586, 587, 841, 336,-32766,-32766,-32766, + 815, 588, 589, -628, 139, -628, 133, 134, 135, 575, + 136, 137, 1082, 766, 767, 768, 138, 41,-32766, 1375, + -32766,-32766,-32766,-32766,-32766,-32766,-32766, 1374, 629, 388, + 389,-32766,-32766,-32766,-32766,-32766, -579, -579, 1081, 433, + 321, 760, 759, -577, -577,-32766, 1293,-32766,-32766, 111, + 112, 113, -579, 282, 843, 851, 623, 1400, 936, -577, + 1401, 769, 333, 938, -585, 114, -579, 725, 294, 298, + 1119, -584, 349, -577, 752, 272, 53, 391, 773, 774, + 775, 776, 145, 86, 434, 306, 336, 336, -625, 731, + -625, 830, 777, 778, 779, 780, 781, 782, 783, 784, + 785, 786, 806, 576, 807, 808, 809, 810, 798, 799, + 353, 354, 801, 802, 787, 788, 789, 791, 792, 793, + 364, 833, 834, 835, 836, 837, 577, -576, 850, -578, + 794, 795, 578, 579, 845, 818, 816, 817, 829, 813, + 814, 727, 926, 580, 581, 812, 582, 583, 584, 585, + 740, 586, 587, 243, 1055,-32766,-32766, -85, 815, 588, + 589, 878, 152, 879, 133, 134, 135, 575, 136, 137, + 1087, 766, 767, 768, 138, 41, 350, 961, 960, 1058, + 1058, 1058,-32766,-32766,-32766, 841,-32766, 131, 977, 978, + 400, 1055, 10, 979, -576, -576, -578, -578, 378, 760, + 759, 936, 973, 290, 297, 297,-32766, 846, 936, 154, + -576, 79, -578, 382, 849, 936, 1058, 336, 878, 769, + 879, 938, -583, -85, -576, 725, -578, 959, 108, 109, + 110, 1058, 732, 272, 53, 391, 773, 774, 775, 776, + 290, 155, 434, 470, 471, 472, 735, 760, 759, 830, + 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, + 806, 576, 807, 808, 809, 810, 798, 799, 353, 354, + 801, 802, 787, 788, 789, 791, 792, 793, 364, 833, + 834, 835, 836, 837, 577, 926, 434, 847, 794, 795, + 578, 579, 926, 818, 816, 817, 829, 813, 814, 926, + 398, 580, 581, 812, 582, 583, 584, 585, 452, 586, + 587, 157, 87, 88, 89, 453, 815, 588, 589, 454, + 152, 790, 761, 762, 763, 764, 765, 158, 766, 767, + 768, 803, 804, 40, 27, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 1134, + 282, 1055, 455,-32766, 994, 1288, 1287, 1289, 725, 390, + 389, 938, 114, 856, 1120, 725, 769, 159, 938, 433, + 672, 23, 725, 1118, 691, 692, 1058,-32766, 153, 416, + 770, 771, 772, 773, 774, 775, 776, -78, -619, 839, + -619, -581, 386, 387, 392, 393, 830, 777, 778, 779, + 780, 781, 782, 783, 784, 785, 786, 806, 828, 807, + 808, 809, 810, 798, 799, 800, 827, 801, 802, 787, + 788, 789, 791, 792, 793, 832, 833, 834, 835, 836, + 837, 838, 161, 663, 664, 794, 795, 796, 797, 36, + 818, 816, 817, 829, 813, 814, -58, -57, 805, 811, + 812, 819, 820, 822, 821, -87, 823, 824, -581, -581, + 128, 129, 141, 815, 826, 825, 54, 55, 56, 57, + 527, 58, 59, 142, -110, 148, 162, 60, 61, -110, + 62, -110, 936, 163, 164, 165, 313, 166, -581, -110, + -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, + 1293, -84, 953, -78, -73, -72, -71, -70, -69, -68, + -67, -66, -65, 742, -46, 63, 64, -18, -575, 1286, + 146, 65, 51, 66, 251, 252, 67, 68, 69, 70, + 71, 72, 73, 74, 281, 31, 273, 47, 450, 528, + 291, -357, 741, 1319, 1320, 529, 744, 850, 935, 151, + 295, 1317, 45, 22, 530, 1284, 531, -309, 532, -305, + 533, 286, 936, 534, 535, 287, 926, 292, 48, 49, + 456, 385, 384, 293, 50, 536, 342, 296, 282, 1057, + 376, 348, 850, 299, 300, -575, -575, 1279, 114, 307, + 308, 701, 538, 539, 540, 150, 841,-32766, 1288, 1287, + 1289, -575, 850, 294, 542, 543, 1402, 1305, 1306, 1307, + 1308, 1310, 1302, 1303, 305, -575, 716, -110, -110, 130, + 1309, 1304, -110, 593, 1288, 1287, 1289, 306, 13, 673, + 75, -110, 1152, 678, 331, 332, 336, -154, -154, -154, + -32766, 718, 694, -4, 936, 938, 926, 314, 478, 725, + 506, 1324, -154, 705, -154, 679, -154, 695, -154, 974, + 1326, -541, 306, 312, 311, 79, 849, 661, 383, 43, + 320, 336, 37, 1252, 0, 0, 52, 0, 0, 977, + 978, 0, 760, 759, 537,-32766, 0, 0, 0, 706, + 0, 0, 912, 973, -110, -110, -110, 35, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, -531, 11, 707, 708, 31, 274, 30, 380, 955, + 599, -613, 306, 627, 0, 938, 0, 850, 926, 725, + -154, 1317, 1288, 1287, 1289, 44, -612, 749, 290, 750, + 1194, 1196, 869, 309, 310, 917, 1018, 995, 1002, 992, + 383, -575, 446, 1003, 915, 990, 1123, 304, 1126, 381, + 1127, 977, 978, 1124, 1125, 1131, 537, 1279, 1314, 861, + 330, 760, 759, 132, 541, 973, -110, -110, -110, 1341, + 1359, 1393, 1293, 666, 542, 543, -611, 1305, 1306, 1307, + 1308, 1310, 1302, 1303, -585, -584, -583, -582, 21, -525, + 1309, 1304, 1, 32, 760, 759, 33, 938,-32766, -278, + 77, 725, -4, -16, 1286, 332, 336, 42, -575, -575, + 46,-32766,-32766,-32766, 76,-32766, 80,-32766, 81,-32766, + 82, 83,-32766, 84, -575, 85, 147,-32766,-32766,-32766, + 156,-32766, 160,-32766,-32766, 249, 379, 1286, -575,-32766, + 430, 31, 273, 338,-32766,-32766,-32766, 365,-32766, 366, + -32766,-32766,-32766, 850, 850,-32766, 367, 1317, 368, 369, + -32766,-32766,-32766, 370, 371, 372,-32766,-32766, 373, 374, + 375, 377,-32766, 430, 447, 570, 31, 274, -276, -275, + 15, 16, 78, 17,-32766, 18, 20, 414, 850, -110, + -110, 497, 1317, 1279, -110, 498, 505, 508, 509, 510, + 511, 515, 516, -110, 517, 525, 604, 711, 1088, 1084, + 1234, 543,-32766, 1305, 1306, 1307, 1308, 1310, 1302, 1303, + 1315, 1086, 1083, -50, 1064, 1274, 1309, 1304, 1279, 1060, + -280, -102, 14, 19, 306, 24, 77, 79, 415, 303, + 413, 332, 336, 336, 618, 624, 543, 652, 1305, 1306, + 1307, 1308, 1310, 1302, 1303, 717, 143, 1238, 1292, 1235, + 1372, 1309, 1304, 726, 729, 733,-32766, 734, 736, 737, + 738, 77, 1286, 419, 739, 743, 332, 336, 728,-32766, + -32766,-32766, 746,-32766, 913,-32766, 1397,-32766, 1399, 872, + -32766, 871, 967, 1010, 1398,-32766,-32766,-32766, 966,-32766, + 964,-32766,-32766, 965, 968, 1286, 1267,-32766, 430, 946, + 956, 944,-32766,-32766,-32766, 1000,-32766, 1001,-32766,-32766, + -32766, 650, 1396,-32766, 1353, 1342, 1360, 1369,-32766,-32766, + -32766, 1318,-32766, 336,-32766,-32766, 936, 0, 1286, 0, + -32766, 430, 0, 0, 0,-32766,-32766,-32766, 0,-32766, + 0,-32766,-32766,-32766, 0, 0,-32766, 0, 0, 936, + 0,-32766,-32766,-32766, 0,-32766, 0,-32766,-32766, 0, + 0, 1286, 0,-32766, 430, 0, 0, 0,-32766,-32766, + -32766, 0,-32766, 0,-32766,-32766,-32766, 0, 0,-32766, + 0, 0, 0, 501,-32766,-32766,-32766, 0,-32766, 0, + -32766,-32766, 0, 0, 1286, 606,-32766, 430, 0, 0, + 0,-32766,-32766,-32766, 0,-32766, 0,-32766,-32766,-32766, + 926, 0,-32766, 2, 0, 0, 0,-32766,-32766,-32766, + 0, 0, 0,-32766,-32766, 0, -253, -253, -253,-32766, + 430, 0, 383, 926, 0, 0, 0, 0, 0, 0, + 0,-32766, 0, 977, 978, 0, 0, 0, 537, -252, + -252, -252, 0, 0, 0, 383, 912, 973, -110, -110, + -110, 0, 0, 0, 0, 0, 977, 978, 0, 0, + 0, 537, 0, 0, 0, 0, 0, 0, 0, 912, + 973, -110, -110, -110,-32766, 0, 0, 0, 0, 938, + 1286, 0, 0, 725, -253, 0, 0,-32766,-32766,-32766, + 0,-32766, 0,-32766, 0,-32766, 0, 0,-32766, 0, + 0, 0, 938,-32766,-32766,-32766, 725, -252, 0,-32766, + -32766, 0, 0, 0, 0,-32766, 430, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,-32766 + ); + + protected array $actionCheck = array( + 3, 4, 5, 6, 7, 8, 1, 10, 11, 12, + 13, 14, 83, 9, 32, 86, 10, 11, 12, 32, + 81, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 10, 11, 12, 9, 38, 39, 31, 9, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 0, 31, 9, 9, 58, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 107, 108, 109, 72, + 73, 74, 75, 76, 77, 78, 117, 9, 81, 86, + 71, 152, 153, 9, 31, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 107, 163, 109, 127, 128, 129, 130, 15, 132, + 133, 134, 135, 136, 137, 1, 9, 140, 141, 142, + 143, 144, 145, 146, 151, 148, 149, 138, 139, 1, + 168, 164, 155, 156, 157, 9, 159, 9, 3, 4, + 5, 6, 7, 8, 167, 10, 11, 12, 13, 14, + 117, 167, 119, 120, 121, 122, 123, 124, 125, 126, + 10, 11, 12, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 167, 38, 39, 142, 167, 10, 11, 12, + 9, 31, 1, 33, 34, 35, 36, 37, 38, 39, + 1, 167, 9, 58, 10, 11, 12, 83, 31, 166, + 33, 34, 35, 36, 37, 1, 1, 72, 73, 74, + 75, 76, 77, 78, 1, 31, 81, 33, 34, 35, + 36, 32, 9, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 71, + 167, 9, 127, 128, 129, 130, 71, 132, 133, 134, + 135, 136, 137, 1, 85, 140, 141, 142, 143, 144, + 145, 146, 168, 148, 149, 81, 172, 10, 11, 12, + 155, 156, 157, 165, 159, 167, 3, 4, 5, 6, + 7, 8, 167, 10, 11, 12, 13, 14, 31, 1, + 33, 34, 35, 10, 10, 11, 12, 9, 52, 107, + 108, 10, 11, 12, 10, 11, 138, 139, 1, 117, + 9, 38, 39, 138, 139, 31, 1, 33, 34, 54, + 55, 56, 154, 58, 81, 164, 1, 81, 1, 154, + 84, 58, 9, 164, 166, 70, 168, 168, 31, 31, + 164, 166, 9, 168, 168, 72, 73, 74, 75, 76, + 77, 78, 168, 168, 81, 163, 172, 172, 165, 32, + 167, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 71, 83, 71, + 127, 128, 129, 130, 161, 132, 133, 134, 135, 136, + 137, 168, 85, 140, 141, 142, 143, 144, 145, 146, + 168, 148, 149, 98, 117, 117, 117, 32, 155, 156, + 157, 107, 159, 109, 3, 4, 5, 6, 7, 8, + 167, 10, 11, 12, 13, 14, 9, 73, 74, 142, + 142, 142, 10, 11, 12, 81, 141, 15, 118, 119, + 107, 117, 109, 123, 138, 139, 138, 139, 9, 38, + 39, 1, 132, 166, 166, 166, 117, 81, 1, 15, + 154, 166, 154, 9, 160, 1, 142, 172, 107, 58, + 109, 164, 166, 98, 168, 168, 168, 123, 51, 52, + 53, 142, 32, 72, 73, 74, 75, 76, 77, 78, + 166, 15, 81, 133, 134, 135, 32, 38, 39, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 85, 81, 161, 127, 128, + 129, 130, 85, 132, 133, 134, 135, 136, 137, 85, + 9, 140, 141, 142, 143, 144, 145, 146, 9, 148, + 149, 15, 10, 11, 12, 9, 155, 156, 157, 9, + 159, 3, 4, 5, 6, 7, 8, 15, 10, 11, + 12, 13, 14, 31, 102, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 127, + 58, 117, 9, 117, 164, 160, 161, 162, 168, 107, + 108, 164, 70, 9, 169, 168, 58, 15, 164, 117, + 76, 77, 168, 1, 76, 77, 142, 141, 102, 103, + 72, 73, 74, 75, 76, 77, 78, 17, 165, 81, + 167, 71, 107, 108, 107, 108, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 15, 112, 113, 127, 128, 129, 130, 15, + 132, 133, 134, 135, 136, 137, 17, 17, 140, 141, + 142, 143, 144, 145, 146, 32, 148, 149, 138, 139, + 17, 17, 17, 155, 156, 157, 2, 3, 4, 5, + 6, 7, 8, 17, 102, 17, 17, 13, 14, 107, + 16, 109, 1, 17, 17, 17, 114, 17, 168, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 1, 32, 39, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 51, 52, 32, 71, 81, + 32, 57, 71, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 32, 71, 72, 73, 74, 75, + 32, 169, 32, 79, 80, 81, 32, 83, 32, 32, + 38, 87, 88, 89, 90, 117, 92, 36, 94, 36, + 96, 36, 1, 99, 100, 36, 85, 36, 104, 105, + 106, 107, 108, 36, 110, 111, 36, 38, 58, 141, + 116, 117, 83, 38, 38, 138, 139, 123, 70, 138, + 139, 78, 128, 129, 130, 71, 81, 86, 160, 161, + 162, 154, 83, 31, 140, 141, 84, 143, 144, 145, + 146, 147, 148, 149, 150, 168, 81, 118, 119, 168, + 156, 157, 123, 90, 160, 161, 162, 163, 98, 91, + 166, 132, 83, 97, 170, 171, 172, 76, 77, 78, + 141, 93, 95, 0, 1, 164, 85, 115, 98, 168, + 98, 151, 91, 81, 93, 101, 95, 101, 97, 132, + 151, 154, 163, 137, 136, 166, 160, 114, 107, 164, + 136, 172, 168, 170, -1, -1, 71, -1, -1, 118, + 119, -1, 38, 39, 123, 141, -1, -1, -1, 117, + -1, -1, 131, 132, 133, 134, 135, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 154, 154, 141, 142, 71, 72, 154, 154, 159, + 158, 166, 163, 158, -1, 164, -1, 83, 85, 168, + 169, 87, 160, 161, 162, 164, 166, 164, 166, 164, + 60, 61, 164, 138, 139, 164, 164, 164, 164, 164, + 107, 71, 109, 164, 164, 164, 164, 114, 164, 154, + 164, 118, 119, 164, 164, 164, 123, 123, 165, 165, + 168, 38, 39, 168, 131, 132, 133, 134, 135, 165, + 165, 165, 1, 165, 140, 141, 166, 143, 144, 145, + 146, 147, 148, 149, 166, 166, 166, 166, 155, 166, + 156, 157, 166, 166, 38, 39, 166, 164, 75, 167, + 166, 168, 169, 32, 81, 171, 172, 166, 138, 139, + 166, 88, 89, 90, 166, 92, 166, 94, 166, 96, + 166, 166, 99, 166, 154, 166, 166, 104, 105, 106, + 166, 75, 166, 110, 111, 166, 168, 81, 168, 116, + 117, 71, 72, 166, 88, 89, 90, 166, 92, 166, + 94, 128, 96, 83, 83, 99, 166, 87, 166, 166, + 104, 105, 106, 166, 166, 166, 110, 111, 166, 166, + 166, 166, 116, 117, 166, 166, 71, 72, 167, 167, + 167, 167, 159, 167, 128, 167, 167, 167, 83, 118, + 119, 167, 87, 123, 123, 167, 167, 167, 167, 167, + 167, 167, 167, 132, 167, 167, 167, 167, 167, 167, + 167, 141, 141, 143, 144, 145, 146, 147, 148, 149, + 167, 167, 167, 32, 167, 167, 156, 157, 123, 167, + 167, 167, 167, 167, 163, 167, 166, 166, 169, 167, + 167, 171, 172, 172, 167, 167, 141, 167, 143, 144, + 145, 146, 147, 148, 149, 167, 32, 167, 167, 167, + 167, 156, 157, 168, 168, 168, 75, 168, 168, 168, + 168, 166, 81, 169, 168, 168, 171, 172, 168, 88, + 89, 90, 169, 92, 169, 94, 169, 96, 169, 169, + 99, 169, 169, 169, 169, 104, 105, 106, 169, 75, + 169, 110, 111, 169, 169, 81, 169, 116, 117, 169, + 169, 169, 88, 89, 90, 169, 92, 169, 94, 128, + 96, 169, 169, 99, 169, 169, 169, 169, 104, 105, + 106, 171, 75, 172, 110, 111, 1, -1, 81, -1, + 116, 117, -1, -1, -1, 88, 89, 90, -1, 92, + -1, 94, 128, 96, -1, -1, 99, -1, -1, 1, + -1, 104, 105, 106, -1, 75, -1, 110, 111, -1, + -1, 81, -1, 116, 117, -1, -1, -1, 88, 89, + 90, -1, 92, -1, 94, 128, 96, -1, -1, 99, + -1, -1, -1, 103, 104, 105, 106, -1, 75, -1, + 110, 111, -1, -1, 81, 82, 116, 117, -1, -1, + -1, 88, 89, 90, -1, 92, -1, 94, 128, 96, + 85, -1, 99, 166, -1, -1, -1, 104, 105, 106, + -1, -1, -1, 110, 111, -1, 101, 102, 103, 116, + 117, -1, 107, 85, -1, -1, -1, -1, -1, -1, + -1, 128, -1, 118, 119, -1, -1, -1, 123, 101, + 102, 103, -1, -1, -1, 107, 131, 132, 133, 134, + 135, -1, -1, -1, -1, -1, 118, 119, -1, -1, + -1, 123, -1, -1, -1, -1, -1, -1, -1, 131, + 132, 133, 134, 135, 75, -1, -1, -1, -1, 164, + 81, -1, -1, 168, 169, -1, -1, 88, 89, 90, + -1, 92, -1, 94, -1, 96, -1, -1, 99, -1, + -1, -1, 164, 104, 105, 106, 168, 169, -1, 110, + 111, -1, -1, -1, -1, 116, 117, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 128 + ); + + protected array $actionBase = array( + 0, 155, -3, 313, 471, 471, 881, 963, 1365, 1388, + 892, 134, 515, -61, 367, 524, 524, 801, 524, 209, + 510, 283, 517, 517, 517, 920, 855, 628, 628, 855, + 628, 1053, 1053, 1053, 1053, 1086, 1086, 1320, 1320, 1353, + 1254, 1221, 1449, 1449, 1449, 1449, 1449, 1287, 1449, 1449, + 1449, 1449, 1449, 1287, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 201, -13, 44, + 365, 744, 1102, 1120, 1107, 1121, 1096, 1095, 1103, 1108, + 1122, 1183, 1185, 837, 1186, 1187, 1182, 1188, 1110, 938, + 1098, 1118, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 323, 482, 334, 331, 331, 331, 331, 331, 331, 331, + 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, + 331, 331, 331, 964, 964, 21, 21, 21, 324, 1135, + 1100, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 1135, 297, + 204, 1000, 187, 170, 170, 6, 6, 6, 6, 6, + 692, 53, 1101, 819, 819, 138, 138, 138, 138, 542, + 14, 347, 355, -41, 348, 232, 384, 384, 487, 487, + 554, 554, 349, 349, 554, 554, 554, 399, 399, 399, + 399, 208, 215, 366, 364, -7, 864, 224, 224, 224, + 224, 864, 864, 864, 864, 829, 1190, 864, 1011, 1027, + 864, 864, 368, 767, 767, 925, 305, 305, 305, 767, + 421, -71, -71, 421, 380, -71, 225, 286, 556, 847, + 572, 543, 556, 640, 771, 233, 148, 826, 605, 826, + 1094, 831, 831, 802, 792, 921, 1140, 1123, 874, 1176, + 876, 1178, 420, 9, 791, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1191, 519, 1094, 436, + 1191, 1191, 1191, 519, 519, 519, 519, 519, 519, 519, + 519, 805, 519, 519, 641, 436, 614, 618, 436, 860, + 519, 877, 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, -18, 201, 201, -13, 292, 292, 201, + 216, 5, 292, 292, 292, 292, 201, 201, 201, 201, + 605, 840, 882, 607, 435, 885, 29, 840, 840, 840, + 4, 113, 25, 841, 843, 393, 835, 835, 835, 869, + 956, 956, 835, 839, 835, 869, 835, 835, 956, 956, + 879, 956, 146, 609, 373, 514, 616, 956, 272, 835, + 835, 835, 835, 854, 956, 45, 68, 620, 835, 203, + 191, 835, 835, 854, 848, 828, 846, 956, 956, 956, + 854, 499, 846, 846, 846, 893, 895, 873, 822, 363, + 341, 674, 127, 783, 822, 822, 835, 601, 873, 822, + 873, 822, 880, 822, 822, 822, 873, 822, 839, 477, + 822, 779, 786, 663, 74, 822, 51, 978, 980, 743, + 982, 971, 984, 1038, 985, 987, 1125, 953, 999, 974, + 989, 1039, 960, 957, 836, 763, 764, 878, 827, 951, + 838, 838, 838, 948, 949, 838, 838, 838, 838, 838, + 838, 838, 838, 763, 923, 884, 853, 1013, 765, 776, + 1069, 820, 1145, 823, 1011, 978, 987, 789, 974, 989, + 960, 957, 800, 799, 797, 798, 796, 795, 793, 794, + 808, 1071, 1072, 990, 825, 778, 1049, 1020, 1143, 922, + 1022, 1023, 1050, 1073, 898, 1083, 1147, 844, 1149, 1150, + 924, 1028, 1126, 838, 940, 875, 934, 1027, 950, 763, + 935, 1084, 1085, 1043, 824, 1054, 1058, 998, 870, 842, + 936, 1152, 1029, 1032, 1033, 1127, 1129, 891, 1044, 962, + 1059, 872, 1099, 1060, 1061, 1062, 1063, 1130, 1153, 1131, + 890, 1132, 901, 858, 1041, 856, 1154, 504, 851, 857, + 866, 1035, 536, 1007, 1136, 1134, 1155, 1064, 1065, 1067, + 1159, 1161, 994, 902, 1046, 867, 1048, 1042, 903, 904, + 606, 865, 1087, 845, 849, 859, 622, 672, 1164, 1165, + 1167, 996, 830, 833, 905, 909, 1088, 832, 1092, 1170, + 737, 910, 1171, 1070, 787, 788, 690, 750, 749, 790, + 868, 1137, 883, 852, 850, 1034, 788, 834, 911, 1172, + 912, 914, 916, 1068, 919, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 628, 628, 628, 628, 784, 784, + 784, 784, 784, 784, 784, 628, 784, 784, 784, 628, + 628, 0, 0, 628, 0, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 758, 758, 612, + 612, 612, 612, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 612, 612, 0, 612, 612, 612, 612, + 612, 612, 612, 612, 879, 758, 758, 758, 758, 305, + 305, 305, 305, -96, -96, 758, 758, 380, 758, 380, + 758, 758, 305, 305, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 0, 0, 0, 436, -71, + 758, 839, 839, 839, 839, 758, 758, 758, 758, -71, + -71, 758, 414, 414, 758, 758, 0, 0, 0, 0, + 0, 0, 0, 0, 436, 0, 0, 436, 0, 0, + 839, 839, 758, 380, 879, 328, 758, 0, 0, 0, + 0, 436, 839, 436, 519, -71, -71, 519, 519, 292, + 201, 328, 596, 596, 596, 596, 0, 0, 605, 879, + 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, + 839, 0, 879, 0, 839, 839, 839, 0, 0, 0, + 0, 0, 0, 0, 0, 956, 0, 0, 0, 0, + 0, 0, 0, 839, 0, 956, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 839, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 838, 870, 0, 0, 870, + 0, 838, 838, 838, 0, 0, 0, 865, 832 + ); + + protected array $actionDefault = array( + 3,32767,32767,32767, 102, 102,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 100, + 32767, 631, 631, 631, 631,32767,32767, 257, 102,32767, + 32767, 500, 415, 415, 415,32767,32767,32767, 573, 573, + 573, 573, 573, 17,32767,32767,32767,32767,32767,32767, + 32767, 500,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767, 36, 7, 8, 10, 11, 49, 338, + 100,32767,32767,32767,32767,32767,32767,32767,32767, 102, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 624,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767, 403, 494, 504, 482, 483, 485, 486, 414, + 574, 630, 344, 627, 342, 413, 146, 354, 343, 245, + 261, 505, 262, 506, 509, 510, 218, 400, 150, 151, + 446, 501, 448, 499, 503, 447, 420, 427, 428, 429, + 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, + 418, 419, 502,32767,32767, 479, 478, 477, 444,32767, + 32767,32767,32767,32767,32767,32767,32767, 102,32767, 445, + 449, 417, 452, 450, 451, 468, 469, 466, 467, 470, + 32767, 323,32767,32767,32767, 471, 472, 473, 474, 381, + 379,32767,32767, 111, 323, 111,32767,32767, 459, 460, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 517, 567, 476,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767, 102,32767,32767, + 32767, 100, 569, 441, 443, 537, 454, 455, 453, 421, + 32767, 542,32767, 102,32767, 544,32767,32767,32767,32767, + 32767,32767,32767, 568,32767, 575, 575,32767, 530, 100, + 196,32767, 543, 196, 196,32767,32767,32767,32767,32767, + 32767,32767,32767, 638, 530, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110,32767, 196, 110,32767, + 32767,32767, 100, 196, 196, 196, 196, 196, 196, 196, + 196, 545, 196, 196, 191,32767, 271, 273, 102, 592, + 196, 547,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 530, 464, 139,32767, 532, 139, 575, 456, 457, 458, + 575, 575, 575, 319, 296,32767,32767,32767,32767,32767, + 545, 545, 100, 100, 100, 100,32767,32767,32767,32767, + 111, 516, 99, 99, 99, 99, 99, 103, 101,32767, + 32767,32767,32767, 226,32767, 101, 101, 99,32767, 101, + 101,32767,32767, 226, 228, 215, 230,32767, 596, 597, + 226, 101, 230, 230, 230, 250, 250, 519, 325, 101, + 99, 101, 101, 198, 325, 325,32767, 101, 519, 325, + 519, 325, 200, 325, 325, 325, 519, 325,32767, 101, + 325, 217, 403, 99, 99, 325,32767,32767,32767, 532, + 32767,32767,32767,32767,32767,32767,32767, 225,32767,32767, + 32767,32767,32767,32767,32767,32767, 562,32767, 580, 594, + 462, 463, 465, 579, 577, 487, 488, 489, 490, 491, + 492, 493, 496, 626,32767, 536,32767,32767,32767, 353, + 32767, 636,32767,32767,32767, 9, 74, 525, 42, 43, + 51, 57, 551, 552, 553, 554, 548, 549, 555, 550, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 637,32767, 575,32767, + 32767,32767,32767, 461, 557, 602,32767,32767, 576, 629, + 32767,32767,32767,32767,32767,32767,32767,32767, 139,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 562, + 32767, 137,32767,32767,32767,32767,32767,32767,32767,32767, + 558,32767,32767,32767, 575,32767,32767,32767,32767, 321, + 318,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767, 575,32767,32767, + 32767,32767,32767, 298,32767, 315,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767, 399, 532, 301, 303, 304,32767, + 32767,32767,32767, 375,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 153, 153, 3, 3, 356, + 153, 153, 153, 356, 356, 153, 356, 356, 356, 153, + 153, 153, 153, 153, 153, 283, 186, 265, 268, 250, + 250, 153, 367, 153 + ); + + protected array $goto = array( + 202, 169, 202, 202, 202, 1056, 842, 712, 359, 670, + 671, 598, 688, 689, 690, 748, 653, 655, 591, 929, + 675, 930, 1090, 721, 699, 702, 1028, 710, 719, 1024, + 171, 171, 171, 171, 226, 203, 199, 199, 181, 183, + 221, 199, 199, 199, 199, 199, 1180, 200, 200, 200, + 200, 200, 1180, 193, 194, 195, 196, 197, 198, 223, + 221, 224, 550, 551, 431, 552, 555, 556, 557, 558, + 559, 560, 561, 562, 172, 173, 174, 201, 175, 176, + 177, 170, 178, 179, 180, 182, 220, 222, 225, 245, + 248, 259, 260, 262, 263, 264, 265, 266, 267, 268, + 269, 275, 276, 277, 278, 288, 289, 326, 327, 328, + 437, 438, 439, 613, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 184, + 242, 185, 194, 195, 196, 197, 198, 223, 204, 205, + 206, 207, 246, 186, 187, 208, 188, 209, 205, 189, + 247, 204, 168, 210, 211, 190, 212, 213, 214, 191, + 215, 216, 192, 217, 218, 219, 285, 283, 285, 285, + 870, 1089, 1091, 1094, 615, 255, 255, 255, 255, 255, + 441, 677, 614, 1130, 884, 867, 436, 329, 323, 324, + 345, 608, 440, 346, 442, 654, 724, 492, 521, 715, + 896, 1128, 993, 883, 494, 253, 253, 253, 253, 250, + 256, 489, 1361, 1362, 1386, 1386, 925, 920, 921, 934, + 876, 922, 873, 923, 924, 874, 877, 363, 928, 881, + 480, 480, 868, 880, 1386, 848, 474, 363, 363, 480, + 1117, 1112, 1113, 1114, 1229, 351, 362, 362, 362, 362, + 1389, 1389, 429, 363, 363, 1017, 902, 363, 989, 1403, + 747, 360, 361, 566, 1026, 1021, 1056, 1285, 1285, 1285, + 569, 352, 351, 363, 363, 605, 1056, 1285, 848, 1056, + 848, 1056, 1056, 1137, 1138, 1056, 1056, 1056, 1056, 1056, + 1056, 1056, 1056, 1056, 1056, 1056, 357, 1261, 962, 637, + 674, 1285, 1262, 1265, 963, 1266, 1285, 1285, 1285, 1285, + 1376, 435, 1285, 628, 402, 1285, 1285, 1368, 1368, 1368, + 1368, 1347, 574, 567, 1062, 1061, 1059, 1059, 958, 958, + 697, 970, 1014, 942, 1051, 1067, 1068, 943, 565, 565, + 565, 603, 513, 522, 514, 863, 676, 863, 565, 709, + 520, 1176, 318, 567, 574, 600, 601, 319, 611, 617, + 844, 633, 634, 1080, 8, 709, 9, 449, 709, 28, + 1065, 1066, 467, 335, 316, 569, 698, 987, 987, 987, + 987, 1363, 1364, 467, 639, 639, 981, 988, 609, 631, + 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, + 1335, 1335, 863, 469, 682, 469, 1335, 1335, 1335, 1335, + 1335, 1335, 1335, 1335, 1335, 1335, 347, 258, 258, 626, + 640, 643, 644, 645, 646, 667, 668, 669, 723, 632, + 460, 860, 460, 460, 460, 1358, 1358, 1358, 553, 553, + 1278, 985, 420, 720, 553, 1358, 553, 553, 553, 553, + 553, 553, 553, 553, 451, 889, 568, 595, 568, 647, + 649, 651, 568, 976, 595, 411, 405, 473, 886, 1276, + 1370, 1370, 1370, 1370, 909, 866, 909, 909, 1036, 483, + 612, 484, 485, 751, 563, 563, 563, 563, 894, 619, + 1101, 1394, 1395, 412, 1332, 1332, 898, 490, 1151, 1354, + 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, + 279, 1105, 334, 334, 334, 998, 892, 0, 1280, 1047, + 0, 0, 863, 0, 0, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 0, 0, 460, 1103, + 554, 554, 0, 1356, 1356, 1103, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 621, 622, 417, 418, + 947, 1166, 0, 686, 0, 687, 0, 422, 423, 424, + 0, 700, 1033, 0, 425, 1281, 1282, 0, 1268, 355, + 888, 0, 680, 1012, 858, 0, 0, 0, 882, 443, + 0, 1268, 0, 897, 885, 1100, 1104, 0, 0, 0, + 1275, 0, 443, 0, 1283, 1344, 1345, 996, 0, 0, + 1063, 1063, 0, 0, 0, 681, 1074, 1070, 1071, 404, + 407, 616, 620, 0, 0, 0, 0, 0, 0, 0, + 986, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1149, 901, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1031, 1031 + ); + + protected array $gotoCheck = array( + 42, 42, 42, 42, 42, 73, 6, 73, 97, 86, + 86, 48, 86, 86, 86, 48, 48, 48, 127, 65, + 48, 65, 131, 9, 48, 48, 48, 48, 48, 48, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 23, 23, 23, 23, + 15, 130, 130, 130, 134, 5, 5, 5, 5, 5, + 66, 66, 8, 8, 35, 26, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 8, 84, 8, 8, + 35, 8, 49, 35, 84, 5, 5, 5, 5, 5, + 5, 185, 185, 185, 191, 191, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, + 157, 157, 27, 15, 191, 12, 159, 14, 14, 157, + 15, 15, 15, 15, 159, 177, 24, 24, 24, 24, + 191, 191, 43, 14, 14, 50, 45, 14, 50, 14, + 50, 97, 97, 50, 50, 50, 73, 73, 73, 73, + 14, 177, 177, 14, 14, 181, 73, 73, 12, 73, + 12, 73, 73, 148, 148, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 188, 79, 79, 56, + 56, 73, 79, 79, 79, 79, 73, 73, 73, 73, + 190, 13, 73, 13, 62, 73, 73, 9, 9, 9, + 9, 14, 76, 76, 119, 119, 89, 89, 9, 9, + 89, 89, 103, 73, 89, 89, 89, 73, 19, 19, + 19, 104, 163, 14, 163, 22, 64, 22, 19, 7, + 163, 158, 76, 76, 76, 76, 76, 76, 76, 76, + 7, 76, 76, 115, 46, 7, 46, 113, 7, 76, + 120, 120, 19, 178, 178, 14, 117, 19, 19, 19, + 19, 187, 187, 19, 108, 108, 19, 19, 2, 2, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 179, 179, 22, 83, 121, 83, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 29, 5, 5, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 80, + 23, 18, 23, 23, 23, 134, 134, 134, 165, 165, + 14, 93, 93, 93, 165, 134, 165, 165, 165, 165, + 165, 165, 165, 165, 83, 39, 9, 9, 9, 85, + 85, 85, 9, 92, 9, 28, 9, 9, 37, 169, + 134, 134, 134, 134, 25, 25, 25, 25, 110, 9, + 9, 9, 9, 99, 107, 107, 107, 107, 9, 107, + 133, 9, 9, 31, 180, 180, 41, 160, 151, 134, + 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, + 24, 136, 24, 24, 24, 96, 9, -1, 20, 114, + -1, -1, 22, -1, -1, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, -1, -1, 23, 134, + 182, 182, -1, 134, 134, 134, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 17, 17, 82, 82, + 17, 17, -1, 82, -1, 82, -1, 82, 82, 82, + -1, 82, 17, -1, 82, 20, 20, -1, 20, 82, + 17, -1, 17, 17, 20, -1, -1, -1, 17, 118, + -1, 20, -1, 16, 16, 16, 16, -1, -1, -1, + 17, -1, 118, -1, 20, 20, 20, 16, -1, -1, + 118, 118, -1, -1, -1, 118, 118, 118, 118, 59, + 59, 59, 59, -1, -1, -1, -1, -1, -1, -1, + 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 16, 16, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 107, 107 + ); + + protected array $gotoBase = array( + 0, 0, -339, 0, 0, 174, -7, 339, 171, 10, + 0, 0, -69, -36, -78, -186, 130, 81, 114, 66, + 117, 0, 62, 160, 240, 468, 178, 225, 118, 112, + 0, 45, 0, 0, 0, -195, 0, 119, 0, 122, + 0, 44, -1, 226, 0, 227, -387, 0, -715, 182, + 241, 0, 0, 0, 0, 0, 256, 0, 0, 570, + 0, 0, 269, 0, 102, 3, -63, 0, 0, 0, + 0, 0, 0, -5, 0, 0, -31, 0, 0, -120, + 110, 53, 54, 120, -286, -33, -724, 0, 0, 40, + 0, 0, 124, 129, 0, 0, 61, -488, 0, 67, + 0, 0, 0, 294, 295, 0, 0, 453, 141, 0, + 100, 0, 0, 83, -3, 82, 0, 86, 318, 38, + 78, 107, 0, 0, 0, 0, 0, 16, 0, 0, + 168, 20, 0, 108, 163, 0, 58, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 43, 0, 0, 0, 0, 0, 193, 101, -38, + 46, 0, 0, -166, 0, 195, 0, 0, 0, 92, + 0, 0, 0, 0, 0, 0, 0, -60, 42, 157, + 251, 243, 297, 0, 0, -97, 0, 1, 263, 0, + 276, -101, 0, 0 + ); + + protected array $gotoDefault = array( + -32768, 526, 755, 7, 756, 951, 831, 840, 590, 544, + 722, 356, 641, 432, 1352, 927, 1165, 610, 859, 1294, + 1300, 468, 862, 340, 745, 939, 910, 911, 408, 395, + 875, 406, 665, 642, 507, 895, 464, 887, 499, 890, + 463, 899, 167, 428, 524, 903, 6, 906, 572, 937, + 991, 396, 914, 397, 693, 916, 594, 918, 919, 403, + 409, 410, 1170, 602, 638, 931, 261, 596, 932, 394, + 933, 941, 399, 401, 703, 479, 518, 512, 421, 1132, + 597, 625, 662, 457, 486, 636, 648, 635, 493, 444, + 426, 339, 975, 983, 500, 477, 997, 358, 1005, 753, + 1178, 656, 502, 1013, 657, 1020, 1023, 545, 546, 491, + 1035, 271, 1038, 503, 1048, 26, 683, 1053, 1054, 684, + 658, 1076, 659, 685, 660, 1078, 476, 592, 1179, 475, + 1093, 1099, 465, 1102, 1340, 466, 1106, 270, 1109, 284, + 427, 445, 1115, 1116, 12, 1122, 713, 714, 25, 280, + 523, 1150, 704,-32768,-32768,-32768,-32768, 462, 1177, 461, + 1249, 1251, 573, 504, 1269, 301, 1272, 696, 519, 1277, + 458, 1343, 459, 547, 487, 325, 548, 1387, 315, 343, + 322, 564, 302, 344, 549, 488, 1349, 1357, 341, 34, + 1377, 1388, 607, 630 + ); + + protected array $ruleToNonTerminal = array( + 0, 1, 3, 3, 2, 5, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 8, 8, 9, 10, 11, + 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, + 16, 17, 17, 18, 18, 21, 21, 22, 23, 23, + 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 29, 29, 30, 30, 32, 34, + 34, 28, 36, 36, 33, 38, 38, 35, 35, 37, + 37, 39, 39, 31, 40, 40, 41, 43, 44, 44, + 45, 45, 46, 46, 48, 47, 47, 47, 47, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 25, 25, 50, 69, 69, 72, 72, + 71, 70, 70, 63, 75, 75, 76, 76, 77, 77, + 78, 78, 79, 79, 80, 80, 80, 80, 26, 26, + 27, 27, 27, 27, 27, 88, 88, 90, 90, 83, + 83, 91, 91, 92, 92, 92, 84, 84, 87, 87, + 85, 85, 93, 94, 94, 57, 57, 65, 65, 68, + 68, 68, 67, 95, 95, 96, 58, 58, 58, 58, + 97, 97, 98, 98, 99, 99, 100, 101, 101, 102, + 102, 103, 103, 55, 55, 51, 51, 105, 53, 53, + 106, 52, 52, 54, 54, 64, 64, 64, 64, 81, + 81, 109, 109, 111, 111, 112, 112, 112, 112, 112, + 112, 112, 112, 110, 110, 110, 115, 115, 115, 115, + 89, 89, 118, 118, 118, 119, 119, 116, 116, 120, + 120, 122, 122, 123, 123, 117, 124, 124, 121, 125, + 125, 125, 125, 113, 113, 82, 82, 82, 20, 20, + 20, 128, 128, 128, 128, 129, 129, 129, 127, 126, + 126, 131, 131, 131, 130, 130, 60, 132, 132, 133, + 61, 135, 135, 136, 136, 137, 137, 86, 138, 138, + 138, 138, 138, 138, 138, 143, 143, 144, 144, 145, + 145, 145, 145, 145, 146, 147, 147, 142, 142, 139, + 139, 141, 141, 149, 149, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 140, 150, 150, 152, 151, + 151, 153, 153, 114, 154, 154, 156, 156, 156, 155, + 155, 62, 104, 157, 157, 56, 56, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 164, 165, 165, 166, 158, 158, 163, + 163, 167, 168, 168, 169, 170, 171, 171, 171, 171, + 19, 19, 73, 73, 73, 73, 159, 159, 159, 159, + 173, 173, 162, 162, 162, 160, 160, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 180, 180, 180, + 108, 182, 182, 182, 182, 161, 161, 161, 161, 161, + 161, 161, 161, 59, 59, 176, 176, 176, 176, 176, + 183, 183, 172, 172, 172, 172, 184, 184, 184, 184, + 184, 184, 74, 74, 66, 66, 66, 66, 134, 134, + 134, 134, 187, 186, 175, 175, 175, 175, 175, 175, + 175, 174, 174, 174, 185, 185, 185, 185, 107, 181, + 189, 189, 188, 188, 190, 190, 190, 190, 190, 190, + 190, 190, 178, 178, 178, 178, 177, 192, 191, 191, + 191, 191, 191, 191, 191, 191, 193, 193, 193, 193 + ); + + protected array $ruleToLength = array( + 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 0, 1, 1, 2, 1, 3, 4, 1, 2, + 0, 1, 1, 1, 1, 4, 3, 5, 4, 3, + 4, 1, 3, 4, 1, 1, 8, 7, 2, 3, + 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, + 3, 1, 2, 2, 3, 1, 3, 2, 3, 1, + 3, 3, 2, 0, 1, 1, 1, 1, 1, 3, + 7, 10, 5, 7, 9, 5, 3, 3, 3, 3, + 3, 3, 1, 2, 5, 7, 9, 6, 5, 6, + 3, 2, 1, 1, 1, 1, 0, 2, 1, 3, + 8, 0, 4, 2, 1, 3, 0, 1, 0, 1, + 0, 1, 3, 1, 1, 1, 1, 1, 8, 9, + 7, 8, 7, 6, 8, 0, 2, 0, 2, 1, + 2, 1, 2, 1, 1, 1, 0, 2, 0, 2, + 0, 2, 2, 1, 3, 1, 4, 1, 4, 1, + 1, 4, 2, 1, 3, 3, 3, 4, 4, 5, + 0, 2, 4, 3, 1, 1, 7, 0, 2, 1, + 3, 3, 4, 1, 4, 0, 2, 5, 0, 2, + 6, 0, 2, 0, 3, 1, 2, 1, 1, 2, + 0, 1, 3, 0, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 7, 9, 6, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, + 3, 3, 3, 3, 3, 1, 3, 3, 1, 1, + 2, 1, 1, 0, 1, 0, 2, 2, 2, 4, + 3, 2, 4, 4, 3, 3, 1, 3, 1, 1, + 3, 2, 2, 3, 1, 1, 2, 3, 1, 1, + 2, 3, 1, 1, 3, 2, 0, 1, 5, 5, + 6, 10, 3, 5, 1, 1, 3, 0, 2, 4, + 5, 4, 4, 4, 3, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 3, 1, 1, + 3, 0, 2, 0, 5, 8, 1, 3, 3, 0, + 2, 2, 2, 3, 1, 0, 1, 1, 3, 3, + 3, 4, 4, 1, 1, 2, 2, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 5, 4, 3, + 4, 4, 2, 2, 4, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 1, 3, 2, + 1, 2, 4, 2, 2, 8, 9, 8, 9, 9, + 10, 9, 10, 8, 3, 2, 2, 1, 1, 0, + 4, 2, 1, 3, 2, 1, 2, 2, 2, 4, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, + 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 5, 3, + 3, 4, 1, 1, 3, 1, 1, 1, 1, 1, + 3, 2, 3, 0, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 1, 4, 4, 1, + 4, 4, 0, 1, 1, 1, 3, 3, 1, 4, + 2, 2, 1, 3, 1, 4, 4, 3, 3, 3, + 3, 1, 3, 1, 1, 3, 1, 1, 4, 1, + 1, 1, 3, 1, 1, 2, 1, 3, 4, 3, + 2, 0, 2, 2, 1, 2, 1, 1, 1, 4, + 3, 3, 3, 3, 6, 3, 1, 1, 2, 1 + ); + + protected function initReduceCallbacks(): void { + $this->reduceCallbacks = [ + 0 => null, + 1 => static function ($self, $stackPos) { + $self->semValue = $self->handleNamespaces($self->semStack[$stackPos-(1-1)]); + }, + 2 => static function ($self, $stackPos) { + if ($self->semStack[$stackPos-(2-2)] !== null) { $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; } $self->semValue = $self->semStack[$stackPos-(2-1)];; + }, + 3 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 4 => static function ($self, $stackPos) { + $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);; + if ($nop !== null) { $self->semStack[$stackPos-(1-1)][] = $nop; } $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 5 => null, + 6 => null, + 7 => null, + 8 => null, + 9 => null, + 10 => null, + 11 => null, + 12 => null, + 13 => null, + 14 => null, + 15 => null, + 16 => null, + 17 => null, + 18 => null, + 19 => null, + 20 => null, + 21 => null, + 22 => null, + 23 => null, + 24 => null, + 25 => null, + 26 => null, + 27 => null, + 28 => null, + 29 => null, + 30 => null, + 31 => null, + 32 => null, + 33 => null, + 34 => null, + 35 => null, + 36 => null, + 37 => null, + 38 => null, + 39 => null, + 40 => null, + 41 => null, + 42 => null, + 43 => null, + 44 => null, + 45 => null, + 46 => null, + 47 => null, + 48 => null, + 49 => null, + 50 => null, + 51 => null, + 52 => null, + 53 => null, + 54 => null, + 55 => null, + 56 => null, + 57 => null, + 58 => null, + 59 => null, + 60 => null, + 61 => null, + 62 => null, + 63 => null, + 64 => null, + 65 => null, + 66 => null, + 67 => null, + 68 => null, + 69 => null, + 70 => null, + 71 => null, + 72 => null, + 73 => null, + 74 => null, + 75 => null, + 76 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; if ($self->semValue === "emitError(new Error('Cannot use "getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]))); + }, + 77 => null, + 78 => null, + 79 => null, + 80 => null, + 81 => null, + 82 => null, + 83 => null, + 84 => null, + 85 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 86 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 87 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 88 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 89 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 90 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 91 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 92 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 93 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 94 => null, + 95 => static function ($self, $stackPos) { + $self->semValue = new Name(substr($self->semStack[$stackPos-(1-1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 96 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable(substr($self->semStack[$stackPos-(1-1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 97 => static function ($self, $stackPos) { + /* nothing */ + }, + 98 => static function ($self, $stackPos) { + /* nothing */ + }, + 99 => static function ($self, $stackPos) { + /* nothing */ + }, + 100 => static function ($self, $stackPos) { + $self->emitError(new Error('A trailing comma is not allowed here', $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]))); + }, + 101 => null, + 102 => null, + 103 => static function ($self, $stackPos) { + $self->semValue = new Node\Attribute($self->semStack[$stackPos-(1-1)], [], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 104 => static function ($self, $stackPos) { + $self->semValue = new Node\Attribute($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 105 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 106 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 107 => static function ($self, $stackPos) { + $self->semValue = new Node\AttributeGroup($self->semStack[$stackPos-(4-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 108 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 109 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 110 => static function ($self, $stackPos) { + $self->semValue = []; + }, + 111 => null, + 112 => null, + 113 => null, + 114 => null, + 115 => static function ($self, $stackPos) { + $self->semValue = new Stmt\HaltCompiler($self->handleHaltCompiler(), $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 116 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos-(3-2)], null, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); + $self->checkNamespace($self->semValue); + }, + 117 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos-(5-2)], $self->semStack[$stackPos-(5-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $self->checkNamespace($self->semValue); + }, + 118 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Namespace_(null, $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $self->checkNamespace($self->semValue); + }, + 119 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Use_($self->semStack[$stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 120 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Use_($self->semStack[$stackPos-(4-3)], $self->semStack[$stackPos-(4-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 121 => null, + 122 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Const_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]), []); + }, + 123 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Const_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(4-1)]); + $self->checkConstantAttributes($self->semValue); + }, + 124 => static function ($self, $stackPos) { + $self->semValue = Stmt\Use_::TYPE_FUNCTION; + }, + 125 => static function ($self, $stackPos) { + $self->semValue = Stmt\Use_::TYPE_CONSTANT; + }, + 126 => static function ($self, $stackPos) { + $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos-(8-3)], $self->semStack[$stackPos-(8-6)], $self->semStack[$stackPos-(8-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + }, + 127 => static function ($self, $stackPos) { + $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos-(7-2)], $self->semStack[$stackPos-(7-5)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + }, + 128 => null, + 129 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 130 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 131 => null, + 132 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 133 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 134 => null, + 135 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 136 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 137 => static function ($self, $stackPos) { + $self->semValue = new Node\UseItem($self->semStack[$stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); $self->checkUseUse($self->semValue, $stackPos-(1-1)); + }, + 138 => static function ($self, $stackPos) { + $self->semValue = new Node\UseItem($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); $self->checkUseUse($self->semValue, $stackPos-(3-3)); + }, + 139 => static function ($self, $stackPos) { + $self->semValue = new Node\UseItem($self->semStack[$stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); $self->checkUseUse($self->semValue, $stackPos-(1-1)); + }, + 140 => static function ($self, $stackPos) { + $self->semValue = new Node\UseItem($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); $self->checkUseUse($self->semValue, $stackPos-(3-3)); + }, + 141 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; $self->semValue->type = Stmt\Use_::TYPE_NORMAL; + }, + 142 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; $self->semValue->type = $self->semStack[$stackPos-(2-1)]; + }, + 143 => null, + 144 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 145 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 146 => static function ($self, $stackPos) { + $self->semValue = new Node\Const_($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 147 => null, + 148 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 149 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 150 => static function ($self, $stackPos) { + $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos-(3-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos-(3-1)])), $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 151 => static function ($self, $stackPos) { + $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos-(3-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos-(3-1)])), $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 152 => static function ($self, $stackPos) { + if ($self->semStack[$stackPos-(2-2)] !== null) { $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; } $self->semValue = $self->semStack[$stackPos-(2-1)];; + }, + 153 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 154 => static function ($self, $stackPos) { + $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);; + if ($nop !== null) { $self->semStack[$stackPos-(1-1)][] = $nop; } $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 155 => null, + 156 => null, + 157 => null, + 158 => static function ($self, $stackPos) { + throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 159 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Block($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 160 => static function ($self, $stackPos) { + $self->semValue = new Stmt\If_($self->semStack[$stackPos-(7-3)], ['stmts' => $self->semStack[$stackPos-(7-5)], 'elseifs' => $self->semStack[$stackPos-(7-6)], 'else' => $self->semStack[$stackPos-(7-7)]], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + }, + 161 => static function ($self, $stackPos) { + $self->semValue = new Stmt\If_($self->semStack[$stackPos-(10-3)], ['stmts' => $self->semStack[$stackPos-(10-6)], 'elseifs' => $self->semStack[$stackPos-(10-7)], 'else' => $self->semStack[$stackPos-(10-8)]], $self->getAttributes($self->tokenStartStack[$stackPos-(10-1)], $self->tokenEndStack[$stackPos])); + }, + 162 => static function ($self, $stackPos) { + $self->semValue = new Stmt\While_($self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 163 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Do_($self->semStack[$stackPos-(7-5)], $self->semStack[$stackPos-(7-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + }, + 164 => static function ($self, $stackPos) { + $self->semValue = new Stmt\For_(['init' => $self->semStack[$stackPos-(9-3)], 'cond' => $self->semStack[$stackPos-(9-5)], 'loop' => $self->semStack[$stackPos-(9-7)], 'stmts' => $self->semStack[$stackPos-(9-9)]], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 165 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Switch_($self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 166 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Break_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 167 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Continue_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 168 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Return_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 169 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Global_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 170 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Static_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 171 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Echo_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 172 => static function ($self, $stackPos) { + + $self->semValue = new Stmt\InlineHTML($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + $self->semValue->setAttribute('hasLeadingNewline', $self->inlineHtmlHasLeadingNewline($stackPos-(1-1))); + + }, + 173 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Expression($self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 174 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Unset_($self->semStack[$stackPos-(5-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 175 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos-(7-3)], $self->semStack[$stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $self->semStack[$stackPos-(7-5)][1], 'stmts' => $self->semStack[$stackPos-(7-7)]], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + }, + 176 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos-(9-3)], $self->semStack[$stackPos-(9-7)][0], ['keyVar' => $self->semStack[$stackPos-(9-5)], 'byRef' => $self->semStack[$stackPos-(9-7)][1], 'stmts' => $self->semStack[$stackPos-(9-9)]], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 177 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos-(6-3)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(6-4)], $self->tokenEndStack[$stackPos-(6-4)])), ['stmts' => $self->semStack[$stackPos-(6-6)]], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])); + }, + 178 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Declare_($self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 179 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TryCatch($self->semStack[$stackPos-(6-3)], $self->semStack[$stackPos-(6-5)], $self->semStack[$stackPos-(6-6)], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])); $self->checkTryCatch($self->semValue); + }, + 180 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Goto_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 181 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Label($self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 182 => static function ($self, $stackPos) { + $self->semValue = null; /* means: no statement */ + }, + 183 => null, + 184 => static function ($self, $stackPos) { + $self->semValue = $self->maybeCreateNop($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]); + }, + 185 => static function ($self, $stackPos) { + if ($self->semStack[$stackPos-(1-1)] instanceof Stmt\Block) { $self->semValue = $self->semStack[$stackPos-(1-1)]->stmts; } else if ($self->semStack[$stackPos-(1-1)] === null) { $self->semValue = []; } else { $self->semValue = [$self->semStack[$stackPos-(1-1)]]; }; + }, + 186 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 187 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 188 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 189 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 190 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Catch_($self->semStack[$stackPos-(8-3)], $self->semStack[$stackPos-(8-4)], $self->semStack[$stackPos-(8-7)], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + }, + 191 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 192 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Finally_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 193 => null, + 194 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 195 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 196 => static function ($self, $stackPos) { + $self->semValue = false; + }, + 197 => static function ($self, $stackPos) { + $self->semValue = true; + }, + 198 => static function ($self, $stackPos) { + $self->semValue = false; + }, + 199 => static function ($self, $stackPos) { + $self->semValue = true; + }, + 200 => static function ($self, $stackPos) { + $self->semValue = false; + }, + 201 => static function ($self, $stackPos) { + $self->semValue = true; + }, + 202 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 203 => static function ($self, $stackPos) { + $self->semValue = []; + }, + 204 => null, + 205 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 206 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 207 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 208 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Function_($self->semStack[$stackPos-(8-3)], ['byRef' => $self->semStack[$stackPos-(8-2)], 'params' => $self->semStack[$stackPos-(8-5)], 'returnType' => $self->semStack[$stackPos-(8-7)], 'stmts' => $self->semStack[$stackPos-(8-8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + }, + 209 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Function_($self->semStack[$stackPos-(9-4)], ['byRef' => $self->semStack[$stackPos-(9-3)], 'params' => $self->semStack[$stackPos-(9-6)], 'returnType' => $self->semStack[$stackPos-(9-8)], 'stmts' => $self->semStack[$stackPos-(9-9)], 'attrGroups' => $self->semStack[$stackPos-(9-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 210 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Class_($self->semStack[$stackPos-(7-2)], ['type' => $self->semStack[$stackPos-(7-1)], 'extends' => $self->semStack[$stackPos-(7-3)], 'implements' => $self->semStack[$stackPos-(7-4)], 'stmts' => $self->semStack[$stackPos-(7-6)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + $self->checkClass($self->semValue, $stackPos-(7-2)); + }, + 211 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Class_($self->semStack[$stackPos-(8-3)], ['type' => $self->semStack[$stackPos-(8-2)], 'extends' => $self->semStack[$stackPos-(8-4)], 'implements' => $self->semStack[$stackPos-(8-5)], 'stmts' => $self->semStack[$stackPos-(8-7)], 'attrGroups' => $self->semStack[$stackPos-(8-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + $self->checkClass($self->semValue, $stackPos-(8-3)); + }, + 212 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Interface_($self->semStack[$stackPos-(7-3)], ['extends' => $self->semStack[$stackPos-(7-4)], 'stmts' => $self->semStack[$stackPos-(7-6)], 'attrGroups' => $self->semStack[$stackPos-(7-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + $self->checkInterface($self->semValue, $stackPos-(7-3)); + }, + 213 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Trait_($self->semStack[$stackPos-(6-3)], ['stmts' => $self->semStack[$stackPos-(6-5)], 'attrGroups' => $self->semStack[$stackPos-(6-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])); + }, + 214 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Enum_($self->semStack[$stackPos-(8-3)], ['scalarType' => $self->semStack[$stackPos-(8-4)], 'implements' => $self->semStack[$stackPos-(8-5)], 'stmts' => $self->semStack[$stackPos-(8-7)], 'attrGroups' => $self->semStack[$stackPos-(8-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + $self->checkEnum($self->semValue, $stackPos-(8-3)); + }, + 215 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 216 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 217 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 218 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 219 => static function ($self, $stackPos) { + $self->semValue = 0; + }, + 220 => null, + 221 => null, + 222 => static function ($self, $stackPos) { + $self->checkClassModifier($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $self->semValue = $self->semStack[$stackPos-(2-1)] | $self->semStack[$stackPos-(2-2)]; + }, + 223 => static function ($self, $stackPos) { + $self->semValue = Modifiers::ABSTRACT; + }, + 224 => static function ($self, $stackPos) { + $self->semValue = Modifiers::FINAL; + }, + 225 => static function ($self, $stackPos) { + $self->semValue = Modifiers::READONLY; + }, + 226 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 227 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 228 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 229 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 230 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 231 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 232 => null, + 233 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 234 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 235 => null, + 236 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 237 => null, + 238 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 239 => static function ($self, $stackPos) { + if ($self->semStack[$stackPos-(1-1)] instanceof Stmt\Block) { $self->semValue = $self->semStack[$stackPos-(1-1)]->stmts; } else if ($self->semStack[$stackPos-(1-1)] === null) { $self->semValue = []; } else { $self->semValue = [$self->semStack[$stackPos-(1-1)]]; }; + }, + 240 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 241 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 242 => null, + 243 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 244 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 245 => static function ($self, $stackPos) { + $self->semValue = new Node\DeclareItem($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 246 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 247 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-3)]; + }, + 248 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 249 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(5-3)]; + }, + 250 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 251 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 252 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Case_($self->semStack[$stackPos-(4-2)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 253 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Case_(null, $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 254 => null, + 255 => null, + 256 => static function ($self, $stackPos) { + $self->semValue = new Expr\Match_($self->semStack[$stackPos-(7-3)], $self->semStack[$stackPos-(7-6)], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + }, + 257 => static function ($self, $stackPos) { + $self->semValue = []; + }, + 258 => null, + 259 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 260 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 261 => static function ($self, $stackPos) { + $self->semValue = new Node\MatchArm($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 262 => static function ($self, $stackPos) { + $self->semValue = new Node\MatchArm(null, $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 263 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 264 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 265 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 266 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 267 => static function ($self, $stackPos) { + $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 268 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 269 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 270 => static function ($self, $stackPos) { + $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos-(6-3)], $self->semStack[$stackPos-(6-6)], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])); $self->fixupAlternativeElse($self->semValue); + }, + 271 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 272 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Else_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 273 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 274 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Else_($self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); $self->fixupAlternativeElse($self->semValue); + }, + 275 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)], false); + }, + 276 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(2-2)], true); + }, + 277 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)], false); + }, + 278 => static function ($self, $stackPos) { + $self->semValue = array($self->fixupArrayDestructuring($self->semStack[$stackPos-(1-1)]), false); + }, + 279 => null, + 280 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 281 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 282 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 283 => static function ($self, $stackPos) { + $self->semValue = 0; + }, + 284 => static function ($self, $stackPos) { + $self->checkModifier($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $self->semValue = $self->semStack[$stackPos-(2-1)] | $self->semStack[$stackPos-(2-2)]; + }, + 285 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PUBLIC; + }, + 286 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PROTECTED; + }, + 287 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PRIVATE; + }, + 288 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PUBLIC_SET; + }, + 289 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PROTECTED_SET; + }, + 290 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PRIVATE_SET; + }, + 291 => static function ($self, $stackPos) { + $self->semValue = Modifiers::READONLY; + }, + 292 => static function ($self, $stackPos) { + $self->semValue = Modifiers::FINAL; + }, + 293 => static function ($self, $stackPos) { + $self->semValue = new Node\Param($self->semStack[$stackPos-(7-6)], null, $self->semStack[$stackPos-(7-3)], $self->semStack[$stackPos-(7-4)], $self->semStack[$stackPos-(7-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(7-2)], $self->semStack[$stackPos-(7-1)], $self->semStack[$stackPos-(7-7)]); + $self->checkParam($self->semValue); + $self->addPropertyNameToHooks($self->semValue); + }, + 294 => static function ($self, $stackPos) { + $self->semValue = new Node\Param($self->semStack[$stackPos-(9-6)], $self->semStack[$stackPos-(9-8)], $self->semStack[$stackPos-(9-3)], $self->semStack[$stackPos-(9-4)], $self->semStack[$stackPos-(9-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(9-2)], $self->semStack[$stackPos-(9-1)], $self->semStack[$stackPos-(9-9)]); + $self->checkParam($self->semValue); + $self->addPropertyNameToHooks($self->semValue); + }, + 295 => static function ($self, $stackPos) { + $self->semValue = new Node\Param(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])), null, $self->semStack[$stackPos-(6-3)], $self->semStack[$stackPos-(6-4)], $self->semStack[$stackPos-(6-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(6-2)], $self->semStack[$stackPos-(6-1)]); + }, + 296 => null, + 297 => static function ($self, $stackPos) { + $self->semValue = new Node\NullableType($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 298 => static function ($self, $stackPos) { + $self->semValue = new Node\UnionType($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 299 => null, + 300 => null, + 301 => static function ($self, $stackPos) { + $self->semValue = new Node\Name('static', $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 302 => static function ($self, $stackPos) { + $self->semValue = $self->handleBuiltinTypes($self->semStack[$stackPos-(1-1)]); + }, + 303 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier('array', $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 304 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier('callable', $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 305 => null, + 306 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 307 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)]); + }, + 308 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 309 => null, + 310 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 311 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)]); + }, + 312 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 313 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)]); + }, + 314 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 315 => static function ($self, $stackPos) { + $self->semValue = new Node\IntersectionType($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 316 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)]); + }, + 317 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 318 => static function ($self, $stackPos) { + $self->semValue = new Node\IntersectionType($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 319 => null, + 320 => static function ($self, $stackPos) { + $self->semValue = new Node\NullableType($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 321 => static function ($self, $stackPos) { + $self->semValue = new Node\UnionType($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 322 => null, + 323 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 324 => null, + 325 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 326 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 327 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 328 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 329 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 330 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-2)]); + }, + 331 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 332 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 333 => static function ($self, $stackPos) { + $self->semValue = array(new Node\Arg($self->semStack[$stackPos-(4-2)], false, false, $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos]))); + }, + 334 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-2)]); + }, + 335 => static function ($self, $stackPos) { + $self->semValue = array(new Node\Arg($self->semStack[$stackPos-(3-1)], false, false, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos-(3-1)])), $self->semStack[$stackPos-(3-3)]); + }, + 336 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 337 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 338 => static function ($self, $stackPos) { + $self->semValue = new Node\VariadicPlaceholder($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 339 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 340 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 341 => static function ($self, $stackPos) { + $self->semValue = new Node\Arg($self->semStack[$stackPos-(2-2)], true, false, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 342 => static function ($self, $stackPos) { + $self->semValue = new Node\Arg($self->semStack[$stackPos-(2-2)], false, true, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 343 => static function ($self, $stackPos) { + $self->semValue = new Node\Arg($self->semStack[$stackPos-(3-3)], false, false, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(3-1)]); + }, + 344 => static function ($self, $stackPos) { + $self->semValue = new Node\Arg($self->semStack[$stackPos-(1-1)], false, false, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 345 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 346 => null, + 347 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 348 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 349 => null, + 350 => null, + 351 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 352 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 353 => static function ($self, $stackPos) { + $self->semValue = new Node\StaticVar($self->semStack[$stackPos-(1-1)], null, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 354 => static function ($self, $stackPos) { + $self->semValue = new Node\StaticVar($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 355 => static function ($self, $stackPos) { + if ($self->semStack[$stackPos-(2-2)] !== null) { $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; } else { $self->semValue = $self->semStack[$stackPos-(2-1)]; } + }, + 356 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 357 => static function ($self, $stackPos) { + $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);; + if ($nop !== null) { $self->semStack[$stackPos-(1-1)][] = $nop; } $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 358 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Property($self->semStack[$stackPos-(5-2)], $self->semStack[$stackPos-(5-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-1)]); + }, + 359 => static function ($self, $stackPos) { + $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos-(5-4)], $self->semStack[$stackPos-(5-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(5-1)]); + $self->checkClassConst($self->semValue, $stackPos-(5-2)); + }, + 360 => static function ($self, $stackPos) { + $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos-(6-5)], $self->semStack[$stackPos-(6-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(6-1)], $self->semStack[$stackPos-(6-4)]); + $self->checkClassConst($self->semValue, $stackPos-(6-2)); + }, + 361 => static function ($self, $stackPos) { + $self->semValue = new Stmt\ClassMethod($self->semStack[$stackPos-(10-5)], ['type' => $self->semStack[$stackPos-(10-2)], 'byRef' => $self->semStack[$stackPos-(10-4)], 'params' => $self->semStack[$stackPos-(10-7)], 'returnType' => $self->semStack[$stackPos-(10-9)], 'stmts' => $self->semStack[$stackPos-(10-10)], 'attrGroups' => $self->semStack[$stackPos-(10-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(10-1)], $self->tokenEndStack[$stackPos])); + $self->checkClassMethod($self->semValue, $stackPos-(10-2)); + }, + 362 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUse($self->semStack[$stackPos-(3-2)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 363 => static function ($self, $stackPos) { + $self->semValue = new Stmt\EnumCase($self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-4)], $self->semStack[$stackPos-(5-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 364 => static function ($self, $stackPos) { + $self->semValue = null; /* will be skipped */ + }, + 365 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 366 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 367 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 368 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 369 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUseAdaptation\Precedence($self->semStack[$stackPos-(4-1)][0], $self->semStack[$stackPos-(4-1)][1], $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 370 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos-(5-1)][0], $self->semStack[$stackPos-(5-1)][1], $self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 371 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos-(4-1)][0], $self->semStack[$stackPos-(4-1)][1], $self->semStack[$stackPos-(4-3)], null, $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 372 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos-(4-1)][0], $self->semStack[$stackPos-(4-1)][1], null, $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 373 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos-(4-1)][0], $self->semStack[$stackPos-(4-1)][1], null, $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 374 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)]); + }, + 375 => null, + 376 => static function ($self, $stackPos) { + $self->semValue = array(null, $self->semStack[$stackPos-(1-1)]); + }, + 377 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 378 => null, + 379 => null, + 380 => static function ($self, $stackPos) { + $self->semValue = 0; + }, + 381 => static function ($self, $stackPos) { + $self->semValue = 0; + }, + 382 => null, + 383 => null, + 384 => static function ($self, $stackPos) { + $self->checkModifier($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $self->semValue = $self->semStack[$stackPos-(2-1)] | $self->semStack[$stackPos-(2-2)]; + }, + 385 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PUBLIC; + }, + 386 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PROTECTED; + }, + 387 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PRIVATE; + }, + 388 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PUBLIC_SET; + }, + 389 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PROTECTED_SET; + }, + 390 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PRIVATE_SET; + }, + 391 => static function ($self, $stackPos) { + $self->semValue = Modifiers::STATIC; + }, + 392 => static function ($self, $stackPos) { + $self->semValue = Modifiers::ABSTRACT; + }, + 393 => static function ($self, $stackPos) { + $self->semValue = Modifiers::FINAL; + }, + 394 => static function ($self, $stackPos) { + $self->semValue = Modifiers::READONLY; + }, + 395 => null, + 396 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 397 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 398 => static function ($self, $stackPos) { + $self->semValue = new Node\VarLikeIdentifier(substr($self->semStack[$stackPos-(1-1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 399 => static function ($self, $stackPos) { + $self->semValue = new Node\PropertyItem($self->semStack[$stackPos-(1-1)], null, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 400 => static function ($self, $stackPos) { + $self->semValue = new Node\PropertyItem($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 401 => static function ($self, $stackPos) { + $self->semValue = []; + }, + 402 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 403 => static function ($self, $stackPos) { + $self->semValue = []; + }, + 404 => static function ($self, $stackPos) { + $self->semValue = new Node\PropertyHook($self->semStack[$stackPos-(5-4)], $self->semStack[$stackPos-(5-5)], ['flags' => $self->semStack[$stackPos-(5-2)], 'byRef' => $self->semStack[$stackPos-(5-3)], 'params' => [], 'attrGroups' => $self->semStack[$stackPos-(5-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + $self->checkPropertyHook($self->semValue, null); + }, + 405 => static function ($self, $stackPos) { + $self->semValue = new Node\PropertyHook($self->semStack[$stackPos-(8-4)], $self->semStack[$stackPos-(8-8)], ['flags' => $self->semStack[$stackPos-(8-2)], 'byRef' => $self->semStack[$stackPos-(8-3)], 'params' => $self->semStack[$stackPos-(8-6)], 'attrGroups' => $self->semStack[$stackPos-(8-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + $self->checkPropertyHook($self->semValue, $stackPos-(8-5)); + }, + 406 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 407 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 408 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 409 => static function ($self, $stackPos) { + $self->semValue = 0; + }, + 410 => static function ($self, $stackPos) { + $self->checkPropertyHookModifiers($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $self->semValue = $self->semStack[$stackPos-(2-1)] | $self->semStack[$stackPos-(2-2)]; + }, + 411 => null, + 412 => null, + 413 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 414 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 415 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 416 => null, + 417 => null, + 418 => static function ($self, $stackPos) { + $self->semValue = new Expr\Assign($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 419 => static function ($self, $stackPos) { + $self->semValue = new Expr\Assign($self->fixupArrayDestructuring($self->semStack[$stackPos-(3-1)]), $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 420 => static function ($self, $stackPos) { + $self->semValue = new Expr\Assign($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 421 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignRef($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 422 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignRef($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + if (!$self->phpVersion->allowsAssignNewByReference()) { + $self->emitError(new Error('Cannot assign new by reference', $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos]))); + } + + }, + 423 => null, + 424 => null, + 425 => static function ($self, $stackPos) { + $self->semValue = new Expr\FuncCall(new Node\Name($self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos-(2-1)])), $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 426 => static function ($self, $stackPos) { + $self->semValue = new Expr\Clone_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 427 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Plus($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 428 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Minus($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 429 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Mul($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 430 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Div($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 431 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Concat($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 432 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Mod($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 433 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\BitwiseAnd($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 434 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\BitwiseOr($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 435 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\BitwiseXor($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 436 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\ShiftLeft($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 437 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\ShiftRight($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 438 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Pow($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 439 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Coalesce($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 440 => static function ($self, $stackPos) { + $self->semValue = new Expr\PostInc($self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 441 => static function ($self, $stackPos) { + $self->semValue = new Expr\PreInc($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 442 => static function ($self, $stackPos) { + $self->semValue = new Expr\PostDec($self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 443 => static function ($self, $stackPos) { + $self->semValue = new Expr\PreDec($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 444 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BooleanOr($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 445 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BooleanAnd($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 446 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\LogicalOr($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 447 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\LogicalAnd($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 448 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\LogicalXor($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 449 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BitwiseOr($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 450 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 451 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 452 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BitwiseXor($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 453 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Concat($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 454 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Plus($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 455 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Minus($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 456 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Mul($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 457 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Div($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 458 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Mod($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 459 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\ShiftLeft($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 460 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\ShiftRight($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 461 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Pow($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 462 => static function ($self, $stackPos) { + $self->semValue = new Expr\UnaryPlus($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 463 => static function ($self, $stackPos) { + $self->semValue = new Expr\UnaryMinus($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 464 => static function ($self, $stackPos) { + $self->semValue = new Expr\BooleanNot($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 465 => static function ($self, $stackPos) { + $self->semValue = new Expr\BitwiseNot($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 466 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Identical($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 467 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\NotIdentical($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 468 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Equal($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 469 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\NotEqual($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 470 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Spaceship($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 471 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Smaller($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 472 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\SmallerOrEqual($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 473 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Greater($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 474 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\GreaterOrEqual($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 475 => static function ($self, $stackPos) { + $self->semValue = new Expr\Instanceof_($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 476 => static function ($self, $stackPos) { + + $self->semValue = $self->semStack[$stackPos-(3-2)]; + if ($self->semValue instanceof Expr\ArrowFunction) { + $self->parenthesizedArrowFunctions->offsetSet($self->semValue); + } + + }, + 477 => static function ($self, $stackPos) { + $self->semValue = new Expr\Ternary($self->semStack[$stackPos-(5-1)], $self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 478 => static function ($self, $stackPos) { + $self->semValue = new Expr\Ternary($self->semStack[$stackPos-(4-1)], null, $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 479 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Coalesce($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 480 => static function ($self, $stackPos) { + $self->semValue = new Expr\Isset_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 481 => static function ($self, $stackPos) { + $self->semValue = new Expr\Empty_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 482 => static function ($self, $stackPos) { + $self->semValue = new Expr\Include_($self->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 483 => static function ($self, $stackPos) { + $self->semValue = new Expr\Include_($self->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 484 => static function ($self, $stackPos) { + $self->semValue = new Expr\Eval_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 485 => static function ($self, $stackPos) { + $self->semValue = new Expr\Include_($self->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 486 => static function ($self, $stackPos) { + $self->semValue = new Expr\Include_($self->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 487 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]); + $attrs['kind'] = $self->getIntCastKind($self->semStack[$stackPos-(2-1)]); + $self->semValue = new Expr\Cast\Int_($self->semStack[$stackPos-(2-2)], $attrs); + }, + 488 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]); + $attrs['kind'] = $self->getFloatCastKind($self->semStack[$stackPos-(2-1)]); + $self->semValue = new Expr\Cast\Double($self->semStack[$stackPos-(2-2)], $attrs); + }, + 489 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]); + $attrs['kind'] = $self->getStringCastKind($self->semStack[$stackPos-(2-1)]); + $self->semValue = new Expr\Cast\String_($self->semStack[$stackPos-(2-2)], $attrs); + }, + 490 => static function ($self, $stackPos) { + $self->semValue = new Expr\Cast\Array_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 491 => static function ($self, $stackPos) { + $self->semValue = new Expr\Cast\Object_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 492 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]); + $attrs['kind'] = $self->getBoolCastKind($self->semStack[$stackPos-(2-1)]); + $self->semValue = new Expr\Cast\Bool_($self->semStack[$stackPos-(2-2)], $attrs); + }, + 493 => static function ($self, $stackPos) { + $self->semValue = new Expr\Cast\Unset_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 494 => static function ($self, $stackPos) { + $self->semValue = new Expr\Cast\Void_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 495 => static function ($self, $stackPos) { + $self->semValue = $self->createExitExpr($self->semStack[$stackPos-(2-1)], $stackPos-(2-1), $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 496 => static function ($self, $stackPos) { + $self->semValue = new Expr\ErrorSuppress($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 497 => null, + 498 => static function ($self, $stackPos) { + $self->semValue = new Expr\ShellExec($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 499 => static function ($self, $stackPos) { + $self->semValue = new Expr\Print_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 500 => static function ($self, $stackPos) { + $self->semValue = new Expr\Yield_(null, null, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 501 => static function ($self, $stackPos) { + $self->semValue = new Expr\Yield_($self->semStack[$stackPos-(2-2)], null, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 502 => static function ($self, $stackPos) { + $self->semValue = new Expr\Yield_($self->semStack[$stackPos-(4-4)], $self->semStack[$stackPos-(4-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 503 => static function ($self, $stackPos) { + $self->semValue = new Expr\YieldFrom($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 504 => static function ($self, $stackPos) { + $self->semValue = new Expr\Throw_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 505 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrowFunction(['static' => false, 'byRef' => $self->semStack[$stackPos-(8-2)], 'params' => $self->semStack[$stackPos-(8-4)], 'returnType' => $self->semStack[$stackPos-(8-6)], 'expr' => $self->semStack[$stackPos-(8-8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + }, + 506 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrowFunction(['static' => true, 'byRef' => $self->semStack[$stackPos-(9-3)], 'params' => $self->semStack[$stackPos-(9-5)], 'returnType' => $self->semStack[$stackPos-(9-7)], 'expr' => $self->semStack[$stackPos-(9-9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 507 => static function ($self, $stackPos) { + $self->semValue = new Expr\Closure(['static' => false, 'byRef' => $self->semStack[$stackPos-(8-2)], 'params' => $self->semStack[$stackPos-(8-4)], 'uses' => $self->semStack[$stackPos-(8-6)], 'returnType' => $self->semStack[$stackPos-(8-7)], 'stmts' => $self->semStack[$stackPos-(8-8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + }, + 508 => static function ($self, $stackPos) { + $self->semValue = new Expr\Closure(['static' => true, 'byRef' => $self->semStack[$stackPos-(9-3)], 'params' => $self->semStack[$stackPos-(9-5)], 'uses' => $self->semStack[$stackPos-(9-7)], 'returnType' => $self->semStack[$stackPos-(9-8)], 'stmts' => $self->semStack[$stackPos-(9-9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 509 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrowFunction(['static' => false, 'byRef' => $self->semStack[$stackPos-(9-3)], 'params' => $self->semStack[$stackPos-(9-5)], 'returnType' => $self->semStack[$stackPos-(9-7)], 'expr' => $self->semStack[$stackPos-(9-9)], 'attrGroups' => $self->semStack[$stackPos-(9-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 510 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrowFunction(['static' => true, 'byRef' => $self->semStack[$stackPos-(10-4)], 'params' => $self->semStack[$stackPos-(10-6)], 'returnType' => $self->semStack[$stackPos-(10-8)], 'expr' => $self->semStack[$stackPos-(10-10)], 'attrGroups' => $self->semStack[$stackPos-(10-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(10-1)], $self->tokenEndStack[$stackPos])); + }, + 511 => static function ($self, $stackPos) { + $self->semValue = new Expr\Closure(['static' => false, 'byRef' => $self->semStack[$stackPos-(9-3)], 'params' => $self->semStack[$stackPos-(9-5)], 'uses' => $self->semStack[$stackPos-(9-7)], 'returnType' => $self->semStack[$stackPos-(9-8)], 'stmts' => $self->semStack[$stackPos-(9-9)], 'attrGroups' => $self->semStack[$stackPos-(9-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 512 => static function ($self, $stackPos) { + $self->semValue = new Expr\Closure(['static' => true, 'byRef' => $self->semStack[$stackPos-(10-4)], 'params' => $self->semStack[$stackPos-(10-6)], 'uses' => $self->semStack[$stackPos-(10-8)], 'returnType' => $self->semStack[$stackPos-(10-9)], 'stmts' => $self->semStack[$stackPos-(10-10)], 'attrGroups' => $self->semStack[$stackPos-(10-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(10-1)], $self->tokenEndStack[$stackPos])); + }, + 513 => static function ($self, $stackPos) { + $self->semValue = array(new Stmt\Class_(null, ['type' => $self->semStack[$stackPos-(8-2)], 'extends' => $self->semStack[$stackPos-(8-4)], 'implements' => $self->semStack[$stackPos-(8-5)], 'stmts' => $self->semStack[$stackPos-(8-7)], 'attrGroups' => $self->semStack[$stackPos-(8-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])), $self->semStack[$stackPos-(8-3)]); + $self->checkClass($self->semValue[0], -1); + }, + 514 => static function ($self, $stackPos) { + $self->semValue = new Expr\New_($self->semStack[$stackPos-(3-2)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 515 => static function ($self, $stackPos) { + list($class, $ctorArgs) = $self->semStack[$stackPos-(2-2)]; $self->semValue = new Expr\New_($class, $ctorArgs, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 516 => static function ($self, $stackPos) { + $self->semValue = new Expr\New_($self->semStack[$stackPos-(2-2)], [], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 517 => null, + 518 => null, + 519 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 520 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-3)]; + }, + 521 => null, + 522 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 523 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 524 => static function ($self, $stackPos) { + $self->semValue = new Node\ClosureUse($self->semStack[$stackPos-(2-2)], $self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 525 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 526 => static function ($self, $stackPos) { + $self->semValue = new Expr\FuncCall($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 527 => static function ($self, $stackPos) { + $self->semValue = new Expr\FuncCall($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 528 => static function ($self, $stackPos) { + $self->semValue = new Expr\FuncCall($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 529 => static function ($self, $stackPos) { + $self->semValue = new Expr\StaticCall($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 530 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 531 => null, + 532 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 533 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 534 => static function ($self, $stackPos) { + $self->semValue = new Name\FullyQualified(substr($self->semStack[$stackPos-(1-1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 535 => static function ($self, $stackPos) { + $self->semValue = new Name\Relative(substr($self->semStack[$stackPos-(1-1)], 10), $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 536 => null, + 537 => null, + 538 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 539 => static function ($self, $stackPos) { + $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); $self->errorState = 2; + }, + 540 => null, + 541 => null, + 542 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 543 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); foreach ($self->semValue as $s) { if ($s instanceof Node\InterpolatedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes()); } }; + }, + 544 => static function ($self, $stackPos) { + foreach ($self->semStack[$stackPos-(1-1)] as $s) { if ($s instanceof Node\InterpolatedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes()); } }; $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 545 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 546 => null, + 547 => static function ($self, $stackPos) { + $self->semValue = new Expr\ConstFetch($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 548 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Line($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 549 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\File($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 550 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Dir($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 551 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Class_($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 552 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Trait_($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 553 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Method($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 554 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Function_($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 555 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Namespace_($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 556 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Property($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 557 => static function ($self, $stackPos) { + $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 558 => static function ($self, $stackPos) { + $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos-(5-1)], $self->semStack[$stackPos-(5-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 559 => static function ($self, $stackPos) { + $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos-(3-1)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(3-3)], $self->tokenEndStack[$stackPos-(3-3)])), $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); $self->errorState = 2; + }, + 560 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]); $attrs['kind'] = Expr\Array_::KIND_SHORT; + $self->semValue = new Expr\Array_($self->semStack[$stackPos-(3-2)], $attrs); + }, + 561 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos]); $attrs['kind'] = Expr\Array_::KIND_LONG; + $self->semValue = new Expr\Array_($self->semStack[$stackPos-(4-3)], $attrs); + $self->createdArrays->offsetSet($self->semValue); + }, + 562 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; $self->createdArrays->offsetSet($self->semValue); + }, + 563 => static function ($self, $stackPos) { + $self->semValue = Scalar\String_::fromString($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->supportsUnicodeEscapes()); + }, + 564 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + foreach ($self->semStack[$stackPos-(3-2)] as $s) { if ($s instanceof Node\InterpolatedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', $self->phpVersion->supportsUnicodeEscapes()); } }; $self->semValue = new Scalar\InterpolatedString($self->semStack[$stackPos-(3-2)], $attrs); + }, + 565 => static function ($self, $stackPos) { + $self->semValue = $self->parseLNumber($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->allowsInvalidOctals()); + }, + 566 => static function ($self, $stackPos) { + $self->semValue = Scalar\Float_::fromString($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 567 => null, + 568 => null, + 569 => null, + 570 => static function ($self, $stackPos) { + $self->semValue = $self->parseDocString($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-2)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos-(3-3)], $self->tokenEndStack[$stackPos-(3-3)]), true); + }, + 571 => static function ($self, $stackPos) { + $self->semValue = $self->parseDocString($self->semStack[$stackPos-(2-1)], '', $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos-(2-2)], $self->tokenEndStack[$stackPos-(2-2)]), true); + }, + 572 => static function ($self, $stackPos) { + $self->semValue = $self->parseDocString($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-2)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos-(3-3)], $self->tokenEndStack[$stackPos-(3-3)]), true); + }, + 573 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 574 => null, + 575 => null, + 576 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 577 => null, + 578 => null, + 579 => null, + 580 => null, + 581 => null, + 582 => null, + 583 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 584 => null, + 585 => null, + 586 => null, + 587 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 588 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 589 => null, + 590 => static function ($self, $stackPos) { + $self->semValue = new Expr\MethodCall($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 591 => static function ($self, $stackPos) { + $self->semValue = new Expr\NullsafeMethodCall($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 592 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 593 => null, + 594 => null, + 595 => null, + 596 => static function ($self, $stackPos) { + $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 597 => static function ($self, $stackPos) { + $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 598 => null, + 599 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 600 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 601 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])), $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); $self->errorState = 2; + }, + 602 => static function ($self, $stackPos) { + $var = $self->semStack[$stackPos-(1-1)]->name; $self->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])) : $var; + }, + 603 => static function ($self, $stackPos) { + $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 604 => null, + 605 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 606 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 607 => static function ($self, $stackPos) { + $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 608 => static function ($self, $stackPos) { + $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 609 => static function ($self, $stackPos) { + $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 610 => static function ($self, $stackPos) { + $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 611 => null, + 612 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 613 => null, + 614 => null, + 615 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 616 => null, + 617 => static function ($self, $stackPos) { + $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); $self->errorState = 2; + }, + 618 => static function ($self, $stackPos) { + $self->semValue = new Expr\List_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); $self->semValue->setAttribute('kind', Expr\List_::KIND_LIST); + $self->postprocessList($self->semValue); + }, + 619 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; $end = count($self->semValue)-1; if ($self->semValue[$end]->value instanceof Expr\Error) array_pop($self->semValue); + }, + 620 => null, + 621 => static function ($self, $stackPos) { + /* do nothing -- prevent default action of $$=$self->semStack[$1]. See $551. */ + }, + 622 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 623 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 624 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(1-1)], null, false, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 625 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(2-2)], null, true, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 626 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(1-1)], null, false, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 627 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(3-3)], $self->semStack[$stackPos-(3-1)], false, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 628 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(4-4)], $self->semStack[$stackPos-(4-1)], true, $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 629 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(3-3)], $self->semStack[$stackPos-(3-1)], false, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 630 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(2-2)], null, false, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]), true); + }, + 631 => static function ($self, $stackPos) { + /* Create an Error node now to remember the position. We'll later either report an error, + or convert this into a null element, depending on whether this is a creation or destructuring context. */ + $attrs = $self->createEmptyElemAttributes($self->tokenPos); + $self->semValue = new Node\ArrayItem(new Expr\Error($attrs), null, false, $attrs); + }, + 632 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 633 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 634 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 635 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)]); + }, + 636 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]); $attrs['rawValue'] = $self->semStack[$stackPos-(1-1)]; $self->semValue = new Node\InterpolatedStringPart($self->semStack[$stackPos-(1-1)], $attrs); + }, + 637 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 638 => null, + 639 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 640 => static function ($self, $stackPos) { + $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 641 => static function ($self, $stackPos) { + $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 642 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 643 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 644 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos-(6-2)], $self->semStack[$stackPos-(6-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])); + }, + 645 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 646 => static function ($self, $stackPos) { + $self->semValue = new Scalar\String_($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 647 => static function ($self, $stackPos) { + $self->semValue = $self->parseNumString($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 648 => static function ($self, $stackPos) { + $self->semValue = $self->parseNumString('-' . $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 649 => null, + ]; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Parser/Php8.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Parser/Php8.php new file mode 100644 index 00000000..aed45d70 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Parser/Php8.php @@ -0,0 +1,2917 @@ +'", + "T_IS_GREATER_OR_EQUAL", + "T_PIPE", + "'.'", + "T_SL", + "T_SR", + "'+'", + "'-'", + "'*'", + "'/'", + "'%'", + "'!'", + "T_INSTANCEOF", + "'~'", + "T_INC", + "T_DEC", + "T_INT_CAST", + "T_DOUBLE_CAST", + "T_STRING_CAST", + "T_ARRAY_CAST", + "T_OBJECT_CAST", + "T_BOOL_CAST", + "T_UNSET_CAST", + "'@'", + "T_POW", + "'['", + "T_NEW", + "T_CLONE", + "T_EXIT", + "T_IF", + "T_ELSEIF", + "T_ELSE", + "T_ENDIF", + "T_LNUMBER", + "T_DNUMBER", + "T_STRING", + "T_STRING_VARNAME", + "T_VARIABLE", + "T_NUM_STRING", + "T_INLINE_HTML", + "T_ENCAPSED_AND_WHITESPACE", + "T_CONSTANT_ENCAPSED_STRING", + "T_ECHO", + "T_DO", + "T_WHILE", + "T_ENDWHILE", + "T_FOR", + "T_ENDFOR", + "T_FOREACH", + "T_ENDFOREACH", + "T_DECLARE", + "T_ENDDECLARE", + "T_AS", + "T_SWITCH", + "T_MATCH", + "T_ENDSWITCH", + "T_CASE", + "T_DEFAULT", + "T_BREAK", + "T_CONTINUE", + "T_GOTO", + "T_FUNCTION", + "T_FN", + "T_CONST", + "T_RETURN", + "T_TRY", + "T_CATCH", + "T_FINALLY", + "T_USE", + "T_INSTEADOF", + "T_GLOBAL", + "T_STATIC", + "T_ABSTRACT", + "T_FINAL", + "T_PRIVATE", + "T_PROTECTED", + "T_PUBLIC", + "T_READONLY", + "T_PUBLIC_SET", + "T_PROTECTED_SET", + "T_PRIVATE_SET", + "T_VAR", + "T_UNSET", + "T_ISSET", + "T_EMPTY", + "T_HALT_COMPILER", + "T_CLASS", + "T_TRAIT", + "T_INTERFACE", + "T_ENUM", + "T_EXTENDS", + "T_IMPLEMENTS", + "T_OBJECT_OPERATOR", + "T_NULLSAFE_OBJECT_OPERATOR", + "T_LIST", + "T_ARRAY", + "T_CALLABLE", + "T_CLASS_C", + "T_TRAIT_C", + "T_METHOD_C", + "T_FUNC_C", + "T_PROPERTY_C", + "T_LINE", + "T_FILE", + "T_START_HEREDOC", + "T_END_HEREDOC", + "T_DOLLAR_OPEN_CURLY_BRACES", + "T_CURLY_OPEN", + "T_PAAMAYIM_NEKUDOTAYIM", + "T_NAMESPACE", + "T_NS_C", + "T_DIR", + "T_NS_SEPARATOR", + "T_ELLIPSIS", + "T_NAME_FULLY_QUALIFIED", + "T_NAME_QUALIFIED", + "T_NAME_RELATIVE", + "T_ATTRIBUTE", + "';'", + "']'", + "'('", + "')'", + "'{'", + "'}'", + "'`'", + "'\"'", + "'$'" + ); + + protected array $tokenToSymbol = array( + 0, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 58, 172, 174, 173, 57, 174, 174, + 167, 168, 55, 53, 9, 54, 50, 56, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 32, 165, + 45, 17, 47, 31, 70, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 72, 174, 166, 37, 174, 171, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 169, 36, 170, 60, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 174, 174, 174, 174, 1, 2, 3, 4, + 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, + 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 33, 34, 35, 38, 39, 40, + 41, 42, 43, 44, 46, 48, 49, 51, 52, 59, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164 + ); + + protected array $action = array( + 132, 133, 134, 582, 135, 136, 162, 779, 780, 781, + 137, 41, 863,-32766, 970, 1404, -584, 974, 973, 1302, + 0, 395, 396, 455, 246, 854,-32766,-32766,-32766,-32766, + -32766, 440,-32766, 27,-32766, 773, 772,-32766,-32766,-32766, + -32766, 508,-32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766, + 131,-32766,-32766,-32766,-32766, 437, 782, 859, 1148,-32766, + 949,-32766,-32766,-32766,-32766,-32766,-32766, 972, 1385, 300, + 271, 53, 398, 786, 787, 788, 789, 305, 865, 441, + -341, 39, 254, -584, -584, -195, 843, 790, 791, 792, + 793, 794, 795, 796, 797, 798, 799, 819, 583, 820, + 821, 822, 823, 811, 812, 353, 354, 814, 815, 800, + 801, 802, 804, 805, 806, 368, 846, 847, 848, 849, + 850, 584, 1062, -194, 856, 807, 808, 585, 586, 3, + 831, 829, 830, 842, 826, 827, 4, 860, 587, 588, + 825, 589, 590, 591, 592, 939, 593, 594, 5, 854, + -32766,-32766,-32766, 828, 595, 596,-32766, 138, 764, 132, + 133, 134, 582, 135, 136, 1098, 779, 780, 781, 137, + 41,-32766,-32766,-32766,-32766,-32766,-32766, -275, 1302, 613, + 153, 1071, 749, 990, 991,-32766,-32766,-32766, 992,-32766, + 891,-32766, 892,-32766, 773, 772,-32766, 986, 1309, 397, + 396,-32766,-32766,-32766, 858, 299, 630,-32766,-32766, 440, + 502, 736,-32766,-32766, 437, 782,-32767,-32767,-32767,-32767, + 106, 107, 108, 109, 951,-32766, 1021, 29, 734, 271, + 53, 398, 786, 787, 788, 789, 144, 1071, 441, -341, + 332, 38, 864, 862, -195, 843, 790, 791, 792, 793, + 794, 795, 796, 797, 798, 799, 819, 583, 820, 821, + 822, 823, 811, 812, 353, 354, 814, 815, 800, 801, + 802, 804, 805, 806, 368, 846, 847, 848, 849, 850, + 584, 863, -194, 139, 807, 808, 585, 586, 323, 831, + 829, 830, 842, 826, 827, 1370, 148, 587, 588, 825, + 589, 590, 591, 592, 245, 593, 594, 395, 396,-32766, + -32766,-32766, 828, 595, 596, -85, 138, 440, 132, 133, + 134, 582, 135, 136, 1095, 779, 780, 781, 137, 41, + -32766,-32766,-32766,-32766,-32766, 51, 578, 1302, 257,-32766, + 636, 107, 108, 109,-32766,-32766,-32766, 503,-32766, 316, + -32766,-32766,-32766, 773, 772,-32766, -383, 166, -383, 1022, + -32766,-32766,-32766, 305, 79, 1133,-32766,-32766, 1414, 762, + 332, 1415,-32766, 437, 782,-32766, 1071, 110, 111, 112, + 113, 114, -85, 283,-32766, 477, 478, 479, 271, 53, + 398, 786, 787, 788, 789, 115, 407, 441, 10,-32766, + 299, 1341, 306, 307, 843, 790, 791, 792, 793, 794, + 795, 796, 797, 798, 799, 819, 583, 820, 821, 822, + 823, 811, 812, 353, 354, 814, 815, 800, 801, 802, + 804, 805, 806, 368, 846, 847, 848, 849, 850, 584, + 320, 1068, -582, 807, 808, 585, 586, 1389, 831, 829, + 830, 842, 826, 827, 329, 1388, 587, 588, 825, 589, + 590, 591, 592, 86, 593, 594, 1071, 332,-32766,-32766, + -32766, 828, 595, 596, 349, 151, -581, 132, 133, 134, + 582, 135, 136, 1100, 779, 780, 781, 137, 41,-32766, + 290,-32766,-32766,-32766,-32766,-32766,-32766,-32766,-32767,-32767, + -32767,-32767,-32767,-32766,-32766,-32766, 891, 1175, 892, -582, + -582, 754, 773, 772, 1159, 1160, 1161, 1155, 1154, 1153, + 1162, 1156, 1157, 1158,-32766, -582,-32766,-32766,-32766,-32766, + -32766,-32766,-32766, 782,-32766,-32766,-32766, -588, -78,-32766, + -32766,-32766, 350, -581, -581,-32766,-32766, 271, 53, 398, + 786, 787, 788, 789, 383,-32766, 441,-32766,-32766, -581, + -32766, 773, 772, 843, 790, 791, 792, 793, 794, 795, + 796, 797, 798, 799, 819, 583, 820, 821, 822, 823, + 811, 812, 353, 354, 814, 815, 800, 801, 802, 804, + 805, 806, 368, 846, 847, 848, 849, 850, 584, -620, + 1068, -620, 807, 808, 585, 586, 389, 831, 829, 830, + 842, 826, 827, 441, 405, 587, 588, 825, 589, 590, + 591, 592, 333, 593, 594, 1071, 87, 88, 89, 459, + 828, 595, 596, 460, 151, 803, 774, 775, 776, 777, + 778, 854, 779, 780, 781, 816, 817, 40, 461, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 462, 283, 1329, 1159, 1160, 1161, + 1155, 1154, 1153, 1162, 1156, 1157, 1158, 115, 869, 488, + 489, 782, 1304, 1303, 1305, 108, 109, 1132, 154,-32766, + -32766, 1134, 679, 23, 156, 783, 784, 785, 786, 787, + 788, 789, 698, 699, 852, 152, 423, -580, 393, 394, + 157, 843, 790, 791, 792, 793, 794, 795, 796, 797, + 798, 799, 819, 841, 820, 821, 822, 823, 811, 812, + 813, 840, 814, 815, 800, 801, 802, 804, 805, 806, + 845, 846, 847, 848, 849, 850, 851, 1094, -578, 863, + 807, 808, 809, 810, -58, 831, 829, 830, 842, 826, + 827, 399, 400, 818, 824, 825, 832, 833, 835, 834, + 294, 836, 837, 158, -580, -580, 160, 294, 828, 839, + 838, 54, 55, 56, 57, 534, 58, 59, 36, -110, + -580, -57, 60, 61, -110, 62, -110, 670, 671, 129, + 130, 312, -587, 140, -110, -110, -110, -110, -110, -110, + -110, -110, -110, -110, -110, -578, -578, 141, 147, 949, + 161, 712, -87, 163, 164, 165, -84, 949, -78, -73, + -72, -578, 63, 64, 143, -309, -71, 65, 332, 66, + 251, 252, 67, 68, 69, 70, 71, 72, 73, 74, + 739, 31, 276, 47, 457, 535, -357, 713, 740, 1335, + 1336, 536, -70, 863, 1068, -69, -68, 1333, 45, 22, + 537, 949, 538, -67, 539, -66, 540, 52, -65, 541, + 542, 714, 715, -46, 48, 49, 463, 392, 391, 1071, + 50, 543, -18, 145, 281, 1302, 381, 348, 291, 750, + 1304, 1303, 1305, 1295, 939, 753, 290, 948, 545, 546, + 547, 150, 939, 290, -305, 295, 288, 289, 292, 293, + 549, 550, 338, 1321, 1322, 1323, 1324, 1326, 1318, 1319, + 304, 1300, 296, 301, 302, 283, 1325, 1320, 773, 772, + 1304, 1303, 1305, 305, 308, 309, 75, -154, -154, -154, + 327, 328, 332, 966, 854, 1070, 939, 149, 115, 1416, + 388, 680, -154, 708, -154, 725, -154, 13, -154, 668, + 723, 313, 31, 277, 1304, 1303, 1305, 863, 390,-32766, + 600, 1166, 987, 951, 863, 310, 701, 734, 1333, 990, + 991, 951,-32766, 686, 544, 734, 949, 685, 606, 1340, + 485, 513, 925, 986, -110, -110, -110, 35, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 702, 949, 634, 1295, 773, 772, 741, -579, 305, + -614, 1334, 0, 0, 0, 951, 311, 949, 0, 734, + -154, 549, 550, 319, 1321, 1322, 1323, 1324, 1326, 1318, + 1319, 1209, 1211, 744, 0, 1342, 0, 1325, 1320, -544, + -534, 0, -578,-32766, -4, 949, 11, 77, 751, 1302, + 30, 387, 328, 332, 862, 43,-32766,-32766,-32766, -613, + -32766, 939,-32766, 968,-32766, 44, 759,-32766, 1330, 773, + 772, 760,-32766,-32766,-32766, -579, -579, 882,-32766,-32766, + 930, 1031, 1008, 1015,-32766, 437, 1005, 939, 1016, 928, + 1003, -579, 1137, 1140, 1141, 1138,-32766, 1177, 1139, 1145, + 37, 874, 939, -586, 1357, 1374, 1407,-32766, 673, -578, + -578, -612, -588, 1302, -587, -586, -585, 31, 276, -528, + -32766,-32766,-32766, 1,-32766, -578,-32766, 78,-32766, 863, + 939,-32766, 32, 1333, -278, 33,-32766,-32766,-32766, 42, + 1007, 46,-32766,-32766, 734, 76, 80, 81,-32766, 437, + 82, 83, 390, 84, 453, 31, 277, 85, 146, 303, + -32766, 155, 159, 990, 991, 249, 951, 863, 544, 1295, + 734, 1333, 334, 369, 370, 371, 548, 986, -110, -110, + -110, 951, 372, 326, 373, 734, 374, 550, 375, 1321, + 1322, 1323, 1324, 1326, 1318, 1319, 376, 377, 422, 378, + 21, -50, 1325, 1320, 379, 382, 454, 1295, 577, 951, + 380, 384, 77, 734, -4, -276, -275, 328, 332, 15, + 16, 17, 18, 20, 363, 550, 421, 1321, 1322, 1323, + 1324, 1326, 1318, 1319, 142, 504, 505, 512, 515, 516, + 1325, 1320, 949, 517, 518,-32766, 522, 523, 524, 531, + 77, 1302, 611, 718, 1101, 328, 332, 1097,-32766,-32766, + -32766, 1250,-32766, 1331,-32766, 949,-32766, 1099, 1096,-32766, + 1077, 1290, 1309, 1073,-32766,-32766,-32766, -280,-32766, -102, + -32766,-32766, 14, 19, 1302, 24,-32766, 437, 323, 420, + 625,-32766,-32766,-32766, 631,-32766, 659,-32766,-32766,-32766, + 724, 1254,-32766, -16, 1308, 1251, 1386,-32766,-32766,-32766, + 735,-32766, 738,-32766,-32766, 742, 743, 1302, 745,-32766, + 437, 746, 747, 748,-32766,-32766,-32766, 939,-32766, 300, + -32766,-32766,-32766, 752, 1309,-32766, 764, 737, 332, 765, + -32766,-32766,-32766, -253, -253, -253,-32766,-32766, 426, 390, + 939, 756,-32766, 437, 926, 863, 1411, 1413, 885, 884, + 990, 991, 980, 1023,-32766, 544, -252, -252, -252, 1412, + 979, 977, 390, 925, 986, -110, -110, -110, 978, 981, + 1283, 959, 969, 990, 991, 957, 1176, 1172, 544, 1126, + -110, -110, 1013, 1014, 657, -110, 925, 986, -110, -110, + -110, 1410, 2, 1368, -110, 1268, 951, 1383, 0, 0, + 734, -253, 0,-32766, 0, 0,-32766, 863, 1059, 1054, + 1053, 1052, 1058, 1055, 1056, 1057, 0, 0, 0, 951, + 0, 0, 0, 734, -252, 305, 0, 0, 79, 0, + 0, 1071, 0, 0, 332, 0, 0, 0, 0, 0, + 0, 0, -110, -110, 0, 0, 0, -110, 0, 0, + 0, 0, 0, 0, 0, 299, -110, 0, 0, 0, + 0, 0, 0, 0, 0,-32766, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 305, 0, 0, + 79, 0, 0, 0, 0, 0, 332 + ); + + protected array $actionCheck = array( + 3, 4, 5, 6, 7, 8, 17, 10, 11, 12, + 13, 14, 84, 76, 1, 87, 72, 74, 75, 82, + 0, 108, 109, 110, 15, 82, 89, 90, 91, 10, + 93, 118, 95, 103, 97, 38, 39, 100, 10, 11, + 12, 104, 105, 106, 107, 10, 11, 12, 111, 112, + 15, 10, 11, 12, 117, 118, 59, 82, 128, 31, + 1, 33, 34, 35, 36, 37, 129, 124, 1, 31, + 73, 74, 75, 76, 77, 78, 79, 164, 1, 82, + 9, 153, 154, 139, 140, 9, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 1, 9, 82, 128, 129, 130, 131, 9, + 133, 134, 135, 136, 137, 138, 9, 162, 141, 142, + 143, 144, 145, 146, 147, 86, 149, 150, 9, 82, + 10, 11, 12, 156, 157, 158, 118, 160, 169, 3, + 4, 5, 6, 7, 8, 168, 10, 11, 12, 13, + 14, 31, 76, 33, 34, 35, 36, 168, 82, 83, + 15, 143, 169, 119, 120, 89, 90, 91, 124, 93, + 108, 95, 110, 97, 38, 39, 100, 133, 1, 108, + 109, 105, 106, 107, 162, 167, 1, 111, 112, 118, + 32, 169, 118, 117, 118, 59, 45, 46, 47, 48, + 49, 50, 51, 52, 165, 129, 32, 9, 169, 73, + 74, 75, 76, 77, 78, 79, 169, 143, 82, 168, + 173, 9, 165, 161, 168, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 84, 168, 9, 128, 129, 130, 131, 168, 133, + 134, 135, 136, 137, 138, 1, 9, 141, 142, 143, + 144, 145, 146, 147, 99, 149, 150, 108, 109, 10, + 11, 12, 156, 157, 158, 32, 160, 118, 3, 4, + 5, 6, 7, 8, 168, 10, 11, 12, 13, 14, + 31, 76, 33, 34, 35, 72, 87, 82, 9, 142, + 54, 50, 51, 52, 89, 90, 91, 169, 93, 9, + 95, 118, 97, 38, 39, 100, 108, 15, 110, 165, + 105, 106, 107, 164, 167, 165, 111, 112, 82, 169, + 173, 85, 117, 118, 59, 118, 143, 53, 54, 55, + 56, 57, 99, 59, 129, 134, 135, 136, 73, 74, + 75, 76, 77, 78, 79, 71, 108, 82, 110, 142, + 167, 152, 139, 140, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 9, 118, 72, 128, 129, 130, 131, 1, 133, 134, + 135, 136, 137, 138, 9, 9, 141, 142, 143, 144, + 145, 146, 147, 169, 149, 150, 143, 173, 10, 11, + 12, 156, 157, 158, 9, 160, 72, 3, 4, 5, + 6, 7, 8, 168, 10, 11, 12, 13, 14, 31, + 167, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 10, 11, 12, 108, 165, 110, 139, + 140, 169, 38, 39, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 31, 155, 33, 34, 35, 36, + 37, 38, 39, 59, 10, 11, 12, 167, 17, 10, + 11, 12, 9, 139, 140, 10, 11, 73, 74, 75, + 76, 77, 78, 79, 9, 31, 82, 33, 34, 155, + 31, 38, 39, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 166, + 118, 168, 128, 129, 130, 131, 9, 133, 134, 135, + 136, 137, 138, 82, 9, 141, 142, 143, 144, 145, + 146, 147, 72, 149, 150, 143, 10, 11, 12, 9, + 156, 157, 158, 9, 160, 3, 4, 5, 6, 7, + 8, 82, 10, 11, 12, 13, 14, 31, 9, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 9, 59, 1, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 71, 9, 139, + 140, 59, 161, 162, 163, 51, 52, 1, 15, 53, + 54, 170, 77, 78, 15, 73, 74, 75, 76, 77, + 78, 79, 77, 78, 82, 103, 104, 72, 108, 109, + 15, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 1, 72, 84, + 128, 129, 130, 131, 17, 133, 134, 135, 136, 137, + 138, 108, 109, 141, 142, 143, 144, 145, 146, 147, + 31, 149, 150, 15, 139, 140, 15, 31, 156, 157, + 158, 2, 3, 4, 5, 6, 7, 8, 15, 103, + 155, 17, 13, 14, 108, 16, 110, 113, 114, 17, + 17, 115, 167, 17, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 139, 140, 17, 17, 1, + 17, 82, 32, 17, 17, 17, 32, 1, 32, 32, + 32, 155, 53, 54, 169, 36, 32, 58, 173, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 32, 72, 73, 74, 75, 76, 170, 118, 32, 80, + 81, 82, 32, 84, 118, 32, 32, 88, 89, 90, + 91, 1, 93, 32, 95, 32, 97, 72, 32, 100, + 101, 142, 143, 32, 105, 106, 107, 108, 109, 143, + 111, 112, 32, 32, 32, 82, 117, 118, 32, 32, + 161, 162, 163, 124, 86, 32, 167, 32, 129, 130, + 131, 32, 86, 167, 36, 38, 36, 36, 36, 36, + 141, 142, 36, 144, 145, 146, 147, 148, 149, 150, + 151, 118, 38, 38, 38, 59, 157, 158, 38, 39, + 161, 162, 163, 164, 139, 140, 167, 77, 78, 79, + 171, 172, 173, 39, 82, 142, 86, 72, 71, 85, + 155, 92, 92, 79, 94, 94, 96, 99, 98, 115, + 82, 116, 72, 73, 161, 162, 163, 84, 108, 87, + 91, 84, 133, 165, 84, 137, 96, 169, 88, 119, + 120, 165, 142, 102, 124, 169, 1, 98, 159, 152, + 99, 99, 132, 133, 134, 135, 136, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 102, 1, 159, 124, 38, 39, 32, 72, 164, + 167, 172, -1, -1, -1, 165, 138, 1, -1, 169, + 170, 141, 142, 137, 144, 145, 146, 147, 148, 149, + 150, 61, 62, 32, -1, 152, -1, 157, 158, 155, + 155, -1, 72, 76, 0, 1, 155, 167, 32, 82, + 155, 155, 172, 173, 161, 165, 89, 90, 91, 167, + 93, 86, 95, 160, 97, 165, 165, 100, 166, 38, + 39, 165, 105, 106, 107, 139, 140, 165, 111, 112, + 165, 165, 165, 165, 117, 118, 165, 86, 165, 165, + 165, 155, 165, 165, 165, 165, 129, 165, 165, 165, + 169, 166, 86, 167, 166, 166, 166, 76, 166, 139, + 140, 167, 167, 82, 167, 167, 167, 72, 73, 167, + 89, 90, 91, 167, 93, 155, 95, 160, 97, 84, + 86, 100, 167, 88, 168, 167, 105, 106, 107, 167, + 165, 167, 111, 112, 169, 167, 167, 167, 117, 118, + 167, 167, 108, 167, 110, 72, 73, 167, 167, 115, + 129, 167, 167, 119, 120, 167, 165, 84, 124, 124, + 169, 88, 167, 167, 167, 167, 132, 133, 134, 135, + 136, 165, 167, 169, 167, 169, 167, 142, 167, 144, + 145, 146, 147, 148, 149, 150, 167, 167, 170, 167, + 156, 32, 157, 158, 167, 167, 167, 124, 167, 165, + 167, 169, 167, 169, 170, 168, 168, 172, 173, 168, + 168, 168, 168, 168, 168, 142, 168, 144, 145, 146, + 147, 148, 149, 150, 32, 168, 168, 168, 168, 168, + 157, 158, 1, 168, 168, 76, 168, 168, 168, 168, + 167, 82, 168, 168, 168, 172, 173, 168, 89, 90, + 91, 168, 93, 168, 95, 1, 97, 168, 168, 100, + 168, 168, 1, 168, 105, 106, 107, 168, 76, 168, + 111, 112, 168, 168, 82, 168, 117, 118, 168, 168, + 168, 89, 90, 91, 168, 93, 168, 95, 129, 97, + 168, 168, 100, 32, 168, 168, 168, 105, 106, 107, + 169, 76, 169, 111, 112, 169, 169, 82, 169, 117, + 118, 169, 169, 169, 89, 90, 91, 86, 93, 31, + 95, 129, 97, 169, 1, 100, 169, 169, 173, 169, + 105, 106, 107, 102, 103, 104, 111, 112, 170, 108, + 86, 170, 117, 118, 170, 84, 170, 170, 170, 170, + 119, 120, 170, 170, 129, 124, 102, 103, 104, 170, + 170, 170, 108, 132, 133, 134, 135, 136, 170, 170, + 170, 170, 170, 119, 120, 170, 170, 170, 124, 170, + 119, 120, 170, 170, 170, 124, 132, 133, 134, 135, + 136, 170, 167, 170, 133, 171, 165, 170, -1, -1, + 169, 170, -1, 142, -1, -1, 118, 84, 120, 121, + 122, 123, 124, 125, 126, 127, -1, -1, -1, 165, + -1, -1, -1, 169, 170, 164, -1, -1, 167, -1, + -1, 143, -1, -1, 173, -1, -1, -1, -1, -1, + -1, -1, 119, 120, -1, -1, -1, 124, -1, -1, + -1, -1, -1, -1, -1, 167, 133, -1, -1, -1, + -1, -1, -1, -1, -1, 142, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 164, -1, -1, + 167, -1, -1, -1, -1, -1, 173 + ); + + protected array $actionBase = array( + 0, 156, -3, 315, 474, 474, 880, 1074, 1271, 1294, + 749, 675, 531, 559, 836, 1031, 1031, 1046, 1031, 828, + 1005, 42, 59, 59, 59, 963, 898, 632, 632, 898, + 632, 997, 997, 997, 997, 1061, 1061, -63, -63, 96, + 1232, 1199, 255, 255, 255, 255, 255, 1265, 255, 255, + 255, 255, 255, 1265, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 77, 194, 120, + 205, 1197, 783, 1150, 1163, 1152, 1166, 1145, 1144, 1151, + 1156, 1167, 1261, 1263, 889, 1254, 1267, 1158, 972, 1147, + 1162, 962, 616, 616, 616, 616, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 19, + 35, 535, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 529, 529, 529, 910, 910, 524, 299, 1113, + 1075, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 140, + 28, 1000, 493, 493, 458, 458, 458, 458, 458, 696, + 1328, 1301, 171, 171, 171, 171, 1363, 1363, -70, 523, + 248, 756, 291, 197, -87, 644, 38, 199, 323, 323, + 482, 482, 233, 233, 482, 482, 482, 324, 324, 94, + 94, 94, 94, 82, 249, 860, 67, 67, 67, 67, + 860, 860, 860, 860, 913, 869, 860, 1036, 1049, 860, + 860, 370, 645, 966, 646, 646, 398, -72, -72, 398, + 64, -72, 294, 286, 257, 859, 91, 433, 257, 1073, + 404, 686, 686, 815, 686, 686, 686, 923, 610, 923, + 1141, 902, 902, 861, 807, 964, 1198, 1168, 901, 1252, + 929, 1253, 1200, 342, 251, -56, 263, 550, 806, 1139, + 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, 1139, + 1139, 1195, 523, 1141, -25, 1247, 1249, 1195, 1195, 1195, + 523, 523, 523, 523, 523, 523, 523, 523, 870, 523, + 523, 694, -25, 625, 635, -25, 896, 523, 915, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 178, 77, 77, 194, 13, 13, 77, 200, 121, 13, + 13, 13, -11, 13, 77, 77, 77, 610, 886, 849, + 663, 283, 874, 114, 886, 886, 886, 71, 9, 76, + 809, 888, 288, 882, 882, 882, 907, 986, 986, 882, + 903, 882, 907, 882, 882, 986, 986, 875, 986, 274, + 620, 465, 597, 624, 986, 340, 882, 882, 882, 882, + 916, 986, 127, 139, 639, 882, 329, 287, 882, 882, + 916, 858, 876, 908, 986, 986, 986, 916, 545, 908, + 908, 908, 931, 936, 864, 872, 445, 431, 679, 232, + 924, 872, 872, 882, 605, 864, 872, 864, 872, 933, + 872, 872, 872, 864, 872, 903, 533, 872, 813, 665, + 218, 872, 882, 20, 1008, 1009, 800, 1010, 1002, 1013, + 1069, 1014, 1016, 1171, 982, 1028, 1004, 1020, 1071, 998, + 995, 885, 792, 793, 921, 914, 979, 897, 897, 897, + 975, 977, 897, 897, 897, 897, 897, 897, 897, 897, + 792, 932, 926, 899, 1037, 796, 810, 1114, 857, 1214, + 1264, 1036, 1008, 1016, 804, 1004, 1020, 998, 995, 856, + 853, 844, 851, 843, 840, 808, 814, 871, 1116, 1119, + 1021, 920, 811, 1085, 1038, 1211, 1044, 1045, 1047, 1088, + 1123, 942, 1125, 1216, 895, 1217, 1218, 965, 1051, 1173, + 897, 974, 873, 968, 1049, 978, 792, 969, 1129, 1130, + 1081, 961, 1097, 1098, 1072, 911, 884, 970, 1219, 1059, + 1060, 1062, 1176, 1177, 930, 1082, 996, 1099, 912, 1058, + 1100, 1101, 1105, 1106, 1179, 1222, 1182, 922, 1183, 945, + 879, 1077, 909, 1223, 165, 892, 893, 906, 1068, 683, + 1035, 1184, 1208, 1229, 1108, 1109, 1110, 1230, 1231, 1024, + 946, 1083, 900, 1084, 1078, 947, 948, 689, 905, 1132, + 890, 891, 904, 705, 768, 1238, 1239, 1240, 1025, 877, + 894, 951, 953, 1133, 887, 1135, 1241, 771, 954, 1242, + 1115, 816, 817, 521, 784, 747, 818, 881, 1194, 925, + 865, 878, 1067, 817, 883, 955, 1245, 957, 958, 959, + 1111, 960, 1086, 1246, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 632, 632, 632, + 632, 789, 789, 789, 789, 789, 789, 789, 632, 789, + 789, 789, 632, 632, 0, 0, 632, 0, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 616, 616, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, + 616, 616, 823, 823, 616, 616, 823, 823, 823, 823, + 823, 823, 823, 823, 823, 823, 616, 616, 0, 616, + 616, 616, 616, 616, 616, 616, 875, 823, 823, 324, + 324, 324, 324, 823, 823, 396, 396, 396, 823, 324, + 823, 64, 324, 823, 64, 823, 823, 823, 823, 823, + 823, 823, 823, 823, 0, 0, 823, 823, 823, 823, + -25, -72, 823, 903, 903, 903, 903, 823, 823, 823, + 823, -72, -72, 823, -57, -57, 823, 823, 0, 0, + 0, 324, 324, -25, 0, 0, -25, 0, 0, 903, + 903, 823, 64, 875, 446, 823, 342, 0, 0, 0, + 0, 0, 0, 0, -25, 903, -25, 523, -72, -72, + 523, 523, 13, 77, 446, 612, 612, 612, 612, 77, + 0, 0, 0, 0, 0, 610, 875, 875, 875, 875, + 875, 875, 875, 875, 875, 875, 875, 875, 903, 0, + 875, 0, 875, 875, 903, 903, 903, 0, 0, 0, + 0, 0, 0, 0, 0, 986, 0, 0, 0, 0, + 0, 0, 0, 903, 0, 986, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 897, 911, 0, 0, 911, + 0, 897, 897, 897, 0, 0, 0, 905, 887 + ); + + protected array $actionDefault = array( + 3,32767,32767,32767, 102, 102,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 100, + 32767, 632, 632, 632, 632,32767,32767, 257, 102,32767, + 32767, 503, 417, 417, 417,32767,32767,32767, 576, 576, + 576, 576, 576, 17,32767,32767,32767,32767,32767,32767, + 32767, 503,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767, 36, 7, 8, 10, 11, 49, 338, 100, + 32767,32767,32767,32767,32767,32767,32767,32767, 102,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 404, 625,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767, 497, 507, 485, 486, 488, 489, 416, 577, + 631, 344, 628, 342, 415, 146, 354, 343, 245, 261, + 508, 262, 509, 512, 513, 218, 401, 150, 151, 448, + 504, 450, 502, 506, 449, 422, 429, 430, 431, 432, + 433, 434, 435, 436, 437, 438, 439, 440, 441, 420, + 421, 505, 482, 481, 480,32767,32767, 446, 447,32767, + 32767,32767,32767,32767,32767,32767,32767, 102,32767, 451, + 454, 419, 452, 453, 470, 471, 468, 469, 472,32767, + 323,32767, 473, 474, 475, 476,32767,32767, 382, 196, + 380,32767, 477,32767, 111, 455, 323, 111,32767,32767, + 32767,32767,32767,32767,32767,32767,32767, 461, 462,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 102,32767,32767,32767, + 100, 520, 570, 479, 456, 457,32767, 545,32767, 102, + 32767, 547,32767,32767,32767,32767,32767,32767,32767,32767, + 572, 443, 445, 540, 626, 423, 629,32767, 533, 100, + 196,32767, 546, 196, 196,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 571,32767, 639, 533, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110,32767, 196, 110,32767, 110, 110,32767,32767, 100, + 196, 196, 196, 196, 196, 196, 196, 196, 548, 196, + 196, 191,32767, 271, 273, 102, 594, 196, 550,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767, 404,32767,32767,32767,32767, 533, 466, 139, + 32767, 535, 139, 578, 458, 459, 460, 578, 578, 578, + 319, 296,32767,32767,32767,32767,32767, 548, 548, 100, + 100, 100, 100,32767,32767,32767,32767, 111, 519, 99, + 99, 99, 99, 99, 103, 101,32767,32767,32767,32767, + 226,32767, 101, 101, 99,32767, 101, 101,32767,32767, + 226, 228, 215, 230,32767, 598, 599, 226, 101, 230, + 230, 230, 250, 250, 522, 325, 101, 99, 101, 101, + 198, 325, 325,32767, 101, 522, 325, 522, 325, 200, + 325, 325, 325, 522, 325,32767, 101, 325, 217, 99, + 99, 325,32767,32767,32767,32767, 535,32767,32767,32767, + 32767,32767,32767,32767, 225,32767,32767,32767,32767,32767, + 32767,32767,32767, 565,32767, 583, 596, 464, 465, 467, + 582, 580, 490, 491, 492, 493, 494, 495, 496, 499, + 627,32767, 539,32767,32767,32767, 353,32767, 637,32767, + 32767,32767, 9, 74, 528, 42, 43, 51, 57, 554, + 555, 556, 557, 551, 552, 558, 553,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767, 638,32767, 578,32767,32767,32767,32767, + 463, 560, 604,32767,32767, 579, 630,32767,32767,32767, + 32767,32767,32767,32767,32767, 139,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 565,32767, 137,32767, + 32767,32767,32767,32767,32767,32767,32767, 561,32767,32767, + 32767, 578,32767,32767,32767,32767, 321, 318,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767, 578,32767,32767,32767,32767,32767, + 298,32767, 315,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 400, 535, 301, 303, 304,32767,32767,32767,32767, + 376,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767, 153, 153, 3, 3, 356, 153, + 153, 153, 356, 356, 153, 356, 356, 356, 153, 153, + 153, 153, 153, 153, 153, 283, 186, 265, 268, 250, + 250, 153, 368, 153, 402, 402, 411 + ); + + protected array $goto = array( + 201, 169, 201, 201, 201, 1069, 598, 719, 448, 684, + 644, 681, 443, 345, 341, 342, 344, 615, 447, 346, + 449, 661, 481, 728, 570, 570, 570, 570, 1245, 626, + 172, 172, 172, 172, 225, 202, 198, 198, 182, 184, + 220, 198, 198, 198, 198, 198, 1195, 199, 199, 199, + 199, 199, 1195, 192, 193, 194, 195, 196, 197, 222, + 220, 223, 557, 558, 438, 559, 562, 563, 564, 565, + 566, 567, 568, 569, 173, 174, 175, 200, 176, 177, + 178, 170, 179, 180, 181, 183, 219, 221, 224, 242, + 247, 248, 259, 260, 262, 263, 264, 265, 266, 267, + 268, 272, 273, 274, 275, 282, 285, 297, 298, 324, + 325, 444, 445, 446, 620, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 193, 194, 195, 196, 197, 222, 203, 204, 205, + 206, 243, 185, 186, 207, 187, 208, 204, 188, 244, + 203, 168, 209, 210, 189, 211, 212, 213, 190, 214, + 215, 171, 216, 217, 218, 191, 287, 284, 287, 287, + 883, 255, 255, 255, 255, 255, 1125, 605, 487, 487, + 622, 758, 660, 662, 1103, 359, 682, 487, 1075, 1074, + 706, 709, 1041, 717, 726, 1037, 733, 922, 879, 922, + 922, 253, 253, 253, 253, 250, 256, 646, 646, 1078, + 1079, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, + 1332, 880, 351, 938, 933, 934, 947, 889, 935, 886, + 936, 937, 887, 890, 476, 941, 894, 476, 1044, 1044, + 893, 364, 364, 364, 364, 352, 351, 532, 1131, 1127, + 1128, 1351, 1351, 331, 315, 1351, 1351, 1351, 1351, 1351, + 1351, 1351, 1351, 1351, 1351, 1069, 1301, 1072, 1072, 704, + 983, 1301, 1301, 1064, 1080, 1081, 1069, 942, 1301, 943, + 458, 1069, 881, 1069, 1069, 1069, 1069, 1069, 1069, 1069, + 1069, 1069, 897, 855, 1069, 1069, 1069, 1069, 677, 678, + 1301, 695, 696, 697, 1006, 1301, 1301, 1301, 1301, 450, + 909, 1301, 436, 896, 1301, 1301, 1382, 1382, 1382, 1382, + 915, 581, 574, 499, 612, 450, 367, 971, 971, 955, + 501, 1076, 1076, 956, 1400, 1400, 367, 367, 688, 1087, + 1083, 1084, 572, 411, 414, 623, 627, 572, 572, 367, + 367, 1400, 357, 367, 572, 1417, 1377, 1378, 317, 574, + 581, 607, 608, 318, 618, 624, 1390, 640, 641, 1027, + 576, 1403, 1403, 367, 367, 28, 474, 520, 442, 521, + 635, 1000, 1000, 1000, 1000, 527, 409, 474, 1348, 1348, + 994, 1001, 1348, 1348, 1348, 1348, 1348, 1348, 1348, 1348, + 1348, 1348, 633, 647, 650, 651, 652, 653, 674, 675, + 676, 730, 732, 561, 561, 258, 258, 561, 561, 561, + 561, 561, 561, 561, 561, 561, 561, 610, 1362, 467, + 683, 467, 876, 616, 638, 876, 467, 467, 1191, 861, + 1373, 360, 361, 1093, 456, 1373, 1373, 560, 560, 705, + 432, 560, 1373, 560, 560, 560, 560, 560, 560, 560, + 560, 1277, 975, 575, 602, 575, 1278, 1281, 976, 575, + 1282, 602, 689, 412, 480, 1384, 1384, 1384, 1384, 347, + 873, 716, 576, 861, 876, 861, 490, 619, 491, 492, + 639, 8, 857, 9, 902, 907, 989, 716, 1408, 1409, + 716, 1369, 418, 1296, 278, 899, 330, 1174, 424, 425, + 1292, 330, 330, 693, 1049, 694, 1114, 429, 430, 431, + 761, 707, 1060, 905, 433, 1102, 1104, 1107, 355, 467, + 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, + 467, 419, 339, 467, 911, 467, 467, 1294, 628, 629, + 1116, 497, 960, 1181, 621, 1144, 1371, 1371, 1116, 1118, + 1297, 1298, 1011, 1284, 1046, 1151, 1179, 1152, 731, 871, + 528, 722, 901, 1142, 687, 1025, 1284, 496, 1375, 1376, + 895, 910, 898, 1113, 1117, 998, 427, 727, 1165, 1299, + 1359, 1360, 1291, 1030, 386, 1009, 1002, 0, 757, 0, + 0, 573, 1039, 1034, 654, 656, 658, 0, 0, 0, + 0, 0, 0, 0, 0, 876, 0, 0, 999, 0, + 766, 766, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1163, 914 + ); + + protected array $gotoCheck = array( + 42, 42, 42, 42, 42, 73, 127, 73, 66, 66, + 56, 56, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 159, 9, 107, 107, 107, 107, 159, 107, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 23, 23, 23, 23, + 15, 5, 5, 5, 5, 5, 15, 48, 157, 157, + 134, 48, 48, 48, 131, 97, 48, 157, 119, 119, + 48, 48, 48, 48, 48, 48, 48, 25, 25, 25, + 25, 5, 5, 5, 5, 5, 5, 108, 108, 120, + 120, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 26, 177, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 83, 15, 15, 83, 107, 107, + 15, 24, 24, 24, 24, 177, 177, 76, 15, 15, + 15, 179, 179, 178, 178, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 73, 73, 89, 89, 89, + 89, 73, 73, 89, 89, 89, 73, 65, 73, 65, + 83, 73, 27, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 35, 6, 73, 73, 73, 73, 86, 86, + 73, 86, 86, 86, 49, 73, 73, 73, 73, 118, + 35, 73, 43, 35, 73, 73, 9, 9, 9, 9, + 45, 76, 76, 84, 181, 118, 14, 9, 9, 73, + 84, 118, 118, 73, 191, 191, 14, 14, 118, 118, + 118, 118, 19, 59, 59, 59, 59, 19, 19, 14, + 14, 191, 188, 14, 19, 14, 187, 187, 76, 76, + 76, 76, 76, 76, 76, 76, 190, 76, 76, 103, + 14, 191, 191, 14, 14, 76, 19, 163, 13, 163, + 13, 19, 19, 19, 19, 163, 62, 19, 180, 180, + 19, 19, 180, 180, 180, 180, 180, 180, 180, 180, + 180, 180, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 182, 182, 5, 5, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 104, 14, 23, + 64, 23, 22, 2, 2, 22, 23, 23, 158, 12, + 134, 97, 97, 115, 113, 134, 134, 165, 165, 117, + 14, 165, 134, 165, 165, 165, 165, 165, 165, 165, + 165, 79, 79, 9, 9, 9, 79, 79, 79, 9, + 79, 9, 121, 9, 9, 134, 134, 134, 134, 29, + 18, 7, 14, 12, 22, 12, 9, 9, 9, 9, + 80, 46, 7, 46, 39, 9, 92, 7, 9, 9, + 7, 134, 28, 20, 24, 37, 24, 156, 82, 82, + 169, 24, 24, 82, 110, 82, 133, 82, 82, 82, + 99, 82, 114, 9, 82, 130, 130, 130, 82, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 31, 9, 23, 41, 23, 23, 14, 17, 17, + 134, 160, 17, 17, 8, 8, 134, 134, 134, 136, + 20, 20, 96, 20, 17, 149, 149, 149, 8, 20, + 8, 8, 17, 8, 17, 17, 20, 185, 185, 185, + 17, 16, 16, 16, 16, 93, 93, 93, 152, 20, + 20, 20, 17, 50, 141, 16, 50, -1, 50, -1, + -1, 50, 50, 50, 85, 85, 85, -1, -1, -1, + -1, -1, -1, -1, -1, 22, -1, -1, 16, -1, + 24, 24, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 16, 16 + ); + + protected array $gotoBase = array( + 0, 0, -303, 0, 0, 170, 280, 471, 543, 10, + 0, 0, 136, 31, 22, -186, 111, 66, 164, 71, + 95, 0, 148, 160, 235, 191, 214, 275, 155, 176, + 0, 86, 0, 0, 0, -92, 0, 156, 0, 165, + 0, 85, -1, 286, 0, 291, -270, 0, -558, 284, + 579, 0, 0, 0, 0, 0, -33, 0, 0, 294, + 0, 0, 341, 0, 184, 261, -237, 0, 0, 0, + 0, 0, 0, -5, 0, 0, -32, 0, 0, 37, + 172, 32, -3, -50, -167, 105, -444, 0, 0, -21, + 0, 0, 161, 274, 0, 0, 101, -318, 0, 97, + 0, 0, 0, 331, 381, 0, 0, -7, -38, 0, + 131, 0, 0, 158, 90, 162, 0, 159, 39, -100, + -83, 173, 0, 0, 0, 0, 0, 4, 0, 0, + 522, 182, 0, 127, 169, 0, 99, 0, 0, 0, + 0, -171, 0, 0, 0, 0, 0, 0, 0, 287, + 0, 0, 126, 0, 0, 0, 144, 141, 188, -255, + 93, 0, 0, -138, 0, 202, 0, 0, 0, 128, + 0, 0, 0, 0, 0, 0, 0, -82, -74, 6, + 143, 292, 168, 0, 0, 270, 0, -31, 319, 0, + 332, 20, 0, 0 + ); + + protected array $gotoDefault = array( + -32768, 533, 768, 7, 769, 964, 844, 853, 597, 551, + 729, 356, 648, 439, 1367, 940, 1180, 617, 872, 1310, + 1316, 475, 875, 336, 755, 952, 923, 924, 415, 402, + 888, 413, 672, 649, 514, 908, 471, 900, 506, 903, + 470, 912, 167, 435, 530, 916, 6, 919, 579, 950, + 1004, 403, 927, 404, 700, 929, 601, 931, 932, 410, + 416, 417, 1185, 609, 645, 944, 261, 603, 945, 401, + 946, 954, 406, 408, 710, 486, 525, 519, 428, 1146, + 604, 632, 669, 464, 493, 643, 655, 642, 500, 451, + 434, 335, 988, 996, 507, 484, 1010, 358, 1018, 763, + 1193, 663, 509, 1026, 664, 1033, 1036, 552, 553, 498, + 1048, 270, 1051, 510, 1061, 26, 690, 1066, 1067, 691, + 665, 1089, 666, 692, 667, 1091, 483, 599, 1194, 482, + 1106, 1112, 472, 1115, 1356, 473, 1119, 269, 1122, 286, + 362, 385, 452, 1129, 1130, 12, 1136, 720, 721, 25, + 280, 529, 1164, 711, 1170, 279, 1173, 469, 1192, 468, + 1265, 1267, 580, 511, 1285, 321, 1288, 703, 526, 1293, + 465, 1358, 466, 554, 494, 343, 555, 1401, 314, 365, + 340, 571, 322, 366, 556, 495, 1364, 1372, 337, 34, + 1391, 1402, 614, 637 + ); + + protected array $ruleToNonTerminal = array( + 0, 1, 3, 3, 2, 5, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 8, 8, 9, 10, 11, + 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, + 16, 17, 17, 18, 18, 21, 21, 22, 23, 23, + 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 29, 29, 30, 30, 32, 34, + 34, 28, 36, 36, 33, 38, 38, 35, 35, 37, + 37, 39, 39, 31, 40, 40, 41, 43, 44, 44, + 45, 45, 46, 46, 48, 47, 47, 47, 47, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 25, 25, 50, 69, 69, 72, 72, + 71, 70, 70, 63, 75, 75, 76, 76, 77, 77, + 78, 78, 79, 79, 80, 80, 80, 80, 26, 26, + 27, 27, 27, 27, 27, 88, 88, 90, 90, 83, + 83, 91, 91, 92, 92, 92, 84, 84, 87, 87, + 85, 85, 93, 94, 94, 57, 57, 65, 65, 68, + 68, 68, 67, 95, 95, 96, 58, 58, 58, 58, + 97, 97, 98, 98, 99, 99, 100, 101, 101, 102, + 102, 103, 103, 55, 55, 51, 51, 105, 53, 53, + 106, 52, 52, 54, 54, 64, 64, 64, 64, 81, + 81, 109, 109, 111, 111, 112, 112, 112, 112, 112, + 112, 112, 112, 110, 110, 110, 115, 115, 115, 115, + 89, 89, 118, 118, 118, 119, 119, 116, 116, 120, + 120, 122, 122, 123, 123, 117, 124, 124, 121, 125, + 125, 125, 125, 113, 113, 82, 82, 82, 20, 20, + 20, 128, 128, 128, 128, 129, 129, 129, 127, 126, + 126, 131, 131, 131, 130, 130, 60, 132, 132, 133, + 61, 135, 135, 136, 136, 137, 137, 86, 138, 138, + 138, 138, 138, 138, 138, 138, 144, 144, 145, 145, + 146, 146, 146, 146, 146, 147, 148, 148, 143, 143, + 139, 139, 142, 142, 150, 150, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 140, 151, 151, 153, + 152, 152, 141, 141, 114, 114, 154, 154, 156, 156, + 156, 155, 155, 62, 104, 157, 157, 56, 56, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 164, 165, 165, 166, + 158, 158, 163, 163, 167, 168, 168, 169, 170, 171, + 171, 171, 171, 19, 19, 73, 73, 73, 73, 159, + 159, 159, 159, 173, 173, 162, 162, 162, 160, 160, + 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, + 180, 180, 180, 108, 182, 182, 182, 182, 161, 161, + 161, 161, 161, 161, 161, 161, 59, 59, 176, 176, + 176, 176, 176, 183, 183, 172, 172, 172, 172, 184, + 184, 184, 184, 184, 74, 74, 66, 66, 66, 66, + 134, 134, 134, 134, 187, 186, 175, 175, 175, 175, + 175, 175, 174, 174, 174, 185, 185, 185, 185, 107, + 181, 189, 189, 188, 188, 190, 190, 190, 190, 190, + 190, 190, 190, 178, 178, 178, 178, 177, 192, 191, + 191, 191, 191, 191, 191, 191, 191, 193, 193, 193, + 193 + ); + + protected array $ruleToLength = array( + 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 0, 1, 1, 2, 1, 3, 4, 1, 2, + 0, 1, 1, 1, 1, 4, 3, 5, 4, 3, + 4, 1, 3, 4, 1, 1, 8, 7, 2, 3, + 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, + 3, 1, 2, 2, 3, 1, 3, 2, 3, 1, + 3, 3, 2, 0, 1, 1, 1, 1, 1, 3, + 7, 10, 5, 7, 9, 5, 3, 3, 3, 3, + 3, 3, 1, 2, 5, 7, 9, 6, 5, 6, + 3, 2, 1, 1, 1, 1, 0, 2, 1, 3, + 8, 0, 4, 2, 1, 3, 0, 1, 0, 1, + 0, 1, 3, 1, 1, 1, 1, 1, 8, 9, + 7, 8, 7, 6, 8, 0, 2, 0, 2, 1, + 2, 1, 2, 1, 1, 1, 0, 2, 0, 2, + 0, 2, 2, 1, 3, 1, 4, 1, 4, 1, + 1, 4, 2, 1, 3, 3, 3, 4, 4, 5, + 0, 2, 4, 3, 1, 1, 7, 0, 2, 1, + 3, 3, 4, 1, 4, 0, 2, 5, 0, 2, + 6, 0, 2, 0, 3, 1, 2, 1, 1, 2, + 0, 1, 3, 0, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 7, 9, 6, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, + 3, 3, 3, 3, 3, 1, 3, 3, 1, 1, + 2, 1, 1, 0, 1, 0, 2, 2, 2, 4, + 3, 2, 4, 4, 3, 3, 1, 3, 1, 1, + 3, 2, 2, 3, 1, 1, 2, 3, 1, 1, + 2, 3, 1, 1, 3, 2, 0, 1, 5, 7, + 5, 6, 10, 3, 5, 1, 1, 3, 0, 2, + 4, 5, 4, 4, 4, 3, 1, 1, 1, 1, + 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, + 1, 3, 0, 2, 0, 3, 5, 8, 1, 3, + 3, 0, 2, 2, 2, 3, 1, 0, 1, 1, + 3, 3, 3, 4, 4, 1, 1, 2, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 5, 4, 3, 4, 4, 2, 2, 4, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 3, 2, 1, 2, 4, 2, 2, 8, 9, + 8, 9, 9, 10, 9, 10, 8, 3, 2, 2, + 1, 1, 0, 4, 2, 1, 3, 2, 1, 2, + 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 1, 1, 1, 0, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 5, 3, 3, 4, 1, 1, 3, 1, 1, + 1, 1, 1, 3, 2, 3, 0, 1, 1, 3, + 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, + 4, 1, 4, 4, 0, 1, 1, 1, 3, 3, + 1, 4, 2, 2, 1, 3, 1, 4, 3, 3, + 3, 3, 1, 3, 1, 1, 3, 1, 1, 4, + 1, 1, 1, 3, 1, 1, 2, 1, 3, 4, + 3, 2, 0, 2, 2, 1, 2, 1, 1, 1, + 4, 3, 3, 3, 3, 6, 3, 1, 1, 2, + 1 + ); + + protected function initReduceCallbacks(): void { + $this->reduceCallbacks = [ + 0 => null, + 1 => static function ($self, $stackPos) { + $self->semValue = $self->handleNamespaces($self->semStack[$stackPos-(1-1)]); + }, + 2 => static function ($self, $stackPos) { + if ($self->semStack[$stackPos-(2-2)] !== null) { $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; } $self->semValue = $self->semStack[$stackPos-(2-1)];; + }, + 3 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 4 => static function ($self, $stackPos) { + $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);; + if ($nop !== null) { $self->semStack[$stackPos-(1-1)][] = $nop; } $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 5 => null, + 6 => null, + 7 => null, + 8 => null, + 9 => null, + 10 => null, + 11 => null, + 12 => null, + 13 => null, + 14 => null, + 15 => null, + 16 => null, + 17 => null, + 18 => null, + 19 => null, + 20 => null, + 21 => null, + 22 => null, + 23 => null, + 24 => null, + 25 => null, + 26 => null, + 27 => null, + 28 => null, + 29 => null, + 30 => null, + 31 => null, + 32 => null, + 33 => null, + 34 => null, + 35 => null, + 36 => null, + 37 => null, + 38 => null, + 39 => null, + 40 => null, + 41 => null, + 42 => null, + 43 => null, + 44 => null, + 45 => null, + 46 => null, + 47 => null, + 48 => null, + 49 => null, + 50 => null, + 51 => null, + 52 => null, + 53 => null, + 54 => null, + 55 => null, + 56 => null, + 57 => null, + 58 => null, + 59 => null, + 60 => null, + 61 => null, + 62 => null, + 63 => null, + 64 => null, + 65 => null, + 66 => null, + 67 => null, + 68 => null, + 69 => null, + 70 => null, + 71 => null, + 72 => null, + 73 => null, + 74 => null, + 75 => null, + 76 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; if ($self->semValue === "emitError(new Error('Cannot use "getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]))); + }, + 77 => null, + 78 => null, + 79 => null, + 80 => null, + 81 => null, + 82 => null, + 83 => null, + 84 => null, + 85 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 86 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 87 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 88 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 89 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 90 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 91 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 92 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 93 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 94 => null, + 95 => static function ($self, $stackPos) { + $self->semValue = new Name(substr($self->semStack[$stackPos-(1-1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 96 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable(substr($self->semStack[$stackPos-(1-1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 97 => static function ($self, $stackPos) { + /* nothing */ + }, + 98 => static function ($self, $stackPos) { + /* nothing */ + }, + 99 => static function ($self, $stackPos) { + /* nothing */ + }, + 100 => static function ($self, $stackPos) { + $self->emitError(new Error('A trailing comma is not allowed here', $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]))); + }, + 101 => null, + 102 => null, + 103 => static function ($self, $stackPos) { + $self->semValue = new Node\Attribute($self->semStack[$stackPos-(1-1)], [], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 104 => static function ($self, $stackPos) { + $self->semValue = new Node\Attribute($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 105 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 106 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 107 => static function ($self, $stackPos) { + $self->semValue = new Node\AttributeGroup($self->semStack[$stackPos-(4-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 108 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 109 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 110 => static function ($self, $stackPos) { + $self->semValue = []; + }, + 111 => null, + 112 => null, + 113 => null, + 114 => null, + 115 => static function ($self, $stackPos) { + $self->semValue = new Stmt\HaltCompiler($self->handleHaltCompiler(), $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 116 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos-(3-2)], null, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); + $self->checkNamespace($self->semValue); + }, + 117 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Namespace_($self->semStack[$stackPos-(5-2)], $self->semStack[$stackPos-(5-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $self->checkNamespace($self->semValue); + }, + 118 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Namespace_(null, $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + $self->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $self->checkNamespace($self->semValue); + }, + 119 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Use_($self->semStack[$stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 120 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Use_($self->semStack[$stackPos-(4-3)], $self->semStack[$stackPos-(4-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 121 => null, + 122 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Const_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]), []); + }, + 123 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Const_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(4-1)]); + $self->checkConstantAttributes($self->semValue); + }, + 124 => static function ($self, $stackPos) { + $self->semValue = Stmt\Use_::TYPE_FUNCTION; + }, + 125 => static function ($self, $stackPos) { + $self->semValue = Stmt\Use_::TYPE_CONSTANT; + }, + 126 => static function ($self, $stackPos) { + $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos-(8-3)], $self->semStack[$stackPos-(8-6)], $self->semStack[$stackPos-(8-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + }, + 127 => static function ($self, $stackPos) { + $self->semValue = new Stmt\GroupUse($self->semStack[$stackPos-(7-2)], $self->semStack[$stackPos-(7-5)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + }, + 128 => null, + 129 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 130 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 131 => null, + 132 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 133 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 134 => null, + 135 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 136 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 137 => static function ($self, $stackPos) { + $self->semValue = new Node\UseItem($self->semStack[$stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); $self->checkUseUse($self->semValue, $stackPos-(1-1)); + }, + 138 => static function ($self, $stackPos) { + $self->semValue = new Node\UseItem($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); $self->checkUseUse($self->semValue, $stackPos-(3-3)); + }, + 139 => static function ($self, $stackPos) { + $self->semValue = new Node\UseItem($self->semStack[$stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); $self->checkUseUse($self->semValue, $stackPos-(1-1)); + }, + 140 => static function ($self, $stackPos) { + $self->semValue = new Node\UseItem($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); $self->checkUseUse($self->semValue, $stackPos-(3-3)); + }, + 141 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; $self->semValue->type = Stmt\Use_::TYPE_NORMAL; + }, + 142 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; $self->semValue->type = $self->semStack[$stackPos-(2-1)]; + }, + 143 => null, + 144 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 145 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 146 => static function ($self, $stackPos) { + $self->semValue = new Node\Const_($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 147 => null, + 148 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 149 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 150 => static function ($self, $stackPos) { + $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos-(3-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos-(3-1)])), $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 151 => static function ($self, $stackPos) { + $self->semValue = new Node\Const_(new Node\Identifier($self->semStack[$stackPos-(3-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos-(3-1)])), $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 152 => static function ($self, $stackPos) { + if ($self->semStack[$stackPos-(2-2)] !== null) { $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; } $self->semValue = $self->semStack[$stackPos-(2-1)];; + }, + 153 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 154 => static function ($self, $stackPos) { + $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);; + if ($nop !== null) { $self->semStack[$stackPos-(1-1)][] = $nop; } $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 155 => null, + 156 => null, + 157 => null, + 158 => static function ($self, $stackPos) { + throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 159 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Block($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 160 => static function ($self, $stackPos) { + $self->semValue = new Stmt\If_($self->semStack[$stackPos-(7-3)], ['stmts' => $self->semStack[$stackPos-(7-5)], 'elseifs' => $self->semStack[$stackPos-(7-6)], 'else' => $self->semStack[$stackPos-(7-7)]], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + }, + 161 => static function ($self, $stackPos) { + $self->semValue = new Stmt\If_($self->semStack[$stackPos-(10-3)], ['stmts' => $self->semStack[$stackPos-(10-6)], 'elseifs' => $self->semStack[$stackPos-(10-7)], 'else' => $self->semStack[$stackPos-(10-8)]], $self->getAttributes($self->tokenStartStack[$stackPos-(10-1)], $self->tokenEndStack[$stackPos])); + }, + 162 => static function ($self, $stackPos) { + $self->semValue = new Stmt\While_($self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 163 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Do_($self->semStack[$stackPos-(7-5)], $self->semStack[$stackPos-(7-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + }, + 164 => static function ($self, $stackPos) { + $self->semValue = new Stmt\For_(['init' => $self->semStack[$stackPos-(9-3)], 'cond' => $self->semStack[$stackPos-(9-5)], 'loop' => $self->semStack[$stackPos-(9-7)], 'stmts' => $self->semStack[$stackPos-(9-9)]], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 165 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Switch_($self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 166 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Break_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 167 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Continue_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 168 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Return_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 169 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Global_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 170 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Static_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 171 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Echo_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 172 => static function ($self, $stackPos) { + + $self->semValue = new Stmt\InlineHTML($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + $self->semValue->setAttribute('hasLeadingNewline', $self->inlineHtmlHasLeadingNewline($stackPos-(1-1))); + + }, + 173 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Expression($self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 174 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Unset_($self->semStack[$stackPos-(5-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 175 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos-(7-3)], $self->semStack[$stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $self->semStack[$stackPos-(7-5)][1], 'stmts' => $self->semStack[$stackPos-(7-7)]], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + }, + 176 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos-(9-3)], $self->semStack[$stackPos-(9-7)][0], ['keyVar' => $self->semStack[$stackPos-(9-5)], 'byRef' => $self->semStack[$stackPos-(9-7)][1], 'stmts' => $self->semStack[$stackPos-(9-9)]], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 177 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Foreach_($self->semStack[$stackPos-(6-3)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(6-4)], $self->tokenEndStack[$stackPos-(6-4)])), ['stmts' => $self->semStack[$stackPos-(6-6)]], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])); + }, + 178 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Declare_($self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 179 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TryCatch($self->semStack[$stackPos-(6-3)], $self->semStack[$stackPos-(6-5)], $self->semStack[$stackPos-(6-6)], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])); $self->checkTryCatch($self->semValue); + }, + 180 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Goto_($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 181 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Label($self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 182 => static function ($self, $stackPos) { + $self->semValue = null; /* means: no statement */ + }, + 183 => null, + 184 => static function ($self, $stackPos) { + $self->semValue = $self->maybeCreateNop($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]); + }, + 185 => static function ($self, $stackPos) { + if ($self->semStack[$stackPos-(1-1)] instanceof Stmt\Block) { $self->semValue = $self->semStack[$stackPos-(1-1)]->stmts; } else if ($self->semStack[$stackPos-(1-1)] === null) { $self->semValue = []; } else { $self->semValue = [$self->semStack[$stackPos-(1-1)]]; }; + }, + 186 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 187 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 188 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 189 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 190 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Catch_($self->semStack[$stackPos-(8-3)], $self->semStack[$stackPos-(8-4)], $self->semStack[$stackPos-(8-7)], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + }, + 191 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 192 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Finally_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 193 => null, + 194 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 195 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 196 => static function ($self, $stackPos) { + $self->semValue = false; + }, + 197 => static function ($self, $stackPos) { + $self->semValue = true; + }, + 198 => static function ($self, $stackPos) { + $self->semValue = false; + }, + 199 => static function ($self, $stackPos) { + $self->semValue = true; + }, + 200 => static function ($self, $stackPos) { + $self->semValue = false; + }, + 201 => static function ($self, $stackPos) { + $self->semValue = true; + }, + 202 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 203 => static function ($self, $stackPos) { + $self->semValue = []; + }, + 204 => null, + 205 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 206 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 207 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 208 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Function_($self->semStack[$stackPos-(8-3)], ['byRef' => $self->semStack[$stackPos-(8-2)], 'params' => $self->semStack[$stackPos-(8-5)], 'returnType' => $self->semStack[$stackPos-(8-7)], 'stmts' => $self->semStack[$stackPos-(8-8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + }, + 209 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Function_($self->semStack[$stackPos-(9-4)], ['byRef' => $self->semStack[$stackPos-(9-3)], 'params' => $self->semStack[$stackPos-(9-6)], 'returnType' => $self->semStack[$stackPos-(9-8)], 'stmts' => $self->semStack[$stackPos-(9-9)], 'attrGroups' => $self->semStack[$stackPos-(9-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 210 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Class_($self->semStack[$stackPos-(7-2)], ['type' => $self->semStack[$stackPos-(7-1)], 'extends' => $self->semStack[$stackPos-(7-3)], 'implements' => $self->semStack[$stackPos-(7-4)], 'stmts' => $self->semStack[$stackPos-(7-6)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + $self->checkClass($self->semValue, $stackPos-(7-2)); + }, + 211 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Class_($self->semStack[$stackPos-(8-3)], ['type' => $self->semStack[$stackPos-(8-2)], 'extends' => $self->semStack[$stackPos-(8-4)], 'implements' => $self->semStack[$stackPos-(8-5)], 'stmts' => $self->semStack[$stackPos-(8-7)], 'attrGroups' => $self->semStack[$stackPos-(8-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + $self->checkClass($self->semValue, $stackPos-(8-3)); + }, + 212 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Interface_($self->semStack[$stackPos-(7-3)], ['extends' => $self->semStack[$stackPos-(7-4)], 'stmts' => $self->semStack[$stackPos-(7-6)], 'attrGroups' => $self->semStack[$stackPos-(7-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + $self->checkInterface($self->semValue, $stackPos-(7-3)); + }, + 213 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Trait_($self->semStack[$stackPos-(6-3)], ['stmts' => $self->semStack[$stackPos-(6-5)], 'attrGroups' => $self->semStack[$stackPos-(6-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])); + }, + 214 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Enum_($self->semStack[$stackPos-(8-3)], ['scalarType' => $self->semStack[$stackPos-(8-4)], 'implements' => $self->semStack[$stackPos-(8-5)], 'stmts' => $self->semStack[$stackPos-(8-7)], 'attrGroups' => $self->semStack[$stackPos-(8-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + $self->checkEnum($self->semValue, $stackPos-(8-3)); + }, + 215 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 216 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 217 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 218 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 219 => static function ($self, $stackPos) { + $self->semValue = 0; + }, + 220 => null, + 221 => null, + 222 => static function ($self, $stackPos) { + $self->checkClassModifier($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $self->semValue = $self->semStack[$stackPos-(2-1)] | $self->semStack[$stackPos-(2-2)]; + }, + 223 => static function ($self, $stackPos) { + $self->semValue = Modifiers::ABSTRACT; + }, + 224 => static function ($self, $stackPos) { + $self->semValue = Modifiers::FINAL; + }, + 225 => static function ($self, $stackPos) { + $self->semValue = Modifiers::READONLY; + }, + 226 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 227 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 228 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 229 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 230 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 231 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 232 => null, + 233 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 234 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 235 => null, + 236 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 237 => null, + 238 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 239 => static function ($self, $stackPos) { + if ($self->semStack[$stackPos-(1-1)] instanceof Stmt\Block) { $self->semValue = $self->semStack[$stackPos-(1-1)]->stmts; } else if ($self->semStack[$stackPos-(1-1)] === null) { $self->semValue = []; } else { $self->semValue = [$self->semStack[$stackPos-(1-1)]]; }; + }, + 240 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 241 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 242 => null, + 243 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 244 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 245 => static function ($self, $stackPos) { + $self->semValue = new Node\DeclareItem($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 246 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 247 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-3)]; + }, + 248 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 249 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(5-3)]; + }, + 250 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 251 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 252 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Case_($self->semStack[$stackPos-(4-2)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 253 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Case_(null, $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 254 => null, + 255 => null, + 256 => static function ($self, $stackPos) { + $self->semValue = new Expr\Match_($self->semStack[$stackPos-(7-3)], $self->semStack[$stackPos-(7-6)], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos])); + }, + 257 => static function ($self, $stackPos) { + $self->semValue = []; + }, + 258 => null, + 259 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 260 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 261 => static function ($self, $stackPos) { + $self->semValue = new Node\MatchArm($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 262 => static function ($self, $stackPos) { + $self->semValue = new Node\MatchArm(null, $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 263 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 264 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 265 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 266 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 267 => static function ($self, $stackPos) { + $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 268 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 269 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 270 => static function ($self, $stackPos) { + $self->semValue = new Stmt\ElseIf_($self->semStack[$stackPos-(6-3)], $self->semStack[$stackPos-(6-6)], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])); $self->fixupAlternativeElse($self->semValue); + }, + 271 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 272 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Else_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 273 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 274 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Else_($self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); $self->fixupAlternativeElse($self->semValue); + }, + 275 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)], false); + }, + 276 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(2-2)], true); + }, + 277 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)], false); + }, + 278 => static function ($self, $stackPos) { + $self->semValue = array($self->fixupArrayDestructuring($self->semStack[$stackPos-(1-1)]), false); + }, + 279 => null, + 280 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 281 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 282 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 283 => static function ($self, $stackPos) { + $self->semValue = 0; + }, + 284 => static function ($self, $stackPos) { + $self->checkModifier($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $self->semValue = $self->semStack[$stackPos-(2-1)] | $self->semStack[$stackPos-(2-2)]; + }, + 285 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PUBLIC; + }, + 286 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PROTECTED; + }, + 287 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PRIVATE; + }, + 288 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PUBLIC_SET; + }, + 289 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PROTECTED_SET; + }, + 290 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PRIVATE_SET; + }, + 291 => static function ($self, $stackPos) { + $self->semValue = Modifiers::READONLY; + }, + 292 => static function ($self, $stackPos) { + $self->semValue = Modifiers::FINAL; + }, + 293 => static function ($self, $stackPos) { + $self->semValue = new Node\Param($self->semStack[$stackPos-(7-6)], null, $self->semStack[$stackPos-(7-3)], $self->semStack[$stackPos-(7-4)], $self->semStack[$stackPos-(7-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(7-2)], $self->semStack[$stackPos-(7-1)], $self->semStack[$stackPos-(7-7)]); + $self->checkParam($self->semValue); + $self->addPropertyNameToHooks($self->semValue); + }, + 294 => static function ($self, $stackPos) { + $self->semValue = new Node\Param($self->semStack[$stackPos-(9-6)], $self->semStack[$stackPos-(9-8)], $self->semStack[$stackPos-(9-3)], $self->semStack[$stackPos-(9-4)], $self->semStack[$stackPos-(9-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(9-2)], $self->semStack[$stackPos-(9-1)], $self->semStack[$stackPos-(9-9)]); + $self->checkParam($self->semValue); + $self->addPropertyNameToHooks($self->semValue); + }, + 295 => static function ($self, $stackPos) { + $self->semValue = new Node\Param(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])), null, $self->semStack[$stackPos-(6-3)], $self->semStack[$stackPos-(6-4)], $self->semStack[$stackPos-(6-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(6-2)], $self->semStack[$stackPos-(6-1)]); + }, + 296 => null, + 297 => static function ($self, $stackPos) { + $self->semValue = new Node\NullableType($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 298 => static function ($self, $stackPos) { + $self->semValue = new Node\UnionType($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 299 => null, + 300 => null, + 301 => static function ($self, $stackPos) { + $self->semValue = new Node\Name('static', $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 302 => static function ($self, $stackPos) { + $self->semValue = $self->handleBuiltinTypes($self->semStack[$stackPos-(1-1)]); + }, + 303 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier('array', $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 304 => static function ($self, $stackPos) { + $self->semValue = new Node\Identifier('callable', $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 305 => null, + 306 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 307 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)]); + }, + 308 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 309 => null, + 310 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 311 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)]); + }, + 312 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 313 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)]); + }, + 314 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 315 => static function ($self, $stackPos) { + $self->semValue = new Node\IntersectionType($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 316 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)]); + }, + 317 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 318 => static function ($self, $stackPos) { + $self->semValue = new Node\IntersectionType($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 319 => null, + 320 => static function ($self, $stackPos) { + $self->semValue = new Node\NullableType($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 321 => static function ($self, $stackPos) { + $self->semValue = new Node\UnionType($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 322 => null, + 323 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 324 => null, + 325 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 326 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(2-2)]; + }, + 327 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 328 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 329 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 330 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-2)]); + }, + 331 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 332 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-2)]; + }, + 333 => static function ($self, $stackPos) { + $self->semValue = array(new Node\Arg($self->semStack[$stackPos-(4-2)], false, false, $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos]))); + }, + 334 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-2)]); + }, + 335 => static function ($self, $stackPos) { + $self->semValue = array(new Node\Arg($self->semStack[$stackPos-(3-1)], false, false, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos-(3-1)])), $self->semStack[$stackPos-(3-3)]); + }, + 336 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 337 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 338 => static function ($self, $stackPos) { + $self->semValue = new Node\VariadicPlaceholder($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 339 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 340 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 341 => static function ($self, $stackPos) { + $self->semValue = new Node\Arg($self->semStack[$stackPos-(2-2)], true, false, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 342 => static function ($self, $stackPos) { + $self->semValue = new Node\Arg($self->semStack[$stackPos-(2-2)], false, true, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 343 => static function ($self, $stackPos) { + $self->semValue = new Node\Arg($self->semStack[$stackPos-(3-3)], false, false, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(3-1)]); + }, + 344 => static function ($self, $stackPos) { + $self->semValue = new Node\Arg($self->semStack[$stackPos-(1-1)], false, false, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 345 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 346 => null, + 347 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 348 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 349 => null, + 350 => null, + 351 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 352 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 353 => static function ($self, $stackPos) { + $self->semValue = new Node\StaticVar($self->semStack[$stackPos-(1-1)], null, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 354 => static function ($self, $stackPos) { + $self->semValue = new Node\StaticVar($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 355 => static function ($self, $stackPos) { + if ($self->semStack[$stackPos-(2-2)] !== null) { $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; } else { $self->semValue = $self->semStack[$stackPos-(2-1)]; } + }, + 356 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 357 => static function ($self, $stackPos) { + $nop = $self->maybeCreateZeroLengthNop($self->tokenPos);; + if ($nop !== null) { $self->semStack[$stackPos-(1-1)][] = $nop; } $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 358 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Property($self->semStack[$stackPos-(5-2)], $self->semStack[$stackPos-(5-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-1)]); + }, + 359 => static function ($self, $stackPos) { + $self->semValue = new Stmt\Property($self->semStack[$stackPos-(7-2)], $self->semStack[$stackPos-(7-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(7-3)], $self->semStack[$stackPos-(7-1)], $self->semStack[$stackPos-(7-6)]); + $self->checkPropertyHooksForMultiProperty($self->semValue, $stackPos-(7-5)); + $self->checkEmptyPropertyHookList($self->semStack[$stackPos-(7-6)], $stackPos-(7-5)); + $self->addPropertyNameToHooks($self->semValue); + }, + 360 => static function ($self, $stackPos) { + $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos-(5-4)], $self->semStack[$stackPos-(5-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(5-1)]); + $self->checkClassConst($self->semValue, $stackPos-(5-2)); + }, + 361 => static function ($self, $stackPos) { + $self->semValue = new Stmt\ClassConst($self->semStack[$stackPos-(6-5)], $self->semStack[$stackPos-(6-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(6-1)], $self->semStack[$stackPos-(6-4)]); + $self->checkClassConst($self->semValue, $stackPos-(6-2)); + }, + 362 => static function ($self, $stackPos) { + $self->semValue = new Stmt\ClassMethod($self->semStack[$stackPos-(10-5)], ['type' => $self->semStack[$stackPos-(10-2)], 'byRef' => $self->semStack[$stackPos-(10-4)], 'params' => $self->semStack[$stackPos-(10-7)], 'returnType' => $self->semStack[$stackPos-(10-9)], 'stmts' => $self->semStack[$stackPos-(10-10)], 'attrGroups' => $self->semStack[$stackPos-(10-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(10-1)], $self->tokenEndStack[$stackPos])); + $self->checkClassMethod($self->semValue, $stackPos-(10-2)); + }, + 363 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUse($self->semStack[$stackPos-(3-2)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 364 => static function ($self, $stackPos) { + $self->semValue = new Stmt\EnumCase($self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-4)], $self->semStack[$stackPos-(5-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 365 => static function ($self, $stackPos) { + $self->semValue = null; /* will be skipped */ + }, + 366 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 367 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 368 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 369 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 370 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUseAdaptation\Precedence($self->semStack[$stackPos-(4-1)][0], $self->semStack[$stackPos-(4-1)][1], $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 371 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos-(5-1)][0], $self->semStack[$stackPos-(5-1)][1], $self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 372 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos-(4-1)][0], $self->semStack[$stackPos-(4-1)][1], $self->semStack[$stackPos-(4-3)], null, $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 373 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos-(4-1)][0], $self->semStack[$stackPos-(4-1)][1], null, $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 374 => static function ($self, $stackPos) { + $self->semValue = new Stmt\TraitUseAdaptation\Alias($self->semStack[$stackPos-(4-1)][0], $self->semStack[$stackPos-(4-1)][1], null, $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 375 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)]); + }, + 376 => null, + 377 => static function ($self, $stackPos) { + $self->semValue = array(null, $self->semStack[$stackPos-(1-1)]); + }, + 378 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 379 => null, + 380 => null, + 381 => static function ($self, $stackPos) { + $self->semValue = 0; + }, + 382 => static function ($self, $stackPos) { + $self->semValue = 0; + }, + 383 => null, + 384 => null, + 385 => static function ($self, $stackPos) { + $self->checkModifier($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $self->semValue = $self->semStack[$stackPos-(2-1)] | $self->semStack[$stackPos-(2-2)]; + }, + 386 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PUBLIC; + }, + 387 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PROTECTED; + }, + 388 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PRIVATE; + }, + 389 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PUBLIC_SET; + }, + 390 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PROTECTED_SET; + }, + 391 => static function ($self, $stackPos) { + $self->semValue = Modifiers::PRIVATE_SET; + }, + 392 => static function ($self, $stackPos) { + $self->semValue = Modifiers::STATIC; + }, + 393 => static function ($self, $stackPos) { + $self->semValue = Modifiers::ABSTRACT; + }, + 394 => static function ($self, $stackPos) { + $self->semValue = Modifiers::FINAL; + }, + 395 => static function ($self, $stackPos) { + $self->semValue = Modifiers::READONLY; + }, + 396 => null, + 397 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 398 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 399 => static function ($self, $stackPos) { + $self->semValue = new Node\VarLikeIdentifier(substr($self->semStack[$stackPos-(1-1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 400 => static function ($self, $stackPos) { + $self->semValue = new Node\PropertyItem($self->semStack[$stackPos-(1-1)], null, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 401 => static function ($self, $stackPos) { + $self->semValue = new Node\PropertyItem($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 402 => static function ($self, $stackPos) { + $self->semValue = []; + }, + 403 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 404 => static function ($self, $stackPos) { + $self->semValue = []; + }, + 405 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; $self->checkEmptyPropertyHookList($self->semStack[$stackPos-(3-2)], $stackPos-(3-1)); + }, + 406 => static function ($self, $stackPos) { + $self->semValue = new Node\PropertyHook($self->semStack[$stackPos-(5-4)], $self->semStack[$stackPos-(5-5)], ['flags' => $self->semStack[$stackPos-(5-2)], 'byRef' => $self->semStack[$stackPos-(5-3)], 'params' => [], 'attrGroups' => $self->semStack[$stackPos-(5-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + $self->checkPropertyHook($self->semValue, null); + }, + 407 => static function ($self, $stackPos) { + $self->semValue = new Node\PropertyHook($self->semStack[$stackPos-(8-4)], $self->semStack[$stackPos-(8-8)], ['flags' => $self->semStack[$stackPos-(8-2)], 'byRef' => $self->semStack[$stackPos-(8-3)], 'params' => $self->semStack[$stackPos-(8-6)], 'attrGroups' => $self->semStack[$stackPos-(8-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + $self->checkPropertyHook($self->semValue, $stackPos-(8-5)); + }, + 408 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 409 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 410 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 411 => static function ($self, $stackPos) { + $self->semValue = 0; + }, + 412 => static function ($self, $stackPos) { + $self->checkPropertyHookModifiers($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $self->semValue = $self->semStack[$stackPos-(2-1)] | $self->semStack[$stackPos-(2-2)]; + }, + 413 => null, + 414 => null, + 415 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 416 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 417 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 418 => null, + 419 => null, + 420 => static function ($self, $stackPos) { + $self->semValue = new Expr\Assign($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 421 => static function ($self, $stackPos) { + $self->semValue = new Expr\Assign($self->fixupArrayDestructuring($self->semStack[$stackPos-(3-1)]), $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 422 => static function ($self, $stackPos) { + $self->semValue = new Expr\Assign($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 423 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignRef($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 424 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignRef($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + if (!$self->phpVersion->allowsAssignNewByReference()) { + $self->emitError(new Error('Cannot assign new by reference', $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos]))); + } + + }, + 425 => null, + 426 => null, + 427 => static function ($self, $stackPos) { + $self->semValue = new Expr\FuncCall(new Node\Name($self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos-(2-1)])), $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 428 => static function ($self, $stackPos) { + $self->semValue = new Expr\Clone_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 429 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Plus($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 430 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Minus($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 431 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Mul($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 432 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Div($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 433 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Concat($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 434 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Mod($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 435 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\BitwiseAnd($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 436 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\BitwiseOr($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 437 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\BitwiseXor($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 438 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\ShiftLeft($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 439 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\ShiftRight($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 440 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Pow($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 441 => static function ($self, $stackPos) { + $self->semValue = new Expr\AssignOp\Coalesce($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 442 => static function ($self, $stackPos) { + $self->semValue = new Expr\PostInc($self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 443 => static function ($self, $stackPos) { + $self->semValue = new Expr\PreInc($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 444 => static function ($self, $stackPos) { + $self->semValue = new Expr\PostDec($self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 445 => static function ($self, $stackPos) { + $self->semValue = new Expr\PreDec($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 446 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BooleanOr($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 447 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BooleanAnd($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 448 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\LogicalOr($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 449 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\LogicalAnd($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 450 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\LogicalXor($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 451 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BitwiseOr($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 452 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 453 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BitwiseAnd($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 454 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\BitwiseXor($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 455 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Concat($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 456 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Plus($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 457 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Minus($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 458 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Mul($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 459 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Div($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 460 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Mod($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 461 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\ShiftLeft($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 462 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\ShiftRight($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 463 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Pow($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 464 => static function ($self, $stackPos) { + $self->semValue = new Expr\UnaryPlus($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 465 => static function ($self, $stackPos) { + $self->semValue = new Expr\UnaryMinus($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 466 => static function ($self, $stackPos) { + $self->semValue = new Expr\BooleanNot($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 467 => static function ($self, $stackPos) { + $self->semValue = new Expr\BitwiseNot($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 468 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Identical($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 469 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\NotIdentical($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 470 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Equal($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 471 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\NotEqual($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 472 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Spaceship($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 473 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Smaller($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 474 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\SmallerOrEqual($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 475 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Greater($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 476 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\GreaterOrEqual($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 477 => static function ($self, $stackPos) { + + $self->semValue = new Expr\BinaryOp\Pipe($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + $self->checkPipeOperatorParentheses($self->semStack[$stackPos-(3-3)]); + + }, + 478 => static function ($self, $stackPos) { + $self->semValue = new Expr\Instanceof_($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 479 => static function ($self, $stackPos) { + + $self->semValue = $self->semStack[$stackPos-(3-2)]; + if ($self->semValue instanceof Expr\ArrowFunction) { + $self->parenthesizedArrowFunctions->offsetSet($self->semValue); + } + + }, + 480 => static function ($self, $stackPos) { + $self->semValue = new Expr\Ternary($self->semStack[$stackPos-(5-1)], $self->semStack[$stackPos-(5-3)], $self->semStack[$stackPos-(5-5)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 481 => static function ($self, $stackPos) { + $self->semValue = new Expr\Ternary($self->semStack[$stackPos-(4-1)], null, $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 482 => static function ($self, $stackPos) { + $self->semValue = new Expr\BinaryOp\Coalesce($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 483 => static function ($self, $stackPos) { + $self->semValue = new Expr\Isset_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 484 => static function ($self, $stackPos) { + $self->semValue = new Expr\Empty_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 485 => static function ($self, $stackPos) { + $self->semValue = new Expr\Include_($self->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 486 => static function ($self, $stackPos) { + $self->semValue = new Expr\Include_($self->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 487 => static function ($self, $stackPos) { + $self->semValue = new Expr\Eval_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 488 => static function ($self, $stackPos) { + $self->semValue = new Expr\Include_($self->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 489 => static function ($self, $stackPos) { + $self->semValue = new Expr\Include_($self->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 490 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]); + $attrs['kind'] = $self->getIntCastKind($self->semStack[$stackPos-(2-1)]); + $self->semValue = new Expr\Cast\Int_($self->semStack[$stackPos-(2-2)], $attrs); + }, + 491 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]); + $attrs['kind'] = $self->getFloatCastKind($self->semStack[$stackPos-(2-1)]); + $self->semValue = new Expr\Cast\Double($self->semStack[$stackPos-(2-2)], $attrs); + }, + 492 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]); + $attrs['kind'] = $self->getStringCastKind($self->semStack[$stackPos-(2-1)]); + $self->semValue = new Expr\Cast\String_($self->semStack[$stackPos-(2-2)], $attrs); + }, + 493 => static function ($self, $stackPos) { + $self->semValue = new Expr\Cast\Array_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 494 => static function ($self, $stackPos) { + $self->semValue = new Expr\Cast\Object_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 495 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]); + $attrs['kind'] = $self->getBoolCastKind($self->semStack[$stackPos-(2-1)]); + $self->semValue = new Expr\Cast\Bool_($self->semStack[$stackPos-(2-2)], $attrs); + }, + 496 => static function ($self, $stackPos) { + $self->semValue = new Expr\Cast\Unset_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 497 => static function ($self, $stackPos) { + $self->semValue = new Expr\Cast\Void_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 498 => static function ($self, $stackPos) { + $self->semValue = $self->createExitExpr($self->semStack[$stackPos-(2-1)], $stackPos-(2-1), $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 499 => static function ($self, $stackPos) { + $self->semValue = new Expr\ErrorSuppress($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 500 => null, + 501 => static function ($self, $stackPos) { + $self->semValue = new Expr\ShellExec($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 502 => static function ($self, $stackPos) { + $self->semValue = new Expr\Print_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 503 => static function ($self, $stackPos) { + $self->semValue = new Expr\Yield_(null, null, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 504 => static function ($self, $stackPos) { + $self->semValue = new Expr\Yield_($self->semStack[$stackPos-(2-2)], null, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 505 => static function ($self, $stackPos) { + $self->semValue = new Expr\Yield_($self->semStack[$stackPos-(4-4)], $self->semStack[$stackPos-(4-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 506 => static function ($self, $stackPos) { + $self->semValue = new Expr\YieldFrom($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 507 => static function ($self, $stackPos) { + $self->semValue = new Expr\Throw_($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 508 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrowFunction(['static' => false, 'byRef' => $self->semStack[$stackPos-(8-2)], 'params' => $self->semStack[$stackPos-(8-4)], 'returnType' => $self->semStack[$stackPos-(8-6)], 'expr' => $self->semStack[$stackPos-(8-8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + }, + 509 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrowFunction(['static' => true, 'byRef' => $self->semStack[$stackPos-(9-3)], 'params' => $self->semStack[$stackPos-(9-5)], 'returnType' => $self->semStack[$stackPos-(9-7)], 'expr' => $self->semStack[$stackPos-(9-9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 510 => static function ($self, $stackPos) { + $self->semValue = new Expr\Closure(['static' => false, 'byRef' => $self->semStack[$stackPos-(8-2)], 'params' => $self->semStack[$stackPos-(8-4)], 'uses' => $self->semStack[$stackPos-(8-6)], 'returnType' => $self->semStack[$stackPos-(8-7)], 'stmts' => $self->semStack[$stackPos-(8-8)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])); + }, + 511 => static function ($self, $stackPos) { + $self->semValue = new Expr\Closure(['static' => true, 'byRef' => $self->semStack[$stackPos-(9-3)], 'params' => $self->semStack[$stackPos-(9-5)], 'uses' => $self->semStack[$stackPos-(9-7)], 'returnType' => $self->semStack[$stackPos-(9-8)], 'stmts' => $self->semStack[$stackPos-(9-9)], 'attrGroups' => []], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 512 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrowFunction(['static' => false, 'byRef' => $self->semStack[$stackPos-(9-3)], 'params' => $self->semStack[$stackPos-(9-5)], 'returnType' => $self->semStack[$stackPos-(9-7)], 'expr' => $self->semStack[$stackPos-(9-9)], 'attrGroups' => $self->semStack[$stackPos-(9-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 513 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrowFunction(['static' => true, 'byRef' => $self->semStack[$stackPos-(10-4)], 'params' => $self->semStack[$stackPos-(10-6)], 'returnType' => $self->semStack[$stackPos-(10-8)], 'expr' => $self->semStack[$stackPos-(10-10)], 'attrGroups' => $self->semStack[$stackPos-(10-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(10-1)], $self->tokenEndStack[$stackPos])); + }, + 514 => static function ($self, $stackPos) { + $self->semValue = new Expr\Closure(['static' => false, 'byRef' => $self->semStack[$stackPos-(9-3)], 'params' => $self->semStack[$stackPos-(9-5)], 'uses' => $self->semStack[$stackPos-(9-7)], 'returnType' => $self->semStack[$stackPos-(9-8)], 'stmts' => $self->semStack[$stackPos-(9-9)], 'attrGroups' => $self->semStack[$stackPos-(9-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(9-1)], $self->tokenEndStack[$stackPos])); + }, + 515 => static function ($self, $stackPos) { + $self->semValue = new Expr\Closure(['static' => true, 'byRef' => $self->semStack[$stackPos-(10-4)], 'params' => $self->semStack[$stackPos-(10-6)], 'uses' => $self->semStack[$stackPos-(10-8)], 'returnType' => $self->semStack[$stackPos-(10-9)], 'stmts' => $self->semStack[$stackPos-(10-10)], 'attrGroups' => $self->semStack[$stackPos-(10-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(10-1)], $self->tokenEndStack[$stackPos])); + }, + 516 => static function ($self, $stackPos) { + $self->semValue = array(new Stmt\Class_(null, ['type' => $self->semStack[$stackPos-(8-2)], 'extends' => $self->semStack[$stackPos-(8-4)], 'implements' => $self->semStack[$stackPos-(8-5)], 'stmts' => $self->semStack[$stackPos-(8-7)], 'attrGroups' => $self->semStack[$stackPos-(8-1)]], $self->getAttributes($self->tokenStartStack[$stackPos-(8-1)], $self->tokenEndStack[$stackPos])), $self->semStack[$stackPos-(8-3)]); + $self->checkClass($self->semValue[0], -1); + }, + 517 => static function ($self, $stackPos) { + $self->semValue = new Expr\New_($self->semStack[$stackPos-(3-2)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 518 => static function ($self, $stackPos) { + list($class, $ctorArgs) = $self->semStack[$stackPos-(2-2)]; $self->semValue = new Expr\New_($class, $ctorArgs, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 519 => static function ($self, $stackPos) { + $self->semValue = new Expr\New_($self->semStack[$stackPos-(2-2)], [], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 520 => null, + 521 => null, + 522 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 523 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(4-3)]; + }, + 524 => null, + 525 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 526 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 527 => static function ($self, $stackPos) { + $self->semValue = new Node\ClosureUse($self->semStack[$stackPos-(2-2)], $self->semStack[$stackPos-(2-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 528 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 529 => static function ($self, $stackPos) { + $self->semValue = new Expr\FuncCall($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 530 => static function ($self, $stackPos) { + $self->semValue = new Expr\FuncCall($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 531 => static function ($self, $stackPos) { + $self->semValue = new Expr\FuncCall($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 532 => static function ($self, $stackPos) { + $self->semValue = new Expr\StaticCall($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 533 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 534 => null, + 535 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 536 => static function ($self, $stackPos) { + $self->semValue = new Name($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 537 => static function ($self, $stackPos) { + $self->semValue = new Name\FullyQualified(substr($self->semStack[$stackPos-(1-1)], 1), $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 538 => static function ($self, $stackPos) { + $self->semValue = new Name\Relative(substr($self->semStack[$stackPos-(1-1)], 10), $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 539 => null, + 540 => null, + 541 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 542 => static function ($self, $stackPos) { + $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); $self->errorState = 2; + }, + 543 => null, + 544 => null, + 545 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 546 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); foreach ($self->semValue as $s) { if ($s instanceof Node\InterpolatedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes()); } }; + }, + 547 => static function ($self, $stackPos) { + foreach ($self->semStack[$stackPos-(1-1)] as $s) { if ($s instanceof Node\InterpolatedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', $self->phpVersion->supportsUnicodeEscapes()); } }; $self->semValue = $self->semStack[$stackPos-(1-1)]; + }, + 548 => static function ($self, $stackPos) { + $self->semValue = array(); + }, + 549 => null, + 550 => static function ($self, $stackPos) { + $self->semValue = new Expr\ConstFetch($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 551 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Line($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 552 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\File($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 553 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Dir($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 554 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Class_($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 555 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Trait_($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 556 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Method($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 557 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Function_($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 558 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Namespace_($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 559 => static function ($self, $stackPos) { + $self->semValue = new Scalar\MagicConst\Property($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 560 => static function ($self, $stackPos) { + $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 561 => static function ($self, $stackPos) { + $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos-(5-1)], $self->semStack[$stackPos-(5-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(5-1)], $self->tokenEndStack[$stackPos])); + }, + 562 => static function ($self, $stackPos) { + $self->semValue = new Expr\ClassConstFetch($self->semStack[$stackPos-(3-1)], new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(3-3)], $self->tokenEndStack[$stackPos-(3-3)])), $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); $self->errorState = 2; + }, + 563 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]); $attrs['kind'] = Expr\Array_::KIND_SHORT; + $self->semValue = new Expr\Array_($self->semStack[$stackPos-(3-2)], $attrs); + }, + 564 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos]); $attrs['kind'] = Expr\Array_::KIND_LONG; + $self->semValue = new Expr\Array_($self->semStack[$stackPos-(4-3)], $attrs); + $self->createdArrays->offsetSet($self->semValue); + }, + 565 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; $self->createdArrays->offsetSet($self->semValue); + }, + 566 => static function ($self, $stackPos) { + $self->semValue = Scalar\String_::fromString($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->supportsUnicodeEscapes()); + }, + 567 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + foreach ($self->semStack[$stackPos-(3-2)] as $s) { if ($s instanceof Node\InterpolatedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', $self->phpVersion->supportsUnicodeEscapes()); } }; $self->semValue = new Scalar\InterpolatedString($self->semStack[$stackPos-(3-2)], $attrs); + }, + 568 => static function ($self, $stackPos) { + $self->semValue = $self->parseLNumber($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]), $self->phpVersion->allowsInvalidOctals()); + }, + 569 => static function ($self, $stackPos) { + $self->semValue = Scalar\Float_::fromString($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 570 => null, + 571 => null, + 572 => null, + 573 => static function ($self, $stackPos) { + $self->semValue = $self->parseDocString($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-2)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos-(3-3)], $self->tokenEndStack[$stackPos-(3-3)]), true); + }, + 574 => static function ($self, $stackPos) { + $self->semValue = $self->parseDocString($self->semStack[$stackPos-(2-1)], '', $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos-(2-2)], $self->tokenEndStack[$stackPos-(2-2)]), true); + }, + 575 => static function ($self, $stackPos) { + $self->semValue = $self->parseDocString($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-2)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos]), $self->getAttributes($self->tokenStartStack[$stackPos-(3-3)], $self->tokenEndStack[$stackPos-(3-3)]), true); + }, + 576 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 577 => null, + 578 => null, + 579 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 580 => null, + 581 => null, + 582 => null, + 583 => null, + 584 => null, + 585 => null, + 586 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 587 => null, + 588 => null, + 589 => null, + 590 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 591 => null, + 592 => static function ($self, $stackPos) { + $self->semValue = new Expr\MethodCall($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 593 => static function ($self, $stackPos) { + $self->semValue = new Expr\NullsafeMethodCall($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->semStack[$stackPos-(4-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 594 => static function ($self, $stackPos) { + $self->semValue = null; + }, + 595 => null, + 596 => null, + 597 => null, + 598 => static function ($self, $stackPos) { + $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 599 => static function ($self, $stackPos) { + $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 600 => null, + 601 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 602 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable($self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 603 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable(new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])), $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); $self->errorState = 2; + }, + 604 => static function ($self, $stackPos) { + $var = $self->semStack[$stackPos-(1-1)]->name; $self->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])) : $var; + }, + 605 => static function ($self, $stackPos) { + $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 606 => null, + 607 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 608 => static function ($self, $stackPos) { + $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 609 => static function ($self, $stackPos) { + $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 610 => static function ($self, $stackPos) { + $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 611 => static function ($self, $stackPos) { + $self->semValue = new Expr\StaticPropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 612 => null, + 613 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 614 => null, + 615 => null, + 616 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 617 => null, + 618 => static function ($self, $stackPos) { + $self->semValue = new Expr\Error($self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); $self->errorState = 2; + }, + 619 => static function ($self, $stackPos) { + $self->semValue = new Expr\List_($self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); $self->semValue->setAttribute('kind', Expr\List_::KIND_LIST); + $self->postprocessList($self->semValue); + }, + 620 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(1-1)]; $end = count($self->semValue)-1; if ($self->semValue[$end]->value instanceof Expr\Error) array_pop($self->semValue); + }, + 621 => null, + 622 => static function ($self, $stackPos) { + /* do nothing -- prevent default action of $$=$self->semStack[$1]. See $551. */ + }, + 623 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(3-1)][] = $self->semStack[$stackPos-(3-3)]; $self->semValue = $self->semStack[$stackPos-(3-1)]; + }, + 624 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 625 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(1-1)], null, false, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 626 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(2-2)], null, true, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 627 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(1-1)], null, false, $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 628 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(3-3)], $self->semStack[$stackPos-(3-1)], false, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 629 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(4-4)], $self->semStack[$stackPos-(4-1)], true, $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 630 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(3-3)], $self->semStack[$stackPos-(3-1)], false, $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 631 => static function ($self, $stackPos) { + $self->semValue = new Node\ArrayItem($self->semStack[$stackPos-(2-2)], null, false, $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos]), true); + }, + 632 => static function ($self, $stackPos) { + /* Create an Error node now to remember the position. We'll later either report an error, + or convert this into a null element, depending on whether this is a creation or destructuring context. */ + $attrs = $self->createEmptyElemAttributes($self->tokenPos); + $self->semValue = new Node\ArrayItem(new Expr\Error($attrs), null, false, $attrs); + }, + 633 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 634 => static function ($self, $stackPos) { + $self->semStack[$stackPos-(2-1)][] = $self->semStack[$stackPos-(2-2)]; $self->semValue = $self->semStack[$stackPos-(2-1)]; + }, + 635 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(1-1)]); + }, + 636 => static function ($self, $stackPos) { + $self->semValue = array($self->semStack[$stackPos-(2-1)], $self->semStack[$stackPos-(2-2)]); + }, + 637 => static function ($self, $stackPos) { + $attrs = $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos]); $attrs['rawValue'] = $self->semStack[$stackPos-(1-1)]; $self->semValue = new Node\InterpolatedStringPart($self->semStack[$stackPos-(1-1)], $attrs); + }, + 638 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 639 => null, + 640 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos-(4-1)], $self->semStack[$stackPos-(4-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(4-1)], $self->tokenEndStack[$stackPos])); + }, + 641 => static function ($self, $stackPos) { + $self->semValue = new Expr\PropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 642 => static function ($self, $stackPos) { + $self->semValue = new Expr\NullsafePropertyFetch($self->semStack[$stackPos-(3-1)], $self->semStack[$stackPos-(3-3)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 643 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 644 => static function ($self, $stackPos) { + $self->semValue = new Expr\Variable($self->semStack[$stackPos-(3-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(3-1)], $self->tokenEndStack[$stackPos])); + }, + 645 => static function ($self, $stackPos) { + $self->semValue = new Expr\ArrayDimFetch($self->semStack[$stackPos-(6-2)], $self->semStack[$stackPos-(6-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(6-1)], $self->tokenEndStack[$stackPos])); + }, + 646 => static function ($self, $stackPos) { + $self->semValue = $self->semStack[$stackPos-(3-2)]; + }, + 647 => static function ($self, $stackPos) { + $self->semValue = new Scalar\String_($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 648 => static function ($self, $stackPos) { + $self->semValue = $self->parseNumString($self->semStack[$stackPos-(1-1)], $self->getAttributes($self->tokenStartStack[$stackPos-(1-1)], $self->tokenEndStack[$stackPos])); + }, + 649 => static function ($self, $stackPos) { + $self->semValue = $self->parseNumString('-' . $self->semStack[$stackPos-(2-2)], $self->getAttributes($self->tokenStartStack[$stackPos-(2-1)], $self->tokenEndStack[$stackPos])); + }, + 650 => null, + ]; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php new file mode 100644 index 00000000..73ee2dd7 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php @@ -0,0 +1,1342 @@ + Map of PHP token IDs to drop */ + protected array $dropTokens; + /** @var int[] Map of external symbols (static::T_*) to internal symbols */ + protected array $tokenToSymbol; + /** @var string[] Map of symbols to their names */ + protected array $symbolToName; + /** @var array Names of the production rules (only necessary for debugging) */ + protected array $productions; + + /** @var int[] Map of states to a displacement into the $action table. The corresponding action for this + * state/symbol pair is $action[$actionBase[$state] + $symbol]. If $actionBase[$state] is 0, the + * action is defaulted, i.e. $actionDefault[$state] should be used instead. */ + protected array $actionBase; + /** @var int[] Table of actions. Indexed according to $actionBase comment. */ + protected array $action; + /** @var int[] Table indexed analogously to $action. If $actionCheck[$actionBase[$state] + $symbol] != $symbol + * then the action is defaulted, i.e. $actionDefault[$state] should be used instead. */ + protected array $actionCheck; + /** @var int[] Map of states to their default action */ + protected array $actionDefault; + /** @var callable[] Semantic action callbacks */ + protected array $reduceCallbacks; + + /** @var int[] Map of non-terminals to a displacement into the $goto table. The corresponding goto state for this + * non-terminal/state pair is $goto[$gotoBase[$nonTerminal] + $state] (unless defaulted) */ + protected array $gotoBase; + /** @var int[] Table of states to goto after reduction. Indexed according to $gotoBase comment. */ + protected array $goto; + /** @var int[] Table indexed analogously to $goto. If $gotoCheck[$gotoBase[$nonTerminal] + $state] != $nonTerminal + * then the goto state is defaulted, i.e. $gotoDefault[$nonTerminal] should be used. */ + protected array $gotoCheck; + /** @var int[] Map of non-terminals to the default state to goto after their reduction */ + protected array $gotoDefault; + + /** @var int[] Map of rules to the non-terminal on their left-hand side, i.e. the non-terminal to use for + * determining the state to goto after reduction. */ + protected array $ruleToNonTerminal; + /** @var int[] Map of rules to the length of their right-hand side, which is the number of elements that have to + * be popped from the stack(s) on reduction. */ + protected array $ruleToLength; + + /* + * The following members are part of the parser state: + */ + + /** @var mixed Temporary value containing the result of last semantic action (reduction) */ + protected $semValue; + /** @var mixed[] Semantic value stack (contains values of tokens and semantic action results) */ + protected array $semStack; + /** @var int[] Token start position stack */ + protected array $tokenStartStack; + /** @var int[] Token end position stack */ + protected array $tokenEndStack; + + /** @var ErrorHandler Error handler */ + protected ErrorHandler $errorHandler; + /** @var int Error state, used to avoid error floods */ + protected int $errorState; + + /** @var \SplObjectStorage|null Array nodes created during parsing, for postprocessing of empty elements. */ + protected ?\SplObjectStorage $createdArrays; + + /** @var \SplObjectStorage|null + * Arrow functions that are wrapped in parentheses, to enforce the pipe operator parentheses requirements. + */ + protected ?\SplObjectStorage $parenthesizedArrowFunctions; + + /** @var Token[] Tokens for the current parse */ + protected array $tokens; + /** @var int Current position in token array */ + protected int $tokenPos; + + /** + * Initialize $reduceCallbacks map. + */ + abstract protected function initReduceCallbacks(): void; + + /** + * Creates a parser instance. + * + * Options: + * * phpVersion: ?PhpVersion, + * + * @param Lexer $lexer A lexer + * @param PhpVersion $phpVersion PHP version to target, defaults to latest supported. This + * option is best-effort: Even if specified, parsing will generally assume the latest + * supported version and only adjust behavior in minor ways, for example by omitting + * errors in older versions and interpreting type hints as a name or identifier depending + * on version. + */ + public function __construct(Lexer $lexer, ?PhpVersion $phpVersion = null) { + $this->lexer = $lexer; + $this->phpVersion = $phpVersion ?? PhpVersion::getNewestSupported(); + + $this->initReduceCallbacks(); + $this->phpTokenToSymbol = $this->createTokenMap(); + $this->dropTokens = array_fill_keys( + [\T_WHITESPACE, \T_OPEN_TAG, \T_COMMENT, \T_DOC_COMMENT, \T_BAD_CHARACTER], true + ); + } + + /** + * Parses PHP code into a node tree. + * + * If a non-throwing error handler is used, the parser will continue parsing after an error + * occurred and attempt to build a partial AST. + * + * @param string $code The source code to parse + * @param ErrorHandler|null $errorHandler Error handler to use for lexer/parser errors, defaults + * to ErrorHandler\Throwing. + * + * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and + * the parser was unable to recover from an error). + */ + public function parse(string $code, ?ErrorHandler $errorHandler = null): ?array { + $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing(); + $this->createdArrays = new \SplObjectStorage(); + $this->parenthesizedArrowFunctions = new \SplObjectStorage(); + + $this->tokens = $this->lexer->tokenize($code, $this->errorHandler); + $result = $this->doParse(); + + // Report errors for any empty elements used inside arrays. This is delayed until after the main parse, + // because we don't know a priori whether a given array expression will be used in a destructuring context + // or not. + foreach ($this->createdArrays as $node) { + foreach ($node->items as $item) { + if ($item->value instanceof Expr\Error) { + $this->errorHandler->handleError( + new Error('Cannot use empty array elements in arrays', $item->getAttributes())); + } + } + } + + // Clear out some of the interior state, so we don't hold onto unnecessary + // memory between uses of the parser + $this->tokenStartStack = []; + $this->tokenEndStack = []; + $this->semStack = []; + $this->semValue = null; + $this->createdArrays = null; + $this->parenthesizedArrowFunctions = null; + + if ($result !== null) { + $traverser = new NodeTraverser(new CommentAnnotatingVisitor($this->tokens)); + $traverser->traverse($result); + } + + return $result; + } + + public function getTokens(): array { + return $this->tokens; + } + + /** @return Stmt[]|null */ + protected function doParse(): ?array { + // We start off with no lookahead-token + $symbol = self::SYMBOL_NONE; + $tokenValue = null; + $this->tokenPos = -1; + + // Keep stack of start and end attributes + $this->tokenStartStack = []; + $this->tokenEndStack = [0]; + + // Start off in the initial state and keep a stack of previous states + $state = 0; + $stateStack = [$state]; + + // Semantic value stack (contains values of tokens and semantic action results) + $this->semStack = []; + + // Current position in the stack(s) + $stackPos = 0; + + $this->errorState = 0; + + for (;;) { + //$this->traceNewState($state, $symbol); + + if ($this->actionBase[$state] === 0) { + $rule = $this->actionDefault[$state]; + } else { + if ($symbol === self::SYMBOL_NONE) { + do { + $token = $this->tokens[++$this->tokenPos]; + $tokenId = $token->id; + } while (isset($this->dropTokens[$tokenId])); + + // Map the lexer token id to the internally used symbols. + $tokenValue = $token->text; + if (!isset($this->phpTokenToSymbol[$tokenId])) { + throw new \RangeException(sprintf( + 'The lexer returned an invalid token (id=%d, value=%s)', + $tokenId, $tokenValue + )); + } + $symbol = $this->phpTokenToSymbol[$tokenId]; + + //$this->traceRead($symbol); + } + + $idx = $this->actionBase[$state] + $symbol; + if ((($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol) + || ($state < $this->YY2TBLSTATE + && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol)) + && ($action = $this->action[$idx]) !== $this->defaultAction) { + /* + * >= numNonLeafStates: shift and reduce + * > 0: shift + * = 0: accept + * < 0: reduce + * = -YYUNEXPECTED: error + */ + if ($action > 0) { + /* shift */ + //$this->traceShift($symbol); + + ++$stackPos; + $stateStack[$stackPos] = $state = $action; + $this->semStack[$stackPos] = $tokenValue; + $this->tokenStartStack[$stackPos] = $this->tokenPos; + $this->tokenEndStack[$stackPos] = $this->tokenPos; + $symbol = self::SYMBOL_NONE; + + if ($this->errorState) { + --$this->errorState; + } + + if ($action < $this->numNonLeafStates) { + continue; + } + + /* $yyn >= numNonLeafStates means shift-and-reduce */ + $rule = $action - $this->numNonLeafStates; + } else { + $rule = -$action; + } + } else { + $rule = $this->actionDefault[$state]; + } + } + + for (;;) { + if ($rule === 0) { + /* accept */ + //$this->traceAccept(); + return $this->semValue; + } + if ($rule !== $this->unexpectedTokenRule) { + /* reduce */ + //$this->traceReduce($rule); + + $ruleLength = $this->ruleToLength[$rule]; + try { + $callback = $this->reduceCallbacks[$rule]; + if ($callback !== null) { + $callback($this, $stackPos); + } elseif ($ruleLength > 0) { + $this->semValue = $this->semStack[$stackPos - $ruleLength + 1]; + } + } catch (Error $e) { + if (-1 === $e->getStartLine()) { + $e->setStartLine($this->tokens[$this->tokenPos]->line); + } + + $this->emitError($e); + // Can't recover from this type of error + return null; + } + + /* Goto - shift nonterminal */ + $lastTokenEnd = $this->tokenEndStack[$stackPos]; + $stackPos -= $ruleLength; + $nonTerminal = $this->ruleToNonTerminal[$rule]; + $idx = $this->gotoBase[$nonTerminal] + $stateStack[$stackPos]; + if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] === $nonTerminal) { + $state = $this->goto[$idx]; + } else { + $state = $this->gotoDefault[$nonTerminal]; + } + + ++$stackPos; + $stateStack[$stackPos] = $state; + $this->semStack[$stackPos] = $this->semValue; + $this->tokenEndStack[$stackPos] = $lastTokenEnd; + if ($ruleLength === 0) { + // Empty productions use the start attributes of the lookahead token. + $this->tokenStartStack[$stackPos] = $this->tokenPos; + } + } else { + /* error */ + switch ($this->errorState) { + case 0: + $msg = $this->getErrorMessage($symbol, $state); + $this->emitError(new Error($msg, $this->getAttributesForToken($this->tokenPos))); + // Break missing intentionally + // no break + case 1: + case 2: + $this->errorState = 3; + + // Pop until error-expecting state uncovered + while (!( + (($idx = $this->actionBase[$state] + $this->errorSymbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol) + || ($state < $this->YY2TBLSTATE + && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $this->errorSymbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol) + ) || ($action = $this->action[$idx]) === $this->defaultAction) { // Not totally sure about this + if ($stackPos <= 0) { + // Could not recover from error + return null; + } + $state = $stateStack[--$stackPos]; + //$this->tracePop($state); + } + + //$this->traceShift($this->errorSymbol); + ++$stackPos; + $stateStack[$stackPos] = $state = $action; + + // We treat the error symbol as being empty, so we reset the end attributes + // to the end attributes of the last non-error symbol + $this->tokenStartStack[$stackPos] = $this->tokenPos; + $this->tokenEndStack[$stackPos] = $this->tokenEndStack[$stackPos - 1]; + break; + + case 3: + if ($symbol === 0) { + // Reached EOF without recovering from error + return null; + } + + //$this->traceDiscard($symbol); + $symbol = self::SYMBOL_NONE; + break 2; + } + } + + if ($state < $this->numNonLeafStates) { + break; + } + + /* >= numNonLeafStates means shift-and-reduce */ + $rule = $state - $this->numNonLeafStates; + } + } + } + + protected function emitError(Error $error): void { + $this->errorHandler->handleError($error); + } + + /** + * Format error message including expected tokens. + * + * @param int $symbol Unexpected symbol + * @param int $state State at time of error + * + * @return string Formatted error message + */ + protected function getErrorMessage(int $symbol, int $state): string { + $expectedString = ''; + if ($expected = $this->getExpectedTokens($state)) { + $expectedString = ', expecting ' . implode(' or ', $expected); + } + + return 'Syntax error, unexpected ' . $this->symbolToName[$symbol] . $expectedString; + } + + /** + * Get limited number of expected tokens in given state. + * + * @param int $state State + * + * @return string[] Expected tokens. If too many, an empty array is returned. + */ + protected function getExpectedTokens(int $state): array { + $expected = []; + + $base = $this->actionBase[$state]; + foreach ($this->symbolToName as $symbol => $name) { + $idx = $base + $symbol; + if ($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol + || $state < $this->YY2TBLSTATE + && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol + ) { + if ($this->action[$idx] !== $this->unexpectedTokenRule + && $this->action[$idx] !== $this->defaultAction + && $symbol !== $this->errorSymbol + ) { + if (count($expected) === 4) { + /* Too many expected tokens */ + return []; + } + + $expected[] = $name; + } + } + } + + return $expected; + } + + /** + * Get attributes for a node with the given start and end token positions. + * + * @param int $tokenStartPos Token position the node starts at + * @param int $tokenEndPos Token position the node ends at + * @return array Attributes + */ + protected function getAttributes(int $tokenStartPos, int $tokenEndPos): array { + $startToken = $this->tokens[$tokenStartPos]; + $afterEndToken = $this->tokens[$tokenEndPos + 1]; + return [ + 'startLine' => $startToken->line, + 'startTokenPos' => $tokenStartPos, + 'startFilePos' => $startToken->pos, + 'endLine' => $afterEndToken->line, + 'endTokenPos' => $tokenEndPos, + 'endFilePos' => $afterEndToken->pos - 1, + ]; + } + + /** + * Get attributes for a single token at the given token position. + * + * @return array Attributes + */ + protected function getAttributesForToken(int $tokenPos): array { + if ($tokenPos < \count($this->tokens) - 1) { + return $this->getAttributes($tokenPos, $tokenPos); + } + + // Get attributes for the sentinel token. + $token = $this->tokens[$tokenPos]; + return [ + 'startLine' => $token->line, + 'startTokenPos' => $tokenPos, + 'startFilePos' => $token->pos, + 'endLine' => $token->line, + 'endTokenPos' => $tokenPos, + 'endFilePos' => $token->pos, + ]; + } + + /* + * Tracing functions used for debugging the parser. + */ + + /* + protected function traceNewState($state, $symbol): void { + echo '% State ' . $state + . ', Lookahead ' . ($symbol == self::SYMBOL_NONE ? '--none--' : $this->symbolToName[$symbol]) . "\n"; + } + + protected function traceRead($symbol): void { + echo '% Reading ' . $this->symbolToName[$symbol] . "\n"; + } + + protected function traceShift($symbol): void { + echo '% Shift ' . $this->symbolToName[$symbol] . "\n"; + } + + protected function traceAccept(): void { + echo "% Accepted.\n"; + } + + protected function traceReduce($n): void { + echo '% Reduce by (' . $n . ') ' . $this->productions[$n] . "\n"; + } + + protected function tracePop($state): void { + echo '% Recovering, uncovered state ' . $state . "\n"; + } + + protected function traceDiscard($symbol): void { + echo '% Discard ' . $this->symbolToName[$symbol] . "\n"; + } + */ + + /* + * Helper functions invoked by semantic actions + */ + + /** + * Moves statements of semicolon-style namespaces into $ns->stmts and checks various error conditions. + * + * @param Node\Stmt[] $stmts + * @return Node\Stmt[] + */ + protected function handleNamespaces(array $stmts): array { + $hasErrored = false; + $style = $this->getNamespacingStyle($stmts); + if (null === $style) { + // not namespaced, nothing to do + return $stmts; + } + if ('brace' === $style) { + // For braced namespaces we only have to check that there are no invalid statements between the namespaces + $afterFirstNamespace = false; + foreach ($stmts as $stmt) { + if ($stmt instanceof Node\Stmt\Namespace_) { + $afterFirstNamespace = true; + } elseif (!$stmt instanceof Node\Stmt\HaltCompiler + && !$stmt instanceof Node\Stmt\Nop + && $afterFirstNamespace && !$hasErrored) { + $this->emitError(new Error( + 'No code may exist outside of namespace {}', $stmt->getAttributes())); + $hasErrored = true; // Avoid one error for every statement + } + } + return $stmts; + } else { + // For semicolon namespaces we have to move the statements after a namespace declaration into ->stmts + $resultStmts = []; + $targetStmts = &$resultStmts; + $lastNs = null; + foreach ($stmts as $stmt) { + if ($stmt instanceof Node\Stmt\Namespace_) { + if ($lastNs !== null) { + $this->fixupNamespaceAttributes($lastNs); + } + if ($stmt->stmts === null) { + $stmt->stmts = []; + $targetStmts = &$stmt->stmts; + $resultStmts[] = $stmt; + } else { + // This handles the invalid case of mixed style namespaces + $resultStmts[] = $stmt; + $targetStmts = &$resultStmts; + } + $lastNs = $stmt; + } elseif ($stmt instanceof Node\Stmt\HaltCompiler) { + // __halt_compiler() is not moved into the namespace + $resultStmts[] = $stmt; + } else { + $targetStmts[] = $stmt; + } + } + if ($lastNs !== null) { + $this->fixupNamespaceAttributes($lastNs); + } + return $resultStmts; + } + } + + private function fixupNamespaceAttributes(Node\Stmt\Namespace_ $stmt): void { + // We moved the statements into the namespace node, as such the end of the namespace node + // needs to be extended to the end of the statements. + if (empty($stmt->stmts)) { + return; + } + + // We only move the builtin end attributes here. This is the best we can do with the + // knowledge we have. + $endAttributes = ['endLine', 'endFilePos', 'endTokenPos']; + $lastStmt = $stmt->stmts[count($stmt->stmts) - 1]; + foreach ($endAttributes as $endAttribute) { + if ($lastStmt->hasAttribute($endAttribute)) { + $stmt->setAttribute($endAttribute, $lastStmt->getAttribute($endAttribute)); + } + } + } + + /** @return array */ + private function getNamespaceErrorAttributes(Namespace_ $node): array { + $attrs = $node->getAttributes(); + // Adjust end attributes to only cover the "namespace" keyword, not the whole namespace. + if (isset($attrs['startLine'])) { + $attrs['endLine'] = $attrs['startLine']; + } + if (isset($attrs['startTokenPos'])) { + $attrs['endTokenPos'] = $attrs['startTokenPos']; + } + if (isset($attrs['startFilePos'])) { + $attrs['endFilePos'] = $attrs['startFilePos'] + \strlen('namespace') - 1; + } + return $attrs; + } + + /** + * Determine namespacing style (semicolon or brace) + * + * @param Node[] $stmts Top-level statements. + * + * @return null|string One of "semicolon", "brace" or null (no namespaces) + */ + private function getNamespacingStyle(array $stmts): ?string { + $style = null; + $hasNotAllowedStmts = false; + foreach ($stmts as $i => $stmt) { + if ($stmt instanceof Node\Stmt\Namespace_) { + $currentStyle = null === $stmt->stmts ? 'semicolon' : 'brace'; + if (null === $style) { + $style = $currentStyle; + if ($hasNotAllowedStmts) { + $this->emitError(new Error( + 'Namespace declaration statement has to be the very first statement in the script', + $this->getNamespaceErrorAttributes($stmt) + )); + } + } elseif ($style !== $currentStyle) { + $this->emitError(new Error( + 'Cannot mix bracketed namespace declarations with unbracketed namespace declarations', + $this->getNamespaceErrorAttributes($stmt) + )); + // Treat like semicolon style for namespace normalization + return 'semicolon'; + } + continue; + } + + /* declare(), __halt_compiler() and nops can be used before a namespace declaration */ + if ($stmt instanceof Node\Stmt\Declare_ + || $stmt instanceof Node\Stmt\HaltCompiler + || $stmt instanceof Node\Stmt\Nop) { + continue; + } + + /* There may be a hashbang line at the very start of the file */ + if ($i === 0 && $stmt instanceof Node\Stmt\InlineHTML && preg_match('/\A#!.*\r?\n\z/', $stmt->value)) { + continue; + } + + /* Everything else if forbidden before namespace declarations */ + $hasNotAllowedStmts = true; + } + return $style; + } + + /** @return Name|Identifier */ + protected function handleBuiltinTypes(Name $name) { + if (!$name->isUnqualified()) { + return $name; + } + + $lowerName = $name->toLowerString(); + if (!$this->phpVersion->supportsBuiltinType($lowerName)) { + return $name; + } + + return new Node\Identifier($lowerName, $name->getAttributes()); + } + + /** + * Get combined start and end attributes at a stack location + * + * @param int $stackPos Stack location + * + * @return array Combined start and end attributes + */ + protected function getAttributesAt(int $stackPos): array { + return $this->getAttributes($this->tokenStartStack[$stackPos], $this->tokenEndStack[$stackPos]); + } + + protected function getFloatCastKind(string $cast): int { + $cast = strtolower($cast); + if (strpos($cast, 'float') !== false) { + return Double::KIND_FLOAT; + } + + if (strpos($cast, 'real') !== false) { + return Double::KIND_REAL; + } + + return Double::KIND_DOUBLE; + } + + protected function getIntCastKind(string $cast): int { + $cast = strtolower($cast); + if (strpos($cast, 'integer') !== false) { + return Expr\Cast\Int_::KIND_INTEGER; + } + + return Expr\Cast\Int_::KIND_INT; + } + + protected function getBoolCastKind(string $cast): int { + $cast = strtolower($cast); + if (strpos($cast, 'boolean') !== false) { + return Expr\Cast\Bool_::KIND_BOOLEAN; + } + + return Expr\Cast\Bool_::KIND_BOOL; + } + + protected function getStringCastKind(string $cast): int { + $cast = strtolower($cast); + if (strpos($cast, 'binary') !== false) { + return Expr\Cast\String_::KIND_BINARY; + } + + return Expr\Cast\String_::KIND_STRING; + } + + /** @param array $attributes */ + protected function parseLNumber(string $str, array $attributes, bool $allowInvalidOctal = false): Int_ { + try { + return Int_::fromString($str, $attributes, $allowInvalidOctal); + } catch (Error $error) { + $this->emitError($error); + // Use dummy value + return new Int_(0, $attributes); + } + } + + /** + * Parse a T_NUM_STRING token into either an integer or string node. + * + * @param string $str Number string + * @param array $attributes Attributes + * + * @return Int_|String_ Integer or string node. + */ + protected function parseNumString(string $str, array $attributes) { + if (!preg_match('/^(?:0|-?[1-9][0-9]*)$/', $str)) { + return new String_($str, $attributes); + } + + $num = +$str; + if (!is_int($num)) { + return new String_($str, $attributes); + } + + return new Int_($num, $attributes); + } + + /** @param array $attributes */ + protected function stripIndentation( + string $string, int $indentLen, string $indentChar, + bool $newlineAtStart, bool $newlineAtEnd, array $attributes + ): string { + if ($indentLen === 0) { + return $string; + } + + $start = $newlineAtStart ? '(?:(?<=\n)|\A)' : '(?<=\n)'; + $end = $newlineAtEnd ? '(?:(?=[\r\n])|\z)' : '(?=[\r\n])'; + $regex = '/' . $start . '([ \t]*)(' . $end . ')?/'; + return preg_replace_callback( + $regex, + function ($matches) use ($indentLen, $indentChar, $attributes) { + $prefix = substr($matches[1], 0, $indentLen); + if (false !== strpos($prefix, $indentChar === " " ? "\t" : " ")) { + $this->emitError(new Error( + 'Invalid indentation - tabs and spaces cannot be mixed', $attributes + )); + } elseif (strlen($prefix) < $indentLen && !isset($matches[2])) { + $this->emitError(new Error( + 'Invalid body indentation level ' . + '(expecting an indentation level of at least ' . $indentLen . ')', + $attributes + )); + } + return substr($matches[0], strlen($prefix)); + }, + $string + ); + } + + /** + * @param string|(Expr|InterpolatedStringPart)[] $contents + * @param array $attributes + * @param array $endTokenAttributes + */ + protected function parseDocString( + string $startToken, $contents, string $endToken, + array $attributes, array $endTokenAttributes, bool $parseUnicodeEscape + ): Expr { + $kind = strpos($startToken, "'") === false + ? String_::KIND_HEREDOC : String_::KIND_NOWDOC; + + $regex = '/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/'; + $result = preg_match($regex, $startToken, $matches); + assert($result === 1); + $label = $matches[1]; + + $result = preg_match('/\A[ \t]*/', $endToken, $matches); + assert($result === 1); + $indentation = $matches[0]; + + $attributes['kind'] = $kind; + $attributes['docLabel'] = $label; + $attributes['docIndentation'] = $indentation; + + $indentHasSpaces = false !== strpos($indentation, " "); + $indentHasTabs = false !== strpos($indentation, "\t"); + if ($indentHasSpaces && $indentHasTabs) { + $this->emitError(new Error( + 'Invalid indentation - tabs and spaces cannot be mixed', + $endTokenAttributes + )); + + // Proceed processing as if this doc string is not indented + $indentation = ''; + } + + $indentLen = \strlen($indentation); + $indentChar = $indentHasSpaces ? " " : "\t"; + + if (\is_string($contents)) { + if ($contents === '') { + $attributes['rawValue'] = $contents; + return new String_('', $attributes); + } + + $contents = $this->stripIndentation( + $contents, $indentLen, $indentChar, true, true, $attributes + ); + $contents = preg_replace('~(\r\n|\n|\r)\z~', '', $contents); + $attributes['rawValue'] = $contents; + + if ($kind === String_::KIND_HEREDOC) { + $contents = String_::parseEscapeSequences($contents, null, $parseUnicodeEscape); + } + + return new String_($contents, $attributes); + } else { + assert(count($contents) > 0); + if (!$contents[0] instanceof Node\InterpolatedStringPart) { + // If there is no leading encapsed string part, pretend there is an empty one + $this->stripIndentation( + '', $indentLen, $indentChar, true, false, $contents[0]->getAttributes() + ); + } + + $newContents = []; + foreach ($contents as $i => $part) { + if ($part instanceof Node\InterpolatedStringPart) { + $isLast = $i === \count($contents) - 1; + $part->value = $this->stripIndentation( + $part->value, $indentLen, $indentChar, + $i === 0, $isLast, $part->getAttributes() + ); + if ($isLast) { + $part->value = preg_replace('~(\r\n|\n|\r)\z~', '', $part->value); + } + $part->setAttribute('rawValue', $part->value); + $part->value = String_::parseEscapeSequences($part->value, null, $parseUnicodeEscape); + if ('' === $part->value) { + continue; + } + } + $newContents[] = $part; + } + return new InterpolatedString($newContents, $attributes); + } + } + + protected function createCommentFromToken(Token $token, int $tokenPos): Comment { + assert($token->id === \T_COMMENT || $token->id == \T_DOC_COMMENT); + return \T_DOC_COMMENT === $token->id + ? new Comment\Doc($token->text, $token->line, $token->pos, $tokenPos, + $token->getEndLine(), $token->getEndPos() - 1, $tokenPos) + : new Comment($token->text, $token->line, $token->pos, $tokenPos, + $token->getEndLine(), $token->getEndPos() - 1, $tokenPos); + } + + /** + * Get last comment before the given token position, if any + */ + protected function getCommentBeforeToken(int $tokenPos): ?Comment { + while (--$tokenPos >= 0) { + $token = $this->tokens[$tokenPos]; + if (!isset($this->dropTokens[$token->id])) { + break; + } + + if ($token->id === \T_COMMENT || $token->id === \T_DOC_COMMENT) { + return $this->createCommentFromToken($token, $tokenPos); + } + } + return null; + } + + /** + * Create a zero-length nop to capture preceding comments, if any. + */ + protected function maybeCreateZeroLengthNop(int $tokenPos): ?Nop { + $comment = $this->getCommentBeforeToken($tokenPos); + if ($comment === null) { + return null; + } + + $commentEndLine = $comment->getEndLine(); + $commentEndFilePos = $comment->getEndFilePos(); + $commentEndTokenPos = $comment->getEndTokenPos(); + $attributes = [ + 'startLine' => $commentEndLine, + 'endLine' => $commentEndLine, + 'startFilePos' => $commentEndFilePos + 1, + 'endFilePos' => $commentEndFilePos, + 'startTokenPos' => $commentEndTokenPos + 1, + 'endTokenPos' => $commentEndTokenPos, + ]; + return new Nop($attributes); + } + + protected function maybeCreateNop(int $tokenStartPos, int $tokenEndPos): ?Nop { + if ($this->getCommentBeforeToken($tokenStartPos) === null) { + return null; + } + return new Nop($this->getAttributes($tokenStartPos, $tokenEndPos)); + } + + protected function handleHaltCompiler(): string { + // Prevent the lexer from returning any further tokens. + $nextToken = $this->tokens[$this->tokenPos + 1]; + $this->tokenPos = \count($this->tokens) - 2; + + // Return text after __halt_compiler. + return $nextToken->id === \T_INLINE_HTML ? $nextToken->text : ''; + } + + protected function inlineHtmlHasLeadingNewline(int $stackPos): bool { + $tokenPos = $this->tokenStartStack[$stackPos]; + $token = $this->tokens[$tokenPos]; + assert($token->id == \T_INLINE_HTML); + if ($tokenPos > 0) { + $prevToken = $this->tokens[$tokenPos - 1]; + assert($prevToken->id == \T_CLOSE_TAG); + return false !== strpos($prevToken->text, "\n") + || false !== strpos($prevToken->text, "\r"); + } + return true; + } + + /** + * @return array + */ + protected function createEmptyElemAttributes(int $tokenPos): array { + return $this->getAttributesForToken($tokenPos); + } + + protected function fixupArrayDestructuring(Array_ $node): Expr\List_ { + $this->createdArrays->offsetUnset($node); + return new Expr\List_(array_map(function (Node\ArrayItem $item) { + if ($item->value instanceof Expr\Error) { + // We used Error as a placeholder for empty elements, which are legal for destructuring. + return null; + } + if ($item->value instanceof Array_) { + return new Node\ArrayItem( + $this->fixupArrayDestructuring($item->value), + $item->key, $item->byRef, $item->getAttributes()); + } + return $item; + }, $node->items), ['kind' => Expr\List_::KIND_ARRAY] + $node->getAttributes()); + } + + protected function postprocessList(Expr\List_ $node): void { + foreach ($node->items as $i => $item) { + if ($item->value instanceof Expr\Error) { + // We used Error as a placeholder for empty elements, which are legal for destructuring. + $node->items[$i] = null; + } + } + } + + /** @param ElseIf_|Else_ $node */ + protected function fixupAlternativeElse($node): void { + // Make sure a trailing nop statement carrying comments is part of the node. + $numStmts = \count($node->stmts); + if ($numStmts !== 0 && $node->stmts[$numStmts - 1] instanceof Nop) { + $nopAttrs = $node->stmts[$numStmts - 1]->getAttributes(); + if (isset($nopAttrs['endLine'])) { + $node->setAttribute('endLine', $nopAttrs['endLine']); + } + if (isset($nopAttrs['endFilePos'])) { + $node->setAttribute('endFilePos', $nopAttrs['endFilePos']); + } + if (isset($nopAttrs['endTokenPos'])) { + $node->setAttribute('endTokenPos', $nopAttrs['endTokenPos']); + } + } + } + + protected function checkClassModifier(int $a, int $b, int $modifierPos): void { + try { + Modifiers::verifyClassModifier($a, $b); + } catch (Error $error) { + $error->setAttributes($this->getAttributesAt($modifierPos)); + $this->emitError($error); + } + } + + protected function checkModifier(int $a, int $b, int $modifierPos): void { + // Jumping through some hoops here because verifyModifier() is also used elsewhere + try { + Modifiers::verifyModifier($a, $b); + } catch (Error $error) { + $error->setAttributes($this->getAttributesAt($modifierPos)); + $this->emitError($error); + } + } + + protected function checkParam(Param $node): void { + if ($node->variadic && null !== $node->default) { + $this->emitError(new Error( + 'Variadic parameter cannot have a default value', + $node->default->getAttributes() + )); + } + + if ($node->type instanceof Identifier && $node->type->name === 'void') { + $this->emitError(new Error( + 'void cannot be used as a parameter type', + $node->type->getAttributes() + )); + } + } + + protected function checkTryCatch(TryCatch $node): void { + if (empty($node->catches) && null === $node->finally) { + $this->emitError(new Error( + 'Cannot use try without catch or finally', $node->getAttributes() + )); + } + } + + protected function checkNamespace(Namespace_ $node): void { + if (null !== $node->stmts) { + foreach ($node->stmts as $stmt) { + if ($stmt instanceof Namespace_) { + $this->emitError(new Error( + 'Namespace declarations cannot be nested', $stmt->getAttributes() + )); + } + } + } + } + + private function checkClassName(?Identifier $name, int $namePos): void { + if (null !== $name && $name->isSpecialClassName()) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as class name as it is reserved', $name), + $this->getAttributesAt($namePos) + )); + } + } + + /** @param Name[] $interfaces */ + private function checkImplementedInterfaces(array $interfaces): void { + foreach ($interfaces as $interface) { + if ($interface->isSpecialClassName()) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), + $interface->getAttributes() + )); + } + } + } + + protected function checkClass(Class_ $node, int $namePos): void { + $this->checkClassName($node->name, $namePos); + + if ($node->extends && $node->extends->isSpecialClassName()) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as class name as it is reserved', $node->extends), + $node->extends->getAttributes() + )); + } + + $this->checkImplementedInterfaces($node->implements); + } + + protected function checkInterface(Interface_ $node, int $namePos): void { + $this->checkClassName($node->name, $namePos); + $this->checkImplementedInterfaces($node->extends); + } + + protected function checkEnum(Enum_ $node, int $namePos): void { + $this->checkClassName($node->name, $namePos); + $this->checkImplementedInterfaces($node->implements); + } + + protected function checkClassMethod(ClassMethod $node, int $modifierPos): void { + if ($node->flags & Modifiers::STATIC) { + switch ($node->name->toLowerString()) { + case '__construct': + $this->emitError(new Error( + sprintf('Constructor %s() cannot be static', $node->name), + $this->getAttributesAt($modifierPos))); + break; + case '__destruct': + $this->emitError(new Error( + sprintf('Destructor %s() cannot be static', $node->name), + $this->getAttributesAt($modifierPos))); + break; + case '__clone': + $this->emitError(new Error( + sprintf('Clone method %s() cannot be static', $node->name), + $this->getAttributesAt($modifierPos))); + break; + } + } + + if ($node->flags & Modifiers::READONLY) { + $this->emitError(new Error( + sprintf('Method %s() cannot be readonly', $node->name), + $this->getAttributesAt($modifierPos))); + } + } + + protected function checkClassConst(ClassConst $node, int $modifierPos): void { + foreach ([Modifiers::STATIC, Modifiers::ABSTRACT, Modifiers::READONLY] as $modifier) { + if ($node->flags & $modifier) { + $this->emitError(new Error( + "Cannot use '" . Modifiers::toString($modifier) . "' as constant modifier", + $this->getAttributesAt($modifierPos))); + } + } + } + + protected function checkUseUse(UseItem $node, int $namePos): void { + if ($node->alias && $node->alias->isSpecialClassName()) { + $this->emitError(new Error( + sprintf( + 'Cannot use %s as %s because \'%2$s\' is a special class name', + $node->name, $node->alias + ), + $this->getAttributesAt($namePos) + )); + } + } + + protected function checkPropertyHooksForMultiProperty(Property $property, int $hookPos): void { + if (count($property->props) > 1) { + $this->emitError(new Error( + 'Cannot use hooks when declaring multiple properties', $this->getAttributesAt($hookPos))); + } + } + + /** @param PropertyHook[] $hooks */ + protected function checkEmptyPropertyHookList(array $hooks, int $hookPos): void { + if (empty($hooks)) { + $this->emitError(new Error( + 'Property hook list cannot be empty', $this->getAttributesAt($hookPos))); + } + } + + protected function checkPropertyHook(PropertyHook $hook, ?int $paramListPos): void { + $name = $hook->name->toLowerString(); + if ($name !== 'get' && $name !== 'set') { + $this->emitError(new Error( + 'Unknown hook "' . $hook->name . '", expected "get" or "set"', + $hook->name->getAttributes())); + } + if ($name === 'get' && $paramListPos !== null) { + $this->emitError(new Error( + 'get hook must not have a parameter list', $this->getAttributesAt($paramListPos))); + } + } + + protected function checkPropertyHookModifiers(int $a, int $b, int $modifierPos): void { + try { + Modifiers::verifyModifier($a, $b); + } catch (Error $error) { + $error->setAttributes($this->getAttributesAt($modifierPos)); + $this->emitError($error); + } + + if ($b != Modifiers::FINAL) { + $this->emitError(new Error( + 'Cannot use the ' . Modifiers::toString($b) . ' modifier on a property hook', + $this->getAttributesAt($modifierPos))); + } + } + + protected function checkConstantAttributes(Const_ $node): void { + if ($node->attrGroups !== [] && count($node->consts) > 1) { + $this->emitError(new Error( + 'Cannot use attributes on multiple constants at once', $node->getAttributes())); + } + } + + protected function checkPipeOperatorParentheses(Expr $node): void { + if ($node instanceof Expr\ArrowFunction && !$this->parenthesizedArrowFunctions->offsetExists($node)) { + $this->emitError(new Error( + 'Arrow functions on the right hand side of |> must be parenthesized', $node->getAttributes())); + } + } + + /** + * @param Property|Param $node + */ + protected function addPropertyNameToHooks(Node $node): void { + if ($node instanceof Property) { + $name = $node->props[0]->name->toString(); + } else { + $name = $node->var->name; + } + foreach ($node->hooks as $hook) { + $hook->setAttribute('propertyName', $name); + } + } + + /** @param array $args */ + private function isSimpleExit(array $args): bool { + if (\count($args) === 0) { + return true; + } + if (\count($args) === 1) { + $arg = $args[0]; + return $arg instanceof Arg && $arg->name === null && + $arg->byRef === false && $arg->unpack === false; + } + return false; + } + + /** + * @param array $args + * @param array $attrs + */ + protected function createExitExpr(string $name, int $namePos, array $args, array $attrs): Expr { + if ($this->isSimpleExit($args)) { + // Create Exit node for backwards compatibility. + $attrs['kind'] = strtolower($name) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + return new Expr\Exit_(\count($args) === 1 ? $args[0]->value : null, $attrs); + } + return new Expr\FuncCall(new Name($name, $this->getAttributesAt($namePos)), $args, $attrs); + } + + /** + * Creates the token map. + * + * The token map maps the PHP internal token identifiers + * to the identifiers used by the Parser. Additionally it + * maps T_OPEN_TAG_WITH_ECHO to T_ECHO and T_CLOSE_TAG to ';'. + * + * @return array The token map + */ + protected function createTokenMap(): array { + $tokenMap = []; + + // Single-char tokens use an identity mapping. + for ($i = 0; $i < 256; ++$i) { + $tokenMap[$i] = $i; + } + + foreach ($this->symbolToName as $name) { + if ($name[0] === 'T') { + $tokenMap[\constant($name)] = constant(static::class . '::' . $name); + } + } + + // T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO + $tokenMap[\T_OPEN_TAG_WITH_ECHO] = static::T_ECHO; + // T_CLOSE_TAG is equivalent to ';' + $tokenMap[\T_CLOSE_TAG] = ord(';'); + + // We have created a map from PHP token IDs to external symbol IDs. + // Now map them to the internal symbol ID. + $fullTokenMap = []; + foreach ($tokenMap as $phpToken => $extSymbol) { + $intSymbol = $this->tokenToSymbol[$extSymbol]; + if ($intSymbol === $this->invalidSymbol) { + continue; + } + $fullTokenMap[$phpToken] = $intSymbol; + } + + return $fullTokenMap; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php new file mode 100644 index 00000000..3a7586ea --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php @@ -0,0 +1,42 @@ +isHostVersion()) { + $lexer = new Lexer(); + } else { + $lexer = new Lexer\Emulative($version); + } + if ($version->id >= 80000) { + return new Php8($lexer, $version); + } + return new Php7($lexer, $version); + } + + /** + * Create a parser targeting the newest version supported by this library. Code for older + * versions will be accepted if there have been no relevant backwards-compatibility breaks in + * PHP. + */ + public function createForNewestSupportedVersion(): Parser { + return $this->createForVersion(PhpVersion::getNewestSupported()); + } + + /** + * Create a parser targeting the host PHP version, that is the PHP version we're currently + * running on. This parser will not use any token emulation. + */ + public function createForHostVersion(): Parser { + return $this->createForVersion(PhpVersion::getHostVersion()); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/PhpVersion.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/PhpVersion.php new file mode 100644 index 00000000..9517d720 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/PhpVersion.php @@ -0,0 +1,175 @@ + 50100, + 'callable' => 50400, + 'bool' => 70000, + 'int' => 70000, + 'float' => 70000, + 'string' => 70000, + 'iterable' => 70100, + 'void' => 70100, + 'object' => 70200, + 'null' => 80000, + 'false' => 80000, + 'mixed' => 80000, + 'never' => 80100, + 'true' => 80200, + ]; + + private function __construct(int $id) { + $this->id = $id; + } + + /** + * Create a PhpVersion object from major and minor version components. + */ + public static function fromComponents(int $major, int $minor): self { + return new self($major * 10000 + $minor * 100); + } + + /** + * Get the newest PHP version supported by this library. Support for this version may be partial, + * if it is still under development. + */ + public static function getNewestSupported(): self { + return self::fromComponents(8, 5); + } + + /** + * Get the host PHP version, that is the PHP version we're currently running on. + */ + public static function getHostVersion(): self { + return self::fromComponents(\PHP_MAJOR_VERSION, \PHP_MINOR_VERSION); + } + + /** + * Parse the version from a string like "8.1". + */ + public static function fromString(string $version): self { + if (!preg_match('/^(\d+)\.(\d+)/', $version, $matches)) { + throw new \LogicException("Invalid PHP version \"$version\""); + } + return self::fromComponents((int) $matches[1], (int) $matches[2]); + } + + /** + * Check whether two versions are the same. + */ + public function equals(PhpVersion $other): bool { + return $this->id === $other->id; + } + + /** + * Check whether this version is greater than or equal to the argument. + */ + public function newerOrEqual(PhpVersion $other): bool { + return $this->id >= $other->id; + } + + /** + * Check whether this version is older than the argument. + */ + public function older(PhpVersion $other): bool { + return $this->id < $other->id; + } + + /** + * Check whether this is the host PHP version. + */ + public function isHostVersion(): bool { + return $this->equals(self::getHostVersion()); + } + + /** + * Check whether this PHP version supports the given builtin type. Type name must be lowercase. + */ + public function supportsBuiltinType(string $type): bool { + $minVersion = self::BUILTIN_TYPE_VERSIONS[$type] ?? null; + return $minVersion !== null && $this->id >= $minVersion; + } + + /** + * Whether this version supports [] array literals. + */ + public function supportsShortArraySyntax(): bool { + return $this->id >= 50400; + } + + /** + * Whether this version supports [] for destructuring. + */ + public function supportsShortArrayDestructuring(): bool { + return $this->id >= 70100; + } + + /** + * Whether this version supports flexible heredoc/nowdoc. + */ + public function supportsFlexibleHeredoc(): bool { + return $this->id >= 70300; + } + + /** + * Whether this version supports trailing commas in parameter lists. + */ + public function supportsTrailingCommaInParamList(): bool { + return $this->id >= 80000; + } + + /** + * Whether this version allows "$var =& new Obj". + */ + public function allowsAssignNewByReference(): bool { + return $this->id < 70000; + } + + /** + * Whether this version allows invalid octals like "08". + */ + public function allowsInvalidOctals(): bool { + return $this->id < 70000; + } + + /** + * Whether this version allows DEL (\x7f) to occur in identifiers. + */ + public function allowsDelInIdentifiers(): bool { + return $this->id < 70100; + } + + /** + * Whether this version supports yield in expression context without parentheses. + */ + public function supportsYieldWithoutParentheses(): bool { + return $this->id >= 70000; + } + + /** + * Whether this version supports unicode escape sequences in strings. + */ + public function supportsUnicodeEscapes(): bool { + return $this->id >= 70000; + } + + /* + * Whether this version supports attributes. + */ + public function supportsAttributes(): bool { + return $this->id >= 80000; + } + + public function supportsNewDereferenceWithoutParentheses(): bool { + return $this->id >= 80400; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter.php new file mode 100644 index 00000000..892c686e --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter.php @@ -0,0 +1,51 @@ +pAttrGroups($node->attrGroups, $this->phpVersion->supportsAttributes()) + . $this->pModifiers($node->flags) + . ($node->type ? $this->p($node->type) . ' ' : '') + . ($node->byRef ? '&' : '') + . ($node->variadic ? '...' : '') + . $this->p($node->var) + . ($node->default ? ' = ' . $this->p($node->default) : '') + . ($node->hooks ? ' {' . $this->pStmts($node->hooks) . $this->nl . '}' : ''); + } + + protected function pArg(Node\Arg $node): string { + return ($node->name ? $node->name->toString() . ': ' : '') + . ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') + . $this->p($node->value); + } + + protected function pVariadicPlaceholder(Node\VariadicPlaceholder $node): string { + return '...'; + } + + protected function pConst(Node\Const_ $node): string { + return $node->name . ' = ' . $this->p($node->value); + } + + protected function pNullableType(Node\NullableType $node): string { + return '?' . $this->p($node->type); + } + + protected function pUnionType(Node\UnionType $node): string { + $types = []; + foreach ($node->types as $typeNode) { + if ($typeNode instanceof Node\IntersectionType) { + $types[] = '('. $this->p($typeNode) . ')'; + continue; + } + $types[] = $this->p($typeNode); + } + return implode('|', $types); + } + + protected function pIntersectionType(Node\IntersectionType $node): string { + return $this->pImplode($node->types, '&'); + } + + protected function pIdentifier(Node\Identifier $node): string { + return $node->name; + } + + protected function pVarLikeIdentifier(Node\VarLikeIdentifier $node): string { + return '$' . $node->name; + } + + protected function pAttribute(Node\Attribute $node): string { + return $this->p($node->name) + . ($node->args ? '(' . $this->pCommaSeparated($node->args) . ')' : ''); + } + + protected function pAttributeGroup(Node\AttributeGroup $node): string { + return '#[' . $this->pCommaSeparated($node->attrs) . ']'; + } + + // Names + + protected function pName(Name $node): string { + return $node->name; + } + + protected function pName_FullyQualified(Name\FullyQualified $node): string { + return '\\' . $node->name; + } + + protected function pName_Relative(Name\Relative $node): string { + return 'namespace\\' . $node->name; + } + + // Magic Constants + + protected function pScalar_MagicConst_Class(MagicConst\Class_ $node): string { + return '__CLASS__'; + } + + protected function pScalar_MagicConst_Dir(MagicConst\Dir $node): string { + return '__DIR__'; + } + + protected function pScalar_MagicConst_File(MagicConst\File $node): string { + return '__FILE__'; + } + + protected function pScalar_MagicConst_Function(MagicConst\Function_ $node): string { + return '__FUNCTION__'; + } + + protected function pScalar_MagicConst_Line(MagicConst\Line $node): string { + return '__LINE__'; + } + + protected function pScalar_MagicConst_Method(MagicConst\Method $node): string { + return '__METHOD__'; + } + + protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node): string { + return '__NAMESPACE__'; + } + + protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node): string { + return '__TRAIT__'; + } + + protected function pScalar_MagicConst_Property(MagicConst\Property $node): string { + return '__PROPERTY__'; + } + + // Scalars + + private function indentString(string $str): string { + return str_replace("\n", $this->nl, $str); + } + + protected function pScalar_String(Scalar\String_ $node): string { + $kind = $node->getAttribute('kind', Scalar\String_::KIND_SINGLE_QUOTED); + switch ($kind) { + case Scalar\String_::KIND_NOWDOC: + $label = $node->getAttribute('docLabel'); + if ($label && !$this->containsEndLabel($node->value, $label)) { + $shouldIdent = $this->phpVersion->supportsFlexibleHeredoc(); + $nl = $shouldIdent ? $this->nl : $this->newline; + if ($node->value === '') { + return "<<<'$label'$nl$label{$this->docStringEndToken}"; + } + + // Make sure trailing \r is not combined with following \n into CRLF. + if ($node->value[strlen($node->value) - 1] !== "\r") { + $value = $shouldIdent ? $this->indentString($node->value) : $node->value; + return "<<<'$label'$nl$value$nl$label{$this->docStringEndToken}"; + } + } + /* break missing intentionally */ + // no break + case Scalar\String_::KIND_SINGLE_QUOTED: + return $this->pSingleQuotedString($node->value); + case Scalar\String_::KIND_HEREDOC: + $label = $node->getAttribute('docLabel'); + $escaped = $this->escapeString($node->value, null); + if ($label && !$this->containsEndLabel($escaped, $label)) { + $nl = $this->phpVersion->supportsFlexibleHeredoc() ? $this->nl : $this->newline; + if ($escaped === '') { + return "<<<$label$nl$label{$this->docStringEndToken}"; + } + + return "<<<$label$nl$escaped$nl$label{$this->docStringEndToken}"; + } + /* break missing intentionally */ + // no break + case Scalar\String_::KIND_DOUBLE_QUOTED: + return '"' . $this->escapeString($node->value, '"') . '"'; + } + throw new \Exception('Invalid string kind'); + } + + protected function pScalar_InterpolatedString(Scalar\InterpolatedString $node): string { + if ($node->getAttribute('kind') === Scalar\String_::KIND_HEREDOC) { + $label = $node->getAttribute('docLabel'); + if ($label && !$this->encapsedContainsEndLabel($node->parts, $label)) { + $nl = $this->phpVersion->supportsFlexibleHeredoc() ? $this->nl : $this->newline; + if (count($node->parts) === 1 + && $node->parts[0] instanceof Node\InterpolatedStringPart + && $node->parts[0]->value === '' + ) { + return "<<<$label$nl$label{$this->docStringEndToken}"; + } + + return "<<<$label$nl" . $this->pEncapsList($node->parts, null) + . "$nl$label{$this->docStringEndToken}"; + } + } + return '"' . $this->pEncapsList($node->parts, '"') . '"'; + } + + protected function pScalar_Int(Scalar\Int_ $node): string { + if ($node->getAttribute('shouldPrintRawValue') === true) { + return $node->getAttribute('rawValue'); + } + + if ($node->value === -\PHP_INT_MAX - 1) { + // PHP_INT_MIN cannot be represented as a literal, + // because the sign is not part of the literal + return '(-' . \PHP_INT_MAX . '-1)'; + } + + $kind = $node->getAttribute('kind', Scalar\Int_::KIND_DEC); + + if (Scalar\Int_::KIND_DEC === $kind) { + return (string) $node->value; + } + + if ($node->value < 0) { + $sign = '-'; + $str = (string) -$node->value; + } else { + $sign = ''; + $str = (string) $node->value; + } + switch ($kind) { + case Scalar\Int_::KIND_BIN: + return $sign . '0b' . base_convert($str, 10, 2); + case Scalar\Int_::KIND_OCT: + return $sign . '0' . base_convert($str, 10, 8); + case Scalar\Int_::KIND_HEX: + return $sign . '0x' . base_convert($str, 10, 16); + } + throw new \Exception('Invalid number kind'); + } + + protected function pScalar_Float(Scalar\Float_ $node): string { + if (!is_finite($node->value)) { + if ($node->value === \INF) { + return '1.0E+1000'; + } + if ($node->value === -\INF) { + return '-1.0E+1000'; + } else { + return '\NAN'; + } + } + + // Try to find a short full-precision representation + $stringValue = sprintf('%.16G', $node->value); + if ($node->value !== (float) $stringValue) { + $stringValue = sprintf('%.17G', $node->value); + } + + // %G is locale dependent and there exists no locale-independent alternative. We don't want + // mess with switching locales here, so let's assume that a comma is the only non-standard + // decimal separator we may encounter... + $stringValue = str_replace(',', '.', $stringValue); + + // ensure that number is really printed as float + return preg_match('/^-?[0-9]+$/', $stringValue) ? $stringValue . '.0' : $stringValue; + } + + // Assignments + + protected function pExpr_Assign(Expr\Assign $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Expr\Assign::class, $this->p($node->var) . ' = ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignRef(Expr\AssignRef $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Expr\AssignRef::class, $this->p($node->var) . ' =& ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_Plus(AssignOp\Plus $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\Plus::class, $this->p($node->var) . ' += ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_Minus(AssignOp\Minus $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\Minus::class, $this->p($node->var) . ' -= ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_Mul(AssignOp\Mul $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\Mul::class, $this->p($node->var) . ' *= ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_Div(AssignOp\Div $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\Div::class, $this->p($node->var) . ' /= ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_Concat(AssignOp\Concat $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\Concat::class, $this->p($node->var) . ' .= ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_Mod(AssignOp\Mod $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\Mod::class, $this->p($node->var) . ' %= ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\BitwiseAnd::class, $this->p($node->var) . ' &= ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\BitwiseOr::class, $this->p($node->var) . ' |= ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\BitwiseXor::class, $this->p($node->var) . ' ^= ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\ShiftLeft::class, $this->p($node->var) . ' <<= ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\ShiftRight::class, $this->p($node->var) . ' >>= ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_Pow(AssignOp\Pow $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\Pow::class, $this->p($node->var) . ' **= ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_AssignOp_Coalesce(AssignOp\Coalesce $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(AssignOp\Coalesce::class, $this->p($node->var) . ' ??= ', $node->expr, $precedence, $lhsPrecedence); + } + + // Binary expressions + + protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Plus::class, $node->left, ' + ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Minus::class, $node->left, ' - ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Mul::class, $node->left, ' * ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Div(BinaryOp\Div $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Div::class, $node->left, ' / ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Concat::class, $node->left, ' . ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Mod::class, $node->left, ' % ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\BooleanAnd::class, $node->left, ' && ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\BooleanOr::class, $node->left, ' || ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\BitwiseAnd::class, $node->left, ' & ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\BitwiseOr::class, $node->left, ' | ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\BitwiseXor::class, $node->left, ' ^ ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\ShiftLeft::class, $node->left, ' << ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\ShiftRight::class, $node->left, ' >> ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Pow::class, $node->left, ' ** ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\LogicalAnd::class, $node->left, ' and ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\LogicalOr::class, $node->left, ' or ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\LogicalXor::class, $node->left, ' xor ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Equal::class, $node->left, ' == ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\NotEqual::class, $node->left, ' != ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Identical::class, $node->left, ' === ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\NotIdentical::class, $node->left, ' !== ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Spaceship::class, $node->left, ' <=> ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Greater::class, $node->left, ' > ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\GreaterOrEqual::class, $node->left, ' >= ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Smaller::class, $node->left, ' < ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\SmallerOrEqual::class, $node->left, ' <= ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node, int $precedence, int $lhsPrecedence): string { + return $this->pInfixOp(BinaryOp\Coalesce::class, $node->left, ' ?? ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_BinaryOp_Pipe(BinaryOp\Pipe $node, int $precedence, int $lhsPrecedence): string { + if ($node->right instanceof Expr\ArrowFunction) { + // Force parentheses around arrow functions. + $lhsPrecedence = $this->precedenceMap[Expr\ArrowFunction::class][0]; + } + return $this->pInfixOp(BinaryOp\Pipe::class, $node->left, ' |> ', $node->right, $precedence, $lhsPrecedence); + } + + protected function pExpr_Instanceof(Expr\Instanceof_ $node, int $precedence, int $lhsPrecedence): string { + return $this->pPostfixOp( + Expr\Instanceof_::class, $node->expr, + ' instanceof ' . $this->pNewOperand($node->class), + $precedence, $lhsPrecedence); + } + + // Unary expressions + + protected function pExpr_BooleanNot(Expr\BooleanNot $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Expr\BooleanNot::class, '!', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_BitwiseNot(Expr\BitwiseNot $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Expr\BitwiseNot::class, '~', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_UnaryMinus(Expr\UnaryMinus $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Expr\UnaryMinus::class, '-', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_UnaryPlus(Expr\UnaryPlus $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Expr\UnaryPlus::class, '+', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_PreInc(Expr\PreInc $node): string { + return '++' . $this->p($node->var); + } + + protected function pExpr_PreDec(Expr\PreDec $node): string { + return '--' . $this->p($node->var); + } + + protected function pExpr_PostInc(Expr\PostInc $node): string { + return $this->p($node->var) . '++'; + } + + protected function pExpr_PostDec(Expr\PostDec $node): string { + return $this->p($node->var) . '--'; + } + + protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Expr\ErrorSuppress::class, '@', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_YieldFrom(Expr\YieldFrom $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Expr\YieldFrom::class, 'yield from ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_Print(Expr\Print_ $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Expr\Print_::class, 'print ', $node->expr, $precedence, $lhsPrecedence); + } + + // Casts + + protected function pExpr_Cast_Int(Cast\Int_ $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Cast\Int_::class, '(int) ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_Cast_Double(Cast\Double $node, int $precedence, int $lhsPrecedence): string { + $kind = $node->getAttribute('kind', Cast\Double::KIND_DOUBLE); + if ($kind === Cast\Double::KIND_DOUBLE) { + $cast = '(double)'; + } elseif ($kind === Cast\Double::KIND_FLOAT) { + $cast = '(float)'; + } else { + assert($kind === Cast\Double::KIND_REAL); + $cast = '(real)'; + } + return $this->pPrefixOp(Cast\Double::class, $cast . ' ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_Cast_String(Cast\String_ $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Cast\String_::class, '(string) ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_Cast_Array(Cast\Array_ $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Cast\Array_::class, '(array) ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_Cast_Object(Cast\Object_ $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Cast\Object_::class, '(object) ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_Cast_Bool(Cast\Bool_ $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Cast\Bool_::class, '(bool) ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_Cast_Unset(Cast\Unset_ $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Cast\Unset_::class, '(unset) ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_Cast_Void(Cast\Void_ $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Cast\Void_::class, '(void) ', $node->expr, $precedence, $lhsPrecedence); + } + + // Function calls and similar constructs + + protected function pExpr_FuncCall(Expr\FuncCall $node): string { + return $this->pCallLhs($node->name) + . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_MethodCall(Expr\MethodCall $node): string { + return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name) + . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_NullsafeMethodCall(Expr\NullsafeMethodCall $node): string { + return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name) + . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_StaticCall(Expr\StaticCall $node): string { + return $this->pStaticDereferenceLhs($node->class) . '::' + . ($node->name instanceof Expr + ? ($node->name instanceof Expr\Variable + ? $this->p($node->name) + : '{' . $this->p($node->name) . '}') + : $node->name) + . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_Empty(Expr\Empty_ $node): string { + return 'empty(' . $this->p($node->expr) . ')'; + } + + protected function pExpr_Isset(Expr\Isset_ $node): string { + return 'isset(' . $this->pCommaSeparated($node->vars) . ')'; + } + + protected function pExpr_Eval(Expr\Eval_ $node): string { + return 'eval(' . $this->p($node->expr) . ')'; + } + + protected function pExpr_Include(Expr\Include_ $node, int $precedence, int $lhsPrecedence): string { + static $map = [ + Expr\Include_::TYPE_INCLUDE => 'include', + Expr\Include_::TYPE_INCLUDE_ONCE => 'include_once', + Expr\Include_::TYPE_REQUIRE => 'require', + Expr\Include_::TYPE_REQUIRE_ONCE => 'require_once', + ]; + + return $this->pPrefixOp(Expr\Include_::class, $map[$node->type] . ' ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_List(Expr\List_ $node): string { + $syntax = $node->getAttribute('kind', + $this->phpVersion->supportsShortArrayDestructuring() ? Expr\List_::KIND_ARRAY : Expr\List_::KIND_LIST); + if ($syntax === Expr\List_::KIND_ARRAY) { + return '[' . $this->pMaybeMultiline($node->items, true) . ']'; + } else { + return 'list(' . $this->pMaybeMultiline($node->items, true) . ')'; + } + } + + // Other + + protected function pExpr_Error(Expr\Error $node): string { + throw new \LogicException('Cannot pretty-print AST with Error nodes'); + } + + protected function pExpr_Variable(Expr\Variable $node): string { + if ($node->name instanceof Expr) { + return '${' . $this->p($node->name) . '}'; + } else { + return '$' . $node->name; + } + } + + protected function pExpr_Array(Expr\Array_ $node): string { + $syntax = $node->getAttribute('kind', + $this->shortArraySyntax ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG); + if ($syntax === Expr\Array_::KIND_SHORT) { + return '[' . $this->pMaybeMultiline($node->items, true) . ']'; + } else { + return 'array(' . $this->pMaybeMultiline($node->items, true) . ')'; + } + } + + protected function pKey(?Node $node): string { + if ($node === null) { + return ''; + } + + // => is not really an operator and does not typically participate in precedence resolution. + // However, there is an exception if yield expressions with keys are involved: + // [yield $a => $b] is interpreted as [(yield $a => $b)], so we need to ensure that + // [(yield $a) => $b] is printed with parentheses. We approximate this by lowering the LHS + // precedence to that of yield (which will also print unnecessary parentheses for rare low + // precedence unary operators like include). + $yieldPrecedence = $this->precedenceMap[Expr\Yield_::class][0]; + return $this->p($node, self::MAX_PRECEDENCE, $yieldPrecedence) . ' => '; + } + + protected function pArrayItem(Node\ArrayItem $node): string { + return $this->pKey($node->key) + . ($node->byRef ? '&' : '') + . ($node->unpack ? '...' : '') + . $this->p($node->value); + } + + protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node): string { + return $this->pDereferenceLhs($node->var) + . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']'; + } + + protected function pExpr_ConstFetch(Expr\ConstFetch $node): string { + return $this->p($node->name); + } + + protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node): string { + return $this->pStaticDereferenceLhs($node->class) . '::' . $this->pObjectProperty($node->name); + } + + protected function pExpr_PropertyFetch(Expr\PropertyFetch $node): string { + return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name); + } + + protected function pExpr_NullsafePropertyFetch(Expr\NullsafePropertyFetch $node): string { + return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name); + } + + protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node): string { + return $this->pStaticDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name); + } + + protected function pExpr_ShellExec(Expr\ShellExec $node): string { + return '`' . $this->pEncapsList($node->parts, '`') . '`'; + } + + protected function pExpr_Closure(Expr\Closure $node): string { + return $this->pAttrGroups($node->attrGroups, true) + . $this->pStatic($node->static) + . 'function ' . ($node->byRef ? '&' : '') + . '(' . $this->pParams($node->params) . ')' + . (!empty($node->uses) ? ' use (' . $this->pCommaSeparated($node->uses) . ')' : '') + . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') + . ' {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pExpr_Match(Expr\Match_ $node): string { + return 'match (' . $this->p($node->cond) . ') {' + . $this->pCommaSeparatedMultiline($node->arms, true) + . $this->nl + . '}'; + } + + protected function pMatchArm(Node\MatchArm $node): string { + $result = ''; + if ($node->conds) { + for ($i = 0, $c = \count($node->conds); $i + 1 < $c; $i++) { + $result .= $this->p($node->conds[$i]) . ', '; + } + $result .= $this->pKey($node->conds[$i]); + } else { + $result = 'default => '; + } + return $result . $this->p($node->body); + } + + protected function pExpr_ArrowFunction(Expr\ArrowFunction $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp( + Expr\ArrowFunction::class, + $this->pAttrGroups($node->attrGroups, true) + . $this->pStatic($node->static) + . 'fn' . ($node->byRef ? '&' : '') + . '(' . $this->pParams($node->params) . ')' + . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') + . ' => ', + $node->expr, $precedence, $lhsPrecedence); + } + + protected function pClosureUse(Node\ClosureUse $node): string { + return ($node->byRef ? '&' : '') . $this->p($node->var); + } + + protected function pExpr_New(Expr\New_ $node): string { + if ($node->class instanceof Stmt\Class_) { + $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : ''; + return 'new ' . $this->pClassCommon($node->class, $args); + } + return 'new ' . $this->pNewOperand($node->class) + . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_Clone(Expr\Clone_ $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Expr\Clone_::class, 'clone ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_Ternary(Expr\Ternary $node, int $precedence, int $lhsPrecedence): string { + // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator. + // this is okay because the part between ? and : never needs parentheses. + return $this->pInfixOp(Expr\Ternary::class, + $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else, + $precedence, $lhsPrecedence + ); + } + + protected function pExpr_Exit(Expr\Exit_ $node): string { + $kind = $node->getAttribute('kind', Expr\Exit_::KIND_DIE); + return ($kind === Expr\Exit_::KIND_EXIT ? 'exit' : 'die') + . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : ''); + } + + protected function pExpr_Throw(Expr\Throw_ $node, int $precedence, int $lhsPrecedence): string { + return $this->pPrefixOp(Expr\Throw_::class, 'throw ', $node->expr, $precedence, $lhsPrecedence); + } + + protected function pExpr_Yield(Expr\Yield_ $node, int $precedence, int $lhsPrecedence): string { + if ($node->value === null) { + $opPrecedence = $this->precedenceMap[Expr\Yield_::class][0]; + return $opPrecedence >= $lhsPrecedence ? '(yield)' : 'yield'; + } else { + if (!$this->phpVersion->supportsYieldWithoutParentheses()) { + return '(yield ' . $this->pKey($node->key) . $this->p($node->value) . ')'; + } + return $this->pPrefixOp( + Expr\Yield_::class, 'yield ' . $this->pKey($node->key), + $node->value, $precedence, $lhsPrecedence); + } + } + + // Declarations + + protected function pStmt_Namespace(Stmt\Namespace_ $node): string { + if ($this->canUseSemicolonNamespaces) { + return 'namespace ' . $this->p($node->name) . ';' + . $this->nl . $this->pStmts($node->stmts, false); + } else { + return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '') + . ' {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + } + + protected function pStmt_Use(Stmt\Use_ $node): string { + return 'use ' . $this->pUseType($node->type) + . $this->pCommaSeparated($node->uses) . ';'; + } + + protected function pStmt_GroupUse(Stmt\GroupUse $node): string { + return 'use ' . $this->pUseType($node->type) . $this->pName($node->prefix) + . '\{' . $this->pCommaSeparated($node->uses) . '};'; + } + + protected function pUseItem(Node\UseItem $node): string { + return $this->pUseType($node->type) . $this->p($node->name) + . (null !== $node->alias ? ' as ' . $node->alias : ''); + } + + protected function pUseType(int $type): string { + return $type === Stmt\Use_::TYPE_FUNCTION ? 'function ' + : ($type === Stmt\Use_::TYPE_CONSTANT ? 'const ' : ''); + } + + protected function pStmt_Interface(Stmt\Interface_ $node): string { + return $this->pAttrGroups($node->attrGroups) + . 'interface ' . $node->name + . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '') + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Enum(Stmt\Enum_ $node): string { + return $this->pAttrGroups($node->attrGroups) + . 'enum ' . $node->name + . ($node->scalarType ? ' : ' . $this->p($node->scalarType) : '') + . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Class(Stmt\Class_ $node): string { + return $this->pClassCommon($node, ' ' . $node->name); + } + + protected function pStmt_Trait(Stmt\Trait_ $node): string { + return $this->pAttrGroups($node->attrGroups) + . 'trait ' . $node->name + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_EnumCase(Stmt\EnumCase $node): string { + return $this->pAttrGroups($node->attrGroups) + . 'case ' . $node->name + . ($node->expr ? ' = ' . $this->p($node->expr) : '') + . ';'; + } + + protected function pStmt_TraitUse(Stmt\TraitUse $node): string { + return 'use ' . $this->pCommaSeparated($node->traits) + . (empty($node->adaptations) + ? ';' + : ' {' . $this->pStmts($node->adaptations) . $this->nl . '}'); + } + + protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node): string { + return $this->p($node->trait) . '::' . $node->method + . ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';'; + } + + protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node): string { + return (null !== $node->trait ? $this->p($node->trait) . '::' : '') + . $node->method . ' as' + . (null !== $node->newModifier ? ' ' . rtrim($this->pModifiers($node->newModifier), ' ') : '') + . (null !== $node->newName ? ' ' . $node->newName : '') + . ';'; + } + + protected function pStmt_Property(Stmt\Property $node): string { + return $this->pAttrGroups($node->attrGroups) + . (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags)) + . ($node->type ? $this->p($node->type) . ' ' : '') + . $this->pCommaSeparated($node->props) + . ($node->hooks ? ' {' . $this->pStmts($node->hooks) . $this->nl . '}' : ';'); + } + + protected function pPropertyItem(Node\PropertyItem $node): string { + return '$' . $node->name + . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); + } + + protected function pPropertyHook(Node\PropertyHook $node): string { + return $this->pAttrGroups($node->attrGroups) + . $this->pModifiers($node->flags) + . ($node->byRef ? '&' : '') . $node->name + . ($node->params ? '(' . $this->pParams($node->params) . ')' : '') + . (\is_array($node->body) ? ' {' . $this->pStmts($node->body) . $this->nl . '}' + : ($node->body !== null ? ' => ' . $this->p($node->body) : '') . ';'); + } + + protected function pStmt_ClassMethod(Stmt\ClassMethod $node): string { + return $this->pAttrGroups($node->attrGroups) + . $this->pModifiers($node->flags) + . 'function ' . ($node->byRef ? '&' : '') . $node->name + . '(' . $this->pParams($node->params) . ')' + . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') + . (null !== $node->stmts + ? $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}' + : ';'); + } + + protected function pStmt_ClassConst(Stmt\ClassConst $node): string { + return $this->pAttrGroups($node->attrGroups) + . $this->pModifiers($node->flags) + . 'const ' + . (null !== $node->type ? $this->p($node->type) . ' ' : '') + . $this->pCommaSeparated($node->consts) . ';'; + } + + protected function pStmt_Function(Stmt\Function_ $node): string { + return $this->pAttrGroups($node->attrGroups) + . 'function ' . ($node->byRef ? '&' : '') . $node->name + . '(' . $this->pParams($node->params) . ')' + . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Const(Stmt\Const_ $node): string { + return $this->pAttrGroups($node->attrGroups) + . 'const ' + . $this->pCommaSeparated($node->consts) . ';'; + } + + protected function pStmt_Declare(Stmt\Declare_ $node): string { + return 'declare (' . $this->pCommaSeparated($node->declares) . ')' + . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . $this->nl . '}' : ';'); + } + + protected function pDeclareItem(Node\DeclareItem $node): string { + return $node->key . '=' . $this->p($node->value); + } + + // Control flow + + protected function pStmt_If(Stmt\If_ $node): string { + return 'if (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->stmts) . $this->nl . '}' + . ($node->elseifs ? ' ' . $this->pImplode($node->elseifs, ' ') : '') + . (null !== $node->else ? ' ' . $this->p($node->else) : ''); + } + + protected function pStmt_ElseIf(Stmt\ElseIf_ $node): string { + return 'elseif (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Else(Stmt\Else_ $node): string { + if (\count($node->stmts) === 1 && $node->stmts[0] instanceof Stmt\If_) { + // Print as "else if" rather than "else { if }" + return 'else ' . $this->p($node->stmts[0]); + } + return 'else {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_For(Stmt\For_ $node): string { + return 'for (' + . $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '') + . $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '') + . $this->pCommaSeparated($node->loop) + . ') {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Foreach(Stmt\Foreach_ $node): string { + return 'foreach (' . $this->p($node->expr) . ' as ' + . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '') + . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {' + . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_While(Stmt\While_ $node): string { + return 'while (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Do(Stmt\Do_ $node): string { + return 'do {' . $this->pStmts($node->stmts) . $this->nl + . '} while (' . $this->p($node->cond) . ');'; + } + + protected function pStmt_Switch(Stmt\Switch_ $node): string { + return 'switch (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->cases) . $this->nl . '}'; + } + + protected function pStmt_Case(Stmt\Case_ $node): string { + return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':' + . $this->pStmts($node->stmts); + } + + protected function pStmt_TryCatch(Stmt\TryCatch $node): string { + return 'try {' . $this->pStmts($node->stmts) . $this->nl . '}' + . ($node->catches ? ' ' . $this->pImplode($node->catches, ' ') : '') + . ($node->finally !== null ? ' ' . $this->p($node->finally) : ''); + } + + protected function pStmt_Catch(Stmt\Catch_ $node): string { + return 'catch (' . $this->pImplode($node->types, '|') + . ($node->var !== null ? ' ' . $this->p($node->var) : '') + . ') {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Finally(Stmt\Finally_ $node): string { + return 'finally {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Break(Stmt\Break_ $node): string { + return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';'; + } + + protected function pStmt_Continue(Stmt\Continue_ $node): string { + return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';'; + } + + protected function pStmt_Return(Stmt\Return_ $node): string { + return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';'; + } + + protected function pStmt_Label(Stmt\Label $node): string { + return $node->name . ':'; + } + + protected function pStmt_Goto(Stmt\Goto_ $node): string { + return 'goto ' . $node->name . ';'; + } + + // Other + + protected function pStmt_Expression(Stmt\Expression $node): string { + return $this->p($node->expr) . ';'; + } + + protected function pStmt_Echo(Stmt\Echo_ $node): string { + return 'echo ' . $this->pCommaSeparated($node->exprs) . ';'; + } + + protected function pStmt_Static(Stmt\Static_ $node): string { + return 'static ' . $this->pCommaSeparated($node->vars) . ';'; + } + + protected function pStmt_Global(Stmt\Global_ $node): string { + return 'global ' . $this->pCommaSeparated($node->vars) . ';'; + } + + protected function pStaticVar(Node\StaticVar $node): string { + return $this->p($node->var) + . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); + } + + protected function pStmt_Unset(Stmt\Unset_ $node): string { + return 'unset(' . $this->pCommaSeparated($node->vars) . ');'; + } + + protected function pStmt_InlineHTML(Stmt\InlineHTML $node): string { + $newline = $node->getAttribute('hasLeadingNewline', true) ? $this->newline : ''; + return '?>' . $newline . $node->value . 'remaining; + } + + protected function pStmt_Nop(Stmt\Nop $node): string { + return ''; + } + + protected function pStmt_Block(Stmt\Block $node): string { + return '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + // Helpers + + protected function pClassCommon(Stmt\Class_ $node, string $afterClassToken): string { + return $this->pAttrGroups($node->attrGroups, $node->name === null) + . $this->pModifiers($node->flags) + . 'class' . $afterClassToken + . (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '') + . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pObjectProperty(Node $node): string { + if ($node instanceof Expr) { + return '{' . $this->p($node) . '}'; + } else { + assert($node instanceof Node\Identifier); + return $node->name; + } + } + + /** @param (Expr|Node\InterpolatedStringPart)[] $encapsList */ + protected function pEncapsList(array $encapsList, ?string $quote): string { + $return = ''; + foreach ($encapsList as $element) { + if ($element instanceof Node\InterpolatedStringPart) { + $return .= $this->escapeString($element->value, $quote); + } else { + $return .= '{' . $this->p($element) . '}'; + } + } + + return $return; + } + + protected function pSingleQuotedString(string $string): string { + // It is idiomatic to only escape backslashes when necessary, i.e. when followed by ', \ or + // the end of the string ('Foo\Bar' instead of 'Foo\\Bar'). However, we also don't want to + // produce an odd number of backslashes, so '\\\\a' should not get rendered as '\\\a', even + // though that would be legal. + $regex = '/\'|\\\\(?=[\'\\\\]|$)|(?<=\\\\)\\\\/'; + return '\'' . preg_replace($regex, '\\\\$0', $string) . '\''; + } + + protected function escapeString(string $string, ?string $quote): string { + if (null === $quote) { + // For doc strings, don't escape newlines + $escaped = addcslashes($string, "\t\f\v$\\"); + // But do escape isolated \r. Combined with the terminating newline, it might get + // interpreted as \r\n and dropped from the string contents. + $escaped = preg_replace('/\r(?!\n)/', '\\r', $escaped); + if ($this->phpVersion->supportsFlexibleHeredoc()) { + $escaped = $this->indentString($escaped); + } + } else { + $escaped = addcslashes($string, "\n\r\t\f\v$" . $quote . "\\"); + } + + // Escape control characters and non-UTF-8 characters. + // Regex based on https://stackoverflow.com/a/11709412/385378. + $regex = '/( + [\x00-\x08\x0E-\x1F] # Control characters + | [\xC0-\xC1] # Invalid UTF-8 Bytes + | [\xF5-\xFF] # Invalid UTF-8 Bytes + | \xE0(?=[\x80-\x9F]) # Overlong encoding of prior code point + | \xF0(?=[\x80-\x8F]) # Overlong encoding of prior code point + | [\xC2-\xDF](?![\x80-\xBF]) # Invalid UTF-8 Sequence Start + | [\xE0-\xEF](?![\x80-\xBF]{2}) # Invalid UTF-8 Sequence Start + | [\xF0-\xF4](?![\x80-\xBF]{3}) # Invalid UTF-8 Sequence Start + | (?<=[\x00-\x7F\xF5-\xFF])[\x80-\xBF] # Invalid UTF-8 Sequence Middle + | (? $part) { + if ($part instanceof Node\InterpolatedStringPart + && $this->containsEndLabel($this->escapeString($part->value, null), $label, $i === 0) + ) { + return true; + } + } + return false; + } + + protected function pDereferenceLhs(Node $node): string { + if (!$this->dereferenceLhsRequiresParens($node)) { + return $this->p($node); + } else { + return '(' . $this->p($node) . ')'; + } + } + + protected function pStaticDereferenceLhs(Node $node): string { + if (!$this->staticDereferenceLhsRequiresParens($node)) { + return $this->p($node); + } else { + return '(' . $this->p($node) . ')'; + } + } + + protected function pCallLhs(Node $node): string { + if (!$this->callLhsRequiresParens($node)) { + return $this->p($node); + } else { + return '(' . $this->p($node) . ')'; + } + } + + protected function pNewOperand(Node $node): string { + if (!$this->newOperandRequiresParens($node)) { + return $this->p($node); + } else { + return '(' . $this->p($node) . ')'; + } + } + + /** + * @param Node[] $nodes + */ + protected function hasNodeWithComments(array $nodes): bool { + foreach ($nodes as $node) { + if ($node && $node->getComments()) { + return true; + } + } + return false; + } + + /** @param Node[] $nodes */ + protected function pMaybeMultiline(array $nodes, bool $trailingComma = false): string { + if (!$this->hasNodeWithComments($nodes)) { + return $this->pCommaSeparated($nodes); + } else { + return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . $this->nl; + } + } + + /** @param Node\Param[] $params + */ + private function hasParamWithAttributes(array $params): bool { + foreach ($params as $param) { + if ($param->attrGroups) { + return true; + } + } + return false; + } + + /** @param Node\Param[] $params */ + protected function pParams(array $params): string { + if ($this->hasNodeWithComments($params) || + ($this->hasParamWithAttributes($params) && !$this->phpVersion->supportsAttributes()) + ) { + return $this->pCommaSeparatedMultiline($params, $this->phpVersion->supportsTrailingCommaInParamList()) . $this->nl; + } + return $this->pCommaSeparated($params); + } + + /** @param Node\AttributeGroup[] $nodes */ + protected function pAttrGroups(array $nodes, bool $inline = false): string { + $result = ''; + $sep = $inline ? ' ' : $this->nl; + foreach ($nodes as $node) { + $result .= $this->p($node) . $sep; + } + + return $result; + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php new file mode 100644 index 00000000..50a8e504 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php @@ -0,0 +1,1722 @@ + */ + protected array $precedenceMap = [ + // [precedence, precedenceLHS, precedenceRHS] + // Where the latter two are the precedences to use for the LHS and RHS of a binary operator, + // where 1 is added to one of the sides depending on associativity. This information is not + // used for unary operators and set to -1. + Expr\Clone_::class => [-10, 0, 1], + BinaryOp\Pow::class => [ 0, 0, 1], + Expr\BitwiseNot::class => [ 10, -1, -1], + Expr\UnaryPlus::class => [ 10, -1, -1], + Expr\UnaryMinus::class => [ 10, -1, -1], + Cast\Int_::class => [ 10, -1, -1], + Cast\Double::class => [ 10, -1, -1], + Cast\String_::class => [ 10, -1, -1], + Cast\Array_::class => [ 10, -1, -1], + Cast\Object_::class => [ 10, -1, -1], + Cast\Bool_::class => [ 10, -1, -1], + Cast\Unset_::class => [ 10, -1, -1], + Expr\ErrorSuppress::class => [ 10, -1, -1], + Expr\Instanceof_::class => [ 20, -1, -1], + Expr\BooleanNot::class => [ 30, -1, -1], + BinaryOp\Mul::class => [ 40, 41, 40], + BinaryOp\Div::class => [ 40, 41, 40], + BinaryOp\Mod::class => [ 40, 41, 40], + BinaryOp\Plus::class => [ 50, 51, 50], + BinaryOp\Minus::class => [ 50, 51, 50], + // FIXME: This precedence is incorrect for PHP 8. + BinaryOp\Concat::class => [ 50, 51, 50], + BinaryOp\ShiftLeft::class => [ 60, 61, 60], + BinaryOp\ShiftRight::class => [ 60, 61, 60], + BinaryOp\Pipe::class => [ 65, 66, 65], + BinaryOp\Smaller::class => [ 70, 70, 70], + BinaryOp\SmallerOrEqual::class => [ 70, 70, 70], + BinaryOp\Greater::class => [ 70, 70, 70], + BinaryOp\GreaterOrEqual::class => [ 70, 70, 70], + BinaryOp\Equal::class => [ 80, 80, 80], + BinaryOp\NotEqual::class => [ 80, 80, 80], + BinaryOp\Identical::class => [ 80, 80, 80], + BinaryOp\NotIdentical::class => [ 80, 80, 80], + BinaryOp\Spaceship::class => [ 80, 80, 80], + BinaryOp\BitwiseAnd::class => [ 90, 91, 90], + BinaryOp\BitwiseXor::class => [100, 101, 100], + BinaryOp\BitwiseOr::class => [110, 111, 110], + BinaryOp\BooleanAnd::class => [120, 121, 120], + BinaryOp\BooleanOr::class => [130, 131, 130], + BinaryOp\Coalesce::class => [140, 140, 141], + Expr\Ternary::class => [150, 150, 150], + Expr\Assign::class => [160, -1, -1], + Expr\AssignRef::class => [160, -1, -1], + AssignOp\Plus::class => [160, -1, -1], + AssignOp\Minus::class => [160, -1, -1], + AssignOp\Mul::class => [160, -1, -1], + AssignOp\Div::class => [160, -1, -1], + AssignOp\Concat::class => [160, -1, -1], + AssignOp\Mod::class => [160, -1, -1], + AssignOp\BitwiseAnd::class => [160, -1, -1], + AssignOp\BitwiseOr::class => [160, -1, -1], + AssignOp\BitwiseXor::class => [160, -1, -1], + AssignOp\ShiftLeft::class => [160, -1, -1], + AssignOp\ShiftRight::class => [160, -1, -1], + AssignOp\Pow::class => [160, -1, -1], + AssignOp\Coalesce::class => [160, -1, -1], + Expr\YieldFrom::class => [170, -1, -1], + Expr\Yield_::class => [175, -1, -1], + Expr\Print_::class => [180, -1, -1], + BinaryOp\LogicalAnd::class => [190, 191, 190], + BinaryOp\LogicalXor::class => [200, 201, 200], + BinaryOp\LogicalOr::class => [210, 211, 210], + Expr\Include_::class => [220, -1, -1], + Expr\ArrowFunction::class => [230, -1, -1], + Expr\Throw_::class => [240, -1, -1], + Expr\Cast\Void_::class => [250, -1, -1], + ]; + + /** @var int Current indentation level. */ + protected int $indentLevel; + /** @var string String for single level of indentation */ + private string $indent; + /** @var int Width in spaces to indent by. */ + private int $indentWidth; + /** @var bool Whether to use tab indentation. */ + private bool $useTabs; + /** @var int Width in spaces of one tab. */ + private int $tabWidth = 4; + + /** @var string Newline style. Does not include current indentation. */ + protected string $newline; + /** @var string Newline including current indentation. */ + protected string $nl; + /** @var string|null Token placed at end of doc string to ensure it is followed by a newline. + * Null if flexible doc strings are used. */ + protected ?string $docStringEndToken; + /** @var bool Whether semicolon namespaces can be used (i.e. no global namespace is used) */ + protected bool $canUseSemicolonNamespaces; + /** @var bool Whether to use short array syntax if the node specifies no preference */ + protected bool $shortArraySyntax; + /** @var PhpVersion PHP version to target */ + protected PhpVersion $phpVersion; + + /** @var TokenStream|null Original tokens for use in format-preserving pretty print */ + protected ?TokenStream $origTokens; + /** @var Internal\Differ Differ for node lists */ + protected Differ $nodeListDiffer; + /** @var array Map determining whether a certain character is a label character */ + protected array $labelCharMap; + /** + * @var array> Map from token classes and subnode names to FIXUP_* constants. + * This is used during format-preserving prints to place additional parens/braces if necessary. + */ + protected array $fixupMap; + /** + * @var array Map from "{$node->getType()}->{$subNode}" + * to ['left' => $l, 'right' => $r], where $l and $r specify the token type that needs to be stripped + * when removing this node. + */ + protected array $removalMap; + /** + * @var array Map from + * "{$node->getType()}->{$subNode}" to [$find, $beforeToken, $extraLeft, $extraRight]. + * $find is an optional token after which the insertion occurs. $extraLeft/Right + * are optionally added before/after the main insertions. + */ + protected array $insertionMap; + /** + * @var array Map From "{$class}->{$subNode}" to string that should be inserted + * between elements of this list subnode. + */ + protected array $listInsertionMap; + + /** + * @var array + */ + protected array $emptyListInsertionMap; + /** @var array + * Map from "{$class}->{$subNode}" to [$printFn, $skipToken, $findToken] where $printFn is the function to + * print the modifiers, $skipToken is the token to skip at the start and $findToken is the token before which + * the modifiers should be reprinted. */ + protected array $modifierChangeMap; + + /** + * Creates a pretty printer instance using the given options. + * + * Supported options: + * * PhpVersion $phpVersion: The PHP version to target (default to PHP 7.4). This option + * controls compatibility of the generated code with older PHP + * versions in cases where a simple stylistic choice exists (e.g. + * array() vs []). It is safe to pretty-print an AST for a newer + * PHP version while specifying an older target (but the result will + * of course not be compatible with the older version in that case). + * * string $newline: The newline style to use. Should be "\n" (default) or "\r\n". + * * string $indent: The indentation to use. Should either be all spaces or a single + * tab. Defaults to four spaces (" "). + * * bool $shortArraySyntax: Whether to use [] instead of array() as the default array + * syntax, if the node does not specify a format. Defaults to whether + * the phpVersion support short array syntax. + * + * @param array{ + * phpVersion?: PhpVersion, newline?: string, indent?: string, shortArraySyntax?: bool + * } $options Dictionary of formatting options + */ + public function __construct(array $options = []) { + $this->phpVersion = $options['phpVersion'] ?? PhpVersion::fromComponents(7, 4); + + $this->newline = $options['newline'] ?? "\n"; + if ($this->newline !== "\n" && $this->newline != "\r\n") { + throw new \LogicException('Option "newline" must be one of "\n" or "\r\n"'); + } + + $this->shortArraySyntax = + $options['shortArraySyntax'] ?? $this->phpVersion->supportsShortArraySyntax(); + $this->docStringEndToken = + $this->phpVersion->supportsFlexibleHeredoc() ? null : '_DOC_STRING_END_' . mt_rand(); + + $this->indent = $indent = $options['indent'] ?? ' '; + if ($indent === "\t") { + $this->useTabs = true; + $this->indentWidth = $this->tabWidth; + } elseif ($indent === \str_repeat(' ', \strlen($indent))) { + $this->useTabs = false; + $this->indentWidth = \strlen($indent); + } else { + throw new \LogicException('Option "indent" must either be all spaces or a single tab'); + } + } + + /** + * Reset pretty printing state. + */ + protected function resetState(): void { + $this->indentLevel = 0; + $this->nl = $this->newline; + $this->origTokens = null; + } + + /** + * Set indentation level + * + * @param int $level Level in number of spaces + */ + protected function setIndentLevel(int $level): void { + $this->indentLevel = $level; + if ($this->useTabs) { + $tabs = \intdiv($level, $this->tabWidth); + $spaces = $level % $this->tabWidth; + $this->nl = $this->newline . \str_repeat("\t", $tabs) . \str_repeat(' ', $spaces); + } else { + $this->nl = $this->newline . \str_repeat(' ', $level); + } + } + + /** + * Increase indentation level. + */ + protected function indent(): void { + $this->indentLevel += $this->indentWidth; + $this->nl .= $this->indent; + } + + /** + * Decrease indentation level. + */ + protected function outdent(): void { + assert($this->indentLevel >= $this->indentWidth); + $this->setIndentLevel($this->indentLevel - $this->indentWidth); + } + + /** + * Pretty prints an array of statements. + * + * @param Node[] $stmts Array of statements + * + * @return string Pretty printed statements + */ + public function prettyPrint(array $stmts): string { + $this->resetState(); + $this->preprocessNodes($stmts); + + return ltrim($this->handleMagicTokens($this->pStmts($stmts, false))); + } + + /** + * Pretty prints an expression. + * + * @param Expr $node Expression node + * + * @return string Pretty printed node + */ + public function prettyPrintExpr(Expr $node): string { + $this->resetState(); + return $this->handleMagicTokens($this->p($node)); + } + + /** + * Pretty prints a file of statements (includes the opening newline . $this->newline; + } + + $p = "newline . $this->newline . $this->prettyPrint($stmts); + + if ($stmts[0] instanceof Stmt\InlineHTML) { + $p = preg_replace('/^<\?php\s+\?>\r?\n?/', '', $p); + } + if ($stmts[count($stmts) - 1] instanceof Stmt\InlineHTML) { + $p = preg_replace('/<\?php$/', '', rtrim($p)); + } + + return $p; + } + + /** + * Preprocesses the top-level nodes to initialize pretty printer state. + * + * @param Node[] $nodes Array of nodes + */ + protected function preprocessNodes(array $nodes): void { + /* We can use semicolon-namespaces unless there is a global namespace declaration */ + $this->canUseSemicolonNamespaces = true; + foreach ($nodes as $node) { + if ($node instanceof Stmt\Namespace_ && null === $node->name) { + $this->canUseSemicolonNamespaces = false; + break; + } + } + } + + /** + * Handles (and removes) doc-string-end tokens. + */ + protected function handleMagicTokens(string $str): string { + if ($this->docStringEndToken !== null) { + // Replace doc-string-end tokens with nothing or a newline + $str = str_replace( + $this->docStringEndToken . ';' . $this->newline, + ';' . $this->newline, + $str); + $str = str_replace($this->docStringEndToken, $this->newline, $str); + } + + return $str; + } + + /** + * Pretty prints an array of nodes (statements) and indents them optionally. + * + * @param Node[] $nodes Array of nodes + * @param bool $indent Whether to indent the printed nodes + * + * @return string Pretty printed statements + */ + protected function pStmts(array $nodes, bool $indent = true): string { + if ($indent) { + $this->indent(); + } + + $result = ''; + foreach ($nodes as $node) { + $comments = $node->getComments(); + if ($comments) { + $result .= $this->nl . $this->pComments($comments); + if ($node instanceof Stmt\Nop) { + continue; + } + } + + $result .= $this->nl . $this->p($node); + } + + if ($indent) { + $this->outdent(); + } + + return $result; + } + + /** + * Pretty-print an infix operation while taking precedence into account. + * + * @param string $class Node class of operator + * @param Node $leftNode Left-hand side node + * @param string $operatorString String representation of the operator + * @param Node $rightNode Right-hand side node + * @param int $precedence Precedence of parent operator + * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator + * + * @return string Pretty printed infix operation + */ + protected function pInfixOp( + string $class, Node $leftNode, string $operatorString, Node $rightNode, + int $precedence, int $lhsPrecedence + ): string { + list($opPrecedence, $newPrecedenceLHS, $newPrecedenceRHS) = $this->precedenceMap[$class]; + $prefix = ''; + $suffix = ''; + if ($opPrecedence >= $precedence) { + $prefix = '('; + $suffix = ')'; + $lhsPrecedence = self::MAX_PRECEDENCE; + } + return $prefix . $this->p($leftNode, $newPrecedenceLHS, $newPrecedenceLHS) + . $operatorString . $this->p($rightNode, $newPrecedenceRHS, $lhsPrecedence) . $suffix; + } + + /** + * Pretty-print a prefix operation while taking precedence into account. + * + * @param string $class Node class of operator + * @param string $operatorString String representation of the operator + * @param Node $node Node + * @param int $precedence Precedence of parent operator + * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator + * + * @return string Pretty printed prefix operation + */ + protected function pPrefixOp(string $class, string $operatorString, Node $node, int $precedence, int $lhsPrecedence): string { + $opPrecedence = $this->precedenceMap[$class][0]; + $prefix = ''; + $suffix = ''; + if ($opPrecedence >= $lhsPrecedence) { + $prefix = '('; + $suffix = ')'; + $lhsPrecedence = self::MAX_PRECEDENCE; + } + $printedArg = $this->p($node, $opPrecedence, $lhsPrecedence); + if (($operatorString === '+' && $printedArg[0] === '+') || + ($operatorString === '-' && $printedArg[0] === '-') + ) { + // Avoid printing +(+$a) as ++$a and similar. + $printedArg = '(' . $printedArg . ')'; + } + return $prefix . $operatorString . $printedArg . $suffix; + } + + /** + * Pretty-print a postfix operation while taking precedence into account. + * + * @param string $class Node class of operator + * @param string $operatorString String representation of the operator + * @param Node $node Node + * @param int $precedence Precedence of parent operator + * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator + * + * @return string Pretty printed postfix operation + */ + protected function pPostfixOp(string $class, Node $node, string $operatorString, int $precedence, int $lhsPrecedence): string { + $opPrecedence = $this->precedenceMap[$class][0]; + $prefix = ''; + $suffix = ''; + if ($opPrecedence >= $precedence) { + $prefix = '('; + $suffix = ')'; + $lhsPrecedence = self::MAX_PRECEDENCE; + } + if ($opPrecedence < $lhsPrecedence) { + $lhsPrecedence = $opPrecedence; + } + return $prefix . $this->p($node, $opPrecedence, $lhsPrecedence) . $operatorString . $suffix; + } + + /** + * Pretty prints an array of nodes and implodes the printed values. + * + * @param Node[] $nodes Array of Nodes to be printed + * @param string $glue Character to implode with + * + * @return string Imploded pretty printed nodes> $pre + */ + protected function pImplode(array $nodes, string $glue = ''): string { + $pNodes = []; + foreach ($nodes as $node) { + if (null === $node) { + $pNodes[] = ''; + } else { + $pNodes[] = $this->p($node); + } + } + + return implode($glue, $pNodes); + } + + /** + * Pretty prints an array of nodes and implodes the printed values with commas. + * + * @param Node[] $nodes Array of Nodes to be printed + * + * @return string Comma separated pretty printed nodes + */ + protected function pCommaSeparated(array $nodes): string { + return $this->pImplode($nodes, ', '); + } + + /** + * Pretty prints a comma-separated list of nodes in multiline style, including comments. + * + * The result includes a leading newline and one level of indentation (same as pStmts). + * + * @param Node[] $nodes Array of Nodes to be printed + * @param bool $trailingComma Whether to use a trailing comma + * + * @return string Comma separated pretty printed nodes in multiline style + */ + protected function pCommaSeparatedMultiline(array $nodes, bool $trailingComma): string { + $this->indent(); + + $result = ''; + $lastIdx = count($nodes) - 1; + foreach ($nodes as $idx => $node) { + if ($node !== null) { + $comments = $node->getComments(); + if ($comments) { + $result .= $this->nl . $this->pComments($comments); + } + + $result .= $this->nl . $this->p($node); + } else { + $result .= $this->nl; + } + if ($trailingComma || $idx !== $lastIdx) { + $result .= ','; + } + } + + $this->outdent(); + return $result; + } + + /** + * Prints reformatted text of the passed comments. + * + * @param Comment[] $comments List of comments + * + * @return string Reformatted text of comments + */ + protected function pComments(array $comments): string { + $formattedComments = []; + + foreach ($comments as $comment) { + $formattedComments[] = str_replace("\n", $this->nl, $comment->getReformattedText()); + } + + return implode($this->nl, $formattedComments); + } + + /** + * Perform a format-preserving pretty print of an AST. + * + * The format preservation is best effort. For some changes to the AST the formatting will not + * be preserved (at least not locally). + * + * In order to use this method a number of prerequisites must be satisfied: + * * The startTokenPos and endTokenPos attributes in the lexer must be enabled. + * * The CloningVisitor must be run on the AST prior to modification. + * * The original tokens must be provided, using the getTokens() method on the lexer. + * + * @param Node[] $stmts Modified AST with links to original AST + * @param Node[] $origStmts Original AST with token offset information + * @param Token[] $origTokens Tokens of the original code + */ + public function printFormatPreserving(array $stmts, array $origStmts, array $origTokens): string { + $this->initializeNodeListDiffer(); + $this->initializeLabelCharMap(); + $this->initializeFixupMap(); + $this->initializeRemovalMap(); + $this->initializeInsertionMap(); + $this->initializeListInsertionMap(); + $this->initializeEmptyListInsertionMap(); + $this->initializeModifierChangeMap(); + + $this->resetState(); + $this->origTokens = new TokenStream($origTokens, $this->tabWidth); + + $this->preprocessNodes($stmts); + + $pos = 0; + $result = $this->pArray($stmts, $origStmts, $pos, 0, 'File', 'stmts', null); + if (null !== $result) { + $result .= $this->origTokens->getTokenCode($pos, count($origTokens) - 1, 0); + } else { + // Fallback + // TODO Add newline . $this->pStmts($stmts, false); + } + + return $this->handleMagicTokens($result); + } + + protected function pFallback(Node $node, int $precedence, int $lhsPrecedence): string { + return $this->{'p' . $node->getType()}($node, $precedence, $lhsPrecedence); + } + + /** + * Pretty prints a node. + * + * This method also handles formatting preservation for nodes. + * + * @param Node $node Node to be pretty printed + * @param int $precedence Precedence of parent operator + * @param int $lhsPrecedence Precedence for unary operator on LHS of binary operator + * @param bool $parentFormatPreserved Whether parent node has preserved formatting + * + * @return string Pretty printed node + */ + protected function p( + Node $node, int $precedence = self::MAX_PRECEDENCE, int $lhsPrecedence = self::MAX_PRECEDENCE, + bool $parentFormatPreserved = false + ): string { + // No orig tokens means this is a normal pretty print without preservation of formatting + if (!$this->origTokens) { + return $this->{'p' . $node->getType()}($node, $precedence, $lhsPrecedence); + } + + /** @var Node|null $origNode */ + $origNode = $node->getAttribute('origNode'); + if (null === $origNode) { + return $this->pFallback($node, $precedence, $lhsPrecedence); + } + + $class = \get_class($node); + \assert($class === \get_class($origNode)); + + $startPos = $origNode->getStartTokenPos(); + $endPos = $origNode->getEndTokenPos(); + \assert($startPos >= 0 && $endPos >= 0); + + $fallbackNode = $node; + if ($node instanceof Expr\New_ && $node->class instanceof Stmt\Class_) { + // Normalize node structure of anonymous classes + assert($origNode instanceof Expr\New_); + $node = PrintableNewAnonClassNode::fromNewNode($node); + $origNode = PrintableNewAnonClassNode::fromNewNode($origNode); + $class = PrintableNewAnonClassNode::class; + } + + // InlineHTML node does not contain closing and opening PHP tags. If the parent formatting + // is not preserved, then we need to use the fallback code to make sure the tags are + // printed. + if ($node instanceof Stmt\InlineHTML && !$parentFormatPreserved) { + return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence); + } + + $indentAdjustment = $this->indentLevel - $this->origTokens->getIndentationBefore($startPos); + + $type = $node->getType(); + $fixupInfo = $this->fixupMap[$class] ?? null; + + $result = ''; + $pos = $startPos; + foreach ($node->getSubNodeNames() as $subNodeName) { + $subNode = $node->$subNodeName; + $origSubNode = $origNode->$subNodeName; + + if ((!$subNode instanceof Node && $subNode !== null) + || (!$origSubNode instanceof Node && $origSubNode !== null) + ) { + if ($subNode === $origSubNode) { + // Unchanged, can reuse old code + continue; + } + + if (is_array($subNode) && is_array($origSubNode)) { + // Array subnode changed, we might be able to reconstruct it + $listResult = $this->pArray( + $subNode, $origSubNode, $pos, $indentAdjustment, $class, $subNodeName, + $fixupInfo[$subNodeName] ?? null + ); + if (null === $listResult) { + return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence); + } + + $result .= $listResult; + continue; + } + + // Check if this is a modifier change + $key = $class . '->' . $subNodeName; + if (!isset($this->modifierChangeMap[$key])) { + return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence); + } + + [$printFn, $skipToken, $findToken] = $this->modifierChangeMap[$key]; + $skipWSPos = $this->origTokens->skipRight($pos, $skipToken); + $result .= $this->origTokens->getTokenCode($pos, $skipWSPos, $indentAdjustment); + $result .= $this->$printFn($subNode); + $pos = $this->origTokens->findRight($skipWSPos, $findToken); + continue; + } + + $extraLeft = ''; + $extraRight = ''; + if ($origSubNode !== null) { + $subStartPos = $origSubNode->getStartTokenPos(); + $subEndPos = $origSubNode->getEndTokenPos(); + \assert($subStartPos >= 0 && $subEndPos >= 0); + } else { + if ($subNode === null) { + // Both null, nothing to do + continue; + } + + // A node has been inserted, check if we have insertion information for it + $key = $type . '->' . $subNodeName; + if (!isset($this->insertionMap[$key])) { + return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence); + } + + list($findToken, $beforeToken, $extraLeft, $extraRight) = $this->insertionMap[$key]; + if (null !== $findToken) { + $subStartPos = $this->origTokens->findRight($pos, $findToken) + + (int) !$beforeToken; + } else { + $subStartPos = $pos; + } + + if (null === $extraLeft && null !== $extraRight) { + // If inserting on the right only, skipping whitespace looks better + $subStartPos = $this->origTokens->skipRightWhitespace($subStartPos); + } + $subEndPos = $subStartPos - 1; + } + + if (null === $subNode) { + // A node has been removed, check if we have removal information for it + $key = $type . '->' . $subNodeName; + if (!isset($this->removalMap[$key])) { + return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence); + } + + // Adjust positions to account for additional tokens that must be skipped + $removalInfo = $this->removalMap[$key]; + if (isset($removalInfo['left'])) { + $subStartPos = $this->origTokens->skipLeft($subStartPos - 1, $removalInfo['left']) + 1; + } + if (isset($removalInfo['right'])) { + $subEndPos = $this->origTokens->skipRight($subEndPos + 1, $removalInfo['right']) - 1; + } + } + + $result .= $this->origTokens->getTokenCode($pos, $subStartPos, $indentAdjustment); + + if (null !== $subNode) { + $result .= $extraLeft; + + $origIndentLevel = $this->indentLevel; + $this->setIndentLevel(max($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment, 0)); + + // If it's the same node that was previously in this position, it certainly doesn't + // need fixup. It's important to check this here, because our fixup checks are more + // conservative than strictly necessary. + if (isset($fixupInfo[$subNodeName]) + && $subNode->getAttribute('origNode') !== $origSubNode + ) { + $fixup = $fixupInfo[$subNodeName]; + $res = $this->pFixup($fixup, $subNode, $class, $subStartPos, $subEndPos); + } else { + $res = $this->p($subNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, true); + } + + $this->safeAppend($result, $res); + $this->setIndentLevel($origIndentLevel); + + $result .= $extraRight; + } + + $pos = $subEndPos + 1; + } + + $result .= $this->origTokens->getTokenCode($pos, $endPos + 1, $indentAdjustment); + return $result; + } + + /** + * Perform a format-preserving pretty print of an array. + * + * @param Node[] $nodes New nodes + * @param Node[] $origNodes Original nodes + * @param int $pos Current token position (updated by reference) + * @param int $indentAdjustment Adjustment for indentation + * @param string $parentNodeClass Class of the containing node. + * @param string $subNodeName Name of array subnode. + * @param null|int $fixup Fixup information for array item nodes + * + * @return null|string Result of pretty print or null if cannot preserve formatting + */ + protected function pArray( + array $nodes, array $origNodes, int &$pos, int $indentAdjustment, + string $parentNodeClass, string $subNodeName, ?int $fixup + ): ?string { + $diff = $this->nodeListDiffer->diffWithReplacements($origNodes, $nodes); + + $mapKey = $parentNodeClass . '->' . $subNodeName; + $insertStr = $this->listInsertionMap[$mapKey] ?? null; + $isStmtList = $subNodeName === 'stmts'; + + $beforeFirstKeepOrReplace = true; + $skipRemovedNode = false; + $delayedAdd = []; + $lastElemIndentLevel = $this->indentLevel; + + $insertNewline = false; + if ($insertStr === "\n") { + $insertStr = ''; + $insertNewline = true; + } + + if ($isStmtList && \count($origNodes) === 1 && \count($nodes) !== 1) { + $startPos = $origNodes[0]->getStartTokenPos(); + $endPos = $origNodes[0]->getEndTokenPos(); + \assert($startPos >= 0 && $endPos >= 0); + if (!$this->origTokens->haveBraces($startPos, $endPos)) { + // This was a single statement without braces, but either additional statements + // have been added, or the single statement has been removed. This requires the + // addition of braces. For now fall back. + // TODO: Try to preserve formatting + return null; + } + } + + $result = ''; + foreach ($diff as $i => $diffElem) { + $diffType = $diffElem->type; + /** @var Node|string|null $arrItem */ + $arrItem = $diffElem->new; + /** @var Node|string|null $origArrItem */ + $origArrItem = $diffElem->old; + + if ($diffType === DiffElem::TYPE_KEEP || $diffType === DiffElem::TYPE_REPLACE) { + $beforeFirstKeepOrReplace = false; + + if ($origArrItem === null || $arrItem === null) { + // We can only handle the case where both are null + if ($origArrItem === $arrItem) { + continue; + } + return null; + } + + if (!$arrItem instanceof Node || !$origArrItem instanceof Node) { + // We can only deal with nodes. This can occur for Names, which use string arrays. + return null; + } + + $itemStartPos = $origArrItem->getStartTokenPos(); + $itemEndPos = $origArrItem->getEndTokenPos(); + \assert($itemStartPos >= 0 && $itemEndPos >= 0 && $itemStartPos >= $pos); + + $origIndentLevel = $this->indentLevel; + $lastElemIndentLevel = max($this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment, 0); + $this->setIndentLevel($lastElemIndentLevel); + + $comments = $arrItem->getComments(); + $origComments = $origArrItem->getComments(); + $commentStartPos = $origComments ? $origComments[0]->getStartTokenPos() : $itemStartPos; + \assert($commentStartPos >= 0); + + if ($commentStartPos < $pos) { + // Comments may be assigned to multiple nodes if they start at the same position. + // Make sure we don't try to print them multiple times. + $commentStartPos = $itemStartPos; + } + + if ($skipRemovedNode) { + if ($isStmtList && $this->origTokens->haveTagInRange($pos, $itemStartPos)) { + // We'd remove an opening/closing PHP tag. + // TODO: Preserve formatting. + $this->setIndentLevel($origIndentLevel); + return null; + } + } else { + $result .= $this->origTokens->getTokenCode( + $pos, $commentStartPos, $indentAdjustment); + } + + if (!empty($delayedAdd)) { + /** @var Node $delayedAddNode */ + foreach ($delayedAdd as $delayedAddNode) { + if ($insertNewline) { + $delayedAddComments = $delayedAddNode->getComments(); + if ($delayedAddComments) { + $result .= $this->pComments($delayedAddComments) . $this->nl; + } + } + + $this->safeAppend($result, $this->p($delayedAddNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, true)); + + if ($insertNewline) { + $result .= $insertStr . $this->nl; + } else { + $result .= $insertStr; + } + } + + $delayedAdd = []; + } + + if ($comments !== $origComments) { + if ($comments) { + $result .= $this->pComments($comments) . $this->nl; + } + } else { + $result .= $this->origTokens->getTokenCode( + $commentStartPos, $itemStartPos, $indentAdjustment); + } + + // If we had to remove anything, we have done so now. + $skipRemovedNode = false; + } elseif ($diffType === DiffElem::TYPE_ADD) { + if (null === $insertStr) { + // We don't have insertion information for this list type + return null; + } + + if (!$arrItem instanceof Node) { + // We only support list insertion of nodes. + return null; + } + + // We go multiline if the original code was multiline, + // or if it's an array item with a comment above it. + // Match always uses multiline formatting. + if ($insertStr === ', ' && + ($this->isMultiline($origNodes) || $arrItem->getComments() || + $parentNodeClass === Expr\Match_::class) + ) { + $insertStr = ','; + $insertNewline = true; + } + + if ($beforeFirstKeepOrReplace) { + // Will be inserted at the next "replace" or "keep" element + $delayedAdd[] = $arrItem; + continue; + } + + $itemStartPos = $pos; + $itemEndPos = $pos - 1; + + $origIndentLevel = $this->indentLevel; + $this->setIndentLevel($lastElemIndentLevel); + + if ($insertNewline) { + $result .= $insertStr . $this->nl; + $comments = $arrItem->getComments(); + if ($comments) { + $result .= $this->pComments($comments) . $this->nl; + } + } else { + $result .= $insertStr; + } + } elseif ($diffType === DiffElem::TYPE_REMOVE) { + if (!$origArrItem instanceof Node) { + // We only support removal for nodes + return null; + } + + $itemStartPos = $origArrItem->getStartTokenPos(); + $itemEndPos = $origArrItem->getEndTokenPos(); + \assert($itemStartPos >= 0 && $itemEndPos >= 0); + + // Consider comments part of the node. + $origComments = $origArrItem->getComments(); + if ($origComments) { + $itemStartPos = $origComments[0]->getStartTokenPos(); + } + + if ($i === 0) { + // If we're removing from the start, keep the tokens before the node and drop those after it, + // instead of the other way around. + $result .= $this->origTokens->getTokenCode( + $pos, $itemStartPos, $indentAdjustment); + $skipRemovedNode = true; + } else { + if ($isStmtList && $this->origTokens->haveTagInRange($pos, $itemStartPos)) { + // We'd remove an opening/closing PHP tag. + // TODO: Preserve formatting. + return null; + } + } + + $pos = $itemEndPos + 1; + continue; + } else { + throw new \Exception("Shouldn't happen"); + } + + if (null !== $fixup && $arrItem->getAttribute('origNode') !== $origArrItem) { + $res = $this->pFixup($fixup, $arrItem, null, $itemStartPos, $itemEndPos); + } else { + $res = $this->p($arrItem, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, true); + } + $this->safeAppend($result, $res); + + $this->setIndentLevel($origIndentLevel); + $pos = $itemEndPos + 1; + } + + if ($skipRemovedNode) { + // TODO: Support removing single node. + return null; + } + + if (!empty($delayedAdd)) { + if (!isset($this->emptyListInsertionMap[$mapKey])) { + return null; + } + + list($findToken, $extraLeft, $extraRight) = $this->emptyListInsertionMap[$mapKey]; + if (null !== $findToken) { + // For anon classes skip to the class keyword. + $isAnonClassArgs = $mapKey === PrintableNewAnonClassNode::class . '->args'; + if ($isAnonClassArgs) { + $insertPos = $this->origTokens->findRight($pos, \T_CLASS) + 1; + $result .= $this->origTokens->getTokenCode($pos, $insertPos, $indentAdjustment); + $pos = $insertPos; + } + + // If "new Foo" was used without arguments, we need to convert to "new Foo()". + if (($mapKey === Expr\New_::class . '->args' || $isAnonClassArgs) && + !$this->origTokens->haveTokenImmediatelyAfter($pos - 1, '(') + ) { + $extraLeft = '('; + $extraRight = ')'; + } else { + $insertPos = $this->origTokens->findRight($pos, $findToken) + 1; + $result .= $this->origTokens->getTokenCode($pos, $insertPos, $indentAdjustment); + $pos = $insertPos; + } + } + + $first = true; + $result .= $extraLeft; + foreach ($delayedAdd as $delayedAddNode) { + if (!$first) { + $result .= $insertStr; + if ($insertNewline) { + $result .= $this->nl; + } + } + $result .= $this->p($delayedAddNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, true); + $first = false; + } + $result .= $extraRight === "\n" ? $this->nl : $extraRight; + } + + return $result; + } + + /** + * Print node with fixups. + * + * Fixups here refer to the addition of extra parentheses, braces or other characters, that + * are required to preserve program semantics in a certain context (e.g. to maintain precedence + * or because only certain expressions are allowed in certain places). + * + * @param int $fixup Fixup type + * @param Node $subNode Subnode to print + * @param string|null $parentClass Class of parent node + * @param int $subStartPos Original start pos of subnode + * @param int $subEndPos Original end pos of subnode + * + * @return string Result of fixed-up print of subnode + */ + protected function pFixup(int $fixup, Node $subNode, ?string $parentClass, int $subStartPos, int $subEndPos): string { + switch ($fixup) { + case self::FIXUP_PREC_LEFT: + // We use a conservative approximation where lhsPrecedence == precedence. + if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) { + $precedence = $this->precedenceMap[$parentClass][1]; + return $this->p($subNode, $precedence, $precedence); + } + break; + case self::FIXUP_PREC_RIGHT: + if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) { + $precedence = $this->precedenceMap[$parentClass][2]; + return $this->p($subNode, $precedence, $precedence); + } + break; + case self::FIXUP_PREC_UNARY: + if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) { + $precedence = $this->precedenceMap[$parentClass][0]; + return $this->p($subNode, $precedence, $precedence); + } + break; + case self::FIXUP_CALL_LHS: + if ($this->callLhsRequiresParens($subNode) + && !$this->origTokens->haveParens($subStartPos, $subEndPos) + ) { + return '(' . $this->p($subNode) . ')'; + } + break; + case self::FIXUP_DEREF_LHS: + if ($this->dereferenceLhsRequiresParens($subNode) + && !$this->origTokens->haveParens($subStartPos, $subEndPos) + ) { + return '(' . $this->p($subNode) . ')'; + } + break; + case self::FIXUP_STATIC_DEREF_LHS: + if ($this->staticDereferenceLhsRequiresParens($subNode) + && !$this->origTokens->haveParens($subStartPos, $subEndPos) + ) { + return '(' . $this->p($subNode) . ')'; + } + break; + case self::FIXUP_NEW: + if ($this->newOperandRequiresParens($subNode) + && !$this->origTokens->haveParens($subStartPos, $subEndPos)) { + return '(' . $this->p($subNode) . ')'; + } + break; + case self::FIXUP_BRACED_NAME: + case self::FIXUP_VAR_BRACED_NAME: + if ($subNode instanceof Expr + && !$this->origTokens->haveBraces($subStartPos, $subEndPos) + ) { + return ($fixup === self::FIXUP_VAR_BRACED_NAME ? '$' : '') + . '{' . $this->p($subNode) . '}'; + } + break; + case self::FIXUP_ENCAPSED: + if (!$subNode instanceof Node\InterpolatedStringPart + && !$this->origTokens->haveBraces($subStartPos, $subEndPos) + ) { + return '{' . $this->p($subNode) . '}'; + } + break; + default: + throw new \Exception('Cannot happen'); + } + + // Nothing special to do + return $this->p($subNode); + } + + /** + * Appends to a string, ensuring whitespace between label characters. + * + * Example: "echo" and "$x" result in "echo$x", but "echo" and "x" result in "echo x". + * Without safeAppend the result would be "echox", which does not preserve semantics. + */ + protected function safeAppend(string &$str, string $append): void { + if ($str === "") { + $str = $append; + return; + } + + if ($append === "") { + return; + } + + if (!$this->labelCharMap[$append[0]] + || !$this->labelCharMap[$str[\strlen($str) - 1]]) { + $str .= $append; + } else { + $str .= " " . $append; + } + } + + /** + * Determines whether the LHS of a call must be wrapped in parenthesis. + * + * @param Node $node LHS of a call + * + * @return bool Whether parentheses are required + */ + protected function callLhsRequiresParens(Node $node): bool { + if ($node instanceof Expr\New_) { + return !$this->phpVersion->supportsNewDereferenceWithoutParentheses(); + } + return !($node instanceof Node\Name + || $node instanceof Expr\Variable + || $node instanceof Expr\ArrayDimFetch + || $node instanceof Expr\FuncCall + || $node instanceof Expr\MethodCall + || $node instanceof Expr\NullsafeMethodCall + || $node instanceof Expr\StaticCall + || $node instanceof Expr\Array_); + } + + /** + * Determines whether the LHS of an array/object operation must be wrapped in parentheses. + * + * @param Node $node LHS of dereferencing operation + * + * @return bool Whether parentheses are required + */ + protected function dereferenceLhsRequiresParens(Node $node): bool { + // A constant can occur on the LHS of an array/object deref, but not a static deref. + return $this->staticDereferenceLhsRequiresParens($node) + && !$node instanceof Expr\ConstFetch; + } + + /** + * Determines whether the LHS of a static operation must be wrapped in parentheses. + * + * @param Node $node LHS of dereferencing operation + * + * @return bool Whether parentheses are required + */ + protected function staticDereferenceLhsRequiresParens(Node $node): bool { + if ($node instanceof Expr\New_) { + return !$this->phpVersion->supportsNewDereferenceWithoutParentheses(); + } + return !($node instanceof Expr\Variable + || $node instanceof Node\Name + || $node instanceof Expr\ArrayDimFetch + || $node instanceof Expr\PropertyFetch + || $node instanceof Expr\NullsafePropertyFetch + || $node instanceof Expr\StaticPropertyFetch + || $node instanceof Expr\FuncCall + || $node instanceof Expr\MethodCall + || $node instanceof Expr\NullsafeMethodCall + || $node instanceof Expr\StaticCall + || $node instanceof Expr\Array_ + || $node instanceof Scalar\String_ + || $node instanceof Expr\ClassConstFetch); + } + + /** + * Determines whether an expression used in "new" or "instanceof" requires parentheses. + * + * @param Node $node New or instanceof operand + * + * @return bool Whether parentheses are required + */ + protected function newOperandRequiresParens(Node $node): bool { + if ($node instanceof Node\Name || $node instanceof Expr\Variable) { + return false; + } + if ($node instanceof Expr\ArrayDimFetch || $node instanceof Expr\PropertyFetch || + $node instanceof Expr\NullsafePropertyFetch + ) { + return $this->newOperandRequiresParens($node->var); + } + if ($node instanceof Expr\StaticPropertyFetch) { + return $this->newOperandRequiresParens($node->class); + } + return true; + } + + /** + * Print modifiers, including trailing whitespace. + * + * @param int $modifiers Modifier mask to print + * + * @return string Printed modifiers + */ + protected function pModifiers(int $modifiers): string { + return ($modifiers & Modifiers::FINAL ? 'final ' : '') + . ($modifiers & Modifiers::ABSTRACT ? 'abstract ' : '') + . ($modifiers & Modifiers::PUBLIC ? 'public ' : '') + . ($modifiers & Modifiers::PROTECTED ? 'protected ' : '') + . ($modifiers & Modifiers::PRIVATE ? 'private ' : '') + . ($modifiers & Modifiers::PUBLIC_SET ? 'public(set) ' : '') + . ($modifiers & Modifiers::PROTECTED_SET ? 'protected(set) ' : '') + . ($modifiers & Modifiers::PRIVATE_SET ? 'private(set) ' : '') + . ($modifiers & Modifiers::STATIC ? 'static ' : '') + . ($modifiers & Modifiers::READONLY ? 'readonly ' : ''); + } + + protected function pStatic(bool $static): string { + return $static ? 'static ' : ''; + } + + /** + * Determine whether a list of nodes uses multiline formatting. + * + * @param (Node|null)[] $nodes Node list + * + * @return bool Whether multiline formatting is used + */ + protected function isMultiline(array $nodes): bool { + if (\count($nodes) < 2) { + return false; + } + + $pos = -1; + foreach ($nodes as $node) { + if (null === $node) { + continue; + } + + $endPos = $node->getEndTokenPos() + 1; + if ($pos >= 0) { + $text = $this->origTokens->getTokenCode($pos, $endPos, 0); + if (false === strpos($text, "\n")) { + // We require that a newline is present between *every* item. If the formatting + // is inconsistent, with only some items having newlines, we don't consider it + // as multiline + return false; + } + } + $pos = $endPos; + } + + return true; + } + + /** + * Lazily initializes label char map. + * + * The label char map determines whether a certain character may occur in a label. + */ + protected function initializeLabelCharMap(): void { + if (isset($this->labelCharMap)) { + return; + } + + $this->labelCharMap = []; + for ($i = 0; $i < 256; $i++) { + $chr = chr($i); + $this->labelCharMap[$chr] = (bool) preg_match('/^[a-zA-Z0-9_\x80-\xff]$/', $chr); + } + + if ($this->phpVersion->allowsDelInIdentifiers()) { + $this->labelCharMap["\x7f"] = true; + } + } + + /** + * Lazily initializes node list differ. + * + * The node list differ is used to determine differences between two array subnodes. + */ + protected function initializeNodeListDiffer(): void { + if (isset($this->nodeListDiffer)) { + return; + } + + $this->nodeListDiffer = new Internal\Differ(function ($a, $b) { + if ($a instanceof Node && $b instanceof Node) { + return $a === $b->getAttribute('origNode'); + } + // Can happen for array destructuring + return $a === null && $b === null; + }); + } + + /** + * Lazily initializes fixup map. + * + * The fixup map is used to determine whether a certain subnode of a certain node may require + * some kind of "fixup" operation, e.g. the addition of parenthesis or braces. + */ + protected function initializeFixupMap(): void { + if (isset($this->fixupMap)) { + return; + } + + $this->fixupMap = [ + Expr\Instanceof_::class => [ + 'expr' => self::FIXUP_PREC_UNARY, + 'class' => self::FIXUP_NEW, + ], + Expr\Ternary::class => [ + 'cond' => self::FIXUP_PREC_LEFT, + 'else' => self::FIXUP_PREC_RIGHT, + ], + Expr\Yield_::class => ['value' => self::FIXUP_PREC_UNARY], + + Expr\FuncCall::class => ['name' => self::FIXUP_CALL_LHS], + Expr\StaticCall::class => ['class' => self::FIXUP_STATIC_DEREF_LHS], + Expr\ArrayDimFetch::class => ['var' => self::FIXUP_DEREF_LHS], + Expr\ClassConstFetch::class => [ + 'class' => self::FIXUP_STATIC_DEREF_LHS, + 'name' => self::FIXUP_BRACED_NAME, + ], + Expr\New_::class => ['class' => self::FIXUP_NEW], + Expr\MethodCall::class => [ + 'var' => self::FIXUP_DEREF_LHS, + 'name' => self::FIXUP_BRACED_NAME, + ], + Expr\NullsafeMethodCall::class => [ + 'var' => self::FIXUP_DEREF_LHS, + 'name' => self::FIXUP_BRACED_NAME, + ], + Expr\StaticPropertyFetch::class => [ + 'class' => self::FIXUP_STATIC_DEREF_LHS, + 'name' => self::FIXUP_VAR_BRACED_NAME, + ], + Expr\PropertyFetch::class => [ + 'var' => self::FIXUP_DEREF_LHS, + 'name' => self::FIXUP_BRACED_NAME, + ], + Expr\NullsafePropertyFetch::class => [ + 'var' => self::FIXUP_DEREF_LHS, + 'name' => self::FIXUP_BRACED_NAME, + ], + Scalar\InterpolatedString::class => [ + 'parts' => self::FIXUP_ENCAPSED, + ], + ]; + + $binaryOps = [ + BinaryOp\Pow::class, BinaryOp\Mul::class, BinaryOp\Div::class, BinaryOp\Mod::class, + BinaryOp\Plus::class, BinaryOp\Minus::class, BinaryOp\Concat::class, + BinaryOp\ShiftLeft::class, BinaryOp\ShiftRight::class, BinaryOp\Smaller::class, + BinaryOp\SmallerOrEqual::class, BinaryOp\Greater::class, BinaryOp\GreaterOrEqual::class, + BinaryOp\Equal::class, BinaryOp\NotEqual::class, BinaryOp\Identical::class, + BinaryOp\NotIdentical::class, BinaryOp\Spaceship::class, BinaryOp\BitwiseAnd::class, + BinaryOp\BitwiseXor::class, BinaryOp\BitwiseOr::class, BinaryOp\BooleanAnd::class, + BinaryOp\BooleanOr::class, BinaryOp\Coalesce::class, BinaryOp\LogicalAnd::class, + BinaryOp\LogicalXor::class, BinaryOp\LogicalOr::class, BinaryOp\Pipe::class, + ]; + foreach ($binaryOps as $binaryOp) { + $this->fixupMap[$binaryOp] = [ + 'left' => self::FIXUP_PREC_LEFT, + 'right' => self::FIXUP_PREC_RIGHT + ]; + } + + $prefixOps = [ + Expr\Clone_::class, Expr\BitwiseNot::class, Expr\BooleanNot::class, Expr\UnaryPlus::class, Expr\UnaryMinus::class, + Cast\Int_::class, Cast\Double::class, Cast\String_::class, Cast\Array_::class, + Cast\Object_::class, Cast\Bool_::class, Cast\Unset_::class, Expr\ErrorSuppress::class, + Expr\YieldFrom::class, Expr\Print_::class, Expr\Include_::class, + Expr\Assign::class, Expr\AssignRef::class, AssignOp\Plus::class, AssignOp\Minus::class, + AssignOp\Mul::class, AssignOp\Div::class, AssignOp\Concat::class, AssignOp\Mod::class, + AssignOp\BitwiseAnd::class, AssignOp\BitwiseOr::class, AssignOp\BitwiseXor::class, + AssignOp\ShiftLeft::class, AssignOp\ShiftRight::class, AssignOp\Pow::class, AssignOp\Coalesce::class, + Expr\ArrowFunction::class, Expr\Throw_::class, + ]; + foreach ($prefixOps as $prefixOp) { + $this->fixupMap[$prefixOp] = ['expr' => self::FIXUP_PREC_UNARY]; + } + } + + /** + * Lazily initializes the removal map. + * + * The removal map is used to determine which additional tokens should be removed when a + * certain node is replaced by null. + */ + protected function initializeRemovalMap(): void { + if (isset($this->removalMap)) { + return; + } + + $stripBoth = ['left' => \T_WHITESPACE, 'right' => \T_WHITESPACE]; + $stripLeft = ['left' => \T_WHITESPACE]; + $stripRight = ['right' => \T_WHITESPACE]; + $stripDoubleArrow = ['right' => \T_DOUBLE_ARROW]; + $stripColon = ['left' => ':']; + $stripEquals = ['left' => '=']; + $this->removalMap = [ + 'Expr_ArrayDimFetch->dim' => $stripBoth, + 'ArrayItem->key' => $stripDoubleArrow, + 'Expr_ArrowFunction->returnType' => $stripColon, + 'Expr_Closure->returnType' => $stripColon, + 'Expr_Exit->expr' => $stripBoth, + 'Expr_Ternary->if' => $stripBoth, + 'Expr_Yield->key' => $stripDoubleArrow, + 'Expr_Yield->value' => $stripBoth, + 'Param->type' => $stripRight, + 'Param->default' => $stripEquals, + 'Stmt_Break->num' => $stripBoth, + 'Stmt_Catch->var' => $stripLeft, + 'Stmt_ClassConst->type' => $stripRight, + 'Stmt_ClassMethod->returnType' => $stripColon, + 'Stmt_Class->extends' => ['left' => \T_EXTENDS], + 'Stmt_Enum->scalarType' => $stripColon, + 'Stmt_EnumCase->expr' => $stripEquals, + 'Expr_PrintableNewAnonClass->extends' => ['left' => \T_EXTENDS], + 'Stmt_Continue->num' => $stripBoth, + 'Stmt_Foreach->keyVar' => $stripDoubleArrow, + 'Stmt_Function->returnType' => $stripColon, + 'Stmt_If->else' => $stripLeft, + 'Stmt_Namespace->name' => $stripLeft, + 'Stmt_Property->type' => $stripRight, + 'PropertyItem->default' => $stripEquals, + 'Stmt_Return->expr' => $stripBoth, + 'Stmt_StaticVar->default' => $stripEquals, + 'Stmt_TraitUseAdaptation_Alias->newName' => $stripLeft, + 'Stmt_TryCatch->finally' => $stripLeft, + // 'Stmt_Case->cond': Replace with "default" + // 'Stmt_Class->name': Unclear what to do + // 'Stmt_Declare->stmts': Not a plain node + // 'Stmt_TraitUseAdaptation_Alias->newModifier': Not a plain node + ]; + } + + protected function initializeInsertionMap(): void { + if (isset($this->insertionMap)) { + return; + } + + // TODO: "yield" where both key and value are inserted doesn't work + // [$find, $beforeToken, $extraLeft, $extraRight] + $this->insertionMap = [ + 'Expr_ArrayDimFetch->dim' => ['[', false, null, null], + 'ArrayItem->key' => [null, false, null, ' => '], + 'Expr_ArrowFunction->returnType' => [')', false, ': ', null], + 'Expr_Closure->returnType' => [')', false, ': ', null], + 'Expr_Ternary->if' => ['?', false, ' ', ' '], + 'Expr_Yield->key' => [\T_YIELD, false, null, ' => '], + 'Expr_Yield->value' => [\T_YIELD, false, ' ', null], + 'Param->type' => [null, false, null, ' '], + 'Param->default' => [null, false, ' = ', null], + 'Stmt_Break->num' => [\T_BREAK, false, ' ', null], + 'Stmt_Catch->var' => [null, false, ' ', null], + 'Stmt_ClassMethod->returnType' => [')', false, ': ', null], + 'Stmt_ClassConst->type' => [\T_CONST, false, ' ', null], + 'Stmt_Class->extends' => [null, false, ' extends ', null], + 'Stmt_Enum->scalarType' => [null, false, ' : ', null], + 'Stmt_EnumCase->expr' => [null, false, ' = ', null], + 'Expr_PrintableNewAnonClass->extends' => [null, false, ' extends ', null], + 'Stmt_Continue->num' => [\T_CONTINUE, false, ' ', null], + 'Stmt_Foreach->keyVar' => [\T_AS, false, null, ' => '], + 'Stmt_Function->returnType' => [')', false, ': ', null], + 'Stmt_If->else' => [null, false, ' ', null], + 'Stmt_Namespace->name' => [\T_NAMESPACE, false, ' ', null], + 'Stmt_Property->type' => [\T_VARIABLE, true, null, ' '], + 'PropertyItem->default' => [null, false, ' = ', null], + 'Stmt_Return->expr' => [\T_RETURN, false, ' ', null], + 'Stmt_StaticVar->default' => [null, false, ' = ', null], + //'Stmt_TraitUseAdaptation_Alias->newName' => [T_AS, false, ' ', null], // TODO + 'Stmt_TryCatch->finally' => [null, false, ' ', null], + + // 'Expr_Exit->expr': Complicated due to optional () + // 'Stmt_Case->cond': Conversion from default to case + // 'Stmt_Class->name': Unclear + // 'Stmt_Declare->stmts': Not a proper node + // 'Stmt_TraitUseAdaptation_Alias->newModifier': Not a proper node + ]; + } + + protected function initializeListInsertionMap(): void { + if (isset($this->listInsertionMap)) { + return; + } + + $this->listInsertionMap = [ + // special + //'Expr_ShellExec->parts' => '', // TODO These need to be treated more carefully + //'Scalar_InterpolatedString->parts' => '', + Stmt\Catch_::class . '->types' => '|', + UnionType::class . '->types' => '|', + IntersectionType::class . '->types' => '&', + Stmt\If_::class . '->elseifs' => ' ', + Stmt\TryCatch::class . '->catches' => ' ', + + // comma-separated lists + Expr\Array_::class . '->items' => ', ', + Expr\ArrowFunction::class . '->params' => ', ', + Expr\Closure::class . '->params' => ', ', + Expr\Closure::class . '->uses' => ', ', + Expr\FuncCall::class . '->args' => ', ', + Expr\Isset_::class . '->vars' => ', ', + Expr\List_::class . '->items' => ', ', + Expr\MethodCall::class . '->args' => ', ', + Expr\NullsafeMethodCall::class . '->args' => ', ', + Expr\New_::class . '->args' => ', ', + PrintableNewAnonClassNode::class . '->args' => ', ', + Expr\StaticCall::class . '->args' => ', ', + Stmt\ClassConst::class . '->consts' => ', ', + Stmt\ClassMethod::class . '->params' => ', ', + Stmt\Class_::class . '->implements' => ', ', + Stmt\Enum_::class . '->implements' => ', ', + PrintableNewAnonClassNode::class . '->implements' => ', ', + Stmt\Const_::class . '->consts' => ', ', + Stmt\Declare_::class . '->declares' => ', ', + Stmt\Echo_::class . '->exprs' => ', ', + Stmt\For_::class . '->init' => ', ', + Stmt\For_::class . '->cond' => ', ', + Stmt\For_::class . '->loop' => ', ', + Stmt\Function_::class . '->params' => ', ', + Stmt\Global_::class . '->vars' => ', ', + Stmt\GroupUse::class . '->uses' => ', ', + Stmt\Interface_::class . '->extends' => ', ', + Expr\Match_::class . '->arms' => ', ', + Stmt\Property::class . '->props' => ', ', + Stmt\StaticVar::class . '->vars' => ', ', + Stmt\TraitUse::class . '->traits' => ', ', + Stmt\TraitUseAdaptation\Precedence::class . '->insteadof' => ', ', + Stmt\Unset_::class . '->vars' => ', ', + Stmt\UseUse::class . '->uses' => ', ', + MatchArm::class . '->conds' => ', ', + AttributeGroup::class . '->attrs' => ', ', + PropertyHook::class . '->params' => ', ', + + // statement lists + Expr\Closure::class . '->stmts' => "\n", + Stmt\Case_::class . '->stmts' => "\n", + Stmt\Catch_::class . '->stmts' => "\n", + Stmt\Class_::class . '->stmts' => "\n", + Stmt\Enum_::class . '->stmts' => "\n", + PrintableNewAnonClassNode::class . '->stmts' => "\n", + Stmt\Interface_::class . '->stmts' => "\n", + Stmt\Trait_::class . '->stmts' => "\n", + Stmt\ClassMethod::class . '->stmts' => "\n", + Stmt\Declare_::class . '->stmts' => "\n", + Stmt\Do_::class . '->stmts' => "\n", + Stmt\ElseIf_::class . '->stmts' => "\n", + Stmt\Else_::class . '->stmts' => "\n", + Stmt\Finally_::class . '->stmts' => "\n", + Stmt\Foreach_::class . '->stmts' => "\n", + Stmt\For_::class . '->stmts' => "\n", + Stmt\Function_::class . '->stmts' => "\n", + Stmt\If_::class . '->stmts' => "\n", + Stmt\Namespace_::class . '->stmts' => "\n", + Stmt\Block::class . '->stmts' => "\n", + + // Attribute groups + Stmt\Class_::class . '->attrGroups' => "\n", + Stmt\Enum_::class . '->attrGroups' => "\n", + Stmt\EnumCase::class . '->attrGroups' => "\n", + Stmt\Interface_::class . '->attrGroups' => "\n", + Stmt\Trait_::class . '->attrGroups' => "\n", + Stmt\Function_::class . '->attrGroups' => "\n", + Stmt\ClassMethod::class . '->attrGroups' => "\n", + Stmt\ClassConst::class . '->attrGroups' => "\n", + Stmt\Property::class . '->attrGroups' => "\n", + PrintableNewAnonClassNode::class . '->attrGroups' => ' ', + Expr\Closure::class . '->attrGroups' => ' ', + Expr\ArrowFunction::class . '->attrGroups' => ' ', + Param::class . '->attrGroups' => ' ', + PropertyHook::class . '->attrGroups' => ' ', + + Stmt\Switch_::class . '->cases' => "\n", + Stmt\TraitUse::class . '->adaptations' => "\n", + Stmt\TryCatch::class . '->stmts' => "\n", + Stmt\While_::class . '->stmts' => "\n", + PropertyHook::class . '->body' => "\n", + Stmt\Property::class . '->hooks' => "\n", + Param::class . '->hooks' => "\n", + + // dummy for top-level context + 'File->stmts' => "\n", + ]; + } + + protected function initializeEmptyListInsertionMap(): void { + if (isset($this->emptyListInsertionMap)) { + return; + } + + // TODO Insertion into empty statement lists. + + // [$find, $extraLeft, $extraRight] + $this->emptyListInsertionMap = [ + Expr\ArrowFunction::class . '->params' => ['(', '', ''], + Expr\Closure::class . '->uses' => [')', ' use (', ')'], + Expr\Closure::class . '->params' => ['(', '', ''], + Expr\FuncCall::class . '->args' => ['(', '', ''], + Expr\MethodCall::class . '->args' => ['(', '', ''], + Expr\NullsafeMethodCall::class . '->args' => ['(', '', ''], + Expr\New_::class . '->args' => ['(', '', ''], + PrintableNewAnonClassNode::class . '->args' => ['(', '', ''], + PrintableNewAnonClassNode::class . '->implements' => [null, ' implements ', ''], + Expr\StaticCall::class . '->args' => ['(', '', ''], + Stmt\Class_::class . '->implements' => [null, ' implements ', ''], + Stmt\Enum_::class . '->implements' => [null, ' implements ', ''], + Stmt\ClassMethod::class . '->params' => ['(', '', ''], + Stmt\Interface_::class . '->extends' => [null, ' extends ', ''], + Stmt\Function_::class . '->params' => ['(', '', ''], + Stmt\Interface_::class . '->attrGroups' => [null, '', "\n"], + Stmt\Class_::class . '->attrGroups' => [null, '', "\n"], + Stmt\ClassConst::class . '->attrGroups' => [null, '', "\n"], + Stmt\ClassMethod::class . '->attrGroups' => [null, '', "\n"], + Stmt\Function_::class . '->attrGroups' => [null, '', "\n"], + Stmt\Property::class . '->attrGroups' => [null, '', "\n"], + Stmt\Trait_::class . '->attrGroups' => [null, '', "\n"], + Expr\ArrowFunction::class . '->attrGroups' => [null, '', ' '], + Expr\Closure::class . '->attrGroups' => [null, '', ' '], + Stmt\Const_::class . '->attrGroups' => [null, '', "\n"], + PrintableNewAnonClassNode::class . '->attrGroups' => [\T_NEW, ' ', ''], + + /* These cannot be empty to start with: + * Expr_Isset->vars + * Stmt_Catch->types + * Stmt_Const->consts + * Stmt_ClassConst->consts + * Stmt_Declare->declares + * Stmt_Echo->exprs + * Stmt_Global->vars + * Stmt_GroupUse->uses + * Stmt_Property->props + * Stmt_StaticVar->vars + * Stmt_TraitUse->traits + * Stmt_TraitUseAdaptation_Precedence->insteadof + * Stmt_Unset->vars + * Stmt_Use->uses + * UnionType->types + */ + + /* TODO + * Stmt_If->elseifs + * Stmt_TryCatch->catches + * Expr_Array->items + * Expr_List->items + * Stmt_For->init + * Stmt_For->cond + * Stmt_For->loop + */ + ]; + } + + protected function initializeModifierChangeMap(): void { + if (isset($this->modifierChangeMap)) { + return; + } + + $this->modifierChangeMap = [ + Stmt\ClassConst::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_CONST], + Stmt\ClassMethod::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_FUNCTION], + Stmt\Class_::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_CLASS], + Stmt\Property::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_VARIABLE], + PrintableNewAnonClassNode::class . '->flags' => ['pModifiers', \T_NEW, \T_CLASS], + Param::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_VARIABLE], + PropertyHook::class . '->flags' => ['pModifiers', \T_WHITESPACE, \T_STRING], + Expr\Closure::class . '->static' => ['pStatic', \T_WHITESPACE, \T_FUNCTION], + Expr\ArrowFunction::class . '->static' => ['pStatic', \T_WHITESPACE, \T_FN], + //Stmt\TraitUseAdaptation\Alias::class . '->newModifier' => 0, // TODO + ]; + + // List of integer subnodes that are not modifiers: + // Expr_Include->type + // Stmt_GroupUse->type + // Stmt_Use->type + // UseItem->type + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/Token.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Token.php new file mode 100644 index 00000000..6683310f --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/Token.php @@ -0,0 +1,18 @@ +pos + \strlen($this->text); + } + + /** Get 1-based end line number of the token. */ + public function getEndLine(): int { + return $this->line + \substr_count($this->text, "\n"); + } +} diff --git a/upload/api/vendor/nikic/php-parser/lib/PhpParser/compatibility_tokens.php b/upload/api/vendor/nikic/php-parser/lib/PhpParser/compatibility_tokens.php new file mode 100644 index 00000000..ced038d4 --- /dev/null +++ b/upload/api/vendor/nikic/php-parser/lib/PhpParser/compatibility_tokens.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if ('cli' !== \PHP_SAPI) { + throw new Exception('This script must be run from the command line.'); +} + +/** + * Runs the Yaml lint command. + * + * @author Jan Schädlich + */ + +use Symfony\Component\Console\Application; +use Symfony\Component\Yaml\Command\LintCommand; + +function includeIfExists(string $file): bool +{ + return file_exists($file) && include $file; +} + +if ( + !includeIfExists(__DIR__ . '/../../../../autoload.php') && + !includeIfExists(__DIR__ . '/../../vendor/autoload.php') && + !includeIfExists(__DIR__ . '/../../../../../../vendor/autoload.php') +) { + fwrite(STDERR, 'Install dependencies using Composer.'.PHP_EOL); + exit(1); +} + +if (!class_exists(Application::class)) { + fwrite(STDERR, 'You need the "symfony/console" component in order to run the Yaml linter.'.PHP_EOL); + exit(1); +} + +$command = new LintCommand(); +if (method_exists($app = new Application(), 'addCommand')) { + $app->addCommand($command); +} else { + $app->add($command); +} +$app + ->setDefaultCommand($command->getName(), true) + ->run() +; diff --git a/upload/api/vendor/zircote/swagger-php/bin/openapi b/upload/api/vendor/zircote/swagger-php/bin/openapi new file mode 100755 index 00000000..1f35209e --- /dev/null +++ b/upload/api/vendor/zircote/swagger-php/bin/openapi @@ -0,0 +1,245 @@ +#!/usr/bin/env php + [], + 'output' => false, + 'format' => 'auto', + 'exclude' => [], + 'pattern' => '*.php', + 'bootstrap' => [], + 'help' => false, + 'debug' => false, + 'processor' => [], + 'version' => null, +]; +$aliases = [ + 'c' => 'config', + 'o' => 'output', + 'e' => 'exclude', + 'n' => 'pattern', + 'b' => 'bootstrap', + 'h' => 'help', + 'd' => 'debug', + 'p' => 'processor', + 'f' => 'format' +]; +$needsArgument = [ + 'config', + 'output', + 'format', + 'exclude', + 'pattern', + 'bootstrap', + 'processor', + 'version', +]; +$paths = []; +$error = false; + +try { + // Parse cli arguments + for ($i = 1; $i < $argc; $i++) { + $arg = $argv[$i]; + if (substr($arg, 0, 2) === '--') { // longopt + $option = substr($arg, 2); + } elseif ($arg[0] === '-') { // shortopt + if (array_key_exists(substr($arg, 1), $aliases)) { + $option = $aliases[$arg[1]]; + } else { + throw new Exception('Unknown option: "' . $arg . '"'); + } + } else { + $paths[] = $arg; + continue; + } + if (array_key_exists($option, $options) === false) { + throw new Exception('Unknown option: "' . $arg . '"'); + } + if (in_array($option, $needsArgument)) { + if (empty($argv[$i + 1]) || $argv[$i + 1][0] === '-') { + throw new Exception('Missing argument for "' . $arg . '"'); + } + if (is_array($options[$option])) { + $options[$option][] = $argv[$i + 1]; + } else { + $options[$option] = $argv[$i + 1]; + } + $i++; + } else { + $options[$option] = true; + } + } +} catch (\Exception $e) { + $error = $e->getMessage(); +} + +$logger = new ConsoleLogger($options['debug']); + +if (!$error && $options['bootstrap']) { + foreach ($options['bootstrap'] as $bootstrap) { + $filenames = glob($bootstrap); + if (false === $filenames) { + $error = 'Invalid `--bootstrap` value: "' . $bootstrap . '"'; + break; + } + foreach ($filenames as $filename) { + if ($options['debug']) { + $logger->debug('Bootstrapping: ' . $filename); + } + require_once($filename); + } + } +} +if (count($paths) === 0) { + $error = 'Specify at least one path.'; +} + +if ($options['help'] === false && $error) { + $logger->error('', ['prefix' => '']); + $logger->error($error); + // Show help + $options['help'] = true; +} +$defaultVersion = OpenApi::DEFAULT_VERSION; +if ($options['help']) { + $help = <<info($help); + exit(1); +} + +$errorTypes = [ + E_ERROR => 'Error', + E_WARNING => 'Warning', + E_PARSE => 'Parser error', + E_NOTICE => 'Notice', + E_DEPRECATED => 'Deprecated', + E_CORE_ERROR => 'Error(Core)', + E_CORE_WARNING => 'Warning(Core)', + E_COMPILE_ERROR => 'Error(compile)', + E_COMPILE_WARNING => 'Warning(Compile)', + E_RECOVERABLE_ERROR => 'Error(Recoverable)', + E_USER_ERROR => 'Error', + E_USER_WARNING => 'Warning', + E_USER_NOTICE => 'Notice', + E_USER_DEPRECATED => 'Deprecated', +]; +set_error_handler(function ($errno, $errstr, $file, $line) use ($errorTypes, $options, $logger) { + if (!(error_reporting() & $errno)) { + // This error code is not included in error_reporting + return; + } + $type = array_key_exists($errno, $errorTypes) ? $errorTypes[$errno] : 'Error'; + if ($type === 'Deprecated') { + $logger->info($errstr, ['prefix' => $type . ': ']); + } else { + $logger->error($errstr, ['prefix' => $type . ': ']); + } + + if ($options['debug']) { + $logger->info(' in '.$file.' on line '.$line); + } + if (substr($type, 0, 5) === 'Error') { + exit($errno); + } +}); + +set_exception_handler(function ($exception) use ($logger) { + $logger->error($exception); + exit($exception->getCode() ?: 1); +}); + +$exclude = null; +if ($options['exclude']) { + $exclude = $options['exclude']; + if (strpos($exclude[0], ',') !== false) { + $exploded = explode(',', $exclude[0]); + $logger->error('Comma-separated exclude paths are deprecated, use multiple --exclude statements: --exclude '.$exploded[0].' --exclude '.$exploded[1]); + $exclude[0] = array_shift($exploded); + $exclude = array_merge($exclude, $exploded); + } +} + +$pattern = "*.php"; +if ($options['pattern']) { + $pattern = $options['pattern']; +} + +$generator = new Generator($logger); +foreach ($options["processor"] as $processor) { + $class = '\OpenApi\Processors\\'.$processor; + if (class_exists($class)) { + $processor = new $class(); + } elseif (class_exists($processor)) { + $processor = new $processor(); + } + $generator->getProcessorPipeline()->add($processor); +} + +$analyser = new ReflectionAnalyser([ + new AttributeAnnotationFactory(), + new DocBlockAnnotationFactory(), +]); +$analyser->setGenerator($generator); + +$openapi = $generator + ->setVersion($options['version']) + ->setConfig($options['config']) + ->setAnalyser($analyser) + ->generate(Util::finder($paths, $exclude, $pattern)); + +if ($options['output'] === false) { + if (strtolower($options['format']) === 'json') { + echo $openapi->toJson(); + } else { + echo $openapi->toYaml(); + } + echo "\n"; +} else { + if (is_dir($options['output'])) { + $options['output'] .= '/openapi.yaml'; + } + $openapi->saveAs($options['output'], $options['format']); +} +exit($logger->loggedMessageAboveNotice() ? 1 : 0);