diff --git a/.ci/after-failure.sh b/.ci/after-failure.sh deleted file mode 100755 index bad9ec49d8..0000000000 --- a/.ci/after-failure.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash -# -# This file is part of the Zephir. -# -# (c) Phalcon Team -# -# For the full copyright and license information, please view -# the LICENSE file that was distributed with this source code. - -autoconf --version -echo "-------------------------------------------------------------------------" - -cc --version -echo "-------------------------------------------------------------------------" - -make --version -echo "-------------------------------------------------------------------------" - -re2c --version -echo "-------------------------------------------------------------------------" - -command -v php && (php -v; php -m) -echo "-------------------------------------------------------------------------" - -command -v php-config && (php-config || true) # php-config returns 1 -echo "-------------------------------------------------------------------------" - -command -v phpize && phpize --version -echo "-------------------------------------------------------------------------" - -ls -al "$(php-config --extension-dir)" -echo "-------------------------------------------------------------------------" - -if [ -f ./compile-errors.log ]; then - log_contents=$(cat ./compile-errors.log) - [[ -z "${log_contents// }" ]] || { - (>&1 echo "Compiler log:") - (>&1 printf "%s\\n" "$log_contents") - } -fi diff --git a/.ci/release-notes.sh b/.ci/release-notes.sh new file mode 100755 index 0000000000..1bf304eb52 --- /dev/null +++ b/.ci/release-notes.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# This file is part of the Zephir. +# +# (c) Zephir Team +# +# For the full copyright and license information, please view +# the LICENSE file that was distributed with this source code. + +# shellcheck disable=SC2002 + +# -e Exit immediately if a command exits with a non-zero status. +# -u Treat unset variables as an error when substituting. + +set -eu +set -o pipefail + +# Get Release notes for the latest release from CHANGELOG.md +# How to use: +# release-notes.sh CHANGELOG.md > ReleaseNotes.md + + +startline=$(cat "$1" | grep -nE '^### ' | head -n 1 | cut -d ":" -f 1) +finishline=$(($(cat "$1" | grep -nE '^## \[[0-9]+' | head -n 2 | tail -n 1 | cut -d ":" -f 1) - 1)) +changelog=$(sed -n "${startline},${finishline}p" "$1"); + +echo "${changelog}" diff --git a/.ci/run-tests.sh b/.ci/run-tests.sh deleted file mode 100755 index 0f472f3be0..0000000000 --- a/.ci/run-tests.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -# -# This file is part of the Zephir. -# -# (c) Phalcon Team -# -# For the full copyright and license information, please view -# the LICENSE file that was distributed with this source code. - -# -e Exit immediately if a command exits with a non-zero status. -# -u Treat unset variables as an error when substituting. -set -eu - -php \ - -d extension=ext/modules/stub.so \ - vendor/bin/phpunit \ - --bootstrap tests/ext-bootstrap.php \ - --testsuite Extension - -php \ - vendor/bin/phpunit \ - --colors=always \ - --testsuite Zephir diff --git a/.ci/vsenv.bat b/.ci/vsenv.bat deleted file mode 100644 index 1b7dd2fb0b..0000000000 --- a/.ci/vsenv.bat +++ /dev/null @@ -1,41 +0,0 @@ -@echo off -rem This file is part of the Zephir. -rem -rem (c) Phalcon Team -rem -rem For the full copyright and license information, please view -rem the LICENSE file that was distributed with this source code. -cls - -rem For more see: https://github.com/microsoft/vswhere/wiki/Find-VC -rem -rem For the software installed on GitHub-hosted runners see: -rem https://help.github.com/en/actions/automating-your-workflow-with-github-actions/software-installed-on-github-hosted-runners -rem -echo "Find VC..." -SET VSWHERE="C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere" - -for /f "usebackq tokens=*" %%i in (`%VSWHERE% -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do ( - set InstallDir=%%i -) - -if exist "%InstallDir%\Common7\Tools\vsdevcmd.bat" ( - echo "Found %InstallDir%\Common7\Tools\vsdevcmd.bat" - call "%InstallDir%\Common7\Tools\vsdevcmd.bat" %* -) else "VC not found" - -echo "------------- phpsdk-starter ---------------------------" -call "%PHP_SDK_PATH%\phpsdk-vs16-%PHP_ARCH%.bat" - -echo "------------- phpsdk_setvars ---------------------------" -call "%PHP_SDK_PATH%\bin\phpsdk_setvars.bat" - -rem Loop over all environment variables and make them global using set-env. -rem -rem See: https://help.github.com/en/articles/development-tools-for-github-actions#set-an-environment-variable-set-env -rem See: https://stackoverflow.com/questions/39183272/loop-through-all-environmental-variables-and-take-actions-depending-on-prefix -setlocal -for /f "delims== tokens=1,2" %%a in ('set') do ( - powershell -Command "& {Write-Output '%%a=%%b' | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append;}" -) -endlocal diff --git a/.ci/win-ci-tools.psm1 b/.ci/win-ci-tools.psm1 deleted file mode 100644 index c55fcdffe5..0000000000 --- a/.ci/win-ci-tools.psm1 +++ /dev/null @@ -1,382 +0,0 @@ -# This file is part of the Zephir. -# -# (c) Phalcon Team -# -# For the full copyright and license information, please view -# the LICENSE file that was distributed with this source code. - -function SetupCommonEnvironment { - <# - .SYNOPSIS - Creates common directories if not exists - #> - - $CommonPath = "C:\Downloads", "C:\Downloads\Choco" - - foreach ($path in $CommonPath) { - if (-not (Test-Path $path)) { - New-Item -ItemType Directory -Force -Path $path | Out-Null - } - } - - # Hide "You are in 'detached HEAD' state" message - git config --global advice.detachedHead false -} - -function InstallPhpSdk { - <# - .SYNOPSIS - Install PHP SDK binary tools from sources. - #> - - Write-Output "Install PHP SDK binary tools: ${env:PHP_SDK_VERSION}" - - $PhpSdk = "php-sdk-${env:PHP_SDK_VERSION}.zip" - $RemoteUrl = "https://github.com/microsoft/php-sdk-binary-tools/archive/${PhpSdk}" - $DestinationPath = "C:\Downloads\${PhpSdk}" - - if (-not (Test-Path $env:PHP_SDK_PATH)) { - if (-not [System.IO.File]::Exists($DestinationPath)) { - Write-Output "Downloading PHP SDK binary tools: $RemoteUrl ..." - DownloadFile $RemoteUrl $DestinationPath - } - - $DestinationUnzipPath = "${env:Temp}\php-sdk-binary-tools-php-sdk-${env:PHP_SDK_VERSION}" - - if (-not (Test-Path "$DestinationUnzipPath")) { - Expand-Item7zip $DestinationPath $env:Temp - } - - Move-Item -Path $DestinationUnzipPath -Destination $env:PHP_SDK_PATH - } -} - -function InstallPhpDevPack { - <# - .SYNOPSIS - Intstall PHP Developer pack from sources. - #> - - Write-Output "Install PHP Dev pack: ${env:PHP_VERSION}" - - $TS = Get-ThreadSafety - - $BaseUrl = "http://windows.php.net/downloads/releases" - $DevPack = "php-devel-pack-${env:PHP_VERSION}${TS}-Win32-vc${env:VC_VERSION}-${env:PHP_ARCH}.zip" - - $RemoteUrl = "${BaseUrl}/${DevPack}" - $RemoteArchiveUrl = "${BaseUrl}/archives/${DevPack}" - $DestinationPath = "C:\Downloads\php-devel-pack-${env:PHP_VERSION}${TS}-VC${env:VC_VERSION}-${env:PHP_ARCH}.zip" - - if (-not (Test-Path $env:PHP_DEVPACK)) { - if (-not [System.IO.File]::Exists($DestinationPath)) { - DownloadFileUsingAlternative -RemoteUrl $RemoteUrl ` - -RemoteArchiveUrl $RemoteArchiveUrl ` - -DestinationPath $DestinationPath ` - -Message "Downloading PHP Dev pack" - } - - $DestinationUnzipPath = "${env:Temp}\php-${env:PHP_VERSION}-devel-VC${env:VC_VERSION}-${env:PHP_ARCH}" - - if (-not (Test-Path "$DestinationUnzipPath")) { - Expand-Item7zip $DestinationPath $env:Temp - } - - Move-Item -Path $DestinationUnzipPath -Destination $env:PHP_DEVPACK - } -} - -function InstallZephirParser { - <# - .SYNOPSIS - Download and install Zephir parser PHP extension - #> - - $BaseUri = "https://github.com/zephir-lang/php-zephir-parser/releases/download" - $LocalPart = "zephir-parser-php-${env:PHP_MINOR}-${env:BUILD_TYPE}-win32-vc${env:VC_VERSION}-${env:PHP_ARCH}.zip" - - $RemoteUrl = "${BaseUri}/v${env:PARSER_VERSION}/${LocalPart}" - $DestinationPath = "C:\Downloads\${LocalPart}" - - if (-not (Test-Path "${env:PHPROOT}\ext\php_zephir_parser.dll")) { - if (-not [System.IO.File]::Exists($DestinationPath)) { - Write-Output "Downloading Zephir Parser: ${RemoteUrl} ..." - DownloadFile $RemoteUrl $DestinationPath - } - - Expand-Item7zip $DestinationPath "${env:PHPROOT}\ext" - } -} - -function Get-ThreadSafety { - <# - .SYNOPSIS - Detects if Build is Thread Safety or not and returns `ts` suffix. - #> - - if ($env:BUILD_TYPE -Match "nts") { - return "-nts" - } - - return [string]::Empty -} - - -function Expand-Item7zip { - <# - .SYNOPSIS - Extracts ZIP archives to specified directory - #> - - param( - [Parameter(Mandatory = $true)] [System.String] $Archive, - [Parameter(Mandatory = $true)] [System.String] $Destination - ) - - if (-not (Test-Path -Path $Archive -PathType Leaf)) { - throw "Specified archive File is invalid: [$Archive]" - } - - if (-not (Test-Path -Path $Destination -PathType Container)) { - New-Item $Destination -ItemType Directory | Out-Null - } - - $Result = (& 7z x "$Archive" "-o$Destination" -aoa -bd -y -r) - - if ($LastExitCode -ne 0) { - Write-Output "An error occurred while unzipping [$Archive] to [$Destination]. Error code was: ${LastExitCode}" - Exit $LastExitCode - } -} - -function DownloadFileUsingAlternative { - <# - .SYNOPSIS - Downloads files from URL using alternative ULR if primary URL not found - #> - - [CmdletBinding()] - param( - [parameter(Mandatory = $true, ValueFromPipeline = $true)] [ValidateNotNullOrEmpty()] [System.String] $RemoteUrl, - [parameter(Mandatory = $true, ValueFromPipeline = $true)] [ValidateNotNullOrEmpty()] [System.String] $RemoteArchiveUrl, - [parameter(Mandatory = $true, ValueFromPipeline = $true)] [ValidateNotNullOrEmpty()] [System.String] $DestinationPath, - [parameter(Mandatory = $true, ValueFromPipeline = $true)] [ValidateNotNullOrEmpty()] [System.String] $Message - ) - - process { - try { - Write-Output "${Message}: ${RemoteUrl} ..." - DownloadFile $RemoteUrl $DestinationPath - } catch [System.Net.WebException] { - Write-Output "${Message} from archive: ${RemoteArchiveUrl} ..." - DownloadFile $RemoteArchiveUrl $DestinationPath - } - } -} - -function DownloadFile { - <# - .SYNOPSIS - Downloads file from providing URL to specified destionation. - - .NOTES - Throws System.Net.WebException if $RequestUrl not found. - #> - - [CmdletBinding()] - param( - [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $RemoteUrl, - [parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $DestinationPath - ) - - process { - $RetryMax = 5 - $RetryCount = 0 - $Completed = $false - - $WebClient = New-Object System.Net.WebClient - $WebClient.Headers.Add('User-Agent', 'GitHub Actions PowerShell Script') - - while (-not $Completed -or $RetryCount -eq $RetryMax) { - try { - $WebClient.DownloadFile($RemoteUrl, $DestinationPath) - $Completed = $true - } catch [System.Net.WebException] { - $ErrorMessage = $_.Exception.Message - - if ($_.Exception.Response.StatusCode -eq 404) { - Write-Warning -Message "Error downloading ${RemoteUrl}: $ErrorMessage" - throw [System.Net.WebException] "Error downloading ${RemoteUrl}" - } - - if ($RetryCount -ge $RetryMax) { - Write-Output "Error downloading ${RemoteUrl}: $ErrorMessage" - $Completed = $true - } else { - $RetryCount++ - } - } - } - } -} - -function PrintLogs { - <# - .SYNOPSIS - Prints logs files details. - #> - - $Logs = "${env:GITHUB_WORKSPACE}\compile-errors.log", - "${env:GITHUB_WORKSPACE}\compile.log", - "${env:GITHUB_WORKSPACE}\ext\configure.js" - - foreach ($logFile in $Logs) { - if (Test-Path -Path $logFile) { - Get-Content -Path $logFile - } - } -} - -function PrintEnvVars { - <# - .SYNOPSIS - Prints environment variables. - #> - - Write-Output ($env:Path).Replace(';', "`n") - Get-ChildItem env: -} - -function PrintDirectoriesContent { - <# - .SYNOPSIS - Prints Builds, Release, Projects, Downloads and Extensions directories contents. - #> - - Get-ChildItem -Path "${env:GITHUB_WORKSPACE}" - - $Directories = "C:\Downloads", - "C:\Projects", - "${env:PHPROOT}\ext" - - if ("${env:RELEASE_DLL_PATH}") { - # Might be empty - $ReleasePath = Split-Path -Path "${env:RELEASE_DLL_PATH}" - $BuildPath = Split-Path -Path "${ReleasePath}" - - $Directories.Add($ReleasePath) - $Directories.Add($BuildPath) - } - - foreach ($dir in $Directories) { - if (Test-Path -Path $dir) { - Get-ChildItem -Path $dir - } - } -} - -# TODO(klay): Add phpize and phpconfig here -function PrintPhpInfo { - <# - .SYNOPSIS - Prints PHP info. - #> - - $IniFile = "${env:PHPROOT}\php.ini" - $PhpExe = "${env:PHPROOT}\php.exe" - - if (Test-Path -Path "${PhpExe}") { - Write-Output "" - & "${PhpExe}" -v - - Write-Output "" - & "${PhpExe}" -m - - Write-Output "" - & "${PhpExe}" -i - } elseif (Test-Path -Path "${IniFile}") { - Get-Content -Path "${IniFile}" - } -} - -function PrintBuildDetails { - <# - .SYNOPSIS - Prints various Build details information. - #> - - $BuildDate = Get-Date -Format g - - Write-Output "Build date: ${BuildDate}" - Write-Output "Build Worker Image Version: ${env:ImageVersion}" - Write-Output "Build Type: ${env:BUILD_TYPE}" - Write-Output "Git commit: ${env:GITHUB_SHA}" - Write-Output "Target PHP version: ${env:PHP_MINOR}" - Write-Output "PHP SDK Toolset Version: ${env:PHP_SDK_VC_TOOLSET_VER}" - Write-Output "Processor ID: ${env:PROCESSOR_IDENTIFIER}" - Write-Output "Processor Architecture: ${env:PROCESSOR_ARCHITECTURE}" - Write-Output "Number of Processors: ${env:NUMBER_OF_PROCESSORS}" - Write-Output "Visual Studio Version: ${env:VisualStudioVersion}" - Write-Output "Host Architecture: ${env:VSCMD_ARG_HOST_ARCH}" - Write-Output "Target Architecture: ${env:VSCMD_ARG_TGT_ARCH}" - Write-Output "VC Tools Version: ${env:VCToolsVersion}" - Write-Output "Windows SDK Version: ${env:WindowsSDKVersion}" -} - - -function InitializeReleaseVars { - <# - .SYNOPSIS - Configures Environment variables for Release build. - #> - - if ($env:BUILD_TYPE -Match "nts") { - $env:RELEASE_ZIPBALL = "${env:PACKAGE_PREFIX}_${env:PHP_ARCH}_vc${env:VC_VERSION}_php${env:PHP_MINOR}_nts" - - if ($env:PHP_ARCH -eq 'x86') { - $env:RELEASE_FOLDER = "Release" - } else { - $env:RELEASE_FOLDER = "x64\Release" - } - } else { - $env:RELEASE_ZIPBALL = "${env:PACKAGE_PREFIX}_${env:PHP_ARCH}_vc${env:VC_VERSION}_php${env:PHP_MINOR}" - - if ($env:PHP_ARCH -eq 'x86') { - $env:RELEASE_FOLDER = "Release_TS" - } else { - $env:RELEASE_FOLDER = "x64\Release_TS" - } - } - - $env:RELEASE_DLL_PATH = "${env:GITHUB_WORKSPACE}\ext\${env:RELEASE_FOLDER}\${env:EXTENSION_FILE}" - - Write-Output "RELEASE_ZIPBALL=${env:RELEASE_ZIPBALL}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - Write-Output "RELEASE_DLL_PATH=${env:RELEASE_DLL_PATH}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append -} - -function EnableTestExtension { - <# - .SYNOPSIS - Enables PHP Extension. - #> - - if (-not (Test-Path env:RELEASE_DLL_PATH)) { - InitializeReleaseVars - } - - if (-not (Test-Path "${env:RELEASE_DLL_PATH}")) { - throw "Unable to locate extension path: ${env:RELEASE_DLL_PATH}" - } - - Copy-Item "${env:RELEASE_DLL_PATH}" "${env:PHPROOT}\ext\${env:EXTENSION_FILE}" - - # TODO(klay): Sort out with this: - # - # Multiple extensions match the name (or handle) "test": - # - handle: test version 1.0.0 - # - handle: test version 0.1.0 - # You can filter the extension to enable by adding :version to the -Extension parameter - # (example: "-Extension 'test:0.1.0'") - # - Enable-PhpExtension -Extension "${env:EXTENSION_NAME}:1.0.0" -Path "${env:PHPROOT}" -} diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml deleted file mode 100644 index ab3b0a5041..0000000000 --- a/.github/workflows/analysis.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Static Code Analysis - -on: - push: - paths-ignore: - - '**.md' - - '**.txt' - pull_request: - branches: - - master - - develoment - -jobs: - analysis: - runs-on: ubuntu-18.04 - - steps: - - name: Checkout Code - uses: actions/checkout@v2 - with: - fetch-depth: 1 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '7.4' - coverage: none - tools: php-cs-fixer, phpcs - - - name: Run PHP_CodeSniffer - run: | - phpcs --version - phpcs --runtime-set ignore_warnings_on_exit true - - - name: Run PHP CS Fixer - if: always() - run: | - php-cs-fixer --version - php-cs-fixer fix --diff --dry-run -v || true - - - name: Run Shell Check - if: always() - run: shellcheck .ci/*.sh diff --git a/.github/workflows/build-linux-ext/action.yml b/.github/workflows/build-linux-ext/action.yml new file mode 100644 index 0000000000..68c66ca96c --- /dev/null +++ b/.github/workflows/build-linux-ext/action.yml @@ -0,0 +1,61 @@ +name: 'Zephir Stub PHP Extension Build' +description: 'Build Stub extension for Linux according to various php versions.' +inputs: + compiler: + description: 'compiler name' + required: false + default: 'gcc' + cflags: + description: 'CFLAGS for GCC compiler' + required: false + default: '' + ldflags: + description: 'LDFLAGS for Linker' + required: false + default: '' + +runs: + using: 'composite' + steps: + - name: Setup Prerequisites + shell: bash + run: | + echo "::group::Remove APT Microsoft Sources list" + # We don't need this at all, and our + # builds often fails because Microsoft + # servers are unstable or even offline. + sudo rm -f /etc/apt/sources.list.d/dotnetdev.list + sudo rm -f /etc/apt/sources.list.d/azure*.list + echo "::endgroup::" + + echo "::group::Install dependencies" + sudo apt-get update --quiet --yes 1>/dev/null + sudo apt-get install --no-install-recommends -q -y re2c + echo "::endgroup::" + + - name: Compile Stub Extension + shell: bash + run: | + echo "::group::Configure compiler" + CC=${{ inputs.compiler }} + CFLAGS="${{ inputs.cflags }}" + CXXFLAGS="${{ inputs.cflags }}" + LDFLAGS="${{ inputs.ldflags }}" + + export CC CFLAGS CXXFLAGS LDFLAGS + echo "::endgroup::" + + echo "::group::Init stage" + php zephir fullclean + echo "::endgroup::" + + echo "::group::Generate stage" + php zephir generate + echo "::endgroup::" + + echo "::group::Compile stage" + cd ./ext + phpize + ./configure --enable-stub CFLAGS="${{ inputs.cflags }}" CXXFLAGS="${{ inputs.cflags }}" LDFLAGS="${{ inputs.ldflags }}" + make + echo "::endgroup::" diff --git a/.github/workflows/build-macos-ext/action.yml b/.github/workflows/build-macos-ext/action.yml new file mode 100644 index 0000000000..c530e117b4 --- /dev/null +++ b/.github/workflows/build-macos-ext/action.yml @@ -0,0 +1,53 @@ +name: 'Zephir Stub PHP Extension Build' +description: 'Build Stub extension for macOS according to various php versions.' +inputs: + compiler: + description: 'compiler name' + required: false + default: 'clang' + cflags: + description: 'CFLAGS for GCC compiler' + required: false + default: '' + ldflags: + description: 'LDFLAGS for Linker' + required: false + default: '' + +runs: + using: 'composite' + steps: + - name: Setup Prerequisites + shell: bash + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + run: | + echo "::group::Install dependencies" + brew install re2c + echo "::endgroup::" + + - name: Compile Stub Extension + shell: bash + run: | + echo "::group::Configure compiler" + CFLAGS="${{ inputs.cflags }}" + CXXFLAGS="${{ inputs.cflags }}" + LDFLAGS="${{ inputs.ldflags }}" + + export CFLAGS CXXFLAGS LDFLAGS + echo "::endgroup::" + + echo "::group::Init stage" + php zephir fullclean + echo "::endgroup::" + + echo "::group::Generate stage" + php zephir generate + echo "::endgroup::" + + echo "::group::Compile stage" + cd ./ext + phpize + ./configure --enable-stub CFLAGS="${{ inputs.cflags }}" CXXFLAGS="${{ inputs.cflags }}" LDFLAGS="${{ inputs.ldflags }}" + make + echo "::endgroup::" diff --git a/.github/workflows/build-unix.yml b/.github/workflows/build-unix.yml deleted file mode 100644 index cb90141c32..0000000000 --- a/.github/workflows/build-unix.yml +++ /dev/null @@ -1,186 +0,0 @@ -name: Unix CI - -on: - push: - paths-ignore: - - '**.md' - - '**.txt' - pull_request: - branches: - - master - - development - -env: - ZEPHIR_PARSER_VERSION: 1.4.1 - -jobs: - linux: - # To prevent build a particular commit use - # git commit -m "......... [ci skip]" - if: "!contains(github.event.head_commit.message, '[ci skip]')" - - name: "${{ matrix.os }}: PHP v${{ matrix.php }}" - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - - matrix: - os: - - ubuntu-18.04 - # - macos-latest - - php: - - '7.4' - - '8.0' - - steps: - - name: Setup Prerequisites - run: | - # We don't need this at all, and our - # builds often fails because Microsoft - # servers are unstable or even offline. - sudo rm -f /etc/apt/sources.list.d/dotnetdev.list - sudo rm -f /etc/apt/sources.list.d/azure*.list - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: gmp, pdo_sqlite, psr, zip, zephir_parser-${{ env.ZEPHIR_PARSER_VERSION }} - tools: phpize, php-config - coverage: xdebug - # variables_order: https://github.com/zephir-lang/zephir/pull/1537 - # enable_dl: https://github.com/zephir-lang/zephir/pull/1654 - # allow_url_fopen: https://github.com/zephir-lang/zephir/issues/1713 - # error_reporting: https://github.com/zendframework/zend-code/issues/160 - ini-values: >- - variables_order=EGPCS, - enable_dl=On, - allow_url_fopen=On, - error_reporting=-1, - memory_limit=1G, - date.timezone=UTC, - xdebug.max_nesting_level=256 - env: - COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Checkout Code - uses: actions/checkout@v2 - with: - fetch-depth: 5 - - - name: Common Settings - run: | - # Core dump settings - ulimit -c unlimited -S || true - - # Hide "You are in 'detached HEAD' state" message - git config --global advice.detachedHead false - - # Will be used before as a cache key - export CPUHASH="$(cat /proc/cpuinfo | grep "model name" | head -n 1 | cut -d':' -f2 | md5sum)" - - - name: Setup APT Repositories - if: startsWith(runner.os, 'Linux') - run: | - # We don't need this at all, and our - # builds often fails because Microsoft - # servers are unstable or even offline. - sudo rm -f /etc/apt/sources.list.d/dotnetdev.list - sudo rm -f /etc/apt/sources.list.d/azure*.list - - # - name: Install System Dependencies (macOS) - # if: startsWith(runner.os, 'macOS') - # run: brew install re2c - - - name: Install System Dependencies (Linux) - if: startsWith(runner.os, 'Linux') - run: | - sudo apt-get update --quiet --yes 1>/dev/null - sudo apt-get install --no-install-recommends -q -y re2c - - - name: Get Composer Cache Directory - id: composer-cache - run: echo ::set-output name=dir::$(composer config cache-files-dir) - - - name: Setup Composer Cache - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Install Project Dependencies for PHP - run: composer install --prefer-dist --no-interaction --no-ansi --no-progress - - - name: Prepare Zephir Executable - run: sudo ln -s "$(pwd)/zephir" /usr/local/bin/zephir - - - name: Fast Commands Test - run: | - zephir --help - zephir clean - zephir fullclean - zephir generate - zephir stubs - zephir api - - # - name: Compile Test Project (macOS) - # if: startsWith(runner.os, 'macOS') - # run: | - # # These variables are needed to produce non optimized code - # CFLAGS="-O0 -g" - # CXXFLAGS="-O0 -g" - - # # Export variables in the subshell to not shadow global variables - # ( export CFLAGS CXXFLAGS; zephir compile ) || false - - - name: Compile Stub Project (Linux) - if: startsWith(runner.os, 'Linux') - run: | - # These variables are needed to produce non optimized code as well as for code coverage - LDFLAGS="--coverage" - CFLAGS="-O0 -ggdb -fprofile-arcs -ftest-coverage" - CXXFLAGS="-O0 -ggdb -fprofile-arcs -ftest-coverage" - - # Export variables in the subshell to not shadow global variables - ( export LDFLAGS CFLAGS CXXFLAGS; zephir fullclean && zephir generate && cd ext/ && ./install ) || false - - - name: Setup Problem Matchers for PHPUnit - run: echo ::add-matcher::${{ runner.tool_cache }}/phpunit.json - - - name: Unit Testing - Extension - if: always() - run: | - php \ - -d extension=ext/modules/stub.so \ - vendor/bin/phpunit \ - --colors=always \ - --bootstrap tests/ext-bootstrap.php \ - --testsuite Extension - - - name: Unit Testing - Zephir - if: always() - run: vendor/bin/phpunit --colors=always --testsuite Zephir - - - name: Black-box Testing - if: always() - run: cd tests/sharness && PHP=$(which php) make - - - name: After Failure - if: failure() - run: .ci/after-failure.sh - - - name: Upload Code Coverage Report - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - name: codecov-umbrella - flags: unittests - fail_ci_if_error: false - - - name: Success Reporting - if: success() - run: git log --format=fuller -5 diff --git a/.github/workflows/build-win-ext/action.yml b/.github/workflows/build-win-ext/action.yml new file mode 100644 index 0000000000..bb8601d409 --- /dev/null +++ b/.github/workflows/build-win-ext/action.yml @@ -0,0 +1,145 @@ +name: 'Zephir Stub PHP Extension Build' +description: 'Build Stub extension for Windows according to various php versions.' + +inputs: + php_version: + description: 'PHP version to build for (e.g: 7.4, 8.0)' + required: true + ts: + description: 'Thread Safety' + required: false + default: 'nts' + msvc: + description: 'Microsoft Visual C++ compiler toolset prefix (e.g: vc14, vs15, vs16)' + required: true + arch: + description: 'Target architecture (x64, x86)' + required: false + default: 'x64' + install_dir: + description: 'Target directory for php-sdk tools installation (e.g: C:\tools)' + required: false + default: 'C:\tools' + cflags: + description: 'CFLAGS for MSVC compiler' + required: false + default: '' + ldflags: + description: 'LDFLAGS for Linker' + required: false + default: '' + +runs: + using: 'composite' + steps: + - name: Setup Downloads Cache + uses: actions/cache@v2 + with: + path: ${{ env.CACHE_DIR }} + key: ${{ runner.os }}-downloads-${{ hashFiles('**/.github/workflows/build-win-ext/actions.yml') }} + restore-keys: | + ${{ runner.os }}-downloads-${{ env.cache-name }}- + ${{ runner.os }}-downloads- + ${{ runner.os }} + + - name: Setup Prerequisites + shell: powershell + run: | + Write-Output "::group::Install dependencies" + mkdir ${{ env.CACHE_DIR }}\Choco + choco install --no-progress -y --cache-location=${{ env.CACHE_DIR }}\Choco re2c + Write-Output "::endgroup::" + + Write-Output "Install PowerShell PHP Manager module" + if (Get-Module -ListAvailable -Name PhpManager) { + Write-Host "PhpManager powershell module exist, skip install" + } else { + Install-Module -Name PhpManager -Repository PSGallery -Force + } + Write-Output "::endgroup::" + + - name: Setup PHP SDK tool kit + uses: zephir-lang/setup-php-sdk@v1 + with: + php_version: ${{ inputs.php_version }} + ts: ${{ inputs.ts }} + msvc: ${{ inputs.msvc }} + arch: ${{ inputs.arch }} + install_dir: ${{ inputs.install_dir }} + cache_dir: ${{ env.CACHE_DIR }} + + - name: Configure Developer Command Prompt for MSVC compiler + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: ${{ inputs.arch }} + + - name: Generate C code + shell: powershell + run: | + Write-Output "::group::Zephir generate" + php zephir generate + Write-Output "::endgroup::" + + - name: PHPIZE + shell: powershell + working-directory: ext + run: phpize + + - name: Configure + shell: powershell + working-directory: ext + run: | + Write-Output "::group::Configure" + .\configure.bat --enable-stub --with-prefix=${{ env.PHP_ROOT }} ` + CFLAGS="${{ inputs.cflags }}" CXXFLAGS="${{ inputs.cflags }}" LDFLAGS="${{ inputs.ldflags }}" + Write-Output "::endgroup::" + + - name: Zephir compile + shell: powershell + run: php zephir compile ` + -Wnonexistent-function ` + -Wnonexistent-class ` + -Wunused-variable ` + -Wnonexistent-constant ` + -Wunreachable-code ` + -Wnot-supported-magic-constant ` + -Wnon-valid-decrement + + - name: Compile + shell: powershell + working-directory: ext + run: nmake 1> ..\compile.log + + - name: Install Extension + shell: powershell + working-directory: ext + run: | + $ReleaseFolder = if ("${{ inputs.ts }}" -eq "ts") { "Release_TS" } else { "Release" } + $ReleaseFolder = if ("${{ inputs.arch }}" -eq "x64") { "x64\${ReleaseFolder}" } else { "${ReleaseFolder}" } + + $DllPath = "${env:GITHUB_WORKSPACE}\ext\${ReleaseFolder}\php_stub.dll" + + Write-Output "DLL_PATH=${DllPath}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + Copy-Item -Path "${DllPath}" -Destination "${{ env.PHP_ROOT }}\ext\" + Enable-PhpExtension -Extension 'stub' -Path "${{ env.PHP_ROOT }}" + + - name: Check Stub Extension after build + shell: powershell + run: | + Write-Output "::group::PHP path" + Get-Php (Get-Command php).Path + Write-Output "::endgroup::" + + Write-Output "::group::PHP Extension directory" + dir ${{ env.PHP_ROOT }}\ext + Write-Output "::endgroup::" + + Write-Output "::group::PHP ini" + php --ini + Write-Output "::endgroup::" + + Write-Output "::group::Extensions in PHP ini" + php -r "echo php_ini_loaded_file();" + (cat $(php -r "echo php_ini_loaded_file();") | Select-String -Pattern "^;?extension(\s+)?=").Line + Write-Output "::endgroup::" diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml deleted file mode 100644 index 1cfb1619a2..0000000000 --- a/.github/workflows/build-windows.yml +++ /dev/null @@ -1,223 +0,0 @@ -name: Windows CI - -on: - push: - branches: - - development - paths-ignore: - - '**.md' - - '**.txt' - pull_request: - branches: - - master - - development - -env: - PARSER_VERSION: 1.4.1 - PARSER_RELEASE: 559 - PHP_SDK_VERSION: 2.2.0 - PHP_DEVPACK: C:\tools\php-devpack - PHP_SDK_PATH: C:\tools\php-sdk - PACKAGE_PREFIX: stub - EXTENSION_NAME: stub - EXTENSION_FILE: php_stub.dll - -jobs: - windows: - name: "Windows: PHP v${{ matrix.php }}" - runs-on: windows-2016 - - strategy: - fail-fast: false - - matrix: - php: - - '7.4' - #- '8.0' - - include: - - php: '7.4' - vc_num: '15' - arch: x64 - build_type: nts - - #- php: '8.0' - # vc_num: '15' - # arch: x64 - # build_type: nts - - steps: - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: mbstring, fileinfo, gmp, sqlite, pdo_sqlite, psr, zip, mysqli - coverage: none - # variables_order: https://github.com/zephir-lang/zephir/pull/1537 - # enable_dl: https://github.com/zephir-lang/zephir/pull/1654 - # allow_url_fopen: https://github.com/zephir-lang/zephir/issues/1713 - # error_reporting: https://github.com/zendframework/zend-code/issues/160 - ini-values: >- - variables_order=EGPCS, - enable_dl=On, - allow_url_fopen=On, - error_reporting=-1, - memory_limit=1G, - date.timezone=UTC, - xdebug.max_nesting_level=256 - env: - PHPTS: ${{ matrix.build_type }} - COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Set Environment Variables - run: | - Write-Output "PHP_VERSION=$(php -r 'echo phpversion();')" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - Write-Output "PHP_MINOR=${{ matrix.php }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - Write-Output "TEST_PHP_EXECUTABLE=${env:PHPROOT}\php.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - Write-Output "BUILD_TYPE=${{ matrix.build_type }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - Write-Output "VC_VERSION=${{ matrix.vc_num }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - Write-Output "PHP_ARCH=${{ matrix.arch }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - - name: Checkout Code - uses: actions/checkout@v2 - with: - fetch-depth: 1 - - - name: Setup Downloads Cache - uses: actions/cache@v1 - with: - path: C:\Downloads - key: ${{ runner.os }}-downloads-${{ hashFiles('**/.github/workflows/build-windows.yml') }} - restore-keys: | - ${{ runner.os }}-downloads-${{ env.cache-name }}- - ${{ runner.os }}-downloads- - ${{ runner.os }} - - - name: Setup Common Environmet - run: | - Import-Module .\.ci\win-ci-tools.psm1 - SetupCommonEnvironment - - - name: Install PHP SDK Binary Tools - run: | - Import-Module .\.ci\win-ci-tools.psm1 - InstallPhpSdk - - - name: Install PHP Dev pack - run: | - Import-Module .\.ci\win-ci-tools.psm1 - InstallPhpDevPack - - - name: Getting Details About Installed PHP - run: Get-Php "${env:PHPROOT}" - - - name: Install System Dependencies - run: choco install -y --cache-location=C:\Downloads\Choco re2c - - - name: Install Zephir Parser - run: | - Import-Module .\.ci\win-ci-tools.psm1 - InstallZephirParser - - - name: Enable Zephir Parser - run: Enable-PhpExtension -Extension zephir_parser -Path "${env:PHPROOT}" - - - name: Minimal Zephir Parser Load Test - run: php --ri zephir_parser - - - name: "Setup Visual Studio Command Line for PHP SDK ${{ matrix.arch }}" - run: .ci\vsenv.bat -arch=${{ matrix.arch }} -host_arch=${{ matrix.arch }} - - - name: Fix Environment Variables - shell: powershell - run: | - $v = "${env:WindowsSDKVersion}" -replace '\\$', '' - Write-Output "WindowsSDKVersion=$v" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - $v = "${env:WindowsSDKLibVersion}" -replace '\\$', '' - Write-Output "WindowsSDKLibVersion=$v" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Setup Composer Cache - uses: actions/cache@v1 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Install Project Dependencies - run: composer install --prefer-dist --no-interaction --no-ansi --no-progress - - - name: Initialize Release Variables - run: | - Import-Module .\.ci\win-ci-tools.psm1 - InitializeReleaseVars - - - name: Fast Commands Test - # TODO(klay): Enable all commands - run: | - .\zephir.bat --help - # .\zephir.bat clean - # .\zephir.bat fullclean - # .\zephir.bat generate - # .\zephir.bat stubs - # .\zephir.bat api - - - name: Compile Stub Project - run: | - .\zephir.bat generate - .\zephir.bat compile ` - -Wnonexistent-function ` - -Wnonexistent-class ` - -Wunused-variable ` - -Wnonexistent-constant ` - -Wunreachable-code ` - -Wnot-supported-magic-constant ` - -Wnon-valid-decrement - - - name: Make Stub Extension - shell: cmd - run: | - cd ext - nmake 2> "%GITHUB_WORKSPACE%\compile-errors.log" 1> "%GITHUB_WORKSPACE%\compile.log" - - - name: Inspecting Stub Extension DLL File - run: Get-PhpExtension "${env:RELEASE_DLL_PATH}" - - - name: Enable Stub Extension - run: | - Import-Module .\.ci\win-ci-tools.psm1 - EnableTestExtension - - - name: Minimal Load Test for Stub Extension - run: php --ri "${env:EXTENSION_NAME}" - - - name: Unit Testing - Extension - if: always() - run: | - .\vendor\bin\phpunit ` - --colors=always ` - --bootstrap tests\ext-bootstrap.php ` - --testsuite Extension - - - name: Unit Testing - Zephir - if: always() - run: vendor/bin/phpunit --colors=always --testsuite Zephir - - - name: After Failure - if: failure() - run: | - Import-Module .\.ci\win-ci-tools.psm1 - PrintLogs - PrintEnvVars - PrintDirectoriesContent - - - name: After Success - if: success() - run: | - Import-Module .\.ci\win-ci-tools.psm1 - PrintBuildDetails diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000000..f0ea57a358 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,234 @@ +name: Zephir CI + +on: + schedule: + - cron: '0 2 * * *' # Daily at 02:00 runs only on default branch + push: + paths-ignore: + - '**.md' + - '**.txt' + - '**/nightly.yml' + pull_request: + branches: + - master + - develoment + +env: + RE2C_VERSION: 2.2 + ZEPHIR_PARSER_VERSION: 1.4.1 + CACHE_DIR: .cache + +jobs: + analyze: + name: Static Code Analysis + runs-on: ubuntu-18.04 + steps: + - name: Checkout Code + uses: actions/checkout@v2 + with: + fetch-depth: 1 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + env: + PHP_CS_FIXER_VERSION: 3.2.0 + with: + php-version: '7.4' + coverage: none + tools: php-cs-fixer:${{ env.PHP_CS_FIXER_VERSION }}, phpcs + + - name: Run PHP_CodeSniffer + run: | + phpcs --version + phpcs --runtime-set ignore_warnings_on_exit true + + - name: Run PHP CS Fixer + if: always() + run: | + php-cs-fixer fix --diff --dry-run -v --using-cache=no + + - name: Run Shell Check + if: always() + run: shellcheck .ci/*.sh + + build-and-test: + # To prevent build a particular commit use + # git commit -m "......... [ci skip]" + if: "!contains(github.event.head_commit.message, '[ci skip]')" + + name: "PHP-${{ matrix.php }}-${{ matrix.build_type }}-${{ matrix.name }}-${{ matrix.arch }}" + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + + matrix: + php: ['7.4', '8.0'] + build_type: ['ts', 'nts'] + arch: ['x64'] + + name: + - ubuntu-gcc + - macos-clang + - win2016-vc15 + - win2019-vs16 + + # matrix names should be in next format: + # {php}-{ts}-{os.name}-{compiler}-{arch} + include: + # Linux + - name: ubuntu-gcc + os: ubuntu-18.04 + compiler: gcc + + # macOS + - name: macos-clang + os: macos-10.15 + compiler: clang + + # Windows + - name: win2016-vc15 + os: windows-2016 + compiler: vc15 + + - name: win2019-vs16 + os: windows-2019 + compiler: vs16 + + exclude: + - name: win2019-vs16 + php: '7.4' + + - name: win2016-vc15 + php: '8.0' + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 5 + + - name: Install PHP ${{ matrix.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: '${{ matrix.php }}' + extensions: mbstring, fileinfo, gmp, sqlite, pdo_sqlite, psr, zip, mysqli, zephir_parser-${{ env.ZEPHIR_PARSER_VERSION }} + tools: phpize, php-config + coverage: xdebug + # variables_order: https://github.com/zephir-lang/zephir/pull/1537 + # enable_dl: https://github.com/zephir-lang/zephir/pull/1654 + # allow_url_fopen: https://github.com/zephir-lang/zephir/issues/1713 + # error_reporting: https://github.com/zendframework/zend-code/issues/160 + ini-values: >- + variables_order=EGPCS, + enable_dl=On, + allow_url_fopen=On, + error_reporting=-1, + memory_limit=1G, + date.timezone=UTC, + xdebug.max_nesting_level=256 + env: + PHPTS: ${{ matrix.build_type }} + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Set Up Composer Cache + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install Project Dependencies + run: | + echo "::group::Install composer dependencies" + composer install --prefer-dist --no-interaction --no-ansi --no-progress + echo "::endgroup::" + + - name: Fast Commands Test + run: php zephir --help + + - name: Build Test Extension (Linux) + if: runner.os == 'Linux' + uses: ./.github/workflows/build-linux-ext + with: + compiler: ${{ matrix.compiler }} + cflags: '-O2 -Wall -fvisibility=hidden -flto -DZEPHIR_RELEASE=1' + ldflags: '--coverage' + + - name: Build Test Extension (macOS) + if: runner.os == 'macOS' + uses: ./.github/workflows/build-macos-ext + with: + compiler: ${{ matrix.compiler }} + cflags: '-O2 -fvisibility=hidden -Wparentheses -flto -DZEPHIR_RELEASE=1' + + - name: Build Test Extension (Windows) + if: runner.os == 'Windows' + uses: ./.github/workflows/build-win-ext + with: + php_version: ${{ matrix.php }} + ts: ${{ matrix.build_type }} + msvc: ${{ matrix.compiler }} + arch: ${{ matrix.arch }} + env: + CACHE_DIR: 'C:\Downloads' + PHP_ROOT: 'C:\tools\php' + + - name: Stub Extension Info + shell: pwsh + run: | + if ("${{ runner.os }}" -eq "Windows") { + php --ri stub + } else { + php -d extension=./ext/modules/stub.so --ri stub + } + + - name: Setup problem matchers for PHPUnit + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Unit Tests (Stub Extension) + shell: pwsh + run: | + if ("${{ runner.os }}" -eq "Windows") { + php vendor/bin/phpunit -c phpunit.ext.xml + } else { + php -d extension=./ext/modules/stub.so vendor/bin/phpunit -c phpunit.ext.xml + } + + - name: Unit Tests (Zephir) + if: always() + run: vendor/bin/phpunit --testsuite Zephir + env: + XDEBUG_MODE: coverage + + - name: Black-box Testing + if: always() && runner.os != 'Windows' + shell: bash + working-directory: tests/sharness + run: | + make -j$(getconf _NPROCESSORS_ONLN) + + - name: Upload Code Coverage Report + uses: codecov/codecov-action@v2 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./tests/output/clover.xml + flags: unittests,${{ matrix.name }},php-${{ matrix.php }} + name: codecov-umbrella + + - name: Upload build artifacts after Failure + if: failure() + uses: actions/upload-artifact@v2 + with: + name: debug-${{ matrix.name }}-${{ matrix.php }}-${{ matrix.build_type }}-${{ matrix.name }}-${{ matrix.compiler }}-${{ matrix.arch }} + path: | + ${{ github.workspace }}/*.log + ${{ github.workspace }}/ext/ + !${{ github.workspace }}/ext/kernel/ + !${{ github.workspace }}/ext/stub/ + !${{ github.workspace }}/ext/Release/ + !${{ github.workspace }}/ext/x64/Release/ + retention-days: 1 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 0000000000..4a1577d53a --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,123 @@ +name: Zephir Nightly + +on: + schedule: + - cron: '0 3 * * *' # Daily at 03:00 runs only on default branch + workflow_dispatch: + +env: + RE2C_VERSION: 2.2 + ZEPHIR_PARSER_VERSION: 1.4.1 + CACHE_DIR: .cache + +jobs: + nightly: + name: "PHP-${{ matrix.php }}-${{ matrix.build_type }}-${{ matrix.name }}-${{ matrix.arch }}" + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + + matrix: + php: [ '8.1', '8.2' ] + build_type: [ 'ts', 'nts' ] + arch: [ 'x64' ] + + # matrix names should be in next format: + # {php}-{ts}-{os.name}-{compiler}-{arch} + include: + # Linux + - name: ubuntu-gcc + os: ubuntu-20.04 + compiler: gcc + + steps: + - name: Checkout Code + uses: actions/checkout@v2 + with: + fetch-depth: 5 + + - name: Install PHP ${{ matrix.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: '${{ matrix.php }}' + extensions: mbstring, fileinfo, gmp, sqlite, pdo_sqlite, psr, zip, mysqli, zephir_parser-${{ env.ZEPHIR_PARSER_VERSION }} + tools: phpize, php-config + coverage: xdebug + # variables_order: https://github.com/zephir-lang/zephir/pull/1537 + # enable_dl: https://github.com/zephir-lang/zephir/pull/1654 + # allow_url_fopen: https://github.com/zephir-lang/zephir/issues/1713 + # error_reporting: https://github.com/zendframework/zend-code/issues/160 + ini-values: >- + variables_order=EGPCS, + enable_dl=On, + allow_url_fopen=On, + error_reporting=-1, + memory_limit=1G, + date.timezone=UTC, + xdebug.max_nesting_level=256 + env: + PHPTS: ${{ matrix.build_type }} + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Set Up Composer Cache + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install Project Dependencies + run: | + echo "::group::Install composer dependencies" + composer install --prefer-dist --no-interaction --no-ansi --no-progress + echo "::endgroup::" + + - name: Fast Commands Test + run: php zephir --help + + - name: Build Test Extension (Linux) + uses: ./.github/workflows/build-linux-ext + with: + compiler: ${{ matrix.compiler }} + cflags: '-O2 -Wall -fvisibility=hidden -flto -DZEPHIR_RELEASE=1' + ldflags: '--coverage' + + - name: Stub Extension Info + run: | + php -d extension=./ext/modules/stub.so --ri stub + + - name: Setup problem matchers for PHPUnit + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Unit Tests (Stub Extension) + run: | + php -d extension=./ext/modules/stub.so vendor/bin/phpunit -c phpunit.ext.xml + + - name: Unit Tests (Zephir) + run: vendor/bin/phpunit --testsuite Zephir + env: + XDEBUG_MODE: coverage + + - name: Black-box Testing + working-directory: tests/sharness + run: | + make -j$(getconf _NPROCESSORS_ONLN) + + - name: Upload build artifacts after Failure + if: failure() + uses: actions/upload-artifact@v2 + with: + name: debug-${{ matrix.name }}-${{ matrix.php }}-${{ matrix.build_type }}-${{ matrix.name }}-${{ matrix.compiler }}-${{ matrix.arch }} + path: | + ${{ github.workspace }}/*.log + ${{ github.workspace }}/ext/ + !${{ github.workspace }}/ext/kernel/ + !${{ github.workspace }}/ext/stub/ + !${{ github.workspace }}/ext/Release/ + !${{ github.workspace }}/ext/x64/Release/ + retention-days: 30 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2d6caf8b7d..c8d0857b29 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,13 +6,14 @@ on: - '*' jobs: - build: - runs-on: ubuntu-18.04 + release: + name: Create Release + runs-on: ubuntu-20.04 - steps: - - name: Setup Environment Variables - run: echo "BOX_VERSION=3.12.2" >> $GITHUB_ENV + env: + BOX_VERSION: 3.12.2 + steps: - name: Checkout Code uses: actions/checkout@v2 with: @@ -34,7 +35,7 @@ jobs: uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: | ${{ runner.os }}-composer- @@ -44,7 +45,7 @@ jobs: - name: Install Box run: | wget \ - "https://github.com/humbug/box/releases/download/${BOX_VERSION}/box.phar" \ + "https://github.com/humbug/box/releases/download/${{ env.BOX_VERSION }}/box.phar" \ --quiet \ -O ./box @@ -54,20 +55,18 @@ jobs: - name: Build Zephir PHAR run: .ci/build-phar.sh - - name: Geting Tag Name + - name: Get the release version id: get-version - run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/} + run: | + echo ::set-output name=version::${GITHUB_REF#refs/tags/} - name: Create Release uses: ncipollo/release-action@v1 with: - # This token is provided by GitHub Actions. - # You DO NOT need to create your own token. token: ${{ secrets.GITHUB_TOKEN }} name: ${{ steps.get-version.outputs.version }} tag: ${{ steps.get-version.outputs.version }} - body: 'All notable changes to this version has been documented in the CHANGELOG.md file.' - # This will update existing tags if any + bodyFile: "./release-notes.md" allowUpdates: true artifacts: zephir.phar artifactContentType: application/x-php diff --git a/.gitignore b/.gitignore index e0854891d4..47b158cc97 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ phpcs.xml phpmd.xml phpunit.xml .phpunit.result.cache +.php-cs-fixer.cache # Build artefact zephir.phar diff --git a/.php_cs.dist b/.php-cs-fixer.dist.php similarity index 54% rename from .php_cs.dist rename to .php-cs-fixer.dist.php index 7c939776cb..d65f15480c 100644 --- a/.php_cs.dist +++ b/.php-cs-fixer.dist.php @@ -1,5 +1,7 @@ exclude([ 'ext', 'ide', + 'config/class-entries', 'templates/ZendEngine3', 'templates/Api', + 'tests/ext-bootstrap', 'tests/fixtures', 'tests/sharness', ]) - ->notPath('#tests/fixtures/stubs/.*#'); + ->notPath('#config/class-entries.php#') + ->notPath('#tests/fixtures/stubs/.*#') + ->notPath('#tests/ext-bootstrap.php#'); -return PhpCsFixer\Config::create() +$config = new PhpCsFixer\Config(); +$config ->setRiskyAllowed(true) ->setFinder($finder) ->setRules([ @@ -46,10 +53,38 @@ 'php_unit_no_expectation_annotation' => false, 'array_syntax' => ['syntax' => 'short'], 'fopen_flags' => false, - 'ordered_imports' => ['sortAlgorithm' => 'alpha'], + 'ordered_imports' => [ + 'sort_algorithm' => 'alpha', + 'imports_order' => [ + 'class', + 'function', + 'const', + ], + ], 'protected_to_private' => false, + 'phpdoc_summary' => false, + 'phpdoc_to_comment' => false, 'phpdoc_var_annotation_correct_order' => true, 'no_superfluous_phpdoc_tags' => false, + 'native_constant_invocation' => false, + 'native_function_invocation' => false, + 'no_extra_blank_lines' => [ + 'tokens' => [ + 'continue', + 'curly_brace_block', + 'default', + 'extra', + 'parenthesis_brace_block', + 'square_brace_block', + 'switch', + 'throw', + 'use_trait', + ], + ], 'single_line_throw' => false, 'psr_autoloading' => false, + 'types_spaces' => ['space' => 'single'], + 'yoda_style' => false, ]); + +return $config; diff --git a/CHANGELOG.md b/CHANGELOG.md index a2e6245a84..1a10d3c004 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](http://semver.org). ## [Unreleased] +## [0.15.0] - 2021-10-05 +### Added +- Added support for `string` type in php.ini [#2280](https://github.com/zephir-lang/zephir/issues/2280) +- Added support for `mixed` [#2276](https://github.com/zephir-lang/zephir/issues/2276) + +### Fixed +- Fixed multiple return types in stubs [#2283](https://github.com/zephir-lang/zephir/issues/2283) +- Fixed `bool` return type in stubs [#2272](https://github.com/zephir-lang/zephir/issues/2272) + +### Changed +- Removed `.zep` from stubs filenames [#2273](https://github.com/zephir-lang/zephir/issues/2273) + ## [0.14.0] - 2021-09-18 ### Added - Added support for `require_once` [#2253](https://github.com/zephir-lang/zephir/issues/2253) @@ -541,7 +553,8 @@ and this project adheres to [Semantic Versioning](http://semver.org). [#1524](https://github.com/zephir-lang/zephir/issues/1524) -[Unreleased]: https://github.com/zephir-lang/zephir/compare/0.14.0...HEAD +[Unreleased]: https://github.com/zephir-lang/zephir/compare/0.15.0...HEAD +[0.15.0]: https://github.com/zephir-lang/zephir/compare/0.14.0...0.15.0 [0.14.0]: https://github.com/zephir-lang/zephir/compare/0.14.0-beta.3...0.14.0 [0.14.0-beta.3]: https://github.com/zephir-lang/zephir/compare/0.14.0-beta.2...0.14.0-beta.3 [0.14.0-beta.2]: https://github.com/zephir-lang/zephir/compare/0.14.0-beta.1...0.14.0-beta.2 diff --git a/Library/ArgInfoDefinition.php b/Library/ArgInfoDefinition.php index e8165bcca4..b11cf5488d 100644 --- a/Library/ArgInfoDefinition.php +++ b/Library/ArgInfoDefinition.php @@ -1,7 +1,5 @@ functionLike = $functionLike; $this->codePrinter = $codePrinter; @@ -208,16 +205,41 @@ private function richRenderStart(): void return; } - $this->codePrinter->output( - sprintf( - 'ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(%s, %d, %d, %s, %d)', - $this->name, - (int) $this->returnByRef, - $this->functionLike->getNumberOfRequiredParameters(), - $this->getReturnType(), - (int) $this->functionLike->areReturnTypesNullCompatible() - ) - ); + if ($this->functionLike->isMixed()) { + $this->codePrinter->output('#if PHP_VERSION_ID >= 80000'); + $this->codePrinter->output( + sprintf( + 'ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(%s, %d, %d, IS_MIXED, %d)', + $this->name, + (int) $this->returnByRef, + $this->functionLike->getNumberOfRequiredParameters(), + (int) $this->functionLike->areReturnTypesNullCompatible() + ) + ); + $this->codePrinter->output('#else'); + $this->codePrinter->output( + sprintf( + 'ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(%s, %d, %d, %s, %d)', + $this->name, + (int) $this->returnByRef, + $this->functionLike->getNumberOfRequiredParameters(), + $this->getReturnType(), + (int) $this->functionLike->areReturnTypesNullCompatible() + ) + ); + $this->codePrinter->output('#endif'); + } else { + $this->codePrinter->output( + sprintf( + 'ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(%s, %d, %d, %s, %d)', + $this->name, + (int) $this->returnByRef, + $this->functionLike->getNumberOfRequiredParameters(), + $this->getReturnType(), + (int) $this->functionLike->areReturnTypesNullCompatible() + ) + ); + } } private function renderEnd(): void @@ -396,6 +418,11 @@ private function passByReference(array $parameter) private function getReturnType(): string { + // TODO: Come back here when PHP7.4 is deprecated. + /*if (array_key_exists('mixed', $this->functionLike->getReturnTypes())) { + return 'IS_MIXED'; + }*/ + if ($this->functionLike->areReturnTypesIntCompatible()) { return 'IS_LONG'; } diff --git a/Library/Backends/ZendEngine2/Backend.php b/Library/Backends/ZendEngine2/Backend.php index e34cc4546c..1612743bf3 100644 --- a/Library/Backends/ZendEngine2/Backend.php +++ b/Library/Backends/ZendEngine2/Backend.php @@ -1069,11 +1069,11 @@ public function getScalarTempVariable( /** * Assign value to variable helper. * - * @param string $macro - * @param string $variableName - * @param string|null|Variable $value - * @param CompilationContext $context - * @param bool $useCodePrinter + * @param string $macro + * @param string $variableName + * @param string|Variable|null $value + * @param CompilationContext $context + * @param bool $useCodePrinter * * @return string */ @@ -1102,12 +1102,12 @@ protected function assignHelper( return $output; } - protected function returnHelper($macro, $value, CompilationContext $context, $useCodePrinter, $doCopy = null) + protected function returnHelper(string $macro, $value, CompilationContext $context, $useCodePrinter, $doCopy = null): string { if ($value instanceof Variable) { $value = $value->getName(); - } else { - $value = 'RETURN_MM_STRING' == $macro ? '"'.$value.'"' : $value; + } elseif ($macro === 'RETURN_MM_STRING' && !preg_match('/^ZEPHIR_GLOBAL/', $value)) { + $value = '"'.$value.'"'; } $copyStr = ''; diff --git a/Library/Backends/ZendEngine3/Backend.php b/Library/Backends/ZendEngine3/Backend.php index de6fa8db5f..915f562d1e 100644 --- a/Library/Backends/ZendEngine3/Backend.php +++ b/Library/Backends/ZendEngine3/Backend.php @@ -11,7 +11,6 @@ namespace Zephir\Backends\ZendEngine3; -use function Zephir\add_slashes; use Zephir\Backends\ZendEngine2\Backend as BackendZendEngine2; use Zephir\ClassDefinition; use Zephir\ClassMethod; @@ -26,6 +25,8 @@ use Zephir\Variable; use Zephir\Variable\Globals; +use function Zephir\add_slashes; + /** * Zephir\Backends\ZendEngine3\Backend. */ @@ -105,7 +106,7 @@ public function getStringsManager() /** * {@inheritdoc} */ - public function getTypeDefinition($type) + public function getTypeDefinition($type): array { switch ($type) { case 'zend_ulong': @@ -154,6 +155,7 @@ public function getTypeDefinition($type) case 'variable': case 'array': case 'null': + case 'mixed': $pointer = '*'; $code = 'zval'; break; @@ -316,7 +318,7 @@ public function onPostCompile(ClassMethod $method, CompilationContext $context) public function generateInitCode(&$groupVariables, $type, $pointer, Variable $variable) { - $isComplex = \in_array($type, ['variable', 'string', 'array', 'resource', 'callable', 'object'], true); + $isComplex = \in_array($type, ['variable', 'string', 'array', 'resource', 'callable', 'object', 'mixed'], true); if ($isComplex && !$variable->isDoublePointer()) { /* && $variable->mustInitNull() */ $groupVariables[] = $variable->getName(); @@ -365,6 +367,7 @@ public function generateInitCode(&$groupVariables, $type, $pointer, Variable $va case 'resource': case 'callable': case 'object': + case 'mixed': $groupVariables[] = $pointer.$variable->getName(); break; @@ -531,10 +534,10 @@ public function getInternalSignature(ClassMethod $method, CompilationContext $co /** * {@inheritdoc} * - * @param Variable $variable - * @param string|null|Variable $value - * @param CompilationContext $context - * @param bool $useCodePrinter + * @param Variable $variable + * @param string|Variable|null $value + * @param CompilationContext $context + * @param bool $useCodePrinter * * @return string */ @@ -574,7 +577,7 @@ public function assignZval(Variable $variable, $code, CompilationContext $contex public function returnString($value, CompilationContext $context, $useCodePrinter = true, $doCopy = true) { - return $this->returnHelper('RETURN_MM_STRING', $value, $context, $useCodePrinter, null); + return $this->returnHelper('RETURN_MM_STRING', $value, $context, $useCodePrinter); } public function createClosure(Variable $variable, $classDefinition, CompilationContext $context) @@ -594,7 +597,7 @@ public function addArrayEntry(Variable $variable, $key, $value, CompilationConte $keyType = 'append'; } elseif ($key instanceof CompiledExpression) { $typeKey = $key->getType(); - if ('variable' == $typeKey) { + if ('variable' === $typeKey || 'mixed' === $typeKey) { $var = $context->symbolTable->getVariableForRead($key->getCode(), $context); $typeKey = $var->getType(); } @@ -629,6 +632,7 @@ public function addArrayEntry(Variable $variable, $key, $value, CompilationConte case 'variable': case 'array': + case 'mixed': $type = 'zval'; break; } @@ -846,20 +850,21 @@ public function resolveValue($value, CompilationContext $context, $usePointer = $tempVariable = new Variable('variable', $varName, $context->branchManager->getCurrentBranch()); $context->symbolTable->addRawVariable($tempVariable); } + $tempVariable = $context->symbolTable->getVariableForWrite($varName, $context); $tempVariable->increaseUses(); - $tempVariable->setUsed(true, null); + $tempVariable->setUsed(true); + if ('null' == $value) { $tempVariable->setDynamicTypes('null'); } else { $tempVariable->setDynamicTypes('bool'); } + $value = $this->getVariableCode($tempVariable); } else { if ($value instanceof CompiledExpression) { - if ('array' == $value->getType()) { - $value = $context->symbolTable->getVariableForWrite($value->getCode(), $context, null); - } elseif ('variable' == $value->getType()) { + if (in_array($value->getType(), ['array', 'variable', 'mixed'])) { $value = $context->symbolTable->getVariableForWrite($value->getCode(), $context); } else { return $value->getCode(); diff --git a/Library/Backends/ZendEngine3/StringsManager.php b/Library/Backends/ZendEngine3/StringsManager.php index ee396da7ef..a1e19c70ea 100644 --- a/Library/Backends/ZendEngine3/StringsManager.php +++ b/Library/Backends/ZendEngine3/StringsManager.php @@ -9,29 +9,19 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir\Backends\ZendEngine3; -use function Zephir\file_put_contents_ex; use Zephir\StringsManager as BaseStringsManager; +use function Zephir\file_put_contents_ex; + /** - * Class StringsManager. - * * Manages the concatenation keys for the extension and the interned strings */ class StringsManager extends BaseStringsManager { - /** - * List of headers. - * - * @var array - */ - protected $concatKeys = [ - 'vv' => true, - 'vs' => true, - 'sv' => true, - ]; - /** * Adds a concatenation combination to the manager. * @@ -44,10 +34,8 @@ public function addConcatKey($key) /** * Generates the concatenation code. - * - * @return array */ - public function genConcatCode() + public function genConcatCode(): void { $code = ' #ifdef HAVE_CONFIG_H @@ -208,14 +196,4 @@ public function genConcatCode() file_put_contents_ex($contents, 'ext/kernel/concat.h'); file_put_contents_ex($code, 'ext/kernel/concat.c'); } - - /** - * Obtains the existing concatenation keys. - * - * @return array - */ - public function getConcatKeys() - { - return $this->concatKeys; - } } diff --git a/Library/BaseBackend.php b/Library/BaseBackend.php index 14ecf6cc18..d9a8b72b21 100644 --- a/Library/BaseBackend.php +++ b/Library/BaseBackend.php @@ -170,10 +170,10 @@ abstract public function declareConstant($type, $name, $value, CompilationContex /** * Assign value to variable. * - * @param Variable $variable - * @param string|null|Variable $value - * @param CompilationContext $context - * @param bool $useCodePrinter + * @param Variable $variable + * @param string|Variable|null $value + * @param CompilationContext $context + * @param bool $useCodePrinter * * @return string */ diff --git a/Library/Branch.php b/Library/Branch.php index 816493bbe3..eaba669db2 100644 --- a/Library/Branch.php +++ b/Library/Branch.php @@ -9,43 +9,35 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir; use Zephir\Statements\StatementAbstract; /** - * Branch. - * * Represents every branch within a method */ class Branch { - const TYPE_ROOT = 0; - - const TYPE_CONDITIONAL_TRUE = 1; - - const TYPE_CONDITIONAL_FALSE = 2; - - const TYPE_LOOP_INFINITE = 3; - - const TYPE_LOOP_CONDITIONAL = 4; - - const TYPE_SWITCH = 5; - - const TYPE_EXTERNAL = 6; - - const TYPE_UNKNOWN = 7; - protected $parentBranch; - - protected $level = -1; - - /** @var StatementAbstract|null */ - protected $relatedStatement; - - protected $type; - - protected $unreachable; + public const TYPE_ROOT = 0; + public const TYPE_CONDITIONAL_TRUE = 1; + public const TYPE_CONDITIONAL_FALSE = 2; + public const TYPE_LOOP_INFINITE = 3; + public const TYPE_LOOP_CONDITIONAL = 4; + public const TYPE_SWITCH = 5; + public const TYPE_EXTERNAL = 6; + public const TYPE_UNKNOWN = 7; + + protected int $level = -1; + protected int $type = self::TYPE_ROOT; + protected ?bool $unreachable = null; + protected ?Branch $parentBranch = null; + protected ?StatementAbstract $relatedStatement = null; + /** + * @var mixed + */ private $uniqueId; /** @@ -53,7 +45,7 @@ class Branch * * @param Branch $parentBranch */ - public function setParentBranch(self $parentBranch) + public function setParentBranch(self $parentBranch): void { $this->parentBranch = $parentBranch; } @@ -61,9 +53,9 @@ public function setParentBranch(self $parentBranch) /** * Returns the branch's parent. * - * @return Branch + * @return Branch|null */ - public function getParentBranch() + public function getParentBranch(): ?self { return $this->parentBranch; } @@ -73,7 +65,7 @@ public function getParentBranch() * * @param int $type */ - public function setType($type) + public function setType(int $type): void { $this->type = $type; } @@ -83,7 +75,7 @@ public function setType($type) * * @return int */ - public function getType() + public function getType(): int { return $this->type; } @@ -91,25 +83,25 @@ public function getType() /** * Sets if the branch is unreachable. * - * @param bool $unreachable + * @param bool|null $unreachable */ - public function setUnreachable($unreachable) + public function setUnreachable(?bool $unreachable): void { $this->unreachable = $unreachable; } /** - * @return mixed + * @return bool|null */ - public function isUnreachable() + public function isUnreachable(): ?bool { return $this->unreachable; } /** - * @param $level + * @param int $level */ - public function setLevel($level) + public function setLevel(int $level): void { $this->level = $level; } @@ -117,7 +109,7 @@ public function setLevel($level) /** * @return int */ - public function getLevel() + public function getLevel(): int { return $this->level; } @@ -141,7 +133,7 @@ public function getUniqueId() /** * @param StatementAbstract $relatedStatement */ - public function setRelatedStatement(StatementAbstract $relatedStatement) + public function setRelatedStatement(StatementAbstract $relatedStatement): void { $this->relatedStatement = $relatedStatement; } @@ -149,7 +141,7 @@ public function setRelatedStatement(StatementAbstract $relatedStatement) /** * @return StatementAbstract|null */ - public function getRelatedStatement() + public function getRelatedStatement(): ?StatementAbstract { return $this->relatedStatement; } diff --git a/Library/CacheManager.php b/Library/CacheManager.php index 1e1594538f..cd2317308f 100644 --- a/Library/CacheManager.php +++ b/Library/CacheManager.php @@ -9,6 +9,8 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir; use Zephir\Cache\ClassEntryCache; @@ -18,43 +20,41 @@ use Zephir\Passes\CallGathererPass; /** - * CacheManager. - * * Creates and manages function, method and class entries caches */ class CacheManager { /** - * @var FunctionCache + * @var FunctionCache|null */ - protected $functionCache; + protected ?FunctionCache $functionCache = null; /** - * @var MethodCache + * @var MethodCache|null */ - protected $methodCache; + protected ?MethodCache $methodCache = null; /** - * @var StaticMethodCache + * @var StaticMethodCache|null */ - protected $staticMethodCache; + protected ?StaticMethodCache $staticMethodCache = null; /** - * @var ClassEntryCache + * @var ClassEntryCache|null */ - protected $classEntryCache; + protected ?ClassEntryCache $classEntryCache = null; /** * @var CallGathererPass|null */ - protected $gatherer; + protected ?CallGathererPass $gatherer = null; /** * Sets the CallGathererPass. * - * @param CallGathererPass $gatherer + * @param CallGathererPass|null $gatherer */ - public function setGatherer(CallGathererPass $gatherer = null) + public function setGatherer(?CallGathererPass $gatherer = null) { $this->gatherer = $gatherer; } @@ -64,7 +64,7 @@ public function setGatherer(CallGathererPass $gatherer = null) * * @return ClassEntryCache */ - public function getClassEntryCache() + public function getClassEntryCache(): ClassEntryCache { if (!$this->classEntryCache) { $this->classEntryCache = new ClassEntryCache(); @@ -78,7 +78,7 @@ public function getClassEntryCache() * * @return FunctionCache */ - public function getFunctionCache() + public function getFunctionCache(): ?FunctionCache { if (!$this->functionCache) { $this->functionCache = new FunctionCache($this->gatherer); @@ -92,7 +92,7 @@ public function getFunctionCache() * * @return MethodCache */ - public function getMethodCache() + public function getMethodCache(): ?MethodCache { if (!$this->methodCache) { $this->methodCache = new MethodCache($this->gatherer); @@ -106,10 +106,10 @@ public function getMethodCache() * * @return StaticMethodCache */ - public function getStaticMethodCache() + public function getStaticMethodCache(): ?StaticMethodCache { if (!$this->staticMethodCache) { - $this->staticMethodCache = new StaticMethodCache($this->gatherer); + $this->staticMethodCache = new StaticMethodCache(); } return $this->staticMethodCache; diff --git a/Library/Call.php b/Library/Call.php index 19252a563a..ba5aff04f5 100644 --- a/Library/Call.php +++ b/Library/Call.php @@ -172,7 +172,7 @@ public function mustInitSymbolVariable(): bool /** * Returns the symbol variable that must be returned by the call. * - * @param bool $useTemp + * @param bool $useTemp * @param CompilationContext|null $compilationContext * * @return Variable|null @@ -191,12 +191,13 @@ public function getSymbolVariable(bool $useTemp = false, CompilationContext $com /** * Resolves parameters. * - * @param array $parameters + * @param array $parameters * @param CompilationContext $compilationContext - * @param array $expression - * @param bool $readOnly + * @param array $expression + * @param bool $readOnly * * @return CompiledExpression[]|null + * * @throws Exception */ public function getResolvedParamsAsExpr(array $parameters, CompilationContext $compilationContext, array $expression, bool $readOnly = false): ?array @@ -287,12 +288,13 @@ public function getResolvedParamsAsExpr(array $parameters, CompilationContext $c * Resolve parameters getting aware that the target function/method could retain or change * the parameters. * - * @param array $parameters + * @param array $parameters * @param CompilationContext $compilationContext - * @param array $expression - * @param null $calleeDefinition + * @param array $expression + * @param null $calleeDefinition * * @return array + * * @throws Exception */ public function getResolvedParams(array $parameters, CompilationContext $compilationContext, array $expression, $calleeDefinition = null): array @@ -486,11 +488,12 @@ public function getResolvedParams(array $parameters, CompilationContext $compila /** * Resolve parameters using zvals in the stack and without allocating memory for constants. * - * @param array $parameters + * @param array $parameters * @param CompilationContext $compilationContext - * @param array $expression + * @param array $expression * * @return array + * * @throws Exception */ public function getReadOnlyResolvedParams(array $parameters, CompilationContext $compilationContext, array $expression): array diff --git a/Library/ClassConstant.php b/Library/ClassConstant.php index 376d50aa32..6626ff1714 100644 --- a/Library/ClassConstant.php +++ b/Library/ClassConstant.php @@ -18,8 +18,6 @@ use Zephir\Expression\StaticConstantAccess; /** - * ClassConstant. - * * Represents a class constant */ class ClassConstant @@ -42,8 +40,8 @@ class ClassConstant /** * ClassConstant constructor. * - * @param string $name - * @param array $value + * @param string $name + * @param array $value * @param string|null $docBlock */ public function __construct(string $name, array $value, ?string $docBlock = null) diff --git a/Library/ClassDefinition.php b/Library/ClassDefinition.php index 792891580c..3204a2ae82 100644 --- a/Library/ClassDefinition.php +++ b/Library/ClassDefinition.php @@ -23,7 +23,6 @@ use function count; use function gettype; use function is_array; -use function strlen; use const DIRECTORY_SEPARATOR; /** @@ -49,6 +48,7 @@ final class ClassDefinition extends AbstractClassDefinition * If didn't specified, then equals to $name * * @var string + * * @see ClassDefinition::name */ protected string $shortName; @@ -525,7 +525,7 @@ public function getParsedDocBlock(): ?DocBlock return $this->parsedDocblock; } - if (strlen($this->docBlock) === 0) { + if ($this->docBlock === '') { return null; } @@ -538,6 +538,7 @@ public function getParsedDocBlock(): ?DocBlock * Adds a property to the definition. * * @param ClassProperty $property + * * @throws CompilerException */ public function addProperty(ClassProperty $property): void @@ -569,6 +570,7 @@ public function addConstant(ClassConstant $constant) * Checks if a class definition has a property. * * @param string $name + * * @return bool */ public function hasProperty(string $name): bool @@ -578,7 +580,7 @@ public function hasProperty(string $name): bool } $extendsClassDefinition = $this->getExtendsClassDefinition(); - if ($extendsClassDefinition instanceof ClassDefinition && $extendsClassDefinition->hasProperty($name)) { + if ($extendsClassDefinition instanceof self && $extendsClassDefinition->hasProperty($name)) { return true; } @@ -589,7 +591,8 @@ public function hasProperty(string $name): bool * Returns a method definition by its name. * * @param string $propertyName - * @return null|ClassProperty + * + * @return ClassProperty|null */ public function getProperty(string $propertyName): ?ClassProperty { @@ -598,7 +601,7 @@ public function getProperty(string $propertyName): ?ClassProperty } $extendsClassDefinition = $this->getExtendsClassDefinition(); - if ($extendsClassDefinition instanceof ClassDefinition) { + if ($extendsClassDefinition instanceof self) { return $extendsClassDefinition->getProperty($propertyName); } @@ -609,6 +612,7 @@ public function getProperty(string $propertyName): ?ClassProperty * Checks if class definition has a property. * * @param string $name + * * @return bool */ public function hasConstant(string $name): bool @@ -618,7 +622,7 @@ public function hasConstant(string $name): bool } $extendsClassDefinition = $this->getExtendsClassDefinition(); - if ($extendsClassDefinition instanceof ClassDefinition && $extendsClassDefinition->hasConstant($name)) { + if ($extendsClassDefinition instanceof self && $extendsClassDefinition->hasConstant($name)) { return true; } @@ -632,7 +636,9 @@ public function hasConstant(string $name): bool * Returns a constant definition by its name. * * @param string $constantName + * * @return ClassConstant|null + * * @throws InvalidArgumentException */ public function getConstant(string $constantName): ?ClassConstant @@ -642,7 +648,7 @@ public function getConstant(string $constantName): ?ClassConstant } $extendsClassDefinition = $this->getExtendsClassDefinition(); - if ($extendsClassDefinition instanceof ClassDefinition && $extendsClassDefinition->hasConstant($constantName)) { + if ($extendsClassDefinition instanceof self && $extendsClassDefinition->hasConstant($constantName)) { return $extendsClassDefinition->getConstant($constantName); } @@ -674,7 +680,7 @@ public function addMethod(ClassMethod $method, ?array $statement = null) * Updates an existing method definition. * * @param ClassMethod $method - * @param array|null $statement + * @param array|null $statement * * @throws CompilerException */ @@ -722,6 +728,7 @@ public function getMethods(): array * Checks if the class implements an specific name. * * @param string $methodName + * * @return bool */ public function hasMethod(string $methodName): bool @@ -790,7 +797,7 @@ public function getMethod(string $methodName, bool $checkExtends = true): ?Class /** * Set a method and its body. * - * @param string $methodName + * @param string $methodName * @param ClassMethod $method */ public function setMethod(string $methodName, ClassMethod $method): void @@ -812,7 +819,8 @@ public function setMethods(array $methods): void * Tries to find the most similar name. * * @param string $methodName - * @return null|string + * + * @return string|null */ public function getPossibleMethodName(string $methodName): ?string { @@ -824,7 +832,7 @@ public function getPossibleMethodName(string $methodName): ?string } } - if ($this->extendsClassDefinition instanceof ClassDefinition) { + if ($this->extendsClassDefinition instanceof self) { return $this->extendsClassDefinition->getPossibleMethodName($methodName); } @@ -835,7 +843,9 @@ public function getPossibleMethodName(string $methodName): ?string * Returns the name of the zend_class_entry according to the class name. * * @param CompilationContext|null $compilationContext + * * @throws Exception + * * @return string */ public function getClassEntry(?CompilationContext $compilationContext = null): string @@ -880,6 +890,7 @@ public function getNCNamespace(): string * Class name without namespace prefix for class registration. * * @param string $namespace + * * @return string */ public function getSCName(string $namespace): string @@ -896,7 +907,7 @@ public function getExternalHeader(): string { $parts = explode('\\', $this->namespace); - return 'ext/'.strtolower($parts[0]. DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $this->namespace). DIRECTORY_SEPARATOR.$this->name).'.zep'; + return 'ext/'.strtolower($parts[0].DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $this->namespace).DIRECTORY_SEPARATOR.$this->name).'.zep'; } /** @@ -904,6 +915,7 @@ public function getExternalHeader(): string * * @param ClassDefinition $classDefinition * @param ClassDefinition $interfaceDefinition + * * @throws CompilerException */ public function checkInterfaceImplements(self $classDefinition, self $interfaceDefinition) @@ -944,6 +956,7 @@ public function checkInterfaceImplements(self $classDefinition, self $interfaceD * Pre-compiles a class/interface gathering method information required by other methods. * * @param CompilationContext $compilationContext + * * @throws CompilerException */ public function preCompile(CompilationContext $compilationContext) @@ -1057,6 +1070,7 @@ public function addStaticInitMethod(StatementsBlock $statementsBlock): void * Compiles a class/interface. * * @param CompilationContext $compilationContext + * * @throws Exception * @throws ReflectionException */ @@ -1465,9 +1479,10 @@ public function setAliasManager(AliasManager $aliasManager): void * Builds a class definition from reflection. * * @param ReflectionClass $class + * * @return ClassDefinition */ - public static function buildFromReflection(ReflectionClass $class): ClassDefinition + public static function buildFromReflection(ReflectionClass $class): self { $classDefinition = new self($class->getNamespaceName(), $class->getName(), $class->getShortName()); @@ -1549,13 +1564,14 @@ public static function buildFromReflection(ReflectionClass $class): ClassDefinit /** * @param string $name + * * @return bool */ protected function hasConstantFromInterfaces(string $name): bool { if ($interfaces = $this->getImplementedInterfaceDefinitions()) { foreach ($interfaces as $interface) { - if ($interface instanceof ClassDefinition && $interface->hasConstant($name)) { + if ($interface instanceof self && $interface->hasConstant($name)) { return true; } } @@ -1567,13 +1583,13 @@ protected function hasConstantFromInterfaces(string $name): bool /** * @param string $name * - * @return null|ClassConstant + * @return ClassConstant|null */ - protected function getConstantFromInterfaces(string $name) : ?ClassConstant + protected function getConstantFromInterfaces(string $name): ?ClassConstant { if ($interfaces = $this->getImplementedInterfaceDefinitions()) { foreach ($interfaces as $interface) { - if ($interface instanceof ClassDefinition && $interface->hasConstant($name)) { + if ($interface instanceof self && $interface->hasConstant($name)) { return $interface->getConstant($name); } } diff --git a/Library/ClassMethod.php b/Library/ClassMethod.php index 2973b13bdd..4724ba8a42 100644 --- a/Library/ClassMethod.php +++ b/Library/ClassMethod.php @@ -96,6 +96,15 @@ class ClassMethod */ protected bool $void = false; + /** + * Whether the variable is mixed. + * + * Only for PHP >= 8.0 + * + * @var bool + */ + protected bool $mixed = false; + /** * Whether the method is public or not. * @@ -179,15 +188,15 @@ class ClassMethod /** * ClassMethod constructor. * - * @param ClassDefinition $classDefinition - * @param array $visibility - * @param string $name + * @param ClassDefinition $classDefinition + * @param array $visibility + * @param string $name * @param ClassMethodParameters|null $parameters - * @param StatementsBlock|null $statements - * @param string|null $docblock - * @param array|null $returnType - * @param array|null $expression - * @param array|null $staticVariables + * @param StatementsBlock|null $statements + * @param string|null $docblock + * @param array|null $returnType + * @param array|null $expression + * @param array|null $staticVariables */ public function __construct( ClassDefinition $classDefinition, @@ -276,34 +285,42 @@ public function setReturnTypes(?array $returnType = null): void $castTypes = []; foreach ($returnType['list'] as $returnTypeItem) { - if (isset($returnTypeItem['cast'])) { - if (isset($returnTypeItem['cast']['collection'])) { - continue; - } + /** + * We continue the loop, because it only works for PHP >= 8.0. + */ + if (isset($returnTypeItem['data-type']) && $returnTypeItem['data-type'] === 'mixed') { + $this->mixed = true; + } - if (isset($returnTypeItem['collection']) && $returnTypeItem['collection']) { - $types['array'] = [ - 'type' => 'return-type-parameter', - 'data-type' => 'array', - 'mandatory' => 0, - 'file' => $returnTypeItem['cast']['file'], - 'line' => $returnTypeItem['cast']['line'], - 'char' => $returnTypeItem['cast']['char'], - ]; - } else { - $castTypes[$returnTypeItem['cast']['value']] = $returnTypeItem['cast']['value']; - } - } else { + if (!isset($returnTypeItem['cast'])) { $types[$returnTypeItem['data-type']] = $returnTypeItem; + continue; + } + + if (isset($returnTypeItem['cast']['collection'])) { + continue; + } + + if (isset($returnTypeItem['collection']) && $returnTypeItem['collection']) { + $types['array'] = [ + 'type' => 'return-type-parameter', + 'data-type' => 'array', + 'mandatory' => 0, + 'file' => $returnTypeItem['cast']['file'], + 'line' => $returnTypeItem['cast']['line'], + 'char' => $returnTypeItem['cast']['char'], + ]; + } else { + $castTypes[$returnTypeItem['cast']['value']] = $returnTypeItem['cast']['value']; } } - if (count($castTypes)) { + if (count($castTypes) > 0) { $types['object'] = []; $this->returnClassTypes = $castTypes; } - if (count($types)) { + if (count($types) > 0) { $this->returnTypes = $types; } } @@ -460,6 +477,7 @@ public function getClassDefinition(): ?ClassDefinition * allowing bypassing php userspace for internal method calls. * * @param CompilationContext $compilationContext + * * @return $this */ public function setupOptimized(CompilationContext $compilationContext): self @@ -514,7 +532,7 @@ public function setupOptimized(CompilationContext $compilationContext): self return $this; } - public function getOptimizedMethod() + public function getOptimizedMethod(): self { $optimizedName = $this->getName().'_zephir_internal_call'; $optimizedMethod = $this->classDefinition->getMethod($optimizedName, false); @@ -750,13 +768,14 @@ public function getInternalParameters(): string return ''; } - return $this->parameters->count() .', ...'; + return $this->parameters->count().', ...'; } /** * Checks whether the method has a specific modifier. * * @param string $modifier + * * @return bool */ public function hasModifier(string $modifier): bool @@ -783,6 +802,7 @@ public function isDeprecated(): bool * Returns the C-modifier flags. * * @throws Exception + * * @return string */ public function getModifiers(): string @@ -847,6 +867,16 @@ public function isVoid(): bool return $this->void; } + /** + * Checks if the methods return type is `mixed`. + * + * @return bool + */ + public function isMixed(): bool + { + return $this->mixed; + } + /** * Checks if the method is inline. * @@ -1049,9 +1079,11 @@ public function removeMemoryStackReferences(SymbolTable $symbolTable, string $co /** * Assigns a default value. * - * @param array $parameter + * @param array $parameter * @param CompilationContext $compilationContext + * * @return string + * * @throws Exception */ public function assignDefaultValue(array $parameter, CompilationContext $compilationContext): string @@ -1413,15 +1445,17 @@ public function checkStrictType(array $parameter, CompilationContext $compilatio * * @param array $parameter * @param CompilationContext $compilationContext + * * @throws CompilerException + * * @return string */ public function assignZvalValue(array $parameter, CompilationContext $compilationContext): string { $dataType = $this->getParamDataType($parameter); - if (in_array($dataType, ['variable', 'callable', 'object', 'resource'])) { - return ""; + if (in_array($dataType, ['variable', 'callable', 'object', 'resource', 'mixed'])) { + return ''; } $compilationContext->headersManager->add('kernel/operators'); @@ -1465,6 +1499,7 @@ public function assignZvalValue(array $parameter, CompilationContext $compilatio * Pre-compiles the method making compilation pass data (static inference, local-context-pass) available to other methods. * * @param CompilationContext $compilationContext + * * @throws CompilerException */ public function preCompile(CompilationContext $compilationContext): void @@ -1517,6 +1552,7 @@ public function preCompile(CompilationContext $compilationContext): void * Compiles the method. * * @param CompilationContext $compilationContext + * * @throws Exception */ public function compile(CompilationContext $compilationContext): void @@ -1625,6 +1661,7 @@ public function compile(CompilationContext $compilationContext): void case 'callable': case 'resource': case 'variable': + case 'mixed': $symbol = $symbolTable->addVariable($parameter['data-type'], $parameter['name'], $compilationContext); /* TODO: Move this to the respective backend, which requires refactoring how this works */ if ($compilationContext->backend->isZE3()) { @@ -1851,6 +1888,7 @@ public function compile(CompilationContext $compilationContext): void case 'callable': case 'resource': case 'variable': + case 'mixed': $name = $parameter['name']; break; @@ -2195,6 +2233,7 @@ public function getInternalName(): string * Returns arginfo name for current method. * * @param ClassDefinition|null $classDefinition + * * @return string */ public function getArgInfoName(?ClassDefinition $classDefinition = null): string @@ -2300,9 +2339,11 @@ public function areReturnTypesCompatible(): bool /** * Determine Z_PARAM_* * - * @param array $parameter + * @param array $parameter * @param CompilationContext $compilationContext + * * @return string + * * @throws Exception */ public function detectParam(array $parameter, CompilationContext $compilationContext): string @@ -2412,6 +2453,7 @@ public function detectParam(array $parameter, CompilationContext $compilationCon * Get data type of method's parameter * * @param array $parameter + * * @return string */ private function getParamDataType(array $parameter): string diff --git a/Library/ClassMethodParameters.php b/Library/ClassMethodParameters.php index 18de1afad3..13e54efb5d 100644 --- a/Library/ClassMethodParameters.php +++ b/Library/ClassMethodParameters.php @@ -115,6 +115,7 @@ public function fetchParameters(bool $isMethodInternal): array case 'callable': case 'resource': case 'variable': + case 'mixed': $parameters[] = $isMethodInternal ? $name : '&'.$name; break; diff --git a/Library/Classes/Entry.php b/Library/Classes/Entry.php index 701ab9dacc..31ae696ac7 100644 --- a/Library/Classes/Entry.php +++ b/Library/Classes/Entry.php @@ -55,7 +55,7 @@ class Entry /** * Entry constructor. * - * @param string $className + * @param string $className * @param CompilationContext $compilationContext */ public function __construct(string $className, CompilationContext $compilationContext) @@ -73,6 +73,7 @@ public function __construct(string $className, CompilationContext $compilationCo /** * @return string + * * @throws Exception * @throws ReflectionException */ @@ -132,7 +133,7 @@ public function get(): string $className = end($classNamespace); array_pop($classNamespace); - $namespace = join(self::NAMESPACE_SEPARATOR, $classNamespace); + $namespace = implode(self::NAMESPACE_SEPARATOR, $classNamespace); return (new ClassDefinition($namespace, $className))->getClassEntry(); } @@ -147,6 +148,7 @@ public function isInternal(): bool * belongs to project namespace. * * @param string $className + * * @return bool */ private function isInternalClass(string $className): bool diff --git a/Library/Code/Builder/Struct.php b/Library/Code/Builder/Struct.php index cb8a62323d..c59ac0170e 100644 --- a/Library/Code/Builder/Struct.php +++ b/Library/Code/Builder/Struct.php @@ -140,7 +140,7 @@ public function getCDefault(string $name, array $global, string $namespace): str * @see https://docs.zephir-lang.com/latest/en/globals * * @param string $name - global-name - * @param array $global - global structure (type, default...) + * @param array $global - global structure (type, default...) * @param string $namespace - global namespace * * @return string diff --git a/Library/CodePrinter.php b/Library/CodePrinter.php index 35bb839a47..efb7b20224 100644 --- a/Library/CodePrinter.php +++ b/Library/CodePrinter.php @@ -90,7 +90,7 @@ public function outputNoIndent(string $code): void * Add code to the output. * * @param string $code - * @param bool $appendEOL + * @param bool $appendEOL */ public function output(string $code, bool $appendEOL = true): void { @@ -230,7 +230,7 @@ public function clear(): void $this->level = 0; } - public function duplicate(): CodePrinter + public function duplicate(): self { $printer = new self(); $printer->setLevel($this->level); diff --git a/Library/CompiledExpression.php b/Library/CompiledExpression.php index 913623010e..46442c1b60 100644 --- a/Library/CompiledExpression.php +++ b/Library/CompiledExpression.php @@ -16,10 +16,8 @@ use Closure; /** - * CompiledExpression. - * - * This represent a compiled expression, the object can be used to check - * if the expression type is able to be used in certain types of the application + * This represents a compiled expression, the object can be used to check + * if the expression type is able to used in certain types of the application. */ class CompiledExpression implements TypeAwareInterface { @@ -30,9 +28,9 @@ class CompiledExpression implements TypeAwareInterface protected ?array $originalExpr; /** - * @param string $type + * @param string $type * @param string|null $code - * @param array|null $originalExpr + * @param array|null $originalExpr */ public function __construct(string $type, ?string $code, ?array $originalExpr = null) { @@ -80,10 +78,10 @@ public function getBooleanCode(): string { if ($this->code && ('true' == $this->code || true === $this->code)) { return '1'; - } else { - if ('false' == $this->code || false === $this->code) { - return '0'; - } + } + + if ('false' === $this->code || false === $this->code) { + return '0'; } return $this->code; @@ -96,17 +94,7 @@ public function getBooleanCode(): string */ public function isIntCompatibleType(): bool { - switch ($this->type) { - case 'int': - case 'uint': - case 'long': - case 'ulong': - case 'char': - case 'uchar': - return true; - } - - return false; + return in_array($this->type, ['int', 'uint', 'long', 'ulong', 'char', 'uchar'], true); } /** @@ -116,44 +104,39 @@ public function isIntCompatibleType(): bool */ public function isCharCompatibleType(): bool { - switch ($this->type) { - case 'char': - case 'uchar': - return true; - } - - return false; + return in_array($this->type, ['char', 'uchar'], true); } /** * Resolves an expression + * * Some code cannot be directly pushed into the generated source * because it's missing some bound parts, this method resolves the missing parts * returning the generated code. * - * @param string|null $result + * @param string|null $result * @param CompilationContext $compilationContext * * @return string */ public function resolve(?string $result, CompilationContext $compilationContext): string { - if ($this->code instanceof Closure) { - $code = $this->code; - if (!$result) { - $tempVariable = $compilationContext->symbolTable->getTempVariableForWrite( - 'variable', - $compilationContext - ); - $compilationContext->codePrinter->output($code($tempVariable->getName())); - $tempVariable->setIsInitialized(true, $compilationContext); - - return $tempVariable->getName(); - } - - return $code($result); + if (!($this->code instanceof Closure)) { + return $this->code; } - return $this->code; + $code = $this->code; + if (!$result) { + $tempVariable = $compilationContext->symbolTable->getTempVariableForWrite( + 'variable', + $compilationContext + ); + $compilationContext->codePrinter->output($code($tempVariable->getName())); + $tempVariable->setIsInitialized(true, $compilationContext); + + return $tempVariable->getName(); + } + + return $code($result); } } diff --git a/Library/Compiler.php b/Library/Compiler.php index 498aca6ceb..ce760f4c36 100644 --- a/Library/Compiler.php +++ b/Library/Compiler.php @@ -466,6 +466,7 @@ public function isConstant(string $name): bool * Returns a Zephir Constant by its name. * * @param string $name + * * @return mixed */ public function getConstant(string $name) @@ -853,7 +854,7 @@ public function generate(bool $fromGenerate = false): bool /** * Compiles the extension without installing it. * - * @param bool $development + * @param bool $development * @param int|null $jobs * * @throws Exception @@ -1324,7 +1325,7 @@ public function processExtensionGlobals(string $namespace): array $structBuilder->addProperty($field, $global); $isModuleGlobal = (int) !empty($global['module']); - $globalsDefault[$isModuleGlobal][] = $structBuilder->getCDefault($field, $global, $namespace).PHP_EOL; + $globalsDefault[$isModuleGlobal][] = $structBuilder->getCDefault($field, $global, $namespace); $initEntries[] = $structBuilder->getInitEntry($field, $global, $namespace); } @@ -1333,8 +1334,7 @@ public function processExtensionGlobals(string $namespace): array $globalCode = PHP_EOL; foreach ($structures as $structureName => $internalStructure) { - $globalCode .= "\t".'zephir_struct_'.$structureName.' '. - $structureName.';'.PHP_EOL.PHP_EOL; + $globalCode .= "\t".'zephir_struct_'.$structureName.' '.$structureName.';'.PHP_EOL; } /** @@ -1351,16 +1351,16 @@ public function processExtensionGlobals(string $namespace): array $isModuleGlobal = (int) !empty($global['module']); $type = $global['type']; - // TODO: Add support for 'string', 'hash' + // TODO: Add support for 'hash' // TODO: Zephir\Optimizers\FunctionCall\GlobalsSetOptimizer switch ($global['type']) { case 'boolean': case 'bool': $type = 'zend_bool'; if (true === $global['default']) { - $globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = 1;'.PHP_EOL; + $globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = 1;'; } else { - $globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = 0;'.PHP_EOL; + $globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = 0;'; } break; @@ -1368,16 +1368,16 @@ public function processExtensionGlobals(string $namespace): array case 'uint': case 'long': case 'double': - $globalsDefault[$isModuleGlobal][] - = "\t".$namespace.'_globals->'.$name.' = '. - $global['default'].';'.PHP_EOL; + $globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = '.$global['default'].';'; break; case 'char': case 'uchar': - $globalsDefault[$isModuleGlobal][] - = "\t".$namespace.'_globals->'.$name.' = \''. - $global['default'].'\';'.PHP_EOL; + $globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = \''.$global['default'].'\';'; + break; + case 'string': + $type = 'char *'; + $globalsDefault[$isModuleGlobal][] = "\t".$namespace.'_globals->'.$name.' = ZSTR_VAL(zend_string_init(ZEND_STRL("'.$global['default'].'"), 0));'; break; default: throw new Exception( @@ -1385,7 +1385,7 @@ public function processExtensionGlobals(string $namespace): array ); } - $globalCode .= "\t".$type.' '.$name.';'.PHP_EOL.PHP_EOL; + $globalCode .= "\t".$type.' '.$name.';'.PHP_EOL; $iniEntry = []; if (isset($global['ini-entry'])) { $iniEntry = $global['ini-entry']; @@ -1424,8 +1424,8 @@ public function processExtensionGlobals(string $namespace): array } } - $globalsDefault[0] = implode('', $globalsDefault[0]); - $globalsDefault[1] = implode('', $globalsDefault[1]); + $globalsDefault[0] = implode(PHP_EOL, $globalsDefault[0]); + $globalsDefault[1] = implode(PHP_EOL, $globalsDefault[1]); return [$globalCode, $globalStruct, $globalsDefault, $initEntries]; } @@ -1452,7 +1452,7 @@ public function processExtensionInfo(): string $headerArray[] = '"'.htmlentities($header).'"'; } - $phpinfo .= "\t".'php_info_print_table_header('. count($headerArray).', '. + $phpinfo .= "\t".'php_info_print_table_header('.count($headerArray).', '. implode(', ', $headerArray).');'.PHP_EOL; } @@ -1463,7 +1463,7 @@ public function processExtensionInfo(): string $rowArray[] = '"'.htmlentities($field).'"'; } - $phpinfo .= "\t".'php_info_print_table_row('. count($rowArray).', '. + $phpinfo .= "\t".'php_info_print_table_row('.count($rowArray).', '. implode(', ', $rowArray).');'.PHP_EOL; } } @@ -2191,7 +2191,7 @@ private function loadConstantsSources(array $constantsSources) /** * Process config.w32 sections. * - * @param array $sources + * @param array $sources * @param string $project * * @return array diff --git a/Library/CompilerFile.php b/Library/CompilerFile.php index 29fb76d5eb..9364c2d0f2 100644 --- a/Library/CompilerFile.php +++ b/Library/CompilerFile.php @@ -13,6 +13,7 @@ use Psr\Log\LoggerAwareTrait; use Psr\Log\NullLogger; +use ReflectionException; use Zephir\Compiler\FileInterface; use Zephir\Documentation\DocblockParser; use Zephir\Exception\CompilerException; @@ -20,7 +21,7 @@ use Zephir\Exception\ParseException; use Zephir\FileSystem\FileSystemInterface; -use function strlen; +use function is_array; /** * Zephir\CompilerFile. @@ -33,65 +34,71 @@ final class CompilerFile implements FileInterface use LoggerAwareTrait; /** - * @var string + * @var string|null */ - private $namespace; + private ?string $namespace = null; /** - * @var string + * @var string|null */ - private $className; + private ?string $className = null; /** - * @var string + * @var string|null */ - private $filePath; + private ?string $filePath = null; /** * @var bool */ - private $external = false; + private bool $external = false; /** * Original internal representation (IR) of the file. * - * @var array + * @var array|null */ - private $ir; + private ?array $ir = null; + /** + * @var mixed + */ private $originalNode; - private $compiledFile; + /** + * @var string|null + */ + private ?string $compiledFile = null; /** - * @var ClassDefinition + * @var ClassDefinition|null */ - private $classDefinition; + private ?ClassDefinition $classDefinition = null; /** * @var FunctionDefinition[] */ - private $functionDefinitions = []; + private array $functionDefinitions = []; /** * @var array */ - private $headerCBlocks = []; + private array $headerCBlocks = []; /** * @var Config */ - private $config; + private Config $config; /** * @var AliasManager */ - private $aliasManager; + private AliasManager $aliasManager; /** * @var FileSystemInterface */ - private $filesystem; + private FileSystemInterface $filesystem; /** * CompilerFile constructor. @@ -114,7 +121,7 @@ public function __construct( /** * @param string $filePath */ - public function setFilePath($filePath) + public function setFilePath(string $filePath) { $this->filePath = $filePath; } @@ -122,7 +129,7 @@ public function setFilePath($filePath) /** * @param string $className */ - public function setClassName($className) + public function setClassName(string $className) { $this->className = $className; } @@ -149,17 +156,15 @@ public function getFunctionDefinitions() * * @param bool $external */ - public function setIsExternal($external) + public function setIsExternal($external): void { $this->external = (bool) $external; } /** - * {@inheritdoc} - * * @return bool */ - public function isExternal() + public function isExternal(): bool { return $this->external; } @@ -173,7 +178,7 @@ public function isExternal() * * @throws CompilerException */ - public function addFunction(Compiler $compiler, FunctionDefinition $func, $statement = null) + public function addFunction(Compiler $compiler, FunctionDefinition $func, array $statement = []) { $compiler->addFunction($func, $statement); $funcName = strtolower($func->getInternalName()); @@ -183,6 +188,7 @@ public function addFunction(Compiler $compiler, FunctionDefinition $func, $state $statement ); } + $this->functionDefinitions[$funcName] = $func; } @@ -196,69 +202,41 @@ public function addFunction(Compiler $compiler, FunctionDefinition $func, $state * * @return array */ - public function genIR(Compiler $compiler) + public function genIR(Compiler $compiler): array { $normalizedPath = $this->filesystem->normalizePath($this->filePath); - // TODO: JS => JSON - $compilePath = "{$normalizedPath}.js"; + $compilePath = "{$normalizedPath}.json"; $zepRealPath = realpath($this->filePath); if ($this->filesystem->exists($compilePath)) { - $modificationTime = $this->filesystem->modificationTime($compilePath); - if ($modificationTime < filemtime($zepRealPath)) { + if ($this->filesystem->modificationTime($compilePath) < filemtime($zepRealPath)) { $this->filesystem->delete($compilePath); - if (false != $this->filesystem->exists($compilePath.'.php')) { - $this->filesystem->delete($compilePath.'.php'); - } } } - $ir = null; - if (false == $this->filesystem->exists($compilePath)) { + if (!$this->filesystem->exists($compilePath)) { $parser = $compiler->getParserManager()->getParser(); $ir = $parser->parse($zepRealPath); $this->filesystem->write($compilePath, json_encode($ir, JSON_PRETTY_PRINT)); + } else { + $ir = json_decode($this->filesystem->read($compilePath), true); } - if (false == $this->filesystem->exists($compilePath.'.php')) { - if (empty($ir)) { - $ir = json_decode($this->filesystem->read($compilePath), true); - } - - $data = 'filesystem->write($compilePath.'.php', $data); - } - - $contents = $this->filesystem->requireFile($compilePath.'.php'); - - if (false == \is_array($contents)) { - throw new IllegalStateException( - sprintf( - 'Generating the intermediate representation for the file "%s" was failed.', - realpath($this->filePath) - ) - ); - } - - return $contents; + return $ir; } /** * Compiles the class/interface contained in the file. * * @param CompilationContext $compilationContext - * @param string $namespace - * @param array $classStatement + * + * @throws Exception + * @throws ReflectionException */ - public function compileClass(CompilationContext $compilationContext, $namespace, $classStatement) + public function compileClass(CompilationContext $compilationContext): void { - $classDefinition = $this->classDefinition; - - /* - * Do the compilation - */ - $classDefinition->compile($compilationContext); + $this->classDefinition->compile($compilationContext); } /** @@ -317,28 +295,28 @@ public function preCompileInterface($namespace, $topStatement, $docblock) $classDefinition->setType('interface'); - if (\is_array($docblock)) { + if (is_array($docblock)) { $classDefinition->setDocBlock($docblock['value']); } if (isset($topStatement['definition'])) { $definition = $topStatement['definition']; - /* + /** * Register constants */ if (isset($definition['constants'])) { foreach ($definition['constants'] as $constant) { $classConstant = new ClassConstant( $constant['name'], - isset($constant['default']) ? $constant['default'] : null, - isset($constant['docblock']) ? $constant['docblock'] : null + $constant['default'] ?? null, + $constant['docblock'] ?? null ); $classDefinition->addConstant($classConstant); } } - /* + /** * Register methods */ if (isset($definition['methods'])) { @@ -349,8 +327,8 @@ public function preCompileInterface($namespace, $topStatement, $docblock) $method['name'], isset($method['parameters']) ? new ClassMethodParameters($method['parameters']) : null, null, - isset($method['docblock']) ? $method['docblock'] : null, - isset($method['return-type']) ? $method['return-type'] : null, + $method['docblock'] ?? null, + $method['return-type'] ?? null, $method ); $classDefinition->addMethod($classMethod, $method); @@ -393,7 +371,7 @@ public function preCompileClass(CompilationContext $compilationContext, $namespa $classDefinition->setIsFinal($topStatement['final']); } - if (\is_array($docblock)) { + if (is_array($docblock)) { $classDefinition->setDocBlock($docblock['value']); } @@ -402,19 +380,19 @@ public function preCompileClass(CompilationContext $compilationContext, $namespa if (isset($definition['properties'])) { foreach ($definition['properties'] as $property) { - /* + /** * Add property to the definition */ $classDefinition->addProperty(new ClassProperty( $classDefinition, $property['visibility'], $property['name'], - isset($property['default']) ? $property['default'] : null, - isset($property['docblock']) ? $property['docblock'] : null, + $property['default'] ?? null, + $property['docblock'] ?? null, $property )); - /* + /** * Check and process shortcuts */ if (isset($property['shortcuts'])) { @@ -423,20 +401,20 @@ public function preCompileClass(CompilationContext $compilationContext, $namespa } } - /* + /** * Register constants */ if (isset($definition['constants'])) { foreach ($definition['constants'] as $constant) { $classDefinition->addConstant(new ClassConstant( $constant['name'], - isset($constant['default']) ? $constant['default'] : null, - isset($constant['docblock']) ? $constant['docblock'] : null + $constant['default'] ?? null, + $constant['docblock'] ?? null )); } } - /* + /** * Register methods */ if (isset($definition['methods'])) { @@ -447,8 +425,8 @@ public function preCompileClass(CompilationContext $compilationContext, $namespa $method['name'], isset($method['parameters']) ? new ClassMethodParameters($method['parameters']) : null, isset($method['statements']) ? new StatementsBlock($method['statements']) : null, - isset($method['docblock']) ? $method['docblock'] : null, - isset($method['return-type']) ? $method['return-type'] : null, + $method['docblock'] ?? null, + $method['return-type'] ?? null, $method ), $method); } @@ -457,12 +435,12 @@ public function preCompileClass(CompilationContext $compilationContext, $namespa $this->classDefinition = $classDefinition; - /* + /** * Assign current class definition to the compilation context */ $compilationContext->classDefinition = $classDefinition; - /* + /** * Run pre-compilation passes */ $classDefinition->preCompile($compilationContext); @@ -491,27 +469,10 @@ public function preCompile(Compiler $compiler) * Compilation context stores common objects required by compilation entities. */ $compilationContext = new CompilationContext(); - - /* - * Set global compiler in the compilation context - */ $compilationContext->compiler = $compiler; - - /* - * Set global config in the compilation context - */ $compilationContext->config = $this->config; - - /* - * Set global logger in the compilation context - */ $compilationContext->logger = $this->logger; - - /* - * Alias manager - */ $compilationContext->aliasManager = $this->aliasManager; - $compilationContext->backend = $compiler->backend; /** @@ -522,7 +483,7 @@ public function preCompile(Compiler $compiler) foreach ($ir as $topStatement) { switch ($topStatement['type']) { case 'namespace': - if (strlen($namespace) > 0) { + if ($namespace !== '') { throw new CompilerException('The namespace must be defined just one time', $topStatement); } @@ -574,7 +535,7 @@ public function preCompile(Compiler $compiler) } if (!$namespace) { - throw new CompilerException('A namespace is required', isset($topStatement) ? $topStatement : null); + throw new CompilerException('A namespace is required', $topStatement ?? null); } // Set namespace and flag as global, if before namespace declaration @@ -681,7 +642,7 @@ public function preCompile(Compiler $compiler) * * @return string */ - public function getCompiledFile() + public function getCompiledFile(): string { return $this->compiledFile; } @@ -690,6 +651,8 @@ public function getCompiledFile() * Check dependencies. * * @param Compiler $compiler + * + * @throws ReflectionException */ public function checkDependencies(Compiler $compiler) { @@ -745,36 +708,32 @@ public function checkDependencies(Compiler $compiler) } } - $implementedInterfaces = $classDefinition->getImplementedInterfaces(); - if ($implementedInterfaces) { - $interfaceDefinitions = []; - - foreach ($implementedInterfaces as $interface) { - if ($compiler->isInterface($interface)) { - $interfaceDefinitions[$interface] = $compiler->getClassDefinition($interface); + $interfaceDefinitions = []; + foreach ($classDefinition->getImplementedInterfaces() as $interface) { + if ($compiler->isInterface($interface)) { + $interfaceDefinitions[$interface] = $compiler->getClassDefinition($interface); + } else { + if ($compiler->isBundledInterface($interface)) { + $interfaceDefinitions[$interface] = $compiler->getInternalClassDefinition($interface); } else { - if ($compiler->isBundledInterface($interface)) { - $interfaceDefinitions[$interface] = $compiler->getInternalClassDefinition($interface); - } else { - if ($extendedClass !== null) { - $classDefinition->setExtendsClassDefinition(new ClassDefinitionRuntime($extendedClass)); - } - - $this->logger->warning( - sprintf( - 'Cannot locate class "%s" when extending interface "%s"', - $interface, - $classDefinition->getCompleteName() - ), - ['nonexistent-class', $this->originalNode] - ); + if ($extendedClass !== null) { + $classDefinition->setExtendsClassDefinition(new ClassDefinitionRuntime($extendedClass)); } + + $this->logger->warning( + sprintf( + 'Cannot locate class "%s" when extending interface "%s"', + $interface, + $classDefinition->getCompleteName() + ), + ['nonexistent-class', $this->originalNode] + ); } } + } - if ($interfaceDefinitions) { - $classDefinition->setImplementedInterfaceDefinitions($interfaceDefinitions); - } + if (count($interfaceDefinitions) > 0) { + $classDefinition->setImplementedInterfaceDefinitions($interfaceDefinitions); } } @@ -855,7 +814,7 @@ public function compile(Compiler $compiler, StringsManager $stringsManager) throw new CompilerException('More than one class defined in the same file', $topStatement); } $class = true; - $this->compileClass($compilationContext, $this->namespace, $topStatement); + $this->compileClass($compilationContext); break; case 'comment': @@ -898,32 +857,30 @@ public function compile(Compiler $compiler, StringsManager $stringsManager) } } - if ($codePrinter) { + /** + * If the file does not exists we create it for the first time + */ + if (!file_exists($filePath)) { + file_put_contents($filePath, $codePrinter->getOutput()); + if ($compilationContext->headerPrinter) { + file_put_contents($filePathHeader, $compilationContext->headerPrinter->getOutput()); + } + } else { /** - * If the file does not exists we create it for the first time + * Use md5 hash to avoid rewrite the file again and again when it hasn't changed + * thus avoiding unnecessary recompilations. */ - if (!file_exists($filePath)) { - file_put_contents($filePath, $codePrinter->getOutput()); - if ($compilationContext->headerPrinter) { - file_put_contents($filePathHeader, $compilationContext->headerPrinter->getOutput()); - } - } else { - /** - * Use md5 hash to avoid rewrite the file again and again when it hasn't changed - * thus avoiding unnecessary recompilations. - */ - $output = $codePrinter->getOutput(); - $hash = $this->filesystem->getHashFile('md5', $filePath, true); - if (md5($output) != $hash) { - file_put_contents($filePath, $output); - } + $output = $codePrinter->getOutput(); + $hash = $this->filesystem->getHashFile('md5', $filePath, true); + if (md5($output) != $hash) { + file_put_contents($filePath, $output); + } - if ($compilationContext->headerPrinter) { - $output = $compilationContext->headerPrinter->getOutput(); - $hash = $this->filesystem->getHashFile('md5', $filePathHeader, true); - if (md5($output) != $hash) { - file_put_contents($filePathHeader, $output); - } + if ($compilationContext->headerPrinter) { + $output = $compilationContext->headerPrinter->getOutput(); + $hash = $this->filesystem->getHashFile('md5', $filePathHeader, true); + if (md5($output) != $hash) { + file_put_contents($filePathHeader, $output); } } } @@ -984,7 +941,7 @@ public function applyClassHeaders(CompilationContext $compilationContext) * * @return string */ - public function getFilePath() + public function getFilePath(): string { return $this->filePath; } @@ -1163,7 +1120,7 @@ protected function getFullName(string $name): string * Create returns type list. * * @param array $types - * @param bool $annotated + * @param bool $annotated * * @return array */ diff --git a/Library/CompilerFileAnonymous.php b/Library/CompilerFileAnonymous.php index 08554ecda9..b4b54557ef 100644 --- a/Library/CompilerFileAnonymous.php +++ b/Library/CompilerFileAnonymous.php @@ -9,15 +9,18 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir; use Psr\Log\LoggerAwareTrait; use Psr\Log\NullLogger; +use ReflectionException; use Zephir\Compiler\FileInterface; +use function count; + /** - * CompilerFileAnonymous. - * * This class represents an anonymous file created to dump * the code produced by an internal closure */ @@ -25,33 +28,22 @@ final class CompilerFileAnonymous implements FileInterface { use LoggerAwareTrait; - /** @var CompilationContext */ - protected $context; - - /** @var string */ - protected $namespace; - - /** @var string */ - protected $compiledFile; - - /** @var bool */ - protected $external = false; - - /** @var ClassDefinition */ - protected $classDefinition; - - protected $headerCBlocks = []; - - /** @var Config */ - protected $config; + protected ?string $namespace = null; + protected ?string $compiledFile = null; + protected bool $external = false; + protected array $headerCBlocks = []; + protected ?CompilationContext $context = null; + protected ClassDefinition $classDefinition; + protected Config $config; /** * CompilerFileAnonymous constructor. * - * @param ClassDefinition $classDefinition - * @param Config $config + * @param ClassDefinition $classDefinition + * @param Config $config + * @param CompilationContext|null $context */ - public function __construct(ClassDefinition $classDefinition, Config $config, CompilationContext $context = null) + public function __construct(ClassDefinition $classDefinition, Config $config, ?CompilationContext $context = null) { $this->classDefinition = $classDefinition; $this->config = $config; @@ -60,11 +52,9 @@ public function __construct(ClassDefinition $classDefinition, Config $config, Co } /** - * {@inheritdoc} - * * @return ClassDefinition */ - public function getClassDefinition() + public function getClassDefinition(): ClassDefinition { return $this->classDefinition; } @@ -80,11 +70,9 @@ public function setIsExternal($external) } /** - * {@inheritdoc} - * * @return bool */ - public function isExternal() + public function isExternal(): bool { return $this->external; } @@ -95,17 +83,18 @@ public function isExternal() * @param CompilationContext $compilationContext * * @throws Exception + * @throws ReflectionException */ private function compileClass(CompilationContext $compilationContext) { $classDefinition = $this->classDefinition; - /* + /** * Do the compilation */ $classDefinition->compile($compilationContext); - $separators = str_repeat('../', \count(explode('\\', $classDefinition->getCompleteName())) - 1); + $separators = str_repeat('../', count(explode('\\', $classDefinition->getCompleteName())) - 1); $code = ''.PHP_EOL; $code .= '#ifdef HAVE_CONFIG_H'.PHP_EOL; @@ -131,11 +120,11 @@ private function compileClass(CompilationContext $compilationContext) } } - if (\count($this->headerCBlocks) > 0) { + if (count($this->headerCBlocks) > 0) { $code .= implode(PHP_EOL, $this->headerCBlocks).PHP_EOL; } - /* + /** * Prepend the required files to the header */ $compilationContext->codePrinter->preOutput($code); @@ -162,26 +151,10 @@ public function compile(Compiler $compiler, StringsManager $stringsManager) $compilationContext->aliasManager = new AliasManager(); } - /* - * Set global compiler in the compilation context - */ $compilationContext->compiler = $compiler; - - /* - * Set global config in the compilation context - */ $compilationContext->config = $this->config; - - /* - * Set global logger in the compilation context - */ $compilationContext->logger = $this->logger; - - /* - * Set global strings manager - */ $compilationContext->stringsManager = $stringsManager; - $compilationContext->backend = $compiler->backend; /** @@ -214,37 +187,35 @@ public function compile(Compiler $compiler, StringsManager $stringsManager) } } - if ($codePrinter) { - /* - * If the file does not exists we create it for the first time + /** + * If the file does not exist we create it for the first time + */ + if (!file_exists($filePath)) { + file_put_contents($filePath, $codePrinter->getOutput()); + if ($compilationContext->headerPrinter) { + file_put_contents($filePathHeader, $compilationContext->headerPrinter->getOutput()); + } + } else { + /** + * Use md5 hash to avoid rewrite the file again and again when it hasn't changed + * thus avoiding unnecessary recompilations. */ - if (!file_exists($filePath)) { - file_put_contents($filePath, $codePrinter->getOutput()); - if ($compilationContext->headerPrinter) { - file_put_contents($filePathHeader, $compilationContext->headerPrinter->getOutput()); - } - } else { - /** - * Use md5 hash to avoid rewrite the file again and again when it hasn't changed - * thus avoiding unnecessary recompilations. - */ - $output = $codePrinter->getOutput(); - $hash = hash_file('md5', $filePath); - if (md5($output) != $hash) { - file_put_contents($filePath, $output); - } + $output = $codePrinter->getOutput(); + $hash = hash_file('md5', $filePath); + if (md5($output) !== $hash) { + file_put_contents($filePath, $output); + } - if ($compilationContext->headerPrinter) { - $output = $compilationContext->headerPrinter->getOutput(); - $hash = hash_file('md5', $filePathHeader); - if (md5($output) != $hash) { - file_put_contents($filePathHeader, $output); - } + if ($compilationContext->headerPrinter) { + $output = $compilationContext->headerPrinter->getOutput(); + $hash = hash_file('md5', $filePathHeader); + if (md5($output) !== $hash) { + file_put_contents($filePathHeader, $output); } } } - /* + /** * Add to file compiled */ $this->compiledFile = $path.'.c'; diff --git a/Library/Console/Command/CompileCommand.php b/Library/Console/Command/CompileCommand.php index 4914dfaf46..fc82d98caa 100644 --- a/Library/Console/Command/CompileCommand.php +++ b/Library/Console/Command/CompileCommand.php @@ -56,7 +56,7 @@ protected function execute(InputInterface $input, OutputInterface $output) { $io = new SymfonyStyle($input, $output); - $jobs = $input->hasOption('jobs') ? (int)$input->getOption('jobs') : null; + $jobs = $input->hasOption('jobs') ? (int) $input->getOption('jobs') : null; try { // TODO: Move all the stuff from the compiler diff --git a/Library/Console/Command/InitCommand.php b/Library/Console/Command/InitCommand.php index 2da9361699..63f1bf2105 100644 --- a/Library/Console/Command/InitCommand.php +++ b/Library/Console/Command/InitCommand.php @@ -134,10 +134,10 @@ private function sanitizeNamespace(string $namespace): string /** * Copies the base kernel to the extension destination. * - * @param string $src - * @param string $dst + * @param string $src + * @param string $dst * @param string|null $pattern - * @param string $callback + * @param string $callback * * @return bool */ @@ -157,13 +157,13 @@ private function recursiveProcess(string $src, string $dst, ?string $pattern = n if ($item->isDir()) { if ('.' != $fileName && '..' != $fileName && '.libs' != $fileName) { - if (!is_dir($dst. DIRECTORY_SEPARATOR.$fileName)) { - mkdir($dst. DIRECTORY_SEPARATOR.$fileName, 0755, true); + if (!is_dir($dst.DIRECTORY_SEPARATOR.$fileName)) { + mkdir($dst.DIRECTORY_SEPARATOR.$fileName, 0755, true); } - $this->recursiveProcess($pathName, $dst. DIRECTORY_SEPARATOR.$fileName, $pattern, $callback); + $this->recursiveProcess($pathName, $dst.DIRECTORY_SEPARATOR.$fileName, $pattern, $callback); } } elseif ($pattern === null || 1 === preg_match($pattern, $fileName)) { - $path = $dst. DIRECTORY_SEPARATOR.$fileName; + $path = $dst.DIRECTORY_SEPARATOR.$fileName; $success = $success && $callback($pathName, $path); } } diff --git a/Library/DependencyMap.php b/Library/DependencyMap.php deleted file mode 100644 index d41bb4d5e8..0000000000 --- a/Library/DependencyMap.php +++ /dev/null @@ -1,24 +0,0 @@ - - * - * For the full copyright and license information, please view - * the LICENSE file that was distributed with this source code. - */ - -namespace Zephir; - -/** - * DependencyMap. - * - * Manage dependencies between files to perform incremental builds - */ -class DependencyMap -{ - public function addDependency() - { - } -} diff --git a/Library/Documentation/DocblockParser.php b/Library/Documentation/DocblockParser.php index a02364f100..d3596fe418 100644 --- a/Library/Documentation/DocblockParser.php +++ b/Library/Documentation/DocblockParser.php @@ -57,7 +57,7 @@ public function __construct(string $annotation) */ private function __tryRegisterAnnotation() { - if (($this->annotationNameOpen || $this->annotationOpen) && \strlen($this->currentAnnotationStr) > 0) { + if (($this->annotationNameOpen || $this->annotationOpen) && $this->currentAnnotationStr !== '') { $annotation = $this->__createAnnotation($this->currentAnnotationStr, $this->currentAnnotationContentStr); $this->docblockObj->addAnnotation($annotation); } @@ -156,7 +156,7 @@ public function parse() if ('@' == $currentChar) { $this->descriptionStr = trim($this->descriptionStr); - if ($this->descriptionOpen && \strlen($this->descriptionStr) > 0) { + if ($this->descriptionOpen && $this->descriptionStr !== '') { $this->descriptionOpen = false; } @@ -184,7 +184,7 @@ public function parse() } } elseif ($this->summaryOpen) { // stop summary on new line - if (\strlen($this->summaryStr) > 0 && ("\n" == $currentChar || "\r" == $currentChar)) { + if ($this->summaryStr !== '' && ("\n" == $currentChar || "\r" == $currentChar)) { $this->summaryOpen = false; $this->descriptionOpen = true; $this->ignoreStar = true; diff --git a/Library/Documentation/File/ClassFile.php b/Library/Documentation/File/ClassFile.php index a4ff7244df..5c47251b95 100644 --- a/Library/Documentation/File/ClassFile.php +++ b/Library/Documentation/File/ClassFile.php @@ -57,7 +57,7 @@ public function getData(): array $nsStr = ''; foreach ($nsPieces as $n) { - if (\strlen($nsStr) > 0) { + if ($nsStr !== '') { $nsStr .= '\\'; } $nsStr .= $n; diff --git a/Library/Documentation/NamespaceAccessor.php b/Library/Documentation/NamespaceAccessor.php index ca49af220b..0825adce75 100644 --- a/Library/Documentation/NamespaceAccessor.php +++ b/Library/Documentation/NamespaceAccessor.php @@ -52,7 +52,7 @@ public function build() $ns = explode('\\', $class->getClassDefinition()->getNamespace()); $actualStr = ''; foreach ($ns as $n) { - if (\strlen($actualStr) > 0) { + if ($actualStr !== '') { $previous = $byNamespace[$actualStr]; $actualStr .= '\\'; $isRoot = false; diff --git a/Library/Exception/InvalidTypeException.php b/Library/Exception/InvalidTypeException.php index be1542a788..fad4b82b46 100644 --- a/Library/Exception/InvalidTypeException.php +++ b/Library/Exception/InvalidTypeException.php @@ -9,6 +9,8 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir\Exception; final class InvalidTypeException extends CompilerException @@ -19,7 +21,7 @@ final class InvalidTypeException extends CompilerException * @param string $type * @param array|null $expression */ - public function __construct($type, array $expression = null) + public function __construct(string $type, array $expression = null) { $message = sprintf( 'Returning type: %s but this type is not compatible with return-type hints declared in the method', diff --git a/Library/Expression.php b/Library/Expression.php index b9fd3f0aa2..817612f408 100644 --- a/Library/Expression.php +++ b/Library/Expression.php @@ -9,8 +9,11 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir; +use ReflectionException; use Zephir\Exception\CompilerException; use Zephir\Expression\Closure; use Zephir\Expression\ClosureArrow; @@ -66,31 +69,17 @@ use Zephir\Operators\Unary\NotOperator; /** - * Zephir\Expressions. - * - * Represents an expression. Most language constructs in a language are expressions + * Represents an expression. + * Most language constructs in a language are expressions. */ class Expression { - protected $expression; - - protected $expecting = true; - - protected $readOnly = false; - - protected $noisy = true; - - /** - * @deprecated - * - * @var bool - */ - protected $stringOperation = false; - - /** @var Variable */ - protected $expectingVariable; - - protected $evalMode = false; + protected bool $noisy = true; + protected bool $expecting = true; + protected bool $readOnly = false; + protected bool $evalMode = false; + protected array $expression = []; + protected ?Variable $expectingVariable = null; /** * Expression constructor. @@ -107,7 +96,7 @@ public function __construct(array $expression) * * @return array */ - public function getExpression() + public function getExpression(): array { return $this->expression; } @@ -116,10 +105,10 @@ public function getExpression() * Sets if the variable must be resolved into a direct variable symbol * create a temporary value or ignore the return value. * - * @param bool $expecting - * @param Variable $expectingVariable + * @param bool $expecting + * @param Variable|null $expectingVariable */ - public function setExpectReturn($expecting, Variable $expectingVariable = null) + public function setExpectReturn(bool $expecting, Variable $expectingVariable = null): void { $this->expecting = $expecting; $this->expectingVariable = $expectingVariable; @@ -130,7 +119,7 @@ public function setExpectReturn($expecting, Variable $expectingVariable = null) * * @param bool $readOnly */ - public function setReadOnly($readOnly) + public function setReadOnly(bool $readOnly): void { $this->readOnly = $readOnly; } @@ -140,7 +129,7 @@ public function setReadOnly($readOnly) * * @return bool */ - public function isReadOnly() + public function isReadOnly(): bool { return $this->readOnly; } @@ -151,7 +140,7 @@ public function isReadOnly() * * @return bool */ - public function isExpectingReturn() + public function isExpectingReturn(): bool { return $this->expecting; } @@ -160,9 +149,9 @@ public function isExpectingReturn() * Returns the variable which is expected to return the * result of the expression evaluation. * - * @return Variable + * @return Variable|null */ - public function getExpectingVariable() + public function getExpectingVariable(): ?Variable { return $this->expectingVariable; } @@ -172,7 +161,7 @@ public function getExpectingVariable() * * @param bool $noisy */ - public function setNoisy($noisy) + public function setNoisy(bool $noisy): void { $this->noisy = $noisy; } @@ -182,43 +171,17 @@ public function setNoisy($noisy) * * @return bool */ - public function isNoisy() + public function isNoisy(): bool { return $this->noisy; } - /** - * Sets if current operation is a string operation like "concat" - * thus avoiding promote numeric strings to longs. - * - * @deprecated - * - * @param bool $stringOperation - */ - public function setStringOperation($stringOperation) - { - $this->stringOperation = $stringOperation; - } - - /** - * Checks if the result of the evaluated expression is intended to be used - * in a string operation like "concat". - * - * @deprecated - * - * @return bool - */ - public function isStringOperation() - { - return $this->stringOperation; - } - /** * Sets if the expression is being evaluated in an evaluation like the ones in 'if' and 'while' statements. * * @param bool $evalMode */ - public function setEvalMode($evalMode) + public function setEvalMode(bool $evalMode): void { $this->evalMode = $evalMode; } @@ -231,9 +194,9 @@ public function setEvalMode($evalMode) * * @return CompiledExpression */ - public function emptyArray($expression, CompilationContext $compilationContext) + public function emptyArray(array $expression, CompilationContext $compilationContext): CompiledExpression { - /* + /** * Resolves the symbol that expects the value */ if ($this->expecting) { @@ -247,18 +210,17 @@ public function emptyArray($expression, CompilationContext $compilationContext) $symbolVariable = $compilationContext->symbolTable->getTempVariableForWrite('variable', $compilationContext, $expression); } - /* + /** * Variable that receives property accesses must be polymorphic */ if (!$symbolVariable->isVariable() && 'array' != $symbolVariable->getType()) { throw new CompilerException('Cannot use variable: '.$symbolVariable->getName().'('.$symbolVariable->getType().') to create empty array', $expression); } - /* + /** * Mark the variable as an 'array' */ $symbolVariable->setDynamicTypes('array'); - $compilationContext->backend->initArray($symbolVariable, $compilationContext); return new CompiledExpression('array', $symbolVariable->getRealName(), $expression); @@ -272,12 +234,14 @@ public function emptyArray($expression, CompilationContext $compilationContext) * @throws CompilerException|Exception * * @return CompiledExpression + * + * @throws Exception + * @throws ReflectionException */ public function compile(CompilationContext $compilationContext): CompiledExpression { $expression = $this->expression; $type = $expression['type']; - $compilableExpression = null; switch ($type) { case 'null': diff --git a/Library/Expression/Builder/Operators/AssignVariableOperator.php b/Library/Expression/Builder/Operators/AssignVariableOperator.php index c60386a10d..2a9424be5d 100644 --- a/Library/Expression/Builder/Operators/AssignVariableOperator.php +++ b/Library/Expression/Builder/Operators/AssignVariableOperator.php @@ -54,8 +54,6 @@ class AssignVariableOperator extends AbstractOperator // >>= const OPERATOR_BITWISE_SHIFTRIGHT = 'bitwise-shiftright-assign'; - - private $variable; private $operator = self::OPERATOR_ASSIGN; private $expression; diff --git a/Library/Expression/Closure.php b/Library/Expression/Closure.php index 9f7d41e529..a8d4b186e1 100644 --- a/Library/Expression/Closure.php +++ b/Library/Expression/Closure.php @@ -9,21 +9,23 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir\Expression; use Zephir\ClassDefinition; use Zephir\ClassMethod; use Zephir\ClassMethodParameters; +use Zephir\ClassProperty; use Zephir\CompilationContext; use Zephir\CompiledExpression; use Zephir\CompilerFileAnonymous; -use Zephir\Exception\CompilerException; +use Zephir\Exception; use Zephir\StatementsBlock; use Zephir\Variable; +use function is_array; /** - * Closure. - * * Creates an anonymous function within the extension simulating a closure */ class Closure @@ -31,17 +33,17 @@ class Closure /** * @var bool */ - protected $expecting = true; + protected bool $expecting = true; /** * @var bool */ - protected $readOnly = false; + protected bool $readOnly = false; /** - * @var Variable + * @var Variable|null */ - protected $expectingVariable; + protected ?Variable $expectingVariable = null; /** * Unique closure ID. @@ -52,10 +54,10 @@ class Closure * Sets if the variable must be resolved into a direct variable symbol * create a temporary value or ignore the return value. * - * @param bool $expecting - * @param Variable $expectingVariable + * @param bool $expecting + * @param Variable|null $expectingVariable */ - public function setExpectReturn($expecting, Variable $expectingVariable = null) + public function setExpectReturn(bool $expecting, ?Variable $expectingVariable = null): void { $this->expecting = $expecting; $this->expectingVariable = $expectingVariable; @@ -66,7 +68,7 @@ public function setExpectReturn($expecting, Variable $expectingVariable = null) * * @param bool $readOnly */ - public function setReadOnly($readOnly) + public function setReadOnly(bool $readOnly): void { $this->readOnly = $readOnly; } @@ -77,11 +79,11 @@ public function setReadOnly($readOnly) * @param array $expression * @param CompilationContext $compilationContext * - * @throws CompilerException - * * @return CompiledExpression + * + * @throws Exception */ - public function compile(array $expression, CompilationContext $compilationContext) + public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression { $classDefinition = new ClassDefinition( $compilationContext->config->get('namespace'), @@ -95,27 +97,22 @@ public function compile(array $expression, CompilationContext $compilationContex $compilationContext->compiler->addClassDefinition($compilerFile, $classDefinition); + $parameters = null; if (isset($expression['left'])) { $parameters = new ClassMethodParameters($expression['left']); - } else { - $parameters = null; } - if (isset($expression['right'])) { - $block = $expression['right']; - } else { - $block = []; - } + $block = $expression['right'] ?? []; $staticVariables = []; - if (isset($expression['use']) && \is_array($expression['use'])) { + if (isset($expression['use']) && is_array($expression['use'])) { foreach ($expression['use'] as $parameter) { $staticVariables[$parameter['name']] = $compilationContext->symbolTable->getVariable($parameter['name']); } } foreach ($staticVariables as $var) { - $classDefinition->addProperty(new \Zephir\ClassProperty( + $classDefinition->addProperty(new ClassProperty( $classDefinition, ['public', 'static'], $var->getName(), @@ -153,35 +150,40 @@ public function compile(array $expression, CompilationContext $compilationContex $symbolVariable->initVariant($compilationContext); $compilationContext->backend->createClosure($symbolVariable, $classDefinition, $compilationContext); $compilationContext->headersManager->add('kernel/object'); + foreach ($staticVariables as $var) { - if ('variable' == $var->getType() || 'array' == $var->getType()) { + if (in_array($var->getType(), ['variable', 'array'])) { $compilationContext->backend->updateStaticProperty($classDefinition->getClassEntry(), $var->getName(), $var, $compilationContext); - } else { - $tempVariable = $compilationContext->symbolTable->getTempNonTrackedVariable('variable', $compilationContext, true); - switch ($var->getType()) { - case 'int': - case 'uint': - case 'long': - case 'ulong': - case 'char': - case 'uchar': - $compilationContext->backend->assignLong($tempVariable, $var, $compilationContext); - break; - case 'double': - $compilationContext->backend->assignDouble($tempVariable, $var, $compilationContext); - break; - case 'bool': - $compilationContext->backend->assignBool($tempVariable, $var, $compilationContext); - break; - case 'string': - $compilationContext->backend->assignString($tempVariable, $var, $compilationContext); - break; - default: - break; - } - $compilationContext->backend->updateStaticProperty($classDefinition->getClassEntry(), $var->getName(), $tempVariable, $compilationContext); + continue; + } + + $tempVariable = $compilationContext->symbolTable->getTempNonTrackedVariable('variable', $compilationContext, true); + + switch ($var->getType()) { + case 'int': + case 'uint': + case 'long': + case 'ulong': + case 'char': + case 'uchar': + $compilationContext->backend->assignLong($tempVariable, $var, $compilationContext); + break; + case 'double': + $compilationContext->backend->assignDouble($tempVariable, $var, $compilationContext); + break; + case 'bool': + $compilationContext->backend->assignBool($tempVariable, $var, $compilationContext); + break; + case 'string': + $compilationContext->backend->assignString($tempVariable, $var, $compilationContext); + break; + default: + break; } + + $compilationContext->backend->updateStaticProperty($classDefinition->getClassEntry(), $var->getName(), $tempVariable, $compilationContext); } + ++self::$id; return new CompiledExpression('variable', $symbolVariable->getRealName(), $expression); diff --git a/Library/Expression/ClosureArrow.php b/Library/Expression/ClosureArrow.php index d6a7cd6e2b..6c8688c481 100644 --- a/Library/Expression/ClosureArrow.php +++ b/Library/Expression/ClosureArrow.php @@ -9,6 +9,8 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir\Expression; use Zephir\ClassDefinition; @@ -22,8 +24,6 @@ use Zephir\StatementsBlock; /** - * ClosureArrow. - * * Creates an anonymous function within the extension simulating a closure using the arrow syntax */ class ClosureArrow extends Closure @@ -38,7 +38,7 @@ class ClosureArrow extends Closure * * @return CompiledExpression */ - public function compile(array $expression, CompilationContext $compilationContext) + public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression { $classDefinition = new ClassDefinition( $compilationContext->config->get('namespace'), diff --git a/Library/Expression/Constants.php b/Library/Expression/Constants.php index 49a6ec824e..1bed77c32d 100644 --- a/Library/Expression/Constants.php +++ b/Library/Expression/Constants.php @@ -11,13 +11,14 @@ namespace Zephir\Expression; -use function Zephir\add_slashes; use Zephir\CompilationContext; use Zephir\CompiledExpression; use Zephir\Exception\CompilerException; use Zephir\LiteralCompiledExpression; use Zephir\Variable; +use function Zephir\add_slashes; + /** * Zephir\Expression\Constants. * diff --git a/Library/Expression/NativeArray.php b/Library/Expression/NativeArray.php index 23382881cb..8e61539da7 100644 --- a/Library/Expression/NativeArray.php +++ b/Library/Expression/NativeArray.php @@ -152,6 +152,7 @@ public function getArrayValue(CompiledExpression $exprCompiled, CompilationConte case 'string': case 'variable': case 'array': + case 'mixed': return $itemVariable; default: diff --git a/Library/Expression/PropertyDynamicAccess.php b/Library/Expression/PropertyDynamicAccess.php index f3ed932db3..433e0e7f2b 100644 --- a/Library/Expression/PropertyDynamicAccess.php +++ b/Library/Expression/PropertyDynamicAccess.php @@ -11,13 +11,14 @@ namespace Zephir\Expression; -use function Zephir\add_slashes; use Zephir\CompilationContext; use Zephir\CompiledExpression; use Zephir\Exception\CompilerException; use Zephir\Expression; use Zephir\Variable; +use function Zephir\add_slashes; + /** * Zephir\Expression\PropertyDynamicAccess. * diff --git a/Library/Expression/Reference.php b/Library/Expression/Reference.php index 8adb408990..cf5a23425e 100644 --- a/Library/Expression/Reference.php +++ b/Library/Expression/Reference.php @@ -53,7 +53,7 @@ class Reference * Sets if the variable must be resolved into a direct variable symbol * create a temporary value or ignore the return value. * - * @param bool $expecting + * @param bool $expecting * @param Variable|null $expectingVariable */ public function setExpectReturn(bool $expecting, ?Variable $expectingVariable = null) @@ -79,6 +79,7 @@ public function setReadOnly(bool $readOnly): void * @param CompilationContext $compilationContext * * @return GlobalConstant|Variable + * * @throws Exception */ public function getArrayValue(CompiledExpression $exprCompiled, CompilationContext $compilationContext) @@ -174,10 +175,11 @@ public function getArrayValue(CompiledExpression $exprCompiled, CompilationConte /** * Compiles a reference to a value. * - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/FileSystem/FileSystemInterface.php b/Library/FileSystem/FileSystemInterface.php index 2107a3bc0a..2b89cd29a5 100644 --- a/Library/FileSystem/FileSystemInterface.php +++ b/Library/FileSystem/FileSystemInterface.php @@ -9,6 +9,8 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir\FileSystem; interface FileSystemInterface @@ -64,7 +66,7 @@ public function requireFile(string $path); /** * Attempts to remove recursively the temporary directory with all subdirectories and files. */ - public function clean(); + public function clean(): void; /** * Writes data into a temporary entry. @@ -99,7 +101,7 @@ public function delete(string $path); * * @return string */ - public function getHashFile(string $algorithm, string $sourceFile, $useCache = false): string; + public function getHashFile(string $algorithm, string $sourceFile, bool $useCache = false): string; /** * Returns the modification time of a temporary entry. diff --git a/Library/FileSystem/HardDisk.php b/Library/FileSystem/HardDisk.php index c09f07c949..b046773222 100644 --- a/Library/FileSystem/HardDisk.php +++ b/Library/FileSystem/HardDisk.php @@ -13,9 +13,11 @@ namespace Zephir\FileSystem; -use League\Flysystem; -use League\Flysystem\Filesystem; -use League\Flysystem\Local\LocalFilesystemAdapter; +use FilesystemIterator; +use Generator; +use RecursiveDirectoryIterator; +use RecursiveIteratorIterator; +use SplFileInfo; use Zephir\Exception\InvalidArgumentException; use Zephir\Exception\RuntimeException; use Zephir\Zephir; @@ -27,8 +29,6 @@ */ class HardDisk implements FileSystemInterface { - private ?Filesystem $filesystem = null; - /** @var string */ private string $localPath; @@ -68,6 +68,7 @@ public function __construct(string $basePath, string $localPath = Zephir::VERSIO /** * @param string $path + * * @return string */ private function rightTrimPath(string $path): string @@ -91,16 +92,12 @@ public function isInitialized(): bool public function initialize() { $this->initialized = true; - $this->filesystem = new Filesystem(new LocalFilesystemAdapter($this->basePath)); } /** - * {@inheritdoc} - * * @param string $path * * @return bool - * @throws Flysystem\FilesystemException */ public function exists(string $path): bool { @@ -110,16 +107,13 @@ public function exists(string $path): bool $path = "{$this->localPath}/{$path}"; } - return $this->filesystem->fileExists($path); + return is_file($this->basePath.DIRECTORY_SEPARATOR.$path); } /** - * {@inheritdoc} - * * @param string $path * * @return bool - * @throws Flysystem\FilesystemException */ public function makeDirectory(string $path): bool { @@ -129,79 +123,69 @@ public function makeDirectory(string $path): bool $path = "{$this->localPath}/{$path}"; } - $this->filesystem->createDirectory($path); + $dir = $this->basePath.DIRECTORY_SEPARATOR.$path; + + if (is_dir($dir)) { + chmod($dir, 0755); + + return true; + } + + mkdir($this->basePath.DIRECTORY_SEPARATOR.$path, 0755, true); return is_dir($path); } /** - * {@inheritdoc} - * * @param string $path * * @return array - * @throws Flysystem\FilesystemException */ public function file(string $path): array { - $contents = $this->filesystem->read($this->localPath."/{$path}"); + $contents = file_get_contents($this->basePath.DIRECTORY_SEPARATOR.$this->localPath."/{$path}"); return preg_split("/\r\n|\n|\r/", $contents); } /** - * {@inheritdoc} - * * @param string $path * * @return int - * @throws Flysystem\FilesystemException */ public function modificationTime(string $path): int { - return $this->filesystem->lastModified($this->localPath."/{$path}"); + return filemtime($this->basePath.DIRECTORY_SEPARATOR.$this->localPath."/{$path}"); } /** - * Writes data from a temporary entry. - * * @param string $path * * @return string - * @throws Flysystem\FilesystemException */ public function read(string $path): string { - return $this->filesystem->read($this->localPath."/{$path}"); + return file_get_contents($this->basePath.DIRECTORY_SEPARATOR.$this->localPath."/{$path}"); } /** - * {@inheritdoc} - * * @param string $path - * @throws Flysystem\FilesystemException */ public function delete(string $path) { - $this->filesystem->delete($this->localPath."/{$path}"); + unlink($this->basePath.DIRECTORY_SEPARATOR.$this->localPath."/{$path}"); } /** - * {@inheritdoc} - * * @param string $path * @param string $data - * - * @throws Flysystem\FilesystemException */ public function write(string $path, string $data) { - $this->filesystem->write($this->localPath."/{$path}", $data); + file_put_contents($this->basePath.DIRECTORY_SEPARATOR.$this->localPath."/{$path}", $data); } /** - * {@inheritdoc} - * * @param string $command * @param string $descriptor * @param string $destination @@ -226,12 +210,9 @@ public function system(string $command, string $descriptor, string $destination) } /** - * {@inheritdoc} - * * @param string $path * * @return mixed - * @throws Flysystem\FilesystemException */ public function requireFile(string $path) { @@ -239,67 +220,74 @@ public function requireFile(string $path) return require "{$this->basePath}/{$this->localPath}/{$path}"; } - $code = $this->filesystem->read($this->localPath."/{$path}"); + $code = file_get_contents($this->basePath.DIRECTORY_SEPARATOR.$this->localPath."/{$path}"); return eval(str_replace('filesystem->deleteDirectory($this->localPath); + if (!is_dir($this->basePath.DIRECTORY_SEPARATOR.$this->localPath)) { + return; + } + + $contents = $this->listDirectoryRecursively($this->basePath.DIRECTORY_SEPARATOR.$this->localPath, RecursiveIteratorIterator::CHILD_FIRST); + + /** @var SplFileInfo $file */ + foreach ($contents as $file) { + $this->deleteFileInfoObject($file); + } + + unset($contents); + + rmdir($this->basePath.DIRECTORY_SEPARATOR.$this->localPath); } /** - * {@inheritdoc} - * * This function does not perform operations in the temporary - * directory but it caches the results to avoid reprocessing. + * directory, but it caches the results to avoid reprocessing. * * @param string $algorithm * @param string $sourceFile - * @param bool $useCache + * @param bool $useCache * * @return string - * @throws Flysystem\FilesystemException */ - public function getHashFile(string $algorithm, string $sourceFile, $useCache = false): string + public function getHashFile(string $algorithm, string $sourceFile, bool $useCache = false): string { if (false === $useCache) { return hash_file($algorithm, $sourceFile); } $cacheFile = sprintf( - '%s/%s.%s', + '%s/%s/%s.%s', + $this->basePath, $this->localPath, $this->normalizePath($sourceFile), $algorithm ); - if (false === $this->filesystem->fileExists($cacheFile)) { + if (!is_file($cacheFile)) { $contents = hash_file($algorithm, $sourceFile); - $this->filesystem->write($cacheFile, $contents); + file_put_contents($cacheFile, $contents); return $contents; } - if (filemtime($sourceFile) > $this->filesystem->lastModified($cacheFile)) { + if (filemtime($sourceFile) > filemtime($cacheFile)) { $contents = hash_file($algorithm, $sourceFile); - $this->filesystem->write($cacheFile, $contents); + file_put_contents($cacheFile, $contents); return $contents; } - return $this->filesystem->read($cacheFile); + return file_get_contents($cacheFile); } /** - * {@inheritdoc} - * * @param string $path * * @return string @@ -308,4 +296,26 @@ public function normalizePath(string $path): string { return str_replace(['\\', ':', '/'], '_', $path); } + + protected function deleteFileInfoObject(SplFileInfo $file): bool + { + switch ($file->getType()) { + case 'dir': + return @rmdir((string) $file->getRealPath()); + case 'link': + return @unlink($file->getPathname()); + default: + return @unlink((string) $file->getRealPath()); + } + } + + private function listDirectoryRecursively( + string $path, + int $mode = RecursiveIteratorIterator::SELF_FIRST + ): Generator { + yield from new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), + $mode + ); + } } diff --git a/Library/FunctionDefinition.php b/Library/FunctionDefinition.php index 920e788bb5..53116f1c75 100644 --- a/Library/FunctionDefinition.php +++ b/Library/FunctionDefinition.php @@ -35,12 +35,12 @@ class FunctionDefinition extends ClassMethod /** * FunctionDefinition constructor. * - * @param string $namespace - * @param string $name + * @param string $namespace + * @param string $name * @param ClassMethodParameters|null $parameters - * @param StatementsBlock|null $statements - * @param array|null $returnType - * @param array|null $expression + * @param StatementsBlock|null $statements + * @param array|null $returnType + * @param array|null $expression */ public function __construct( string $namespace, diff --git a/Library/Logger/Formatter/CompilerFormatter.php b/Library/Logger/Formatter/CompilerFormatter.php index 34fc1406e4..edb940f9bc 100644 --- a/Library/Logger/Formatter/CompilerFormatter.php +++ b/Library/Logger/Formatter/CompilerFormatter.php @@ -48,6 +48,7 @@ public function __construct(Config $config) /** * @param array $record + * * @return string */ public function format(array $record): string diff --git a/Library/Operators/BaseOperator.php b/Library/Operators/BaseOperator.php index bd8e96b608..0616ddba9e 100644 --- a/Library/Operators/BaseOperator.php +++ b/Library/Operators/BaseOperator.php @@ -35,7 +35,7 @@ class BaseOperator * Sets if the variable must be resolved into a direct variable symbol * create a temporary value or ignore the return value. * - * @param bool $expecting + * @param bool $expecting * @param Variable|null $expectingVariable */ public function setExpectReturn(bool $expecting, ?Variable $expectingVariable = null) @@ -49,8 +49,8 @@ public function setExpectReturn(bool $expecting, ?Variable $expectingVariable = * store the result. This method returns a variable that is always stored in the heap. * * @param CompilationContext $compilationContext - * @param array $expression - * @param bool $init + * @param array $expression + * @param bool $init * * @return Variable */ @@ -82,8 +82,8 @@ public function getExpectedNonLiteral(CompilationContext $compilationContext, ar * store the result. * * @param CompilationContext $compilationContext - * @param array $expression - * @param bool $init + * @param array $expression + * @param bool $init * * @return Variable */ @@ -132,7 +132,7 @@ public function getExpected(CompilationContext $compilationContext, array $expre * on every iteration. * * @param CompilationContext $compilationContext - * @param string $type + * @param string $type * * @return Variable */ diff --git a/Library/Operators/Logical/AndOperator.php b/Library/Operators/Logical/AndOperator.php index dbdf30da1f..29b4e55040 100644 --- a/Library/Operators/Logical/AndOperator.php +++ b/Library/Operators/Logical/AndOperator.php @@ -29,7 +29,9 @@ class AndOperator extends LogicalBaseOperator /** * @param $expression * @param CompilationContext $compilationContext + * * @return CompiledExpression + * * @throws \Zephir\Exception */ public function compile($expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Logical/LogicalBaseOperator.php b/Library/Operators/Logical/LogicalBaseOperator.php index ca5c8ea0f5..f01bcb80ae 100644 --- a/Library/Operators/Logical/LogicalBaseOperator.php +++ b/Library/Operators/Logical/LogicalBaseOperator.php @@ -20,8 +20,6 @@ use Zephir\Operators\BaseOperator; /** - * LogicalBaseOperator. - * * This is the base operator for logical operators */ class LogicalBaseOperator extends BaseOperator @@ -127,10 +125,7 @@ public function compile($expression, CompilationContext $compilationContext): Co break; case 'string': - switch ($right->getType()) { - default: - throw new CompilerException('Operation is not supported between strings', $expression); - } + throw new CompilerException('Operation is not supported between strings', $expression); break; case 'variable': diff --git a/Library/Operators/Other/CloneOperator.php b/Library/Operators/Other/CloneOperator.php index b7a8d6c3c6..97011cd5bb 100644 --- a/Library/Operators/Other/CloneOperator.php +++ b/Library/Operators/Other/CloneOperator.php @@ -28,10 +28,11 @@ class CloneOperator extends BaseOperator { /** - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/ConcatOperator.php b/Library/Operators/Other/ConcatOperator.php index 620dc2ec81..11bf3ec7ec 100644 --- a/Library/Operators/Other/ConcatOperator.php +++ b/Library/Operators/Other/ConcatOperator.php @@ -13,13 +13,13 @@ namespace Zephir\Operators\Other; -use function Zephir\add_slashes; use Zephir\CompilationContext; use Zephir\CompiledExpression; use Zephir\Exception; use Zephir\Exception\CompilerException; use Zephir\Expression; use Zephir\Operators\BaseOperator; +use function Zephir\add_slashes; /** * ConcatOperator. @@ -31,7 +31,7 @@ class ConcatOperator extends BaseOperator /** * Performs concat compilation. * - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression @@ -110,9 +110,9 @@ public function compile(array $expression, CompilationContext $compilationContex } /** - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext - * @param bool $isFullString + * @param bool $isFullString * * @return array * @@ -143,7 +143,6 @@ private function _getOptimizedConcat(array $expression, CompilationContext $comp $parts = array_reverse($parts); foreach ($parts as $part) { $expr = new Expression($part); - $expr->setStringOperation(true); $compiledExpr = $this->compileExpression($expr, $compilationContext, $part['type']); switch ($compiledExpr->getType()) { diff --git a/Library/Operators/Other/EmptyOperator.php b/Library/Operators/Other/EmptyOperator.php index 471b7bddab..6dcb7aad23 100644 --- a/Library/Operators/Other/EmptyOperator.php +++ b/Library/Operators/Other/EmptyOperator.php @@ -28,10 +28,11 @@ class EmptyOperator extends BaseOperator { /** - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/FetchOperator.php b/Library/Operators/Other/FetchOperator.php index f44bc8a3e3..656862e368 100644 --- a/Library/Operators/Other/FetchOperator.php +++ b/Library/Operators/Other/FetchOperator.php @@ -29,10 +29,11 @@ class FetchOperator extends BaseOperator { /** - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/InstanceOfOperator.php b/Library/Operators/Other/InstanceOfOperator.php index 1567dfc743..3da4177c58 100644 --- a/Library/Operators/Other/InstanceOfOperator.php +++ b/Library/Operators/Other/InstanceOfOperator.php @@ -36,6 +36,7 @@ class InstanceOfOperator extends BaseOperator * @param CompilationContext $context * * @return CompiledExpression + * * @throws Exception * @throws ReflectionException */ diff --git a/Library/Operators/Other/IssetOperator.php b/Library/Operators/Other/IssetOperator.php index 45dbd814d2..39017b1334 100644 --- a/Library/Operators/Other/IssetOperator.php +++ b/Library/Operators/Other/IssetOperator.php @@ -30,10 +30,11 @@ class IssetOperator extends BaseOperator /** * Compiles an 'isset' operator. * - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/LikelyOperator.php b/Library/Operators/Other/LikelyOperator.php index 679b001bbd..b691ef3266 100644 --- a/Library/Operators/Other/LikelyOperator.php +++ b/Library/Operators/Other/LikelyOperator.php @@ -28,10 +28,11 @@ class LikelyOperator extends BaseOperator { /** - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/NewInstanceOperator.php b/Library/Operators/Other/NewInstanceOperator.php index 3081c2d520..d1f189ca0b 100644 --- a/Library/Operators/Other/NewInstanceOperator.php +++ b/Library/Operators/Other/NewInstanceOperator.php @@ -38,10 +38,11 @@ class NewInstanceOperator extends BaseOperator /** * Creates a new instance. * - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws ReflectionException * @throws Exception */ diff --git a/Library/Operators/Other/NewInstanceTypeOperator.php b/Library/Operators/Other/NewInstanceTypeOperator.php index d949ddf0ce..47be886329 100644 --- a/Library/Operators/Other/NewInstanceTypeOperator.php +++ b/Library/Operators/Other/NewInstanceTypeOperator.php @@ -34,10 +34,11 @@ class NewInstanceTypeOperator extends BaseOperator /** * Executes the operator. * - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws CompilerException */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/RangeExclusiveOperator.php b/Library/Operators/Other/RangeExclusiveOperator.php index c4f5e7bcea..c22617dd44 100644 --- a/Library/Operators/Other/RangeExclusiveOperator.php +++ b/Library/Operators/Other/RangeExclusiveOperator.php @@ -29,10 +29,11 @@ class RangeExclusiveOperator extends BaseOperator { /** - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/RangeInclusiveOperator.php b/Library/Operators/Other/RangeInclusiveOperator.php index 72ad8419b3..5e41a30422 100644 --- a/Library/Operators/Other/RangeInclusiveOperator.php +++ b/Library/Operators/Other/RangeInclusiveOperator.php @@ -29,10 +29,11 @@ class RangeInclusiveOperator extends BaseOperator { /** - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/RequireOnceOperator.php b/Library/Operators/Other/RequireOnceOperator.php index 65acfc610f..c459b6e8eb 100644 --- a/Library/Operators/Other/RequireOnceOperator.php +++ b/Library/Operators/Other/RequireOnceOperator.php @@ -27,10 +27,11 @@ class RequireOnceOperator extends BaseOperator { /** - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/RequireOperator.php b/Library/Operators/Other/RequireOperator.php index 9103b472ab..bf8139a012 100644 --- a/Library/Operators/Other/RequireOperator.php +++ b/Library/Operators/Other/RequireOperator.php @@ -27,10 +27,11 @@ class RequireOperator extends BaseOperator { /** - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/TypeHintOperator.php b/Library/Operators/Other/TypeHintOperator.php index b53c37b027..6b472b2abc 100644 --- a/Library/Operators/Other/TypeHintOperator.php +++ b/Library/Operators/Other/TypeHintOperator.php @@ -40,10 +40,11 @@ public function setStrict($strict) /** * Performs type-hint compilation. * - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/TypeOfOperator.php b/Library/Operators/Other/TypeOfOperator.php index 29120ecfd5..0d64644184 100644 --- a/Library/Operators/Other/TypeOfOperator.php +++ b/Library/Operators/Other/TypeOfOperator.php @@ -33,6 +33,7 @@ class TypeOfOperator extends BaseOperator * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile($expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Other/UnlikelyOperator.php b/Library/Operators/Other/UnlikelyOperator.php index cdef007d3a..27854b74dc 100644 --- a/Library/Operators/Other/UnlikelyOperator.php +++ b/Library/Operators/Other/UnlikelyOperator.php @@ -32,7 +32,9 @@ class UnlikelyOperator extends BaseOperator * * @param $expression * @param CompilationContext $compilationContext + * * @return CompiledExpression + * * @throws Exception */ public function compile($expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Unary/MinusOperator.php b/Library/Operators/Unary/MinusOperator.php index 2d2e74d311..e9deb251a6 100644 --- a/Library/Operators/Unary/MinusOperator.php +++ b/Library/Operators/Unary/MinusOperator.php @@ -29,6 +29,7 @@ class MinusOperator extends BaseOperator * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile($expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Unary/NotOperator.php b/Library/Operators/Unary/NotOperator.php index 04e05a983c..c701f4ec6d 100644 --- a/Library/Operators/Unary/NotOperator.php +++ b/Library/Operators/Unary/NotOperator.php @@ -27,6 +27,7 @@ class NotOperator extends BaseOperator * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile($expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Operators/Unary/PlusOperator.php b/Library/Operators/Unary/PlusOperator.php index 472589acc7..2b5a077027 100644 --- a/Library/Operators/Unary/PlusOperator.php +++ b/Library/Operators/Unary/PlusOperator.php @@ -29,6 +29,7 @@ class PlusOperator extends BaseOperator * @param CompilationContext $compilationContext * * @return CompiledExpression + * * @throws Exception */ public function compile($expression, CompilationContext $compilationContext): CompiledExpression diff --git a/Library/Optimizers/EvalExpression.php b/Library/Optimizers/EvalExpression.php index ecd151ab3d..f0d19b9faf 100644 --- a/Library/Optimizers/EvalExpression.php +++ b/Library/Optimizers/EvalExpression.php @@ -9,27 +9,26 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir\Optimizers; use Zephir\Branch; use Zephir\CompilationContext; +use Zephir\Exception; use Zephir\Exception\CompilerException; use Zephir\Expression; use Zephir\LiteralCompiledExpression; use Zephir\Variable; /** - * EvalExpression. - * * Resolves evaluation of expressions returning a C-int expression that can be used by 'if'/'while'/'do-while' statements */ class EvalExpression { - protected $unreachable = null; - - protected $unreachableElse = null; - - protected $usedVariables = []; + protected ?bool $unreachable = null; + protected ?bool $unreachableElse = null; + protected array $usedVariables = []; /** * Skips the not operator by recursively optimizing the expression at its right. @@ -37,11 +36,13 @@ class EvalExpression * @param array $expr * @param CompilationContext $compilationContext * - * @return bool|string + * @return string|null + * + * @throws Exception */ - public function optimizeNot($expr, CompilationContext $compilationContext) + public function optimizeNot(array $expr, CompilationContext $compilationContext): ?string { - /* + /** * Compile the expression negating the evaluated expression */ if ('not' == $expr['type']) { @@ -58,7 +59,7 @@ public function optimizeNot($expr, CompilationContext $compilationContext) } } - return false; + return null; } /** @@ -67,22 +68,22 @@ public function optimizeNot($expr, CompilationContext $compilationContext) * @param $exprRaw * @param CompilationContext $compilationContext * - * @throws CompilerException - * * @return bool|string + * + * @throws Exception */ public function optimize($exprRaw, CompilationContext $compilationContext) { $conditions = $this->optimizeNot($exprRaw, $compilationContext); - if (false !== $conditions) { + if (null !== $conditions) { return $conditions; } - /* + /** * Discard first level parentheses */ - if ('list' == $exprRaw['type']) { + if ('list' === $exprRaw['type']) { $expr = new Expression($exprRaw['left']); } else { $expr = new Expression($exprRaw); @@ -92,14 +93,14 @@ public function optimize($exprRaw, CompilationContext $compilationContext) $expr->setEvalMode(true); $compiledExpression = $expr->compile($compilationContext); - /* + /** * Possible corrupted expression? */ if (!\is_object($compiledExpression)) { throw new CompilerException('Corrupted expression: '.$exprRaw['type'], $exprRaw); } - /* + /** * Generate the condition according to the value returned by the evaluated expression */ switch ($compiledExpression->getType()) { @@ -146,7 +147,7 @@ public function optimize($exprRaw, CompilationContext $compilationContext) if (\is_object($possibleValue)) { $possibleValueBranch = $variableRight->getPossibleValueBranch(); if ($possibleValueBranch instanceof Branch) { - /* + /** * Check if the possible value was assigned in the root branch */ if (Branch::TYPE_ROOT == $possibleValueBranch->getType()) { @@ -199,18 +200,14 @@ public function optimize($exprRaw, CompilationContext $compilationContext) case 'char': case 'uchar': case 'long': + case 'bool': + case 'double': case 'ulong': return $variableRight->getName(); case 'string': return '!('.$compilationContext->backend->ifVariableValueUndefined($variableRight, $compilationContext, true, false).')'; - case 'bool': - return $variableRight->getName(); - - case 'double': - return $variableRight->getName(); - case 'variable': $compilationContext->headersManager->add('kernel/operators'); $variableRightCode = $compilationContext->backend->getVariableCode($variableRight); @@ -230,9 +227,9 @@ public function optimize($exprRaw, CompilationContext $compilationContext) /** * Checks if the evaluation produce unreachable code. * - * @return bool + * @return bool|null */ - public function isUnreachable() + public function isUnreachable(): ?bool { return $this->unreachable; } @@ -240,9 +237,9 @@ public function isUnreachable() /** * Checks if the evaluation not produce unreachable code. * - * @return bool + * @return bool|null */ - public function isUnreachableElse() + public function isUnreachableElse(): ?bool { return $this->unreachableElse; } @@ -260,7 +257,7 @@ public function getEvalVariable() /** * @return array */ - public function getUsedVariables() + public function getUsedVariables(): array { return $this->usedVariables; } diff --git a/Library/Optimizers/FunctionCall/ExplodeOptimizer.php b/Library/Optimizers/FunctionCall/ExplodeOptimizer.php index b9b0f0aea9..3ad81dc9d6 100644 --- a/Library/Optimizers/FunctionCall/ExplodeOptimizer.php +++ b/Library/Optimizers/FunctionCall/ExplodeOptimizer.php @@ -11,13 +11,14 @@ namespace Zephir\Optimizers\FunctionCall; -use function Zephir\add_slashes; use Zephir\Call; use Zephir\CompilationContext; use Zephir\CompiledExpression; use Zephir\Exception\CompilerException; use Zephir\Optimizers\OptimizerAbstract; +use function Zephir\add_slashes; + /** * ExplodeOptimizer. * diff --git a/Library/Optimizers/FunctionCall/GlobalsGetOptimizer.php b/Library/Optimizers/FunctionCall/GlobalsGetOptimizer.php index a6cdf43f12..d71f69fb46 100644 --- a/Library/Optimizers/FunctionCall/GlobalsGetOptimizer.php +++ b/Library/Optimizers/FunctionCall/GlobalsGetOptimizer.php @@ -9,6 +9,8 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir\Optimizers\FunctionCall; use Zephir\Call; @@ -17,8 +19,10 @@ use Zephir\Exception\CompilerException; use Zephir\Optimizers\OptimizerAbstract; +use function count; + /** - * GlobalsGetOptimizer. + * `globals_get()` internal function. * * Reads values from extensions globals */ @@ -29,21 +33,21 @@ class GlobalsGetOptimizer extends OptimizerAbstract * @param Call $call * @param CompilationContext $context * - * @throws CompilerException + * @return CompiledExpression|null * - * @return bool|CompiledExpression|mixed + * @throws CompilerException */ - public function optimize(array $expression, Call $call, CompilationContext $context) + public function optimize(array $expression, Call $call, CompilationContext $context): ?CompiledExpression { if (!isset($expression['parameters'])) { - return false; + return null; } - if (1 != \count($expression['parameters'])) { + if (1 !== count($expression['parameters'])) { throw new CompilerException("'globals_get' only accepts one parameter", $expression); } - if ('string' != $expression['parameters'][0]['parameter']['type']) { + if ('string' !== $expression['parameters'][0]['parameter']['type']) { throw new CompilerException("A string parameter is required for 'globals_get'", $expression); } @@ -53,14 +57,14 @@ public function optimize(array $expression, Call $call, CompilationContext $cont throw new CompilerException("Global '".$globalName."' cannot be read because it isn't defined", $expression); } - $globalDefinition = $context->compiler->getExtensionGlobal($globalName); + $type = $context->compiler->getExtensionGlobal($globalName)['type']; if (false !== strpos($globalName, '.')) { $parts = explode('.', $globalName); - return new CompiledExpression($globalDefinition['type'], 'ZEPHIR_GLOBAL('.$parts[0].').'.$parts[1], $expression); + return new CompiledExpression($type, 'ZEPHIR_GLOBAL('.$parts[0].').'.$parts[1], $expression); } - return new CompiledExpression($globalDefinition['type'], 'ZEPHIR_GLOBAL('.$globalName.')', $expression); + return new CompiledExpression($type, 'ZEPHIR_GLOBAL('.$globalName.')', $expression); } } diff --git a/Library/Optimizers/FunctionCall/GlobalsSetOptimizer.php b/Library/Optimizers/FunctionCall/GlobalsSetOptimizer.php index 0100eb25ec..5ff8573b52 100644 --- a/Library/Optimizers/FunctionCall/GlobalsSetOptimizer.php +++ b/Library/Optimizers/FunctionCall/GlobalsSetOptimizer.php @@ -9,6 +9,8 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir\Optimizers\FunctionCall; use Zephir\Call; @@ -18,10 +20,12 @@ use Zephir\Exception\CompilerException; use Zephir\Optimizers\OptimizerAbstract; +use function count; + /** - * Zephir\Optimizers\FunctionCall\GlobalsSetOptimizer. + * `globals_set()` internal function. * - * Writes values from extensions globals + * Writes values from extensions globals. */ class GlobalsSetOptimizer extends OptimizerAbstract { @@ -34,17 +38,17 @@ class GlobalsSetOptimizer extends OptimizerAbstract * * @return CompiledExpression */ - public function optimize(array $expression, Call $call, CompilationContext $context) + public function optimize(array $expression, Call $call, CompilationContext $context): CompiledExpression { if (!isset($expression['parameters'])) { throw new CompilerException("'globals_set' requires two parameters", $expression); } - if (2 != \count($expression['parameters'])) { + if (2 !== count($expression['parameters'])) { throw new CompilerException("'globals_set' only accepts two parameters", $expression); } - if ('string' != $expression['parameters'][0]['parameter']['type']) { + if ('string' !== $expression['parameters'][0]['parameter']['type']) { throw new CompilerException("A string parameter is required for 'globals_set'", $expression); } @@ -88,7 +92,7 @@ public function optimize(array $expression, Call $call, CompilationContext $cont } } - private function resolveInternalAccessor($globalName) + private function resolveInternalAccessor(string $globalName): string { $parts = explode('.', $globalName); @@ -101,7 +105,6 @@ private function resolveInternalAccessor($globalName) /** * TODO: Add 'hash' support - * TODO: Use zval_get_string, zval_get_long, zval_get_double for ZE3 * * @param array $definition * @param array $expression @@ -110,7 +113,7 @@ private function resolveInternalAccessor($globalName) * * @return string */ - private function resolveInternalValue(array $definition, array $expression, $name, $value) + private function resolveInternalValue(array $definition, array $expression, string $name, string $value): string { $type = $definition['type']; @@ -123,22 +126,18 @@ private function resolveInternalValue(array $definition, array $expression, $nam case 'integer': case 'long': case 'ulong': - // TODO: Use zval_get_long when we'll drop Zend Engine 2 - return strtr('Z_LVAL_P(:v)', [':v' => $value]); + return strtr('zval_get_long(:v)', [':v' => $value]); case 'string': - // TODO: Use zval_get_string when we'll drop Zend Engine 2 - return strtr('Z_STRVAL_P(:v)', [':v' => $value]); + return strtr('ZSTR_VAL(zval_get_string(:v))', [':v' => $value]); case 'char': case 'uchar': - // TODO: Use zval_get_string and zval_get_long when we'll drop Zend Engine 2 return strtr( - '(Z_TYPE_P(:v) == IS_STRING ? (Z_STRLEN_P(:v) ? Z_STRVAL_P(:v)[0] : NULL) : Z_LVAL_P(:v))', + '(Z_TYPE_P(:v) == IS_STRING ? (Z_STRLEN_P(:v) ? Z_STRVAL_P(:v)[0] : NULL) : zval_get_long(:v))', [':v' => $value] ); case 'double': case 'float': - // TODO: Use zval_get_double when we'll drop Zend Engine 2 - return strtr('Z_DVAL_P(:v)', [':v' => $value]); + return strtr('zval_get_double(:v)', [':v' => $value]); default: throw new CompilerException( "Unknown type '{$type}' to setting global variable '{$name}'.", diff --git a/Library/Optimizers/FunctionCall/ImplodeOptimizer.php b/Library/Optimizers/FunctionCall/ImplodeOptimizer.php index 7d3be029b5..651c15b55e 100644 --- a/Library/Optimizers/FunctionCall/ImplodeOptimizer.php +++ b/Library/Optimizers/FunctionCall/ImplodeOptimizer.php @@ -11,13 +11,14 @@ namespace Zephir\Optimizers\FunctionCall; -use function Zephir\add_slashes; use Zephir\Call; use Zephir\CompilationContext; use Zephir\CompiledExpression; use Zephir\Exception\CompilerException; use Zephir\Optimizers\OptimizerAbstract; +use function Zephir\add_slashes; + /** * ImplodeOptimizer. * diff --git a/Library/Optimizers/FunctionCall/MemstrOptimizer.php b/Library/Optimizers/FunctionCall/MemstrOptimizer.php index f80ef9d042..e15e454e52 100644 --- a/Library/Optimizers/FunctionCall/MemstrOptimizer.php +++ b/Library/Optimizers/FunctionCall/MemstrOptimizer.php @@ -11,13 +11,14 @@ namespace Zephir\Optimizers\FunctionCall; -use function Zephir\add_slashes; use Zephir\Call; use Zephir\CompilationContext; use Zephir\CompiledExpression; use Zephir\Compiler; use Zephir\Optimizers\OptimizerAbstract; +use function Zephir\add_slashes; + /** * MemnstrOptimizer. * diff --git a/Library/Optimizers/FunctionCall/MethodExistsOptimizer.php b/Library/Optimizers/FunctionCall/MethodExistsOptimizer.php index 5534689aad..362a22596d 100644 --- a/Library/Optimizers/FunctionCall/MethodExistsOptimizer.php +++ b/Library/Optimizers/FunctionCall/MethodExistsOptimizer.php @@ -11,12 +11,13 @@ namespace Zephir\Optimizers\FunctionCall; -use function Zephir\add_slashes; use Zephir\Call; use Zephir\CompilationContext; use Zephir\CompiledExpression; use Zephir\Optimizers\OptimizerAbstract; +use function Zephir\add_slashes; + /** * MethodExistsOptimizer. * diff --git a/Library/Optimizers/IsTypeOptimizerAbstract.php b/Library/Optimizers/IsTypeOptimizerAbstract.php index f826ef7b0a..9b1e0b92b1 100644 --- a/Library/Optimizers/IsTypeOptimizerAbstract.php +++ b/Library/Optimizers/IsTypeOptimizerAbstract.php @@ -9,12 +9,16 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir\Optimizers; use Zephir\Call; use Zephir\CompilationContext; use Zephir\CompiledExpression; -use Zephir\Exception\CompilerException; +use Zephir\Exception; + +use function count; abstract class IsTypeOptimizerAbstract extends OptimizerAbstract { @@ -23,30 +27,26 @@ abstract class IsTypeOptimizerAbstract extends OptimizerAbstract * @param Call $call * @param CompilationContext $context * - * @throws CompilerException + * @return CompiledExpression|null * - * @return bool|CompiledExpression|mixed + * @throws Exception */ - public function optimize(array $expression, Call $call, CompilationContext $context) + public function optimize(array $expression, Call $call, CompilationContext $context): ?CompiledExpression { - if (!isset($expression['parameters'])) { - return false; - } - - if (1 != \count($expression['parameters'])) { - return false; + if (!isset($expression['parameters']) || count($expression['parameters']) !== 1) { + return null; } - $resolvedParams = $call->getReadOnlyResolvedParams($expression['parameters'], $context, $expression); + $resolvedParam = $call->getReadOnlyResolvedParams($expression['parameters'], $context, $expression)[0]; - if ('IS_BOOL' == $this->getType()) { + if ('IS_BOOL' === $this->getType()) { $condition = sprintf( '(Z_TYPE_P(%s) == IS_TRUE || Z_TYPE_P(%s) == IS_FALSE)', - $resolvedParams[0], - $resolvedParams[0] + $resolvedParam, + $resolvedParam, ); } else { - $condition = 'Z_TYPE_P('.$resolvedParams[0].') == '.$this->getType(); + $condition = 'Z_TYPE_P('.$resolvedParam.') == '.$this->getType(); } return new CompiledExpression('bool', $condition, $expression); diff --git a/Library/Optimizers/MathOptimizer.php b/Library/Optimizers/MathOptimizer.php index 09c297cced..36e7ba3da8 100644 --- a/Library/Optimizers/MathOptimizer.php +++ b/Library/Optimizers/MathOptimizer.php @@ -9,6 +9,8 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir\Optimizers; use Zephir\Call; @@ -16,9 +18,6 @@ use Zephir\CompiledExpression; use Zephir\Exception\CompilerException; -/** - * Class OptimizerAbstract. - */ abstract class MathOptimizer extends OptimizerAbstract { /** @@ -47,7 +46,7 @@ public function optimize(array $expression, Call $call, CompilationContext $cont return false; } - /* + /** * Resolve parameters as vars */ $call->getResolvedParams($expression['parameters'], $context, $expression); diff --git a/Library/Optimizers/OptimizerAbstract.php b/Library/Optimizers/OptimizerAbstract.php index 0cdf10f68c..2a8ef25745 100644 --- a/Library/Optimizers/OptimizerAbstract.php +++ b/Library/Optimizers/OptimizerAbstract.php @@ -9,14 +9,13 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir\Optimizers; use Zephir\Call; use Zephir\CompilationContext; -/** - * Class OptimizerAbstract. - */ abstract class OptimizerAbstract { /** diff --git a/Library/Parser/Parser.php b/Library/Parser/Parser.php index 722ab6b7b4..be20898ba4 100644 --- a/Library/Parser/Parser.php +++ b/Library/Parser/Parser.php @@ -47,9 +47,9 @@ public function getVersion(): ?string * @param string $filePath Absolute path to the *.zep file * * @return array + * * @throws InvalidArgumentException * @throws ParseException - * * @throws IllegalStateException */ public function parse(string $filePath): array diff --git a/Library/Passes/CallGathererPass.php b/Library/Passes/CallGathererPass.php index b9f848b774..52807cf31e 100644 --- a/Library/Passes/CallGathererPass.php +++ b/Library/Passes/CallGathererPass.php @@ -16,10 +16,8 @@ use Zephir\StatementsBlock; /** - * Zephir\Passes\CallGathererPass. - * * This pass counts how many times the same function is called inside a - * statements block. It also count how many times a method is calling + * statements block. It also counts how many times a method is calling * trying to track the possible caller. * * This pass is used by the function/method caches to explore possible @@ -27,11 +25,11 @@ */ class CallGathererPass { - protected $functionCalls = []; + protected array $functionCalls = []; - protected $methodCalls = []; + protected array $methodCalls = []; - protected $compilationContext; + protected CompilationContext $compilationContext; /** * CallGathererPass constructor. @@ -48,7 +46,7 @@ public function __construct(CompilationContext $compilationContext) * * @return CompilationContext */ - public function getCompilationContext() + public function getCompilationContext(): CompilationContext { return $this->compilationContext; } @@ -60,7 +58,7 @@ public function getCompilationContext() * * @return int */ - public function getNumberOfFunctionCalls($funcName) + public function getNumberOfFunctionCalls(string $funcName): int { if (isset($this->functionCalls[$funcName])) { return $this->functionCalls[$funcName]; @@ -77,7 +75,7 @@ public function getNumberOfFunctionCalls($funcName) * * @return int */ - public function getNumberOfMethodCalls($className, $methodName) + public function getNumberOfMethodCalls(string $className, string $methodName): int { if (isset($this->methodCalls[$className][$methodName])) { return $this->methodCalls[$className][$methodName]; @@ -91,7 +89,7 @@ public function getNumberOfMethodCalls($className, $methodName) * * @return array */ - public function getAllMethodCalls() + public function getAllMethodCalls(): array { return $this->methodCalls; } @@ -209,16 +207,24 @@ public function passExpression(array $expression) $this->passExpression($expression['right']); break; - case 'typeof': - $this->passExpression($expression['left']); - break; - case 'minus': - $this->passExpression($expression['left']); - break; - - case 'not': case 'bitwise_not': + case 'not': + case 'static-property-access': + case 'array-access': + case 'property-string-access': + case 'property-dynamic-access': + case 'property-access': + case 'unlikely': + case 'likely': + case 'instanceof': + case 'empty': + case 'isset': + case 'list': + case 'require_once': + case 'require': + case 'clone': + case 'typeof': $this->passExpression($expression['left']); break; @@ -265,46 +271,11 @@ public function passExpression(array $expression) $this->passNewType($expression); break; - case 'property-access': - case 'property-dynamic-access': - case 'property-string-access': - case 'array-access': - case 'static-property-access': - $this->passExpression($expression['left']); - break; - - case 'fetch': - $this->passExpression($expression['right']); - break; - - case 'isset': - case 'empty': - case 'instanceof': - case 'likely': - case 'unlikely': - $this->passExpression($expression['left']); - break; - - case 'list': - $this->passExpression($expression['left']); - break; - case 'cast': - $this->passExpression($expression['right']); - break; - case 'type-hint': - $this->passExpression($expression['right']); - break; - - case 'clone': - case 'require': - case 'require_once': - $this->passExpression($expression['left']); - break; - - case 'ternary': case 'short-ternary': + case 'ternary': + case 'fetch': $this->passExpression($expression['right']); break; @@ -318,6 +289,16 @@ public function passStatementBlock(array $statements) { foreach ($statements as $statement) { switch ($statement['type']) { + // empty statement != empty operator + case 'empty': + case 'comment': + case 'cblock': + case 'unset': + case 'continue': + case 'break': + case 'declare': + break; + case 'let': $this->passLetStatement($statement); break; @@ -330,9 +311,6 @@ public function passStatementBlock(array $statements) } break; - case 'declare': - break; - case 'if': if (isset($statement['expr'])) { $this->passExpression($statement['expr']); @@ -362,16 +340,8 @@ public function passStatementBlock(array $statements) break; case 'while': - case 'do-while': - if (isset($statement['expr'])) { - $this->passExpression($statement['expr']); - } - if (isset($statement['statements'])) { - $this->passStatementBlock($statement['statements']); - } - break; - case 'for': + case 'do-while': if (isset($statement['expr'])) { $this->passExpression($statement['expr']); } @@ -380,36 +350,25 @@ public function passStatementBlock(array $statements) } break; + case 'throw': + case 'require_once': + case 'require': case 'return': if (isset($statement['expr'])) { $this->passExpression($statement['expr']); } break; - case 'loop': - if (isset($statement['statements'])) { - $this->passStatementBlock($statement['statements']); - } - break; - case 'try-catch': + case 'loop': if (isset($statement['statements'])) { $this->passStatementBlock($statement['statements']); } break; - case 'throw': - if (isset($statement['expr'])) { - $this->passExpression($statement['expr']); - } - break; - - case 'fetch': - $this->passExpression($statement['expr']); - break; - - case 'mcall': case 'scall': + case 'mcall': + case 'fetch': $this->passExpression($statement['expr']); break; @@ -426,22 +385,6 @@ public function passStatementBlock(array $statements) $this->passCall($expr); break; - case 'require': - case 'require_once': - if (isset($statement['expr'])) { - $this->passExpression($statement['expr']); - } - break; - - case 'break': - case 'continue': - case 'unset': - case 'cblock': - case 'comment': - // empty statement != empty operator - case 'empty': - break; - default: echo 'SCGP=', $statement['type']; } diff --git a/Library/Passes/LocalContextPass.php b/Library/Passes/LocalContextPass.php index 3640e8412f..46fde8523c 100644 --- a/Library/Passes/LocalContextPass.php +++ b/Library/Passes/LocalContextPass.php @@ -419,8 +419,8 @@ public function passExpression(array $expression) case 'require_once': case 'clone': case 'likely': - case 'unlikely' - /* do special pass later */: + case 'unlikely': + /* do special pass later */ case 'ternary': case 'short-ternary': $this->passExpression($expression['left']); diff --git a/Library/Statements/EchoStatement.php b/Library/Statements/EchoStatement.php index 667d1255de..4beaf8a75d 100644 --- a/Library/Statements/EchoStatement.php +++ b/Library/Statements/EchoStatement.php @@ -11,11 +11,12 @@ namespace Zephir\Statements; -use function Zephir\add_slashes; use Zephir\CompilationContext; use Zephir\Exception\CompilerException; use Zephir\Expression; +use function Zephir\add_slashes; + /** * EchoStatement. * diff --git a/Library/Statements/ForStatement.php b/Library/Statements/ForStatement.php index 60d9700eab..f528947fbb 100644 --- a/Library/Statements/ForStatement.php +++ b/Library/Statements/ForStatement.php @@ -11,7 +11,6 @@ namespace Zephir\Statements; -use function Zephir\add_slashes; use Zephir\CompilationContext; use Zephir\Detectors\ForValueUseDetector; use Zephir\Exception\CompilerException; @@ -22,6 +21,8 @@ use Zephir\StatementsBlock; use Zephir\Variable; +use function Zephir\add_slashes; + /** * ForStatement. * diff --git a/Library/Statements/Let/Variable.php b/Library/Statements/Let/Variable.php index 8eae559ed2..00c0b67ce0 100644 --- a/Library/Statements/Let/Variable.php +++ b/Library/Statements/Let/Variable.php @@ -11,7 +11,6 @@ namespace Zephir\Statements\Let; -use function Zephir\add_slashes; use Zephir\CodePrinter; use Zephir\CompilationContext; use Zephir\CompiledExpression; @@ -20,6 +19,8 @@ use Zephir\Exception\IllegalOperationException; use Zephir\Variable as ZephirVariable; +use function Zephir\add_slashes; + /** * Zephir\Statements\Let\Variable. * diff --git a/Library/Statements/LetStatement.php b/Library/Statements/LetStatement.php index ddfefd9a30..6663c36738 100644 --- a/Library/Statements/LetStatement.php +++ b/Library/Statements/LetStatement.php @@ -15,6 +15,9 @@ use Zephir\Detectors\ReadDetector; use Zephir\Exception\CompilerException; use Zephir\Expression; +use Zephir\Expression\Builder\BuilderFactory; +use Zephir\Expression\Builder\Operators\AssignVariableOperator; +use Zephir\Expression\Builder\Operators\BinaryOperator; use Zephir\Statements\Let\ArrayIndex as LetArrayIndex; use Zephir\Statements\Let\ArrayIndexAppend as LetArrayIndexAppend; use Zephir\Statements\Let\Decr as LetDecr; @@ -37,9 +40,6 @@ use Zephir\Statements\Let\StaticPropertySub as LetStaticPropertySub; use Zephir\Statements\Let\Variable as LetVariable; use Zephir\Statements\Let\VariableAppend as LetVariableAppend; -use Zephir\Expression\Builder\BuilderFactory; -use Zephir\Expression\Builder\Operators\AssignVariableOperator; -use Zephir\Expression\Builder\Operators\BinaryOperator; /** * LetStatement. @@ -268,7 +268,9 @@ public function compile(CompilationContext $compilationContext) /** * @param array $assignment + * * @return array + * * @throws CompilerException */ protected function replaceAssignBitwiseOnDirect(array $assignment): array @@ -299,7 +301,7 @@ protected function replaceAssignBitwiseOnDirect(array $assignment): array } if ($assignment['assign-type'] !== 'variable') { - throw new CompilerException("Operator '" . $assignment['operator'] . "' is not supported assign-type: " . $assignment['assign-type']); + throw new CompilerException("Operator '".$assignment['operator']."' is not supported assign-type: ".$assignment['assign-type']); } $builderExpr = BuilderFactory::getInstance(); @@ -311,6 +313,7 @@ protected function replaceAssignBitwiseOnDirect(array $assignment): array ->build(); $assignment['operator'] = AssignVariableOperator::OPERATOR_ASSIGN; + return $assignment; } } diff --git a/Library/Statements/ReturnStatement.php b/Library/Statements/ReturnStatement.php index 37f7f28d03..5ffc637dec 100644 --- a/Library/Statements/ReturnStatement.php +++ b/Library/Statements/ReturnStatement.php @@ -11,13 +11,16 @@ namespace Zephir\Statements; -use function Zephir\add_slashes; +use ReflectionException; use Zephir\CompilationContext; +use Zephir\Exception; use Zephir\Exception\CompilerException; use Zephir\Exception\InvalidTypeException; use Zephir\Expression; use Zephir\Types; +use function Zephir\add_slashes; + /** * ReturnStatement. * @@ -28,9 +31,10 @@ final class ReturnStatement extends StatementAbstract /** * @param CompilationContext $compilationContext * - * @throws CompilerException + * @throws Exception + * @throws ReflectionException */ - public function compile(CompilationContext $compilationContext) + public function compile(CompilationContext $compilationContext): void { $statement = $this->statement; @@ -50,14 +54,14 @@ public function compile(CompilationContext $compilationContext) ); } - /* + /** * Use return member for properties on this */ if ('property-access' == $statement['expr']['type']) { if ('variable' == $statement['expr']['left']['type']) { if ('this' == $statement['expr']['left']['value']) { if ('variable' == $statement['expr']['right']['type']) { - /* + /** * If the property is accessed on 'this', we check if the property does exist. */ $property = $statement['expr']['right']['value']; @@ -82,7 +86,7 @@ public function compile(CompilationContext $compilationContext) } } - /* + /** * Fetches return_value and tries to return the value directly there. */ $variable = $compilationContext->symbolTable->getVariable('return_value'); @@ -92,13 +96,13 @@ public function compile(CompilationContext $compilationContext) $expr->setReadOnly(true); $resolvedExpr = $expr->compile($compilationContext); - /* + /** * Here we check if the variable returns a compatible type according to its type hints */ if ($currentMethod->hasReturnTypes()) { switch ($resolvedExpr->getType()) { case Types::T_NULL: - if (false == $currentMethod->areReturnTypesNullCompatible()) { + if (!$currentMethod->areReturnTypesNullCompatible() && !$currentMethod->isMixed()) { throw new InvalidTypeException($resolvedExpr->getType(), $statement['expr']); } break; @@ -109,31 +113,32 @@ public function compile(CompilationContext $compilationContext) case Types::T_ULONG: case Types::T_CHAR: case Types::T_UCHAR: - if (false == $currentMethod->areReturnTypesIntCompatible()) { + if (!$currentMethod->areReturnTypesIntCompatible() && !$currentMethod->isMixed()) { throw new InvalidTypeException($resolvedExpr->getType(), $statement['expr']); } break; case Types::T_BOOL: - if (false == $currentMethod->areReturnTypesBoolCompatible()) { + if (!$currentMethod->areReturnTypesBoolCompatible() && !$currentMethod->isMixed()) { throw new InvalidTypeException($resolvedExpr->getType(), $statement['expr']); } break; case Types::T_DOUBLE: - if (false == $currentMethod->areReturnTypesDoubleCompatible()) { + if (!$currentMethod->areReturnTypesDoubleCompatible() && !$currentMethod->isMixed()) { throw new InvalidTypeException($resolvedExpr->getType(), $statement['expr']); } break; case Types::T_STRING: case Types::T_ISTRING: - if (false == $currentMethod->areReturnTypesStringCompatible()) { + if (!$currentMethod->areReturnTypesStringCompatible() && !$currentMethod->isMixed()) { throw new InvalidTypeException($resolvedExpr->getType(), $statement['expr']); } break; case Types::T_VARIABLE: + case Types::T_MIXED: $symbolVariable = $compilationContext->symbolTable->getVariableForRead( $resolvedExpr->getCode(), $compilationContext, @@ -147,31 +152,32 @@ public function compile(CompilationContext $compilationContext) case Types::T_ULONG: case Types::T_CHAR: case Types::T_UCHAR: - if (false == $currentMethod->areReturnTypesIntCompatible()) { + if (!$currentMethod->areReturnTypesIntCompatible() && !$currentMethod->isMixed()) { throw new InvalidTypeException($resolvedExpr->getType(), $statement['expr']); } break; case Types::T_DOUBLE: - if (false == $currentMethod->areReturnTypesDoubleCompatible()) { + if (!$currentMethod->areReturnTypesDoubleCompatible() && !$currentMethod->isMixed()) { throw new InvalidTypeException($resolvedExpr->getType(), $statement['expr']); } break; case Types::T_STRING: case Types::T_ISTRING: - if (false == $currentMethod->areReturnTypesStringCompatible()) { + if (!$currentMethod->areReturnTypesStringCompatible() && !$currentMethod->isMixed()) { throw new InvalidTypeException($resolvedExpr->getType(), $statement['expr']); } break; case Types::T_BOOL: - if (false == $currentMethod->areReturnTypesBoolCompatible()) { + if (!$currentMethod->areReturnTypesBoolCompatible() && !$currentMethod->isMixed()) { throw new InvalidTypeException($resolvedExpr->getType(), $statement['expr']); } break; case Types::T_VARIABLE: + case Types::T_MIXED: break; } break; @@ -217,6 +223,7 @@ public function compile(CompilationContext $compilationContext) break; case Types::T_VARIABLE: + case Types::T_MIXED: if (!isset($symbolVariable)) { $symbolVariable = $compilationContext->symbolTable->getVariableForRead( $resolvedExpr->getCode(), @@ -252,6 +259,7 @@ public function compile(CompilationContext $compilationContext) break; case Types::T_VARIABLE: + case Types::T_MIXED: if ('this_ptr' == $symbolVariable->getName()) { $codePrinter->output('RETURN_THIS();'); } else { @@ -314,7 +322,7 @@ public function compile(CompilationContext $compilationContext) return; } - /* + /** * Return without an expression */ $codePrinter->output('RETURN_MM_NULL();'); diff --git a/Library/Statements/UnsetStatement.php b/Library/Statements/UnsetStatement.php index 18922c8315..3dd7e4bc7d 100644 --- a/Library/Statements/UnsetStatement.php +++ b/Library/Statements/UnsetStatement.php @@ -94,9 +94,11 @@ public function compile(CompilationContext $compilationContext): void } /** - * @param array $expression + * @param array $expression * @param CompilationContext $compilationContext + * * @return CompilationContext + * * @throws Exception */ private function generateUnsetPropertyFromObject(array $expression, CompilationContext $compilationContext): CompilationContext diff --git a/Library/StatementsBlock.php b/Library/StatementsBlock.php index 8f1a1a86a0..5067263589 100644 --- a/Library/StatementsBlock.php +++ b/Library/StatementsBlock.php @@ -11,7 +11,7 @@ namespace Zephir; -use Zephir\Operators\Other\RequireOnceOperator; +use ReflectionException; use Zephir\Passes\MutateGathererPass; use Zephir\Statements\BreakStatement; use Zephir\Statements\ContinueStatement; @@ -30,10 +30,9 @@ use Zephir\Statements\TryCatchStatement; use Zephir\Statements\UnsetStatement; use Zephir\Statements\WhileStatement; +use function count; /** - * StatementsBlock. - * * This represents a single basic block in Zephir. * A statements block is simply a container of instructions that execute sequentially. */ @@ -41,7 +40,7 @@ class StatementsBlock { protected $statements; - protected $unreachable; + protected ?bool $unreachable = null; protected $debug = false; @@ -100,8 +99,11 @@ public function isLoop($loop) * @param int $branchType * * @return Branch + * + * @throws Exception + * @throws ReflectionException */ - public function compile(CompilationContext $compilationContext, $unreachable = false, $branchType = Branch::TYPE_UNKNOWN) + public function compile(CompilationContext $compilationContext, ?bool $unreachable = null, int $branchType = Branch::TYPE_UNKNOWN): Branch { $compilationContext->codePrinter->increaseLevel(); ++$compilationContext->currentBranch; @@ -113,7 +115,7 @@ public function compile(CompilationContext $compilationContext, $unreachable = f $currentBranch->setType($branchType); $currentBranch->setUnreachable($unreachable); - /* + /** * Activate branch in the branch manager */ $compilationContext->branchManager->addBranch($currentBranch); @@ -122,7 +124,7 @@ public function compile(CompilationContext $compilationContext, $unreachable = f $statements = $this->statements; - /* + /** * Reference the block if it belongs to a loop */ if ($this->loop) { @@ -155,7 +157,7 @@ public function compile(CompilationContext $compilationContext, $unreachable = f } } - /* + /** * Show warnings if code is generated when the 'unreachable state' is 'on' */ if (true === $this->unreachable) { @@ -354,14 +356,14 @@ public function compile(CompilationContext $compilationContext, $unreachable = f } } - /* + /** * Reference the block if it belongs to a loop */ if ($this->loop) { array_pop($compilationContext->cycleBlocks); } - /* + /** * Traverses temporal variables created in a specific branch * marking them as idle */ @@ -380,7 +382,7 @@ public function compile(CompilationContext $compilationContext, $unreachable = f * * @return array */ - public function getStatements() + public function getStatements(): array { return $this->statements; } @@ -390,7 +392,7 @@ public function getStatements() * * @param array $statements */ - public function setStatements(array $statements) + public function setStatements(array $statements): void { $this->statements = $statements; } @@ -420,9 +422,9 @@ public function getLastStatement() * * @return bool */ - public function isEmpty() + public function isEmpty(): bool { - return 0 == \count($this->statements); + return 0 === count($this->statements); } /** @@ -432,11 +434,12 @@ public function isEmpty() * * @return MutateGathererPass */ - public function getMutateGatherer($pass = false) + public function getMutateGatherer(bool $pass = false): MutateGathererPass { if (!$this->mutateGatherer) { $this->mutateGatherer = new MutateGathererPass(); } + if ($pass) { $this->mutateGatherer->pass($this); } diff --git a/Library/StaticCall.php b/Library/StaticCall.php index 3099f93750..86329d27e8 100644 --- a/Library/StaticCall.php +++ b/Library/StaticCall.php @@ -11,9 +11,14 @@ namespace Zephir; +use ReflectionException; use Zephir\Detectors\ReadDetector; use Zephir\Exception\CompilerException; +use function count; +use function in_array; +use function is_string; + /** * StaticCall. * @@ -27,21 +32,16 @@ class StaticCall extends Call * @param Expression $expr * @param CompilationContext $compilationContext * - * @throws CompilerException - * * @return CompiledExpression + * + * @throws ReflectionException */ - public function compile(Expression $expr, CompilationContext $compilationContext) + public function compile(Expression $expr, CompilationContext $compilationContext): CompiledExpression { $expression = $expr->getExpression(); $methodName = strtolower($expression['name']); - - if (isset($expression['dynamic'])) { - $dynamicMethod = $expression['dynamic']; - } else { - $dynamicMethod = false; - } + $dynamicMethod = $expression['dynamic'] ?? false; $symbolVariable = null; @@ -90,8 +90,8 @@ public function compile(Expression $expr, CompilationContext $compilationContext $className = $expression['class']; $classDefinition = false; - if (!\in_array($className, ['self', 'static', 'parent'])) { - if (\is_string($className)) { + if (!in_array($className, ['self', 'static', 'parent'])) { + if (is_string($className)) { $className = $compilationContext->getFullName($className); if ($compiler->isClass($className)) { $classDefinition = $compiler->getClassDefinition($className); @@ -113,16 +113,15 @@ public function compile(Expression $expr, CompilationContext $compilationContext } } } else { - if ('parent' == $className) { - $classDefinition = $compilationContext->classDefinition; + $classDefinition = $compilationContext->classDefinition; + + if ('parent' === $className) { $extendsClass = $classDefinition->getExtendsClass(); if (!$extendsClass) { throw new CompilerException('Cannot call method "'.$methodName.'" on parent because class '.$classDefinition->getCompleteName().' does not extend any class', $expression); } $currentClassDefinition = $classDefinition; $classDefinition = $classDefinition->getExtendsClassDefinition(); - } else { - $classDefinition = $compilationContext->classDefinition; } } } @@ -147,10 +146,8 @@ public function compile(Expression $expr, CompilationContext $compilationContext throw new CompilerException("Cannot call private method '".$methodName."' out of its scope", $expression); } - if (!\in_array($className, ['self', 'static', 'parent'])) { - if (!$method->isStatic()) { - throw new CompilerException("Cannot call non-static method '".$methodName."' in a static way", $expression); - } + if (!in_array($className, ['self', 'static', 'parent']) && !$method->isStatic()) { + throw new CompilerException("Cannot call non-static method '".$methodName."' in a static way", $expression); } if (!$classDefinition->hasMethod('__callStatic')) { @@ -158,11 +155,7 @@ public function compile(Expression $expr, CompilationContext $compilationContext /** * Try to produce an exception if method is called with a wrong number of parameters */ - if (isset($expression['parameters'])) { - $callNumberParameters = \count($expression['parameters']); - } else { - $callNumberParameters = 0; - } + $callNumberParameters = isset($expression['parameters']) ? count($expression['parameters']) : 0; $classMethod = $classDefinition->getMethod($methodName); $expectedNumberParameters = $classMethod->getNumberOfRequiredParameters(); @@ -189,7 +182,7 @@ public function compile(Expression $expr, CompilationContext $compilationContext } } - /* + /** * Call static methods in the same class, use the special context 'self' or special context 'static' * Call static methods in the 'self' context */ @@ -197,13 +190,13 @@ public function compile(Expression $expr, CompilationContext $compilationContext if ($dynamicClass) { $this->callFromDynamicClass($methodName, $expression, $symbolVariable, $mustInit, $isExpecting, $compilationContext); } else { - if (\in_array($className, ['self', 'static']) || $classDefinition == $compilationContext->classDefinition) { - $this->call(strtoupper($className), $methodName, $expression, $symbolVariable, $mustInit, $isExpecting, $classDefinition, $compilationContext, isset($method) ? $method : null); + if (in_array($className, ['self', 'static']) || $classDefinition == $compilationContext->classDefinition) { + $this->call(strtoupper($className), $methodName, $expression, $mustInit, $isExpecting, $compilationContext, $symbolVariable, $method ?? null); } else { if ('parent' == $className) { - $this->callParent($methodName, $expression, $symbolVariable, $mustInit, $isExpecting, $currentClassDefinition, $compilationContext, isset($method) ? $method : null); + $this->callParent($methodName, $expression, $symbolVariable, $mustInit, $isExpecting, $currentClassDefinition, $compilationContext, $method ?? null); } else { - $this->callFromClass($methodName, $expression, $symbolVariable, $mustInit, $isExpecting, $classDefinition, $compilationContext, isset($method) ? $method : null); + $this->callFromClass($methodName, $expression, $symbolVariable, $mustInit, $isExpecting, $classDefinition, $compilationContext, $method ?? null); } } } @@ -213,36 +206,26 @@ public function compile(Expression $expr, CompilationContext $compilationContext } } - /* + /** * Add the last call status to the current symbol table */ $this->addCallStatusFlag($compilationContext); - /* + /** * Transfer the return type-hint to the returned variable */ - if ($isExpecting) { - if (isset($method)) { - if ($method instanceof ClassMethod) { - $returnClassTypes = $method->getReturnClassTypes(); - if (null !== $returnClassTypes) { - $symbolVariable->setDynamicTypes('object'); - foreach ($returnClassTypes as $classType) { - $symbolVariable->setClassTypes($compilationContext->getFullName($classType)); - } - } + if ($isExpecting && isset($method) && $method instanceof ClassMethod) { + $symbolVariable->setDynamicTypes('object'); + foreach ($method->getReturnClassTypes() as $classType) { + $symbolVariable->setClassTypes($compilationContext->getFullName($classType)); + } - $returnTypes = $method->getReturnTypes(); - if (null !== $returnTypes) { - foreach ($returnTypes as $dataType => $returnType) { - $symbolVariable->setDynamicTypes($dataType); - } - } - } + foreach ($method->getReturnTypes() as $dataType => $returnType) { + $symbolVariable->setDynamicTypes($dataType); } } - /* + /** * We can mark temporary variables generated as idle here */ foreach ($this->getTemporalVariables() as $tempVariable) { @@ -262,36 +245,36 @@ public function compile(Expression $expr, CompilationContext $compilationContext * @param string $context SELF / STATIC * @param string $methodName * @param array $expression - * @param Variable $symbolVariable + * @param Variable|null $symbolVariable * @param bool $mustInit * @param bool $isExpecting - * @param ClassDefinition $classDefinition * @param CompilationContext $compilationContext - * @param ClassMethod $method + * @param ClassMethod|null $method */ protected function call( - $context, - $methodName, + string $context, + string $methodName, array $expression, - $symbolVariable, - $mustInit, - $isExpecting, - ClassDefinition $classDefinition, + bool $mustInit, + bool $isExpecting, CompilationContext $compilationContext, - ClassMethod $method + ?Variable $symbolVariable = null, + ?ClassMethod $method = null ) { - if (!\in_array($context, ['SELF', 'STATIC'])) { + if (!in_array($context, ['SELF', 'STATIC'])) { $context = 'SELF'; } - /* Do not optimize static:: calls, to allow late static binding */ - if ('SELF' == $context) { + /** + * Do not optimize static:: calls, to allow late static binding + */ + if ('SELF' === $context) { $method = $method->getOptimizedMethod(); } $codePrinter = $compilationContext->codePrinter; - /* + /** * Call static methods must grown the stack */ $compilationContext->symbolTable->mustGrownStack(true); @@ -305,12 +288,11 @@ protected function call( * Check if the method call can have an inline cache. */ $methodCache = $compilationContext->cacheManager->getStaticMethodCache(); - $cachePointer = $methodCache->get($compilationContext, isset($method) ? $method : null, false); + $cachePointer = $methodCache->get($compilationContext, $method ?? null, false); - if (isset($expression['parameters']) && \count($expression['parameters'])) { + $params = []; + if (isset($expression['parameters']) && count($expression['parameters'])) { $params = $this->getResolvedParams($expression['parameters'], $compilationContext, $expression); - } else { - $params = []; } $isInternal = false; @@ -322,7 +304,7 @@ protected function call( $symbol = $compilationContext->backend->getVariableCodePointer($symbolVariable); } - $paramCount = \count($params); + $paramCount = count($params); $paramsStr = $paramCount ? ', '.implode(', ', $params) : ''; if (!$isInternal) { if ($isExpecting) { @@ -350,7 +332,7 @@ protected function call( } } - /* + /** * Temporary variables must be copied if they have more than one reference */ foreach ($this->getMustCheckForCopyVariables() as $checkVariable) { @@ -376,9 +358,8 @@ protected function callParent($methodName, array $expression, $symbolVariable, $ { $codePrinter = $compilationContext->codePrinter; $classCe = $classDefinition->getClassEntry($compilationContext); - //$className = str_replace('\\', '\\\\', $classDefinition->getCompleteName()); - /* + /** * Call static methods must grown the stack */ $compilationContext->symbolTable->mustGrownStack(true); @@ -394,13 +375,12 @@ protected function callParent($methodName, array $expression, $symbolVariable, $ $methodCache = $compilationContext->cacheManager->getStaticMethodCache(); $cachePointer = $methodCache->get($compilationContext, isset($method) ? $method : null); - if (isset($expression['parameters']) && \count($expression['parameters'])) { + $params = []; + if (isset($expression['parameters']) && count($expression['parameters'])) { $params = $this->getResolvedParams($expression['parameters'], $compilationContext, $expression); - } else { - $params = []; } - if (!\count($params)) { + if (!count($params)) { if ($isExpecting) { if ('return_value' == $symbolVariable->getName()) { $codePrinter->output('ZEPHIR_RETURN_CALL_PARENT('.$classCe.', getThis(), "'.$methodName.'", '.$cachePointer.');'); @@ -422,7 +402,7 @@ protected function callParent($methodName, array $expression, $symbolVariable, $ } } - /* + /** * Temporary variables must be copied if they have more than one reference */ foreach ($this->getMustCheckForCopyVariables() as $checkVariable) { @@ -449,19 +429,14 @@ protected function callFromClass($methodName, array $expression, $symbolVariable $codePrinter = $compilationContext->codePrinter; if ($classDefinition->isBundled()) { - //if (!$compilationContext->symbolTable->hasVariable($variableName)) { - $classEntryVariable = $compilationContext->symbolTable->addTemp('zend_class_entry', $compilationContext); $compilationContext->backend->fetchClass($classEntryVariable, 'SL("'.str_replace('\\', '\\\\', $classDefinition->getName()).'")', false, $compilationContext); - //} - - //$classEntryVariable = $compilationContext->symbolTable->getVariableForWrite($variableName, $compilationContext, $expression); $classEntry = $classEntryVariable->getName(); } else { $classEntry = $classDefinition->getClassEntry($compilationContext); } - /* + /** * Call static methods must grown the stack */ $compilationContext->symbolTable->mustGrownStack(true); @@ -481,17 +456,16 @@ protected function callFromClass($methodName, array $expression, $symbolVariable $methodCache = $compilationContext->cacheManager->getStaticMethodCache(); $cachePointer = $methodCache->get($compilationContext, isset($method) ? $method : null); - if (isset($expression['parameters']) && \count($expression['parameters'])) { + $params = []; + if (isset($expression['parameters']) && count($expression['parameters'])) { $params = $this->getResolvedParams($expression['parameters'], $compilationContext, $expression); - } else { - $params = []; } if ($symbolVariable) { $symbol = $compilationContext->backend->getVariableCodePointer($symbolVariable); } - $paramCount = \count($params); + $paramCount = count($params); $paramsStr = $paramCount ? ', '.implode(', ', $params) : ''; if ($method->isInternal()) { @@ -520,7 +494,7 @@ protected function callFromClass($methodName, array $expression, $symbolVariable } } - /* + /** * Temporary variables must be copied if they have more than one reference */ foreach ($this->getMustCheckForCopyVariables() as $checkVariable) { @@ -544,7 +518,7 @@ protected function callFromDynamicClass($methodName, array $expression, $symbolV { $codePrinter = $compilationContext->codePrinter; - /* + /** * Call static methods must grown the stack */ $compilationContext->symbolTable->mustGrownStack(true); @@ -556,10 +530,9 @@ protected function callFromDynamicClass($methodName, array $expression, $symbolV $cachePointer = 'NULL, 0'; - if (isset($expression['parameters']) && \count($expression['parameters'])) { + $params = []; + if (isset($expression['parameters']) && count($expression['parameters'])) { $params = $this->getResolvedParams($expression['parameters'], $compilationContext, $expression); - } else { - $params = []; } /** @@ -586,7 +559,7 @@ protected function callFromDynamicClass($methodName, array $expression, $symbolV $symbol = $compilationContext->backend->getVariableCodePointer($symbolVariable); } - if (!\count($params)) { + if (!count($params)) { if ($isExpecting) { if ('return_value' == $symbolVariable->getName()) { $codePrinter->output('ZEPHIR_RETURN_CALL_CE_STATIC('.$classEntry.', "'.$methodName.'", '.$cachePointer.');'); @@ -608,7 +581,7 @@ protected function callFromDynamicClass($methodName, array $expression, $symbolV } } - /* + /** * Temporary variables must be copied if they have more than one reference */ foreach ($this->getMustCheckForCopyVariables() as $checkVariable) { @@ -631,7 +604,7 @@ protected function callFromDynamicClassDynamicMethod(array $expression, $symbolV { $codePrinter = $compilationContext->codePrinter; - /* + /** * Call static methods must grown the stack */ $compilationContext->symbolTable->mustGrownStack(true); @@ -643,10 +616,9 @@ protected function callFromDynamicClassDynamicMethod(array $expression, $symbolV $cachePointer = 'NULL, 0'; - if (isset($expression['parameters']) && \count($expression['parameters'])) { + $params = []; + if (isset($expression['parameters']) && count($expression['parameters'])) { $params = $this->getResolvedParams($expression['parameters'], $compilationContext, $expression); - } else { - $params = []; } /** @@ -683,9 +655,9 @@ protected function callFromDynamicClassDynamicMethod(array $expression, $symbolV $symbol = $compilationContext->backend->getVariableCodePointer($symbolVariable); } - if (!\count($params)) { + if (!count($params)) { if ($isExpecting) { - if ('return_value' == $symbolVariable->getName()) { + if ('return_value' === $symbolVariable->getName()) { $codePrinter->output('ZEPHIR_RETURN_CALL_CE_STATIC_ZVAL('.$classEntry.', '.$methodNameVariable->getName().', '.$cachePointer.');'); } else { $codePrinter->output('ZEPHIR_CALL_CE_STATIC_ZVAL('.$symbol.', '.$classEntry.', '.$methodNameVariable->getName().', '.$cachePointer.');'); @@ -695,7 +667,7 @@ protected function callFromDynamicClassDynamicMethod(array $expression, $symbolV } } else { if ($isExpecting) { - if ('return_value' == $symbolVariable->getName()) { + if ('return_value' === $symbolVariable->getName()) { $codePrinter->output('ZEPHIR_RETURN_CALL_CE_STATIC_ZVAL('.$classEntry.', '.$methodNameVariable->getName().', '.$cachePointer.', '.implode(', ', $params).');'); } else { $codePrinter->output('ZEPHIR_CALL_CE_STATIC_ZVAL('.$symbol.', '.$classEntry.', '.$methodNameVariable->getName().', '.$cachePointer.', '.implode(', ', $params).');'); @@ -705,7 +677,7 @@ protected function callFromDynamicClassDynamicMethod(array $expression, $symbolV } } - /* + /** * Temporary variables must be copied if they have more than one reference */ foreach ($this->getMustCheckForCopyVariables() as $checkVariable) { diff --git a/Library/StringsManager.php b/Library/StringsManager.php index cb1d8f72dc..f94a7bbd2f 100644 --- a/Library/StringsManager.php +++ b/Library/StringsManager.php @@ -9,11 +9,11 @@ * the LICENSE file that was distributed with this source code. */ +declare(strict_types=1); + namespace Zephir; /** - * Class StringsManager. - * * Manages the concatenation keys for the extension and the interned strings */ abstract class StringsManager @@ -23,7 +23,7 @@ abstract class StringsManager * * @var array */ - protected $concatKeys = [ + protected array $concatKeys = [ 'vv' => true, 'vs' => true, 'sv' => true, @@ -34,7 +34,7 @@ abstract class StringsManager * * @param string $key */ - public function addConcatKey($key) + public function addConcatKey(string $key) { $this->concatKeys[$key] = true; } @@ -42,16 +42,16 @@ public function addConcatKey($key) /** * Generates the concatenation code. * - * @return array + * @return void */ - abstract public function genConcatCode(); + abstract public function genConcatCode(): void; /** * Obtains the existing concatenation keys. * * @return array */ - public function getConcatKeys() + public function getConcatKeys(): array { return $this->concatKeys; } diff --git a/Library/Stubs/DocBlock.php b/Library/Stubs/DocBlock.php index f6057dac02..d31b576a47 100644 --- a/Library/Stubs/DocBlock.php +++ b/Library/Stubs/DocBlock.php @@ -37,7 +37,7 @@ class DocBlock /** * @param string|null $source Raw doc-block - * @param string $indent Indent, 4 spaces by default + * @param string $indent Indent, 4 spaces by default */ public function __construct(?string $source, string $indent = ' ') { diff --git a/Library/Stubs/Generator.php b/Library/Stubs/Generator.php index e68a1ed69b..22b8e41548 100644 --- a/Library/Stubs/Generator.php +++ b/Library/Stubs/Generator.php @@ -23,7 +23,6 @@ use Zephir\Exception; use function array_key_exists; -use function count; use function in_array; /** @@ -80,7 +79,7 @@ public function generate(string $namespace, string $path, string $indent, string $class = $file->getClassDefinition(); $source = $this->buildClass($class, $indent, $banner); - $filename = ucfirst($class->getName()).'.zep.php'; + $filename = ucfirst($class->getName()).'.php'; $filePath = $path.str_ireplace( $namespace, '', @@ -177,30 +176,43 @@ protected function buildClass(ClassDefinition $class, string $indent, string $ba $source .= PHP_EOL.'{'.PHP_EOL; + /** + * Build Class constants + */ + $constants = []; foreach ($class->getConstants() as $constant) { - $source .= $this->buildConstant($constant, $indent).PHP_EOL.PHP_EOL; + $constants[] = $this->buildConstant($constant, $indent).PHP_EOL; } + $source .= implode(PHP_EOL, $constants).PHP_EOL; + unset($constants); + + /** + * Build Class properties + */ + $properties = []; foreach ($class->getProperties() as $property) { - $source .= $this->buildProperty($property, $indent).PHP_EOL.PHP_EOL; + $properties[] = $this->buildProperty($property, $indent).PHP_EOL; } - $source .= PHP_EOL; + $source .= implode(PHP_EOL, $properties).PHP_EOL; + unset($properties); + /** + * Build Class methods + */ + $methods = []; foreach ($class->getMethods() as $method) { if ($method->isInternal()) { continue; } - $source .= $this->buildMethod( - $method, - 'interface' === $class->getType(), - $indent - ); - - $source .= PHP_EOL.PHP_EOL; + $methods[] = $this->buildMethod($method, 'interface' === $class->getType(), $indent).PHP_EOL; } + $source .= implode(PHP_EOL, $methods); + unset($methods); + return $source.'}'.PHP_EOL; } @@ -224,7 +236,7 @@ protected function buildProperty(ClassProperty $property, string $indent): strin $visibility = 'static '.$visibility; } - $source = $visibility.' $'.$property->getName(); + $source = $indent.$visibility.' $'.$property->getName(); $original = $property->getOriginal(); if (isset($original['default'])) { @@ -233,9 +245,7 @@ protected function buildProperty(ClassProperty $property, string $indent): strin ]); } - $docBlock = new DocBlock($property->getDocBlock(), $indent); - - return $docBlock."\n".$indent.$source.';'; + return $this->fetchDocBlock($property->getDocBlock(), $indent).$source.';'; } /** @@ -252,9 +262,7 @@ protected function buildConstant(ClassConstant $constant, string $indent): strin 'default' => $constant->getValue(), ]); - $docBlock = new DocBlock($constant->getDocBlock(), $indent); - - return $docBlock."\n".$indent.$source.' = '.$value.';'; + return $this->fetchDocBlock($constant->getDocBlock(), $indent).$indent.$source.' = '.$value.';'; } /** @@ -313,7 +321,7 @@ protected function buildMethod(ClassMethod $method, bool $isInterface, string $i if ($method->hasReturnTypes()) { $supported = 0; - if (array_key_exists('object', $method->getReturnTypes()) && 1 === count($method->getReturnClassTypes())) { + if (array_key_exists('object', $method->getReturnTypes())) { $return = key($method->getReturnClassTypes()); ++$supported; } @@ -348,7 +356,7 @@ protected function buildMethod(ClassMethod $method, bool $isInterface, string $i } // PHP doesn't support multiple return types (yet?) - if ($supported > 1) { + if ($supported > 1 || array_key_exists('variable', $method->getReturnTypes())) { $return = ''; } } elseif ($method->isVoid()) { @@ -368,7 +376,10 @@ protected function buildMethod(ClassMethod $method, bool $isInterface, string $i $methodBody .= PHP_EOL.$indent.'{'.PHP_EOL.$indent.'}'; } - return $docBlock->processMethodDocBlock().PHP_EOL.$methodBody; + $docs = $docBlock->processMethodDocBlock(); + $docs = $docs ? $docs.PHP_EOL : ''; + + return $docs.$methodBody; } /** @@ -437,6 +448,16 @@ protected function wrapPHPValue(array $parameter): string ); } - return (string)$returnValue; + return (string) $returnValue; + } + + private function fetchDocBlock(?string $docBlock, string $indent): string + { + $docBlock = (new DocBlock($docBlock, $indent))->__toString(); + if ($docBlock) { + return $docBlock.PHP_EOL; + } + + return ''; } } diff --git a/Library/Stubs/MethodDocBlock.php b/Library/Stubs/MethodDocBlock.php index 93184cc49a..86a5e48cbb 100644 --- a/Library/Stubs/MethodDocBlock.php +++ b/Library/Stubs/MethodDocBlock.php @@ -100,13 +100,10 @@ public function processMethodDocBlock(): string protected function parseMethodReturnType(ClassMethod $method): void { $return = []; - $returnTypes = $method->getReturnTypes(); - - if ($returnTypes) { - foreach ($returnTypes as $type) { - if (isset($type['data-type'])) { - $return[] = 'variable' == $type['data-type'] ? 'mixed' : $type['data-type']; - } + foreach ($method->getReturnTypes() as $type) { + if (isset($type['data-type'])) { + $dataType = 'variable' === $type['data-type'] ? 'mixed' : $type['data-type']; + $return[$dataType] = $dataType; } } @@ -121,7 +118,10 @@ protected function parseMethodReturnType(ClassMethod $method): void $return = array_merge($return, $returnClassTypes); } - // Prepare return types for Collections compatible types + /** + * Prepare return types for Collections compatible types. + * Only for complex types. + */ $collections = []; if ($method->hasReturnTypesRaw()) { $returnClassTypes = $method->getReturnTypesRaw(); @@ -148,7 +148,7 @@ protected function parseMethodReturnType(ClassMethod $method): void $processedTypes = !empty($method->getReturnClassTypes()) ? $return : null; $returnType = $this->types->getReturnTypeAnnotation( $this->classMethod, - $processedTypes ?? array_merge($method->getReturnTypes(), $collections) + $processedTypes ?: array_merge($method->getReturnTypes(), $collections) ); if (!empty($returnType)) { @@ -247,16 +247,16 @@ private function appendReturnLine(): void } } - private function parseMethodParameters(ClassMethod $method) + private function parseMethodParameters(ClassMethod $method): void { $parameters = $method->getParameters(); $aliasManager = $method->getClassDefinition()->getAliasManager(); - if (!$parameters) { + if ($parameters === null) { return; } - foreach ($method->getParameters() as $parameter) { + foreach ($parameters as $parameter) { if (isset($parameter['cast'])) { if ($aliasManager->isAlias($parameter['cast']['value'])) { $type = '\\'.$aliasManager->getAlias($parameter['cast']['value']); @@ -264,14 +264,11 @@ private function parseMethodParameters(ClassMethod $method) $type = $parameter['cast']['value']; } } elseif (isset($parameter['data-type'])) { - if ('variable' == $parameter['data-type']) { - $type = 'mixed'; - } else { - $type = $parameter['data-type']; - } + $type = 'variable' === $parameter['data-type'] ? 'mixed' : $parameter['data-type']; } else { $type = 'mixed'; } + $this->parameters['$'.trim($parameter['name'], '$')] = [$type, '']; } } diff --git a/Library/SymbolTable.php b/Library/SymbolTable.php index b451929cf0..7fe44386e9 100644 --- a/Library/SymbolTable.php +++ b/Library/SymbolTable.php @@ -253,7 +253,7 @@ public function getVariablesByBranch($branchId) */ public function getVariableForRead($name, CompilationContext $compilationContext = null, array $statement = null) { - /* + /** * Validate that 'this' cannot be used in a static function */ if ('this' == $name || 'this_ptr' == $name) { @@ -262,7 +262,7 @@ public function getVariableForRead($name, CompilationContext $compilationContext } } - /* + /** * Create superglobals just in time */ if ($this->globalsManager->isSuperGlobal($name)) { @@ -295,7 +295,7 @@ public function getVariableForRead($name, CompilationContext $compilationContext $variable->increaseUses(); - /* + /** * Analise branches to detect possible initialization of variables in conditional branches */ if (!$variable->isTemporal() && !$variable->getSkipVariant()) { @@ -306,6 +306,7 @@ public function getVariableForRead($name, CompilationContext $compilationContext case 'variable': case 'string': case 'array': + case 'mixed': if (!$variable->isLocalOnly()) { $variable->setMustInitNull(true); } @@ -380,7 +381,6 @@ public function getVariableForRead($name, CompilationContext $compilationContext foreach ($branches as $branch) { $graph->addLeaf($branch); } - //echo $graph->getRoot()->show(); } else { /* * Variable is assigned just once and it's assigned in a conditional branch diff --git a/Library/TypeAwareInterface.php b/Library/TypeAwareInterface.php index a6f391c9be..1c8abd0292 100644 --- a/Library/TypeAwareInterface.php +++ b/Library/TypeAwareInterface.php @@ -11,9 +11,6 @@ namespace Zephir; -/** - * Zephir\TypeAwareInterface. - */ interface TypeAwareInterface { /** @@ -21,5 +18,5 @@ interface TypeAwareInterface * * @return string */ - public function getType(); + public function getType(): string; } diff --git a/Library/Types.php b/Library/Types.php index e699e0b27a..7ac86b67c8 100644 --- a/Library/Types.php +++ b/Library/Types.php @@ -76,47 +76,47 @@ public function getReturnTypeAnnotation(ClassMethod $method, array $returnTypes $nullableType = $isNullable ? '|null' : ''; if ($method->isVoid() || $isVoid) { - return static::T_VOID; + return self::T_VOID; } if ($isInteger) { - return static::T_INT.$nullableType; + return self::T_INT.$nullableType; } if ($isDouble) { - return static::T_FLOAT.$nullableType; + return self::T_FLOAT.$nullableType; } if ($isBool) { - return static::T_BOOL.$nullableType; + return self::T_BOOL.$nullableType; } if ($isString) { - return static::T_STRING.$nullableType; + return self::T_STRING.$nullableType; } if ($isNull && 1 === $typesCount) { - return static::T_NULL; + return self::T_NULL; } if ($isArray) { - return static::T_ARRAY; + return self::T_ARRAY; } if ($isObject) { - return static::T_OBJECT; + return self::T_OBJECT; } if ($isIterable) { - return static::T_ITERABLE; + return self::T_ITERABLE; } if ($isResource) { - return static::T_RESOURCE; + return self::T_RESOURCE; } if ($method->areReturnTypesCompatible() && !$isTypeHinted) { - return static::T_MIXED.$nullableType; + return self::T_MIXED.$nullableType; } if ($isTypeHinted && !$isBasicTypes && !$isDynamic && !$isNullable) { @@ -125,7 +125,7 @@ public function getReturnTypeAnnotation(ClassMethod $method, array $returnTypes if ($isTypeHinted && $isProcessedReturnType) { $withoutNullable = array_filter(array_keys($returnTypes), static function ($ret) { - if ($ret !== static::T_NULL) { + if ($ret !== self::T_NULL) { return $ret; } }); @@ -137,7 +137,7 @@ public function getReturnTypeAnnotation(ClassMethod $method, array $returnTypes return implode('|', array_values($returnTypes)); } - return static::T_MIXED.$nullableType; + return self::T_MIXED.$nullableType; } /** @@ -189,7 +189,7 @@ private function areReturnTypesFloatCompatible(array $types): bool */ private function areReturnTypesBoolCompatible(array $types): bool { - return $this->areReturnTypesCompatible($types, [static::T_BOOL]); + return $this->areReturnTypesCompatible($types, [self::T_BOOL]); } /** @@ -204,8 +204,8 @@ private function areReturnTypesStringCompatible(array $types): bool return $this->areReturnTypesCompatible( $types, [ - static::T_STRING, - static::T_ISTRING, + self::T_STRING, + self::T_ISTRING, ], $this->isNullable($types) ); @@ -220,7 +220,7 @@ private function areReturnTypesStringCompatible(array $types): bool */ private function areReturnTypesNullCompatible(array $types): bool { - return $this->areReturnTypesCompatible($types, [static::T_NULL]); + return $this->areReturnTypesCompatible($types, [self::T_NULL]); } /** @@ -232,7 +232,7 @@ private function areReturnTypesNullCompatible(array $types): bool */ private function areReturnTypesArrayCompatible(array $types): bool { - return $this->areReturnTypesCompatible($types, [static::T_ARRAY]); + return $this->areReturnTypesCompatible($types, [self::T_ARRAY]); } /** @@ -244,7 +244,7 @@ private function areReturnTypesArrayCompatible(array $types): bool */ private function areReturnTypesObjectCompatible(array $types): bool { - return $this->areReturnTypesCompatible($types, [static::T_OBJECT]); + return $this->areReturnTypesCompatible($types, [self::T_OBJECT]); } /** @@ -256,7 +256,7 @@ private function areReturnTypesObjectCompatible(array $types): bool */ private function areReturnTypesIterableCompatible(array $types): bool { - return $this->areReturnTypesCompatible($types, [static::T_ITERABLE]); + return $this->areReturnTypesCompatible($types, [self::T_ITERABLE]); } /** @@ -268,7 +268,7 @@ private function areReturnTypesIterableCompatible(array $types): bool */ private function areReturnTypesResourceCompatible(array $types): bool { - return $this->areReturnTypesCompatible($types, [static::T_RESOURCE]); + return $this->areReturnTypesCompatible($types, [self::T_RESOURCE]); } /** @@ -300,7 +300,7 @@ private function areReturnTypesCollectionCompatible(array $types): bool */ private function areReturnTypesVoidCompatible(array $types): bool { - return $this->areReturnTypesCompatible($types, [static::T_VOID]); + return $this->areReturnTypesCompatible($types, [self::T_VOID]); } /** @@ -312,7 +312,7 @@ private function areReturnTypesVoidCompatible(array $types): bool */ private function isNumeric(array $types): bool { - return $this->areReturnTypesCompatible($types, [static::T_NUMBER]); + return $this->areReturnTypesCompatible($types, [self::T_NUMBER]); } /** @@ -324,8 +324,8 @@ private function isNumeric(array $types): bool */ private function isNullable(array $types): bool { - return (\array_key_exists(static::T_NULL, $types) - || \in_array(static::T_NULL, $types)) + return (\array_key_exists(self::T_NULL, $types) + || \in_array(self::T_NULL, $types)) && 1 !== \count($types); } @@ -347,7 +347,8 @@ private function isNullable(array $types): bool * * @param array $types - Return types from parser * @param array $allowedTypes - Allowed return types - * @param bool $isNullable + * @param bool $isNullable + * * @return bool */ private function areReturnTypesCompatible(array $types, array $allowedTypes, bool $isNullable = false): bool @@ -355,7 +356,7 @@ private function areReturnTypesCompatible(array $types, array $allowedTypes, boo $result = null; if ($isNullable) { - $allowedTypes[] = static::T_NULL; + $allowedTypes[] = self::T_NULL; } foreach ($types as $type => $data) { diff --git a/Library/Variable.php b/Library/Variable.php index 56947d72bb..77d2370e94 100644 --- a/Library/Variable.php +++ b/Library/Variable.php @@ -219,7 +219,7 @@ public function setType(string $type) * * @return string */ - public function getType() + public function getType(): string { return $this->type; } diff --git a/Library/Zephir.php b/Library/Zephir.php index a8cee23a24..129f5ab398 100644 --- a/Library/Zephir.php +++ b/Library/Zephir.php @@ -16,7 +16,7 @@ */ final class Zephir { - public const VERSION = '0.14.0-$Id$'; + public const VERSION = '0.15.0-$Id$'; public const LOGO = <<<'ASCII' _____ __ _ diff --git a/Library/functions.php b/Library/functions.php index 20be7be875..2d8d8a5e49 100644 --- a/Library/functions.php +++ b/Library/functions.php @@ -11,12 +11,12 @@ namespace Zephir; +use Zephir\Exception\InvalidArgumentException; use const INFO_GENERAL; use const PHP_INT_SIZE; use const PHP_OS; use const PHP_ZTS; use const SCANDIR_SORT_ASCENDING; -use Zephir\Exception\InvalidArgumentException; /** * Attempts to remove recursively the directory with all subdirectories and files. diff --git a/README.md b/README.md index fe19e49153..cce56c3c5b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # [![Zephir][zephir logo]][web site] -[![Build on Linux][actions unix]][actions link] -[![Build on Windows][actions windows]][actions link] +[![Build on Linux|macOS|Windows][actions main]][actions link] +[![Nightly Builds on Linux][actions nightly]][actions link] [![Latest Stable Version][version badge]][packagist link] [![MIT License][license badge]](./LICENSE) @@ -46,15 +46,17 @@ Support us with a monthly donation and help us continue our activities. Zephir licensed under the MIT License. See the [LICENSE](./LICENSE) file for more information. -[docs]: https://docs.zephir-lang.com -[zephir]: https://github.com/zephir-lang/zephir -[facebook]: https://www.facebook.com/groups/zephir.language -[discord]: https://phalcon.link/discord -[zephir logo]: https://assets.phalconphp.com/zephir/zephir_logo-105x36.svg -[web site]: https://zephir-lang.com -[actions link]: https://github.com/zephir-lang/zephir/actions -[actions unix]: https://github.com/zephir-lang/zephir/workflows/Unix%20CI/badge.svg -[actions windows]: https://github.com/zephir-lang/zephir/workflows/Windows%20CI/badge.svg -[version badge]: https://poser.pugx.org/phalcon/zephir/v/stable.svg -[packagist link]: https://packagist.org/packages/phalcon/zephir -[license badge]: https://poser.pugx.org/phalcon/zephir/license.svg +[docs]: https://docs.zephir-lang.com +[zephir]: https://github.com/zephir-lang/zephir +[facebook]: https://www.facebook.com/groups/zephir.language +[discord]: https://phalcon.link/discord +[zephir logo]: https://assets.phalconphp.com/zephir/zephir_logo-105x36.svg +[web site]: https://zephir-lang.com + +[actions link]: https://github.com/zephir-lang/zephir/actions +[actions main]: https://github.com/zephir-lang/zephir/actions/workflows/main.yml/badge.svg +[actions nightly]: https://github.com/zephir-lang/zephir/actions/workflows/nightly.yml/badge.svg + +[version badge]: https://poser.pugx.org/phalcon/zephir/v/stable.svg +[packagist link]: https://packagist.org/packages/phalcon/zephir +[license badge]: https://poser.pugx.org/phalcon/zephir/license.svg diff --git a/composer.json b/composer.json index 1243fa701f..a74c92dc83 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,6 @@ "ext-pcre": "*", "ext-xml": "*", "ext-zlib": "*", - "league/flysystem": "^2.0", "symfony/console": "^5.2", "symfony/framework-bundle": "^5.2", "symfony/monolog-bridge": "^5.2", diff --git a/composer.lock b/composer.lock index c5cae939f6..ad1c1436cb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,161 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5cb6946fb71ae057a80b67d33af6ec1d", + "content-hash": "c88e23f00ee31cde884e4ffb1331ddbc", "packages": [ - { - "name": "league/flysystem", - "version": "2.2.3", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem.git", - "reference": "811bdc2d52a07eafbb6cb68a7b368b0668b362c8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/811bdc2d52a07eafbb6cb68a7b368b0668b362c8", - "reference": "811bdc2d52a07eafbb6cb68a7b368b0668b362c8", - "shasum": "" - }, - "require": { - "ext-json": "*", - "league/mime-type-detection": "^1.0.0", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "guzzlehttp/ringphp": "<1.1.1" - }, - "require-dev": { - "async-aws/s3": "^1.5", - "async-aws/simple-s3": "^1.0", - "aws/aws-sdk-php": "^3.132.4", - "composer/semver": "^3.0", - "ext-fileinfo": "*", - "friendsofphp/php-cs-fixer": "^2.16", - "google/cloud-storage": "^1.23", - "phpseclib/phpseclib": "^2.0", - "phpstan/phpstan": "^0.12.26", - "phpunit/phpunit": "^8.5 || ^9.4", - "sabre/dav": "^4.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\Flysystem\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" - } - ], - "description": "File storage abstraction for PHP", - "keywords": [ - "WebDAV", - "aws", - "cloud", - "file", - "files", - "filesystem", - "filesystems", - "ftp", - "s3", - "sftp", - "storage" - ], - "support": { - "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/2.2.3" - }, - "funding": [ - { - "url": "https://offset.earth/frankdejonge", - "type": "custom" - }, - { - "url": "https://github.com/frankdejonge", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/league/flysystem", - "type": "tidelift" - } - ], - "time": "2021-08-18T19:59:31+00:00" - }, - { - "name": "league/mime-type-detection", - "version": "1.7.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", - "reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.18", - "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\MimeTypeDetection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" - } - ], - "description": "Mime-type detection for Flysystem", - "support": { - "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.7.0" - }, - "funding": [ - { - "url": "https://github.com/frankdejonge", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/league/flysystem", - "type": "tidelift" - } - ], - "time": "2021-01-18T20:58:21+00:00" - }, { "name": "monolog/monolog", - "version": "2.3.4", + "version": "2.3.5", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "437e7a1c50044b92773b361af77620efb76fff59" + "reference": "fd4380d6fc37626e2f799f29d91195040137eba9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/437e7a1c50044b92773b361af77620efb76fff59", - "reference": "437e7a1c50044b92773b361af77620efb76fff59", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd4380d6fc37626e2f799f29d91195040137eba9", + "reference": "fd4380d6fc37626e2f799f29d91195040137eba9", "shasum": "" }, "require": { @@ -174,7 +33,7 @@ "elasticsearch/elasticsearch": "^7", "graylog2/gelf-php": "^1.4.2", "mongodb/mongodb": "^1.8", - "php-amqplib/php-amqplib": "~2.4", + "php-amqplib/php-amqplib": "~2.4 || ^3", "php-console/php-console": "^3.1.3", "phpspec/prophecy": "^1.6.1", "phpstan/phpstan": "^0.12.91", @@ -232,7 +91,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.3.4" + "source": "https://github.com/Seldaek/monolog/tree/2.3.5" }, "funding": [ { @@ -244,7 +103,7 @@ "type": "tidelift" } ], - "time": "2021-09-15T11:27:21+00:00" + "time": "2021-10-01T21:08:31+00:00" }, { "name": "psr/cache", @@ -445,16 +304,16 @@ }, { "name": "symfony/cache", - "version": "v5.3.7", + "version": "v5.3.8", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "864867b13bd67347497ce956f4b253f8fe18b80c" + "reference": "945bcebfef0aeef105de61843dd14105633ae38f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/864867b13bd67347497ce956f4b253f8fe18b80c", - "reference": "864867b13bd67347497ce956f4b253f8fe18b80c", + "url": "https://api.github.com/repos/symfony/cache/zipball/945bcebfef0aeef105de61843dd14105633ae38f", + "reference": "945bcebfef0aeef105de61843dd14105633ae38f", "shasum": "" }, "require": { @@ -522,7 +381,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v5.3.7" + "source": "https://github.com/symfony/cache/tree/v5.3.8" }, "funding": [ { @@ -538,7 +397,7 @@ "type": "tidelift" } ], - "time": "2021-08-29T15:08:21+00:00" + "time": "2021-09-26T18:29:18+00:00" }, { "name": "symfony/cache-contracts", @@ -799,16 +658,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v5.3.7", + "version": "v5.3.8", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "a665946279f566d94ed5eb98999cfa65c6fa5a78" + "reference": "e39c344e06a3ceab531ebeb6c077e6652c4a0829" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a665946279f566d94ed5eb98999cfa65c6fa5a78", - "reference": "a665946279f566d94ed5eb98999cfa65c6fa5a78", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e39c344e06a3ceab531ebeb6c077e6652c4a0829", + "reference": "e39c344e06a3ceab531ebeb6c077e6652c4a0829", "shasum": "" }, "require": { @@ -867,7 +726,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v5.3.7" + "source": "https://github.com/symfony/dependency-injection/tree/v5.3.8" }, "funding": [ { @@ -883,7 +742,7 @@ "type": "tidelift" } ], - "time": "2021-08-02T16:16:27+00:00" + "time": "2021-09-21T20:52:44+00:00" }, { "name": "symfony/deprecation-contracts", @@ -1311,16 +1170,16 @@ }, { "name": "symfony/framework-bundle", - "version": "v5.3.7", + "version": "v5.3.8", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "5d4fcef02a42ea86280afcbacedf8de7a039032c" + "reference": "ea6e30a8c9534d87187375ef4ee39d48ee40dd2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/5d4fcef02a42ea86280afcbacedf8de7a039032c", - "reference": "5d4fcef02a42ea86280afcbacedf8de7a039032c", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/ea6e30a8c9534d87187375ef4ee39d48ee40dd2d", + "reference": "ea6e30a8c9534d87187375ef4ee39d48ee40dd2d", "shasum": "" }, "require": { @@ -1442,7 +1301,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v5.3.7" + "source": "https://github.com/symfony/framework-bundle/tree/v5.3.8" }, "funding": [ { @@ -1458,7 +1317,7 @@ "type": "tidelift" } ], - "time": "2021-08-26T08:37:07+00:00" + "time": "2021-09-28T07:17:01+00:00" }, { "name": "symfony/http-client-contracts", @@ -1613,16 +1472,16 @@ }, { "name": "symfony/http-kernel", - "version": "v5.3.7", + "version": "v5.3.9", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "a3a78e37935a527b50376c22ac1cec35b57fe787" + "reference": "ceaf46a992f60e90645e7279825a830f733a17c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a3a78e37935a527b50376c22ac1cec35b57fe787", - "reference": "a3a78e37935a527b50376c22ac1cec35b57fe787", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/ceaf46a992f60e90645e7279825a830f733a17c5", + "reference": "ceaf46a992f60e90645e7279825a830f733a17c5", "shasum": "" }, "require": { @@ -1705,7 +1564,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.3.7" + "source": "https://github.com/symfony/http-kernel/tree/v5.3.9" }, "funding": [ { @@ -1721,7 +1580,7 @@ "type": "tidelift" } ], - "time": "2021-08-30T12:37:19+00:00" + "time": "2021-09-28T10:25:11+00:00" }, { "name": "symfony/monolog-bridge", @@ -2707,16 +2566,16 @@ }, { "name": "symfony/var-dumper", - "version": "v5.3.7", + "version": "v5.3.8", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "3ad5af4aed07d0a0201bbcfc42658fe6c5b2fb8f" + "reference": "eaaea4098be1c90c8285543e1356a09c8aa5c8da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3ad5af4aed07d0a0201bbcfc42658fe6c5b2fb8f", - "reference": "3ad5af4aed07d0a0201bbcfc42658fe6c5b2fb8f", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/eaaea4098be1c90c8285543e1356a09c8aa5c8da", + "reference": "eaaea4098be1c90c8285543e1356a09c8aa5c8da", "shasum": "" }, "require": { @@ -2775,7 +2634,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.3.7" + "source": "https://github.com/symfony/var-dumper/tree/v5.3.8" }, "funding": [ { @@ -2791,20 +2650,20 @@ "type": "tidelift" } ], - "time": "2021-08-04T23:19:25+00:00" + "time": "2021-09-24T15:59:58+00:00" }, { "name": "symfony/var-exporter", - "version": "v5.3.7", + "version": "v5.3.8", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "2ded877ab0574d8b646f4eb3f716f8ed7ee7f392" + "reference": "a7604de14bcf472fe8e33f758e9e5b7bf07d3b91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/2ded877ab0574d8b646f4eb3f716f8ed7ee7f392", - "reference": "2ded877ab0574d8b646f4eb3f716f8ed7ee7f392", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/a7604de14bcf472fe8e33f758e9e5b7bf07d3b91", + "reference": "a7604de14bcf472fe8e33f758e9e5b7bf07d3b91", "shasum": "" }, "require": { @@ -2848,7 +2707,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v5.3.7" + "source": "https://github.com/symfony/var-exporter/tree/v5.3.8" }, "funding": [ { @@ -2864,7 +2723,7 @@ "type": "tidelift" } ], - "time": "2021-08-04T22:42:42+00:00" + "time": "2021-08-31T12:49:16+00:00" }, { "name": "symfony/yaml", @@ -3072,16 +2931,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.12.0", + "version": "v4.13.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143" + "reference": "50953a2691a922aa1769461637869a0a2faa3f53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53", + "reference": "50953a2691a922aa1769461637869a0a2faa3f53", "shasum": "" }, "require": { @@ -3122,9 +2981,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0" }, - "time": "2021-07-21T10:44:31+00:00" + "time": "2021-09-20T12:20:58+00:00" }, { "name": "phar-io/manifest", @@ -3348,16 +3207,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.5.0", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f" + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/30f38bffc6f24293dadd1823936372dfa9e86e2f", - "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", "shasum": "" }, "require": { @@ -3392,9 +3251,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" }, - "time": "2021-09-17T15:28:14+00:00" + "time": "2021-10-02T14:08:47+00:00" }, { "name": "phpspec/prophecy", @@ -3783,16 +3642,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.9", + "version": "9.5.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b" + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b", - "reference": "ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", "shasum": "" }, "require": { @@ -3808,7 +3667,7 @@ "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.3", + "phpunit/php-code-coverage": "^9.2.7", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -3870,7 +3729,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.9" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" }, "funding": [ { @@ -3882,7 +3741,7 @@ "type": "github" } ], - "time": "2021-08-31T06:47:40+00:00" + "time": "2021-09-25T07:38:51+00:00" }, { "name": "sebastian/cli-parser", diff --git a/config.json b/config.json index c2d4360046..95978e34ec 100644 --- a/config.json +++ b/config.json @@ -5,7 +5,6 @@ "author": "Phalcon Team and contributors", "version": "1.0.0", "verbose": true, - "requires": { "extensions": [ "PDO", @@ -15,27 +14,24 @@ "json" ] }, - "stubs": { "path": "ide\/%version%\/%namespace%\/", "stubs-run-after-generate": false, "banner": "/**\n * This file is part of the Zephir.\n *\n * (c) Phalcon Team \n *\n * For the full copyright and license information, please view\n * the LICENSE file that was distributed with this source code.\n */" }, - "api": { - "path" : "doc/%version%", - "theme" : { - "name":"zephir", - "options" :{ - "github":"https://github.com/user/repo", - "analytics":null, + "path": "doc/%version%", + "theme": { + "name": "zephir", + "options": { + "github": "https://github.com/user/repo", + "analytics": null, "main_color": "#3E6496", "link_color": "#3E6496", "link_hover_color": "#5F9AE7" } } }, - "warnings": { "unused-variable": true, "unused-variable-external": false, @@ -62,7 +58,6 @@ "invalid-typeof-comparison": true, "conditional-initialization": true }, - "optimizations": { "static-type-inference": true, "static-type-inference-second-pass": true, @@ -75,7 +70,6 @@ "public-internal-methods": false, "public-internal-functions": true }, - "globals": { "my_setting_1": { "type": "bool", @@ -101,6 +95,10 @@ "type": "char", "default": "A" }, + "my_setting_5": { + "type": "string", + "default": "custom_value" + }, "db.my_setting_1": { "type": "bool", "default": false diff --git a/docker/7.4/.bashrc b/docker/7.4/.bashrc new file mode 100644 index 0000000000..fd3a636e58 --- /dev/null +++ b/docker/7.4/.bashrc @@ -0,0 +1,5 @@ +#!/bin/bash + +alias test-ext='php -d extension=ext/modules/stub.so vendor/bin/phpunit --bootstrap tests/ext-bootstrap.php --testsuite Extension' +alias test-zephir='php vendor/bin/phpunit --colors=always --testsuite Zephir' +alias test-all='test-ext; test-zephir' diff --git a/docker/7.4/Dockerfile b/docker/7.4/Dockerfile index b3fb2bc67b..a8e41fe611 100644 --- a/docker/7.4/Dockerfile +++ b/docker/7.4/Dockerfile @@ -19,5 +19,7 @@ RUN docker-php-ext-install zip gmp intl mysqli && \ docker-php-ext-enable psr zephir_parser COPY --from=composer /usr/bin/composer /usr/local/bin/composer +# Bash script with helper aliases +COPY ./.bashrc /root/.bashrc CMD ["php-fpm"] diff --git a/docker/8.0/.bashrc b/docker/8.0/.bashrc new file mode 100644 index 0000000000..fd3a636e58 --- /dev/null +++ b/docker/8.0/.bashrc @@ -0,0 +1,5 @@ +#!/bin/bash + +alias test-ext='php -d extension=ext/modules/stub.so vendor/bin/phpunit --bootstrap tests/ext-bootstrap.php --testsuite Extension' +alias test-zephir='php vendor/bin/phpunit --colors=always --testsuite Zephir' +alias test-all='test-ext; test-zephir' diff --git a/docker/8.0/Dockerfile b/docker/8.0/Dockerfile index 642980835d..847ea05e03 100644 --- a/docker/8.0/Dockerfile +++ b/docker/8.0/Dockerfile @@ -19,5 +19,7 @@ RUN docker-php-ext-install zip gmp intl mysqli && \ docker-php-ext-enable psr zephir_parser COPY --from=composer /usr/bin/composer /usr/local/bin/composer +# Bash script with helper aliases +COPY ./.bashrc /root/.bashrc CMD ["php-fpm"] diff --git a/ext/config.m4 b/ext/config.m4 index cceffb6578..8552cc50ac 100644 --- a/ext/config.m4 +++ b/ext/config.m4 @@ -212,6 +212,7 @@ if test "$PHP_STUB" = "yes"; then stub/typehinting/testabstract.zep.c stub/typeinstances.zep.c stub/typeoff.zep.c + stub/types/mixedtype.zep.c stub/unknownclass.zep.c stub/unsettest.zep.c stub/usetest.zep.c @@ -232,7 +233,7 @@ if test "$PHP_STUB" = "yes"; then stub/13__closure.zep.c " PHP_NEW_EXTENSION(stub, $stub_sources, $ext_shared,, ) PHP_ADD_BUILD_DIR([$ext_builddir/kernel/]) - for dir in "stub stub/bench stub/builtin stub/constructors stub/flow stub/globals stub/globals/session stub/integration/psr stub/integration/psr/http/message stub/interfaces stub/invokes stub/issue2165 stub/mcall stub/namespaces stub/namespaces/a/b stub/oo stub/oo/extend stub/oo/extend/db stub/oo/extend/db/query stub/oo/extend/db/query/placeholder stub/oo/extend/spl stub/oo/scopes stub/ooimpl stub/optimizers stub/properties stub/requires stub/router stub/typehinting"; do + for dir in "stub stub/bench stub/builtin stub/constructors stub/flow stub/globals stub/globals/session stub/integration/psr stub/integration/psr/http/message stub/interfaces stub/invokes stub/issue2165 stub/mcall stub/namespaces stub/namespaces/a/b stub/oo stub/oo/extend stub/oo/extend/db stub/oo/extend/db/query stub/oo/extend/db/query/placeholder stub/oo/extend/spl stub/oo/scopes stub/ooimpl stub/optimizers stub/properties stub/requires stub/router stub/typehinting stub/types"; do PHP_ADD_BUILD_DIR([$ext_builddir/$dir]) done PHP_SUBST(STUB_SHARED_LIBADD) diff --git a/ext/config.w32 b/ext/config.w32 index 12199ac28c..7cc2da4067 100644 --- a/ext/config.w32 +++ b/ext/config.w32 @@ -37,7 +37,8 @@ if (PHP_STUB != "no") { ADD_SOURCES(configure_module_dirname + "/stub/optimizers", "isscalar.zep.c acos.zep.c arraymerge.zep.c asin.zep.c cos.zep.c createarray.zep.c ldexp.zep.c sin.zep.c sqrt.zep.c strreplace.zep.c substr.zep.c tan.zep.c", "stub"); ADD_SOURCES(configure_module_dirname + "/stub/requires", "external3.zep.c", "stub"); ADD_SOURCES(configure_module_dirname + "/stub/router", "exception.zep.c route.zep.c", "stub"); - ADD_SOURCES(configure_module_dirname + "/stub/typehinting", "testabstract.zep.c", "stub"); + ADD_SOURCES(configure_module_dirname + "/stub/typehinting", "testabstract.zep.c", "stub"); + ADD_SOURCES(configure_module_dirname + "/stub/types", "mixedtype.zep.c", "stub"); ADD_FLAG("CFLAGS_STUB", "/D ZEPHIR_RELEASE /Oi /Ot /Oy /Ob2 /Gs /GF /Gy /GL"); ADD_FLAG("CFLAGS", "/D ZEPHIR_RELEASE /Oi /Ot /Oy /Ob2 /Gs /GF /Gy /GL"); ADD_FLAG("LDFLAGS", "/LTCG"); diff --git a/ext/php_stub.h b/ext/php_stub.h index 28fcad82c4..33ecd7055d 100644 --- a/ext/php_stub.h +++ b/ext/php_stub.h @@ -14,7 +14,7 @@ #define PHP_STUB_VERSION "1.0.0" #define PHP_STUB_EXTNAME "stub" #define PHP_STUB_AUTHOR "Phalcon Team and contributors" -#define PHP_STUB_ZEPVERSION "0.14.0-$Id$" +#define PHP_STUB_ZEPVERSION "0.15.0-$Id$" #define PHP_STUB_DESCRIPTION "Description test for
Test Extension." typedef struct _zephir_struct_db { @@ -51,21 +51,14 @@ ZEND_BEGIN_MODULE_GLOBALS(stub) zephir_struct_db db; - zephir_struct_orm orm; - zephir_struct_extension extension; - zend_bool my_setting_1; - zend_bool test_setting_1; - int my_setting_2; - double my_setting_3; - char my_setting_4; - + char * my_setting_5; ZEND_END_MODULE_GLOBALS(stub) diff --git a/ext/stub.c b/ext/stub.c index e1f353ba99..26e7660a02 100644 --- a/ext/stub.c +++ b/ext/stub.c @@ -240,6 +240,7 @@ zend_class_entry *stub_trytest_ce; zend_class_entry *stub_typehinting_testabstract_ce; zend_class_entry *stub_typeinstances_ce; zend_class_entry *stub_typeoff_ce; +zend_class_entry *stub_types_mixedtype_ce; zend_class_entry *stub_unknownclass_ce; zend_class_entry *stub_unsettest_ce; zend_class_entry *stub_usetest_ce; @@ -465,6 +466,7 @@ static PHP_MINIT_FUNCTION(stub) ZEPHIR_INIT(Stub_TypeHinting_TestAbstract); ZEPHIR_INIT(Stub_TypeInstances); ZEPHIR_INIT(Stub_Typeoff); + ZEPHIR_INIT(Stub_Types_MixedType); ZEPHIR_INIT(Stub_UnknownClass); ZEPHIR_INIT(Stub_Unsettest); ZEPHIR_INIT(Stub_UseTest); @@ -524,7 +526,7 @@ static void php_zephir_init_globals(zend_stub_globals *stub_globals) stub_globals->my_setting_2 = 10; stub_globals->my_setting_3 = 15.2; stub_globals->my_setting_4 = 'A'; - + stub_globals->my_setting_5 = ZSTR_VAL(zend_string_init(ZEND_STRL("custom_value"), 0)); } diff --git a/ext/stub.h b/ext/stub.h index da8ea50cb6..cf7b456b20 100644 --- a/ext/stub.h +++ b/ext/stub.h @@ -207,6 +207,7 @@ #include "stub/typehinting/testabstract.zep.h" #include "stub/typeinstances.zep.h" #include "stub/typeoff.zep.h" +#include "stub/types/mixedtype.zep.h" #include "stub/unknownclass.zep.h" #include "stub/unsettest.zep.h" #include "stub/usetest.zep.h" diff --git a/ext/stub/globals.zep.c b/ext/stub/globals.zep.c index 26e8618ea8..06647de6aa 100644 --- a/ext/stub/globals.zep.c +++ b/ext/stub/globals.zep.c @@ -14,6 +14,7 @@ #include "kernel/main.h" #include "kernel/memory.h" #include "kernel/object.h" +#include "kernel/operators.h" ZEPHIR_INIT_CLASS(Stub_Globals) @@ -60,7 +61,7 @@ PHP_METHOD(Stub_Globals, setIntValueUsingDotNotation) zephir_fetch_params_without_memory_grow(1, 0, &value); - ZEPHIR_GLOBAL(db).my_setting_2 = Z_LVAL_P(value); + ZEPHIR_GLOBAL(db).my_setting_2 = zval_get_long(value); } PHP_METHOD(Stub_Globals, setCharValue) @@ -80,7 +81,32 @@ PHP_METHOD(Stub_Globals, setCharValue) zephir_fetch_params_without_memory_grow(1, 0, &value); - ZEPHIR_GLOBAL(my_setting_4) = (Z_TYPE_P(value) == IS_STRING ? (Z_STRLEN_P(value) ? Z_STRVAL_P(value)[0] : NULL) : Z_LVAL_P(value)); + ZEPHIR_GLOBAL(my_setting_4) = (Z_TYPE_P(value) == IS_STRING ? (Z_STRLEN_P(value) ? Z_STRVAL_P(value)[0] : NULL) : zval_get_long(value)); +} + +PHP_METHOD(Stub_Globals, setStringValue) +{ + zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL; + zval *value_param = NULL; + zval value; + zval *this_ptr = getThis(); + + ZVAL_UNDEF(&value); +#if PHP_VERSION_ID >= 80000 + bool is_null_true = 1; + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(value) + ZEND_PARSE_PARAMETERS_END(); +#endif + + + ZEPHIR_MM_GROW(); + zephir_fetch_params(1, 1, 0, &value_param); + zephir_get_strval(&value, value_param); + + + ZEPHIR_GLOBAL(my_setting_5) = ZSTR_VAL(zval_get_string(&value)); + ZEPHIR_MM_RESTORE(); } PHP_METHOD(Stub_Globals, setBoolValue) @@ -120,7 +146,7 @@ PHP_METHOD(Stub_Globals, setDefaultGlobalsOrmCacheLevel) zephir_fetch_params_without_memory_grow(1, 0, &value); - ZEPHIR_GLOBAL(orm).cache_level = Z_LVAL_P(value); + ZEPHIR_GLOBAL(orm).cache_level = zval_get_long(value); } /** @@ -207,6 +233,18 @@ PHP_METHOD(Stub_Globals, getDefaultGlobals7) RETURN_LONG(ZEPHIR_GLOBAL(my_setting_4)); } +/** + * @return mixed + */ +PHP_METHOD(Stub_Globals, getDefaultGlobals8) +{ + zval *this_ptr = getThis(); + + + + RETURN_STRING(ZEPHIR_GLOBAL(my_setting_5)); +} + /** * @return mixed */ diff --git a/ext/stub/globals.zep.h b/ext/stub/globals.zep.h index 25887d0210..b8198d31ce 100644 --- a/ext/stub/globals.zep.h +++ b/ext/stub/globals.zep.h @@ -6,6 +6,7 @@ ZEPHIR_INIT_CLASS(Stub_Globals); PHP_METHOD(Stub_Globals, setBoolValueUsingDotNotation); PHP_METHOD(Stub_Globals, setIntValueUsingDotNotation); PHP_METHOD(Stub_Globals, setCharValue); +PHP_METHOD(Stub_Globals, setStringValue); PHP_METHOD(Stub_Globals, setBoolValue); PHP_METHOD(Stub_Globals, setDefaultGlobalsOrmCacheLevel); PHP_METHOD(Stub_Globals, getDefaultGlobals1); @@ -15,6 +16,7 @@ PHP_METHOD(Stub_Globals, getDefaultGlobals4); PHP_METHOD(Stub_Globals, getDefaultGlobals5); PHP_METHOD(Stub_Globals, getDefaultGlobals6); PHP_METHOD(Stub_Globals, getDefaultGlobals7); +PHP_METHOD(Stub_Globals, getDefaultGlobals8); PHP_METHOD(Stub_Globals, getDefaultGlobalsOrmCacheLevel); ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_globals_setboolvalueusingdotnotation, 0, 1, IS_VOID, 0) @@ -32,6 +34,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_globals_setcharvalue, 0, 1, ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_globals_setstringvalue, 0, 1, IS_VOID, 0) + + ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_globals_setboolvalue, 0, 1, IS_VOID, 0) ZEND_ARG_INFO(0, value) @@ -63,6 +70,9 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_stub_globals_getdefaultglobals7, 0, 0, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_stub_globals_getdefaultglobals8, 0, 0, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_stub_globals_getdefaultglobalsormcachelevel, 0, 0, 0) ZEND_END_ARG_INFO() @@ -70,6 +80,7 @@ ZEPHIR_INIT_FUNCS(stub_globals_method_entry) { PHP_ME(Stub_Globals, setBoolValueUsingDotNotation, arginfo_stub_globals_setboolvalueusingdotnotation, ZEND_ACC_PUBLIC) PHP_ME(Stub_Globals, setIntValueUsingDotNotation, arginfo_stub_globals_setintvalueusingdotnotation, ZEND_ACC_PUBLIC) PHP_ME(Stub_Globals, setCharValue, arginfo_stub_globals_setcharvalue, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Globals, setStringValue, arginfo_stub_globals_setstringvalue, ZEND_ACC_PUBLIC) PHP_ME(Stub_Globals, setBoolValue, arginfo_stub_globals_setboolvalue, ZEND_ACC_PUBLIC) PHP_ME(Stub_Globals, setDefaultGlobalsOrmCacheLevel, arginfo_stub_globals_setdefaultglobalsormcachelevel, ZEND_ACC_PUBLIC) #if PHP_VERSION_ID >= 80000 @@ -107,6 +118,11 @@ ZEPHIR_INIT_FUNCS(stub_globals_method_entry) { #else PHP_ME(Stub_Globals, getDefaultGlobals7, NULL, ZEND_ACC_PUBLIC) #endif +#if PHP_VERSION_ID >= 80000 + PHP_ME(Stub_Globals, getDefaultGlobals8, arginfo_stub_globals_getdefaultglobals8, ZEND_ACC_PUBLIC) +#else + PHP_ME(Stub_Globals, getDefaultGlobals8, NULL, ZEND_ACC_PUBLIC) +#endif #if PHP_VERSION_ID >= 80000 PHP_ME(Stub_Globals, getDefaultGlobalsOrmCacheLevel, arginfo_stub_globals_getdefaultglobalsormcachelevel, ZEND_ACC_PUBLIC) #else diff --git a/ext/stub/stubs.zep.c b/ext/stub/stubs.zep.c index 03abe44f1d..278582d5dc 100644 --- a/ext/stub/stubs.zep.c +++ b/ext/stub/stubs.zep.c @@ -170,3 +170,31 @@ PHP_METHOD(Stub_Stubs, testVariableLength) ZEPHIR_MM_RESTORE(); } +PHP_METHOD(Stub_Stubs, testMultiReturnTypeWithMixedInDocAndEmptyInSignature1) +{ + zval *this_ptr = getThis(); + + + + array_init(return_value); + return; +} + +PHP_METHOD(Stub_Stubs, testMultiReturnTypeWithMixedInDocAndEmptyInSignature2) +{ + zval *this_ptr = getThis(); + + + + RETURN_BOOL(0); +} + +PHP_METHOD(Stub_Stubs, testMultiReturnTypeWithBool) +{ + zval *this_ptr = getThis(); + + + + RETURN_BOOL(0); +} + diff --git a/ext/stub/stubs.zep.h b/ext/stub/stubs.zep.h index 2c068a11ab..4362d6a02d 100644 --- a/ext/stub/stubs.zep.h +++ b/ext/stub/stubs.zep.h @@ -8,6 +8,9 @@ PHP_METHOD(Stub_Stubs, testDocBlockAndReturnTypeDeclared); PHP_METHOD(Stub_Stubs, testMixedInputParamsDocBlock); PHP_METHOD(Stub_Stubs, testMixedInputParamsDocBlockDeclared); PHP_METHOD(Stub_Stubs, testVariableLength); +PHP_METHOD(Stub_Stubs, testMultiReturnTypeWithMixedInDocAndEmptyInSignature1); +PHP_METHOD(Stub_Stubs, testMultiReturnTypeWithMixedInDocAndEmptyInSignature2); +PHP_METHOD(Stub_Stubs, testMultiReturnTypeWithBool); ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_stubs_testdockblockandreturntype, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -28,11 +31,35 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_stubs_testvariablelength, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_stub_stubs_testmultireturntypewithmixedindocandemptyinsignature1, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_stub_stubs_testmultireturntypewithmixedindocandemptyinsignature2, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_stub_stubs_testmultireturntypewithbool, 0, 0, 0) +ZEND_END_ARG_INFO() + ZEPHIR_INIT_FUNCS(stub_stubs_method_entry) { PHP_ME(Stub_Stubs, testDockBlockAndReturnType, arginfo_stub_stubs_testdockblockandreturntype, ZEND_ACC_PUBLIC) PHP_ME(Stub_Stubs, testDocBlockAndReturnTypeDeclared, arginfo_stub_stubs_testdocblockandreturntypedeclared, ZEND_ACC_PUBLIC) PHP_ME(Stub_Stubs, testMixedInputParamsDocBlock, arginfo_stub_stubs_testmixedinputparamsdocblock, ZEND_ACC_PUBLIC) PHP_ME(Stub_Stubs, testMixedInputParamsDocBlockDeclared, arginfo_stub_stubs_testmixedinputparamsdocblockdeclared, ZEND_ACC_PUBLIC) PHP_ME(Stub_Stubs, testVariableLength, arginfo_stub_stubs_testvariablelength, ZEND_ACC_PUBLIC) +#if PHP_VERSION_ID >= 80000 + PHP_ME(Stub_Stubs, testMultiReturnTypeWithMixedInDocAndEmptyInSignature1, arginfo_stub_stubs_testmultireturntypewithmixedindocandemptyinsignature1, ZEND_ACC_PUBLIC) +#else + PHP_ME(Stub_Stubs, testMultiReturnTypeWithMixedInDocAndEmptyInSignature1, NULL, ZEND_ACC_PUBLIC) +#endif +#if PHP_VERSION_ID >= 80000 + PHP_ME(Stub_Stubs, testMultiReturnTypeWithMixedInDocAndEmptyInSignature2, arginfo_stub_stubs_testmultireturntypewithmixedindocandemptyinsignature2, ZEND_ACC_PUBLIC) +#else + PHP_ME(Stub_Stubs, testMultiReturnTypeWithMixedInDocAndEmptyInSignature2, NULL, ZEND_ACC_PUBLIC) +#endif +#if PHP_VERSION_ID >= 80000 + PHP_ME(Stub_Stubs, testMultiReturnTypeWithBool, arginfo_stub_stubs_testmultireturntypewithbool, ZEND_ACC_PUBLIC) +#else + PHP_ME(Stub_Stubs, testMultiReturnTypeWithBool, NULL, ZEND_ACC_PUBLIC) +#endif PHP_FE_END }; diff --git a/ext/stub/types/mixedtype.zep.c b/ext/stub/types/mixedtype.zep.c new file mode 100644 index 0000000000..7ec1a3d8ee --- /dev/null +++ b/ext/stub/types/mixedtype.zep.c @@ -0,0 +1,247 @@ + +#ifdef HAVE_CONFIG_H +#include "../../ext_config.h" +#endif + +#include +#include "../../php_ext.h" +#include "../../ext.h" + +#include +#include +#include + +#include "kernel/main.h" +#include "kernel/object.h" +#include "kernel/operators.h" +#include "kernel/memory.h" +#include "kernel/array.h" + + +ZEPHIR_INIT_CLASS(Stub_Types_MixedType) +{ + ZEPHIR_REGISTER_CLASS(Stub\\Types, MixedType, stub, types_mixedtype, stub_types_mixedtype_method_entry, 0); + + return SUCCESS; +} + +/** + * Mixed only as return type methods + */ +PHP_METHOD(Stub_Types_MixedType, returnMixedObject) +{ + zval *this_ptr = getThis(); + + + + object_init(return_value); + return; +} + +PHP_METHOD(Stub_Types_MixedType, returnMixedArray) +{ + zval *this_ptr = getThis(); + + + + array_init(return_value); + return; +} + +PHP_METHOD(Stub_Types_MixedType, returnMixedString) +{ + zval *this_ptr = getThis(); + + + + RETURN_STRING("mixed string"); +} + +PHP_METHOD(Stub_Types_MixedType, returnMixedInt) +{ + zval *this_ptr = getThis(); + + + + RETURN_LONG(1); +} + +PHP_METHOD(Stub_Types_MixedType, returnMixedFloat) +{ + zval *this_ptr = getThis(); + + + + RETURN_DOUBLE(3.14); +} + +PHP_METHOD(Stub_Types_MixedType, returnMixedBool) +{ + zval *this_ptr = getThis(); + + + + RETURN_BOOL(1); +} + +PHP_METHOD(Stub_Types_MixedType, returnMixedNull) +{ + zval *this_ptr = getThis(); + + + + RETURN_NULL(); +} + +PHP_METHOD(Stub_Types_MixedType, returnMixed74) +{ + zval *diff_param = NULL; + zend_bool diff; + zval *this_ptr = getThis(); + +#if PHP_VERSION_ID >= 80000 + bool is_null_true = 1; + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(diff) + ZEND_PARSE_PARAMETERS_END(); +#endif + + + zephir_fetch_params_without_memory_grow(0, 1, &diff_param); + if (!diff_param) { + diff = 0; + } else { + diff = zephir_get_boolval(diff_param); + } + + + if (diff) { + RETURN_STRING("string"); + } + object_init(return_value); + return; +} + +PHP_METHOD(Stub_Types_MixedType, returnMultiButAlwaysMixed) +{ + zval *this_ptr = getThis(); + + + + RETURN_STRING("ZEND_BEGIN_ARG_INFO_EX"); +} + +/** + * Mixed only as parameter in method + */ +PHP_METHOD(Stub_Types_MixedType, paramMixed) +{ + zval val_sub; + zval *val; + zval *this_ptr = getThis(); + + ZVAL_UNDEF(&val_sub); +#if PHP_VERSION_ID >= 80000 + bool is_null_true = 1; + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(val) + ZEND_PARSE_PARAMETERS_END(); +#endif + + + zephir_fetch_params_without_memory_grow(1, 0, &val); + + + RETVAL_ZVAL(val, 1, 0); + return; +} + +PHP_METHOD(Stub_Types_MixedType, paramMixedTwo) +{ + zval val1_sub, val2_sub; + zval *val1, *val2; + zval *this_ptr = getThis(); + + ZVAL_UNDEF(&val1_sub); + ZVAL_UNDEF(&val2_sub); +#if PHP_VERSION_ID >= 80000 + bool is_null_true = 1; + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_ZVAL(val1) + Z_PARAM_ZVAL(val2) + ZEND_PARSE_PARAMETERS_END(); +#endif + + + zephir_fetch_params_without_memory_grow(2, 0, &val1, &val2); + + + zephir_create_array(return_value, 2, 0); + zephir_array_fast_append(return_value, val1); + zephir_array_fast_append(return_value, val2); + return; +} + +PHP_METHOD(Stub_Types_MixedType, paramMixedWithMulti) +{ + zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL; + zval *mixedVal; + zval stringVal; + zval *intVal_param = NULL, *stringVal_param = NULL, mixedVal_sub, _0; + zend_long intVal; + zval *this_ptr = getThis(); + + ZVAL_UNDEF(&mixedVal_sub); + ZVAL_UNDEF(&_0); + ZVAL_UNDEF(&stringVal); +#if PHP_VERSION_ID >= 80000 + bool is_null_true = 1; + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_LONG(intVal) + Z_PARAM_STR(stringVal) + Z_PARAM_ZVAL(mixedVal) + ZEND_PARSE_PARAMETERS_END(); +#endif + + + ZEPHIR_MM_GROW(); + zephir_fetch_params(1, 3, 0, &intVal_param, &stringVal_param, &mixedVal); + intVal = zephir_get_intval(intVal_param); + zephir_get_strval(&stringVal, stringVal_param); + + + zephir_create_array(return_value, 3, 0); + ZEPHIR_INIT_VAR(&_0); + ZVAL_LONG(&_0, intVal); + zephir_array_fast_append(return_value, &_0); + zephir_array_fast_append(return_value, &stringVal); + zephir_array_fast_append(return_value, mixedVal); + RETURN_MM(); +} + +/** + * Mixed as as parameter and return type in method + */ +PHP_METHOD(Stub_Types_MixedType, paramAndReturnMixed) +{ + zval val_sub; + zval *val; + zval *this_ptr = getThis(); + + ZVAL_UNDEF(&val_sub); +#if PHP_VERSION_ID >= 80000 + bool is_null_true = 1; + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(val) + ZEND_PARSE_PARAMETERS_END(); +#endif + + + zephir_fetch_params_without_memory_grow(1, 0, &val); + + + RETVAL_ZVAL(val, 1, 0); + return; +} + diff --git a/ext/stub/types/mixedtype.zep.h b/ext/stub/types/mixedtype.zep.h new file mode 100644 index 0000000000..641da1d00f --- /dev/null +++ b/ext/stub/types/mixedtype.zep.h @@ -0,0 +1,122 @@ + +extern zend_class_entry *stub_types_mixedtype_ce; + +ZEPHIR_INIT_CLASS(Stub_Types_MixedType); + +PHP_METHOD(Stub_Types_MixedType, returnMixedObject); +PHP_METHOD(Stub_Types_MixedType, returnMixedArray); +PHP_METHOD(Stub_Types_MixedType, returnMixedString); +PHP_METHOD(Stub_Types_MixedType, returnMixedInt); +PHP_METHOD(Stub_Types_MixedType, returnMixedFloat); +PHP_METHOD(Stub_Types_MixedType, returnMixedBool); +PHP_METHOD(Stub_Types_MixedType, returnMixedNull); +PHP_METHOD(Stub_Types_MixedType, returnMixed74); +PHP_METHOD(Stub_Types_MixedType, returnMultiButAlwaysMixed); +PHP_METHOD(Stub_Types_MixedType, paramMixed); +PHP_METHOD(Stub_Types_MixedType, paramMixedTwo); +PHP_METHOD(Stub_Types_MixedType, paramMixedWithMulti); +PHP_METHOD(Stub_Types_MixedType, paramAndReturnMixed); + +#if PHP_VERSION_ID >= 80000 +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedobject, 0, 0, IS_MIXED, 0) +#else +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedobject, 0, 0, IS_NULL, 0) +#endif +ZEND_END_ARG_INFO() + +#if PHP_VERSION_ID >= 80000 +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedarray, 0, 0, IS_MIXED, 0) +#else +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedarray, 0, 0, IS_NULL, 0) +#endif +ZEND_END_ARG_INFO() + +#if PHP_VERSION_ID >= 80000 +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedstring, 0, 0, IS_MIXED, 0) +#else +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedstring, 0, 0, IS_NULL, 0) +#endif +ZEND_END_ARG_INFO() + +#if PHP_VERSION_ID >= 80000 +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedint, 0, 0, IS_MIXED, 0) +#else +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedint, 0, 0, IS_NULL, 0) +#endif +ZEND_END_ARG_INFO() + +#if PHP_VERSION_ID >= 80000 +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedfloat, 0, 0, IS_MIXED, 0) +#else +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedfloat, 0, 0, IS_NULL, 0) +#endif +ZEND_END_ARG_INFO() + +#if PHP_VERSION_ID >= 80000 +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedbool, 0, 0, IS_MIXED, 0) +#else +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixedbool, 0, 0, IS_NULL, 0) +#endif +ZEND_END_ARG_INFO() + +#if PHP_VERSION_ID >= 80000 +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixednull, 0, 0, IS_MIXED, 0) +#else +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixednull, 0, 0, IS_NULL, 0) +#endif +ZEND_END_ARG_INFO() + +#if PHP_VERSION_ID >= 80000 +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixed74, 0, 0, IS_MIXED, 0) +#else +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_returnmixed74, 0, 0, IS_NULL, 0) +#endif + ZEND_ARG_TYPE_INFO(0, diff, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_stub_types_mixedtype_returnmultibutalwaysmixed, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_stub_types_mixedtype_parammixed, 0, 0, 1) + ZEND_ARG_INFO(0, val) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_stub_types_mixedtype_parammixedtwo, 0, 0, 2) + ZEND_ARG_INFO(0, val1) + ZEND_ARG_INFO(0, val2) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_stub_types_mixedtype_parammixedwithmulti, 0, 0, 3) + ZEND_ARG_TYPE_INFO(0, intVal, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, stringVal, IS_STRING, 0) + ZEND_ARG_INFO(0, mixedVal) +ZEND_END_ARG_INFO() + +#if PHP_VERSION_ID >= 80000 +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_paramandreturnmixed, 0, 1, IS_MIXED, 0) +#else +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stub_types_mixedtype_paramandreturnmixed, 0, 1, IS_NULL, 0) +#endif + ZEND_ARG_INFO(0, val) +ZEND_END_ARG_INFO() + +ZEPHIR_INIT_FUNCS(stub_types_mixedtype_method_entry) { + PHP_ME(Stub_Types_MixedType, returnMixedObject, arginfo_stub_types_mixedtype_returnmixedobject, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Types_MixedType, returnMixedArray, arginfo_stub_types_mixedtype_returnmixedarray, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Types_MixedType, returnMixedString, arginfo_stub_types_mixedtype_returnmixedstring, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Types_MixedType, returnMixedInt, arginfo_stub_types_mixedtype_returnmixedint, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Types_MixedType, returnMixedFloat, arginfo_stub_types_mixedtype_returnmixedfloat, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Types_MixedType, returnMixedBool, arginfo_stub_types_mixedtype_returnmixedbool, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Types_MixedType, returnMixedNull, arginfo_stub_types_mixedtype_returnmixednull, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Types_MixedType, returnMixed74, arginfo_stub_types_mixedtype_returnmixed74, ZEND_ACC_PUBLIC) +#if PHP_VERSION_ID >= 80000 + PHP_ME(Stub_Types_MixedType, returnMultiButAlwaysMixed, arginfo_stub_types_mixedtype_returnmultibutalwaysmixed, ZEND_ACC_PUBLIC) +#else + PHP_ME(Stub_Types_MixedType, returnMultiButAlwaysMixed, NULL, ZEND_ACC_PUBLIC) +#endif + PHP_ME(Stub_Types_MixedType, paramMixed, arginfo_stub_types_mixedtype_parammixed, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Types_MixedType, paramMixedTwo, arginfo_stub_types_mixedtype_parammixedtwo, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Types_MixedType, paramMixedWithMulti, arginfo_stub_types_mixedtype_parammixedwithmulti, ZEND_ACC_PUBLIC) + PHP_ME(Stub_Types_MixedType, paramAndReturnMixed, arginfo_stub_types_mixedtype_paramandreturnmixed, ZEND_ACC_PUBLIC) + PHP_FE_END +}; diff --git a/phpunit.ext.xml b/phpunit.ext.xml new file mode 100644 index 0000000000..b31dadeedc --- /dev/null +++ b/phpunit.ext.xml @@ -0,0 +1,23 @@ + + + + + tests/Extension + + + + + + + + + + + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist index cd5c47b241..fcdc56b0d6 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,22 +1,27 @@ - + xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" + bootstrap="Library/autoload.php" + colors="true" + verbose="true" +> + - ./Library + Library - + + + - ./tests/Extension + tests/Extension - ./tests/Zephir + tests/Zephir tests/Zephir/KernelTestCase.php @@ -27,6 +32,7 @@ + @@ -36,6 +42,7 @@ + diff --git a/prototypes/apc.php b/prototypes/apc.php index 9064a224a3..03f32c0404 100644 --- a/prototypes/apc.php +++ b/prototypes/apc.php @@ -15,7 +15,7 @@ defined('APC_BIN_VERIFY_MD5') || define('APC_BIN_VERIFY_MD5', 1 << 0); // See: https://github.com/php/pecl-caching-apc/blob/master/apc_iterator.h - defined('APC_ITER_ALL') || define('APC_ITER_ALL', 0xffffffff); + defined('APC_ITER_ALL') || define('APC_ITER_ALL', 0xFFFFFFFF); defined('APC_ITER_ATIME') || define('APC_ITER_ATIME', 1 << 11); defined('APC_ITER_CTIME') || define('APC_ITER_CTIME', 1 << 9); defined('APC_ITER_DEVICE') || define('APC_ITER_DEVICE', 1 << 3); @@ -62,6 +62,7 @@ public function key() { } + #[ReturnTypeWillChange] public function next() { } diff --git a/stub/globals.zep b/stub/globals.zep index bd8c2f302b..4b36341eb7 100644 --- a/stub/globals.zep +++ b/stub/globals.zep @@ -20,6 +20,11 @@ class Globals globals_set("my_setting_4", value); } + public function setStringValue(string value) -> void + { + globals_set("my_setting_5", value); + } + public function setBoolValue(value) -> void { globals_set("my_setting_1", value); @@ -88,6 +93,14 @@ class Globals return globals_get("my_setting_4"); } + /** + * @return mixed + */ + public function getDefaultGlobals8() + { + return globals_get("my_setting_5"); + } + /** * @return mixed */ diff --git a/stub/stubs.zep b/stub/stubs.zep index aada96e1e3..4b4c5a586d 100644 --- a/stub/stubs.zep +++ b/stub/stubs.zep @@ -74,4 +74,19 @@ class Stubs let data = array_merge(data, func_get_args()); } + + public function testMultiReturnTypeWithMixedInDocAndEmptyInSignature1() -> array | object + { + return []; + } + + public function testMultiReturnTypeWithMixedInDocAndEmptyInSignature2() -> var | bool + { + return false; + } + + public function testMultiReturnTypeWithBool() -> | bool + { + return false; + } } diff --git a/stub/types/mixedtype.zep b/stub/types/mixedtype.zep new file mode 100644 index 0000000000..182e3d8f41 --- /dev/null +++ b/stub/types/mixedtype.zep @@ -0,0 +1,87 @@ + +namespace Stub\Types; + +class MixedType +{ + /** + * Mixed only as return type methods + */ + + public function returnMixedObject() -> mixed + { + return new \stdClass(); + } + + public function returnMixedArray() -> mixed + { + return []; + } + + public function returnMixedString() -> mixed + { + return "mixed string"; + } + + public function returnMixedInt() -> mixed + { + return 1; + } + + public function returnMixedFloat() -> mixed + { + return 3.14; + } + + public function returnMixedBool() -> mixed + { + return true; + } + + public function returnMixedNull() -> mixed + { + return null; + } + + public function returnMixed74(bool diff = false) -> mixed + { + if (diff) { + return "string"; + } + + return new \stdClass(); + } + + public function returnMultiButAlwaysMixed() -> mixed | var | int + { + // Maybe in future make sense to generate with `IS_MIXED`. + return "ZEND_BEGIN_ARG_INFO_EX"; + } + + /** + * Mixed only as parameter in method + */ + + public function paramMixed(mixed val) + { + return val; + } + + public function paramMixedTwo(mixed val1, mixed val2) + { + return [val1, val2]; + } + + public function paramMixedWithMulti(int intVal, string stringVal, mixed mixedVal) + { + return [intVal, stringVal, mixedVal]; + } + + /** + * Mixed as as parameter and return type in method + */ + + public function paramAndReturnMixed(mixed val) -> mixed + { + return val; + } +} diff --git a/tests/Extension/ArithmeticTest.php b/tests/Extension/ArithmeticTest.php index bf3af94c92..4922328e31 100644 --- a/tests/Extension/ArithmeticTest.php +++ b/tests/Extension/ArithmeticTest.php @@ -258,7 +258,7 @@ public function testLetStatement(): void $this->assertSame($this->class->letStatementVarMinus(-1), 1); $this->assertSame($this->class->letStatementVarMinus(true), -true); $this->assertSame($this->class->letStatementVarMinus(false), -false); - $this->assertSame($this->class->letStatementVarMinus(''), @-(int)''); + $this->assertSame($this->class->letStatementVarMinus(''), @-(int) ''); $this->assertTrue($this->class->letStatementBoolMinus(-1)); // it is zend_bool not zend_var $this->assertTrue($this->class->letStatementBoolMinus(1)); $this->assertTrue($this->class->letStatementBoolMinus(true)); diff --git a/tests/Extension/BitwiseTest.php b/tests/Extension/BitwiseTest.php index 99f469239f..8281d3d5b3 100644 --- a/tests/Extension/BitwiseTest.php +++ b/tests/Extension/BitwiseTest.php @@ -128,6 +128,7 @@ public function testBitwise() /** * Bitwise XOR + * * @issue https://github.com/zephir-lang/zephir/issues/1581 */ $this->assertSame(123 ^ 321, $test->testbitwiseXor()); diff --git a/tests/Extension/Globals/EnvTest.php b/tests/Extension/Globals/EnvTest.php index 16e46d2470..e2f5b2582d 100644 --- a/tests/Extension/Globals/EnvTest.php +++ b/tests/Extension/Globals/EnvTest.php @@ -39,8 +39,8 @@ public function testEmpty(): void $tester = new Env(); $var = 'non-existing'; - $this->assertSame(false, $tester->read($var)); - $this->assertSame(false, getenv($var)); + $this->assertFalse($tester->read($var)); + $this->assertFalse(getenv($var)); } public function testReadStandard(): void diff --git a/tests/Extension/GlobalsTest.php b/tests/Extension/GlobalsTest.php index c95191f1e8..0f7fa66871 100644 --- a/tests/Extension/GlobalsTest.php +++ b/tests/Extension/GlobalsTest.php @@ -39,6 +39,7 @@ public function testShouldGetGlobalExtensionSettings(): void $this->assertSame(10, $this->test->getDefaultGlobals5()); $this->assertSame(15.2, $this->test->getDefaultGlobals6()); $this->assertSame(65, $this->test->getDefaultGlobals7()); + $this->assertSame('custom_value', $this->test->getDefaultGlobals8()); } public function testShouldSetGlobalExtensionSetting(): void @@ -69,6 +70,21 @@ public function testSetCharValueUsingInt(): void $this->assertSame(90, $this->test->getDefaultGlobals7()); } + public function testSetStringValue(): void + { + $this->test->setStringValue('1'); + $this->assertSame('1', $this->test->getDefaultGlobals8()); + + $this->test->setStringValue('c'); + $this->assertSame('c', $this->test->getDefaultGlobals8()); + + $this->test->setStringValue('char'); + $this->assertSame('char', $this->test->getDefaultGlobals8()); + + $this->test->setStringValue('Long Text without any sense...'); + $this->assertSame('Long Text without any sense...', $this->test->getDefaultGlobals8()); + } + public function testSetBoolValueUsingInt(): void { $this->test->setBoolValue(0); diff --git a/tests/Extension/InvokeTest.php b/tests/Extension/InvokeTest.php index ee3ab11202..4c99420887 100644 --- a/tests/Extension/InvokeTest.php +++ b/tests/Extension/InvokeTest.php @@ -33,7 +33,7 @@ public function testProtectedMethod(): void $fromProtected = new InvokeProtected('random'); $this->assertInstanceOf(InvokeProtected::class, $fromProtected()); - $this->assertSame('random2', (string)$fromProtected()); + $this->assertSame('random2', (string) $fromProtected()); $this->assertSame('random2', $fromProtected()->__toString()); } @@ -43,7 +43,7 @@ public function testProtectedMethodComplex(): void $fromProtected = new InvokeProtectedComplex('random'); $this->assertInstanceOf(InvokeProtectedComplex::class, $fromProtected()); - $this->assertSame($expected, (string)$fromProtected()); + $this->assertSame($expected, (string) $fromProtected()); $this->assertSame($expected, $fromProtected()->__toString()); } } diff --git a/tests/Extension/MCallTest.php b/tests/Extension/MCallTest.php index fbae3ce479..f6e48fa431 100644 --- a/tests/Extension/MCallTest.php +++ b/tests/Extension/MCallTest.php @@ -15,7 +15,6 @@ use PHPUnit\Framework\TestCase; use ReflectionClass; -use ReflectionException; use ReflectionParameter; use Stub\Mcall; use Stub\Oo\Param; @@ -199,7 +198,7 @@ public function testIssue1136(): void { $test = new Mcall(); - if (version_compare(PHP_VERSION, "8.0.0", ">=")) { + if (version_compare(PHP_VERSION, '8.0.0', '>=')) { $this->assertInstanceOf(\finfo::class, $test->issue1136()); } else { $this->assertIsResource($test->issue1136()); diff --git a/tests/Extension/Namespaces/ClassEntryTest.php b/tests/Extension/Namespaces/ClassEntryTest.php index b268a66104..9a7d6ad1c0 100644 --- a/tests/Extension/Namespaces/ClassEntryTest.php +++ b/tests/Extension/Namespaces/ClassEntryTest.php @@ -14,8 +14,8 @@ namespace Extension\Namespaces; use PHPUnit\Framework\TestCase; -use Stub\Namespaces\ClassEntry; use Stub\Namespaces\A\B\Sub; +use Stub\Namespaces\ClassEntry; final class ClassEntryTest extends TestCase { diff --git a/tests/Extension/Optimizers/IsPhpVersionTest.php b/tests/Extension/Optimizers/IsPhpVersionTest.php index 72467c7cef..32d87b0a0d 100644 --- a/tests/Extension/Optimizers/IsPhpVersionTest.php +++ b/tests/Extension/Optimizers/IsPhpVersionTest.php @@ -60,6 +60,7 @@ public function phpVersionProvider(): array * * @param mixed $version * @param mixed $expected + * * @throws Exception */ public function testOptimizer($version, $expected): void @@ -146,6 +147,7 @@ public function releaseVersionProvider(): array * * @param mixed $testName * @param mixed $version + * * @throws Exception */ public function testIsPhpVersionVersionUsing701XX($testName, $version): void @@ -172,6 +174,7 @@ public function minorVersionProvider(): array * * @param mixed $testName * @param mixed $version + * * @throws Exception */ public function testIsPhpVersionVersionUsing70X00($testName, $version): void @@ -208,6 +211,7 @@ public function testZephirUsingString50600(): void /** * @param Throwable $error + * * @throws Throwable */ protected function onNotSuccessfulTest(Throwable $error): void @@ -233,6 +237,7 @@ protected function onNotSuccessfulTest(Throwable $error): void * @param float|int|string $version - PHP version in any format: 7, 7.1, "7.1.1" * * @return bool + * * @throws Exception */ private function isPhpVersion($version): bool diff --git a/tests/Extension/RequiresTest.php b/tests/Extension/RequiresTest.php index 7178c6594c..99bd7ad134 100644 --- a/tests/Extension/RequiresTest.php +++ b/tests/Extension/RequiresTest.php @@ -84,8 +84,7 @@ public function testRequireOnce(): void $this->test->requireOnce(__DIR__.'/../fixtures/require-me-before-once.php') ); - $this->assertSame( - true, + $this->assertTrue( $this->test->requireOnce(__DIR__.'/../fixtures/require-me-before-once.php') ); diff --git a/tests/Extension/ScallLateConstructTest.php b/tests/Extension/ScallLateConstructTest.php index eeba905d5d..5a27cefa78 100644 --- a/tests/Extension/ScallLateConstructTest.php +++ b/tests/Extension/ScallLateConstructTest.php @@ -20,7 +20,7 @@ final class ScallLateConstructTest extends TestCase { /** * @issue https://github.com/zephir-lang/zephir/issues/2111 - */ + */ public function testConstruct(): void { $test = new ScallLateConstruct(); diff --git a/tests/Extension/SplTest.php b/tests/Extension/SplTest.php index 087b145172..270708f32a 100644 --- a/tests/Extension/SplTest.php +++ b/tests/Extension/SplTest.php @@ -23,6 +23,6 @@ final class SplTest extends TestCase */ public function testIssue1212(): void { - $this->assertInstanceOf(\SplFileObject::class, Spl::issue1212(__DIR__ . '/../fixtures/class-empty.php')); + $this->assertInstanceOf(\SplFileObject::class, Spl::issue1212(__DIR__.'/../fixtures/class-empty.php')); } } diff --git a/tests/Extension/StringTest.php b/tests/Extension/StringTest.php index 9336a41b55..580bc40aba 100644 --- a/tests/Extension/StringTest.php +++ b/tests/Extension/StringTest.php @@ -200,8 +200,8 @@ public function providerSubstring(): array * @dataProvider providerSubstring * * @param string $input - * @param int $start - * @param int $end + * @param int $start + * @param int $end * @param string $expected */ public function testSubstr(string $input, int $start, int $end, string $expected): void diff --git a/tests/Extension/Types/MixedTypeTest.php b/tests/Extension/Types/MixedTypeTest.php new file mode 100644 index 0000000000..fc198c5b69 --- /dev/null +++ b/tests/Extension/Types/MixedTypeTest.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Extension\Types; + +use PHPUnit\Framework\TestCase; +use Stub\Types\MixedType; + +final class MixedTypeTest extends TestCase +{ + public function testReturnsOfMixedType(): void + { + $returns = new MixedType(); + + $this->assertEquals((new \stdClass()), $returns->returnMixedObject()); + $this->assertSame([], $returns->returnMixedArray()); + $this->assertSame('mixed string', $returns->returnMixedString()); + $this->assertSame(1, $returns->returnMixedInt()); + $this->assertSame(3.14, $returns->returnMixedFloat()); + $this->assertTrue($returns->returnMixedBool()); + $this->assertNull($returns->returnMixedNull()); + + $this->assertNotNull($returns->returnMixedObject()); + $this->assertNotNull($returns->returnMixedArray()); + $this->assertNotNull($returns->returnMixedString()); + $this->assertNotNull($returns->returnMixedInt()); + $this->assertNotNull($returns->returnMixedFloat()); + $this->assertNotNull($returns->returnMixedBool()); + $this->assertNull($returns->returnMixedNull()); + + $this->assertEquals((new \stdClass()), $returns->returnMixed74()); + $this->assertSame('string', $returns->returnMixed74(true)); + $this->assertEquals((new \stdClass()), $returns->returnMixed74(false)); + } + + public function testParamsOfMixedType(): void + { + $returns = new MixedType(); + + $this->assertEquals((new \stdClass()), $returns->paramMixed((new \stdClass()))); + $this->assertSame([], $returns->paramMixed([])); + $this->assertSame('mixed string', $returns->paramMixed('mixed string')); + $this->assertSame(1, $returns->paramMixed(1)); + $this->assertSame(3.14, $returns->paramMixed(3.14)); + $this->assertTrue($returns->paramMixed(true)); + $this->assertNull($returns->paramMixed(null)); + + $this->assertEquals([(new \stdClass()), []], $returns->paramMixedTwo((new \stdClass()), [])); + $this->assertSame([[], 'mixed string'], $returns->paramMixedTwo([], 'mixed string')); + $this->assertSame([1, 3.14], $returns->paramMixedTwo(1, 3.14)); + $this->assertSame([3.14, true], $returns->paramMixedTwo(3.14, true)); + $this->assertSame([true, null], $returns->paramMixedTwo(true, null)); + $this->assertSame([null, null], $returns->paramMixedTwo(null, null)); + + $this->assertEquals([1337, 'object', (new \stdClass())], $returns->paramMixedWithMulti(1337, 'object', (new \stdClass()))); + $this->assertSame([1337, 'array', []], $returns->paramMixedWithMulti(1337, 'array', [])); + $this->assertSame([1337, 'string', 'mixed string'], $returns->paramMixedWithMulti(1337, 'string', 'mixed string')); + $this->assertSame([1337, 'int', 123], $returns->paramMixedWithMulti(1337, 'int', 123)); + $this->assertSame([1337, 'float', 2.44], $returns->paramMixedWithMulti(1337, 'float', 2.44)); + $this->assertSame([1337, 'bool', false], $returns->paramMixedWithMulti(1337, 'bool', false)); + $this->assertSame([1337, 'null', null], $returns->paramMixedWithMulti(1337, 'null', null)); + } + + public function testParamsAndReturnsOfMixedType(): void + { + $returns = new MixedType(); + + $this->assertEquals((new \stdClass()), $returns->paramAndReturnMixed((new \stdClass()))); + $this->assertSame([], $returns->paramAndReturnMixed([])); + $this->assertSame('mixed string', $returns->paramAndReturnMixed('mixed string')); + $this->assertSame(1, $returns->paramAndReturnMixed(1)); + $this->assertSame(3.14, $returns->paramAndReturnMixed(3.14)); + $this->assertTrue($returns->paramAndReturnMixed(true)); + $this->assertNull($returns->paramAndReturnMixed(null)); + } +} diff --git a/tests/Zephir/AliasManagerTest.php b/tests/Zephir/AliasManagerTest.php index 8b1325cb8d..70e4c66fcb 100644 --- a/tests/Zephir/AliasManagerTest.php +++ b/tests/Zephir/AliasManagerTest.php @@ -121,7 +121,7 @@ public function statementProvider(): array * @dataProvider statementProvider * * @param array $useStatements - * @param bool $expected + * @param bool $expected */ public function testShouldCheckAliasedStatement(array $useStatements, bool $expected): void { @@ -153,7 +153,7 @@ public function classNameDataProvider(): array /** * @dataProvider classNameDataProvider * - * @param array $useStatements + * @param array $useStatements * @param string $expected */ public function testShouldGetAliasForClassName(array $useStatements, string $expected): void diff --git a/tests/Zephir/ConfigTest.php b/tests/Zephir/ConfigTest.php index 153784a70a..e7debd114c 100644 --- a/tests/Zephir/ConfigTest.php +++ b/tests/Zephir/ConfigTest.php @@ -126,6 +126,7 @@ public function setConfigProvider(): array /** * @dataProvider setConfigProvider + * * @param array $test * @param mixed $expected */ @@ -162,9 +163,9 @@ public function defaultConfigProvider(): array /** * @dataProvider defaultConfigProvider * - * @param mixed $namespace + * @param mixed $namespace * @param string $key - * @param mixed $expected + * @param mixed $expected */ public function testShouldGetDefaultConfigParams($namespace, string $key, $expected) { diff --git a/tests/Zephir/HelpersTest.php b/tests/Zephir/HelpersTest.php index 928784b914..376d81467d 100644 --- a/tests/Zephir/HelpersTest.php +++ b/tests/Zephir/HelpersTest.php @@ -70,6 +70,7 @@ public function cStringProvider(): array /** * @dataProvider cStringProvider + * * @param string $testString * @param string $expected */ diff --git a/tests/Zephir/Stubs/GeneratorTest.php b/tests/Zephir/Stubs/GeneratorTest.php index f6d40887d7..e8e6326b02 100644 --- a/tests/Zephir/Stubs/GeneratorTest.php +++ b/tests/Zephir/Stubs/GeneratorTest.php @@ -45,7 +45,9 @@ protected function setUp(): void * Modify method visibility to call protected. * * @param string $name - method name + * * @return mixed + * * @throws ReflectionException */ private function getMethod(string $name) @@ -85,7 +87,6 @@ final class StubsBuildClass extends BaseTestClass implements \Iterator, EventsMa */ static public \$defaultPathDelimiter = null; - /** * @param string \$key * @param int \$priority @@ -93,7 +94,6 @@ final class StubsBuildClass extends BaseTestClass implements \Iterator, EventsMa public static function init(string \$key, int \$priority = 1) { } - } DOC; @@ -241,10 +241,11 @@ public function propertyProvider(): array * @dataProvider propertyProvider * @covers \Zephir\Stubs\Generator::buildProperty * - * @param array $visibility + * @param array $visibility * @param string $type * @param $value * @param string $expected + * * @throws ReflectionException */ public function testShouldBuildProperty(array $visibility, string $type, $value, string $expected): void @@ -281,7 +282,7 @@ public function testShouldBuildProperty(array $visibility, string $type, $value, ] ); - $this->assertSame(PHP_EOL.$expected, $actual); + $this->assertSame($expected, $actual); } public function constantProvider(): array @@ -332,6 +333,7 @@ public function constantProvider(): array * @param string $type * @param $value * @param string $expected + * * @throws ReflectionException */ public function testShouldBuildConstant(string $type, $value, string $expected): void @@ -376,7 +378,7 @@ public function testShouldBuildConstant(string $type, $value, string $expected): ] ); - $this->assertSame(PHP_EOL.$expected, $actual); + $this->assertSame($expected, $actual); } public function testShouldBuildMethod(): void diff --git a/tests/Zephir/TypesTest.php b/tests/Zephir/TypesTest.php index d5e22d3889..a2bccd38d1 100644 --- a/tests/Zephir/TypesTest.php +++ b/tests/Zephir/TypesTest.php @@ -24,6 +24,7 @@ final class TypesTest extends TestCase * Helper to build proper structure with method return types. * * @param array $returnTypesList - collactions with all return types + * * @return array */ private function buildReturnTypes(array $returnTypesList): array @@ -41,8 +42,9 @@ private function buildReturnTypes(array $returnTypesList): array /** * Builds base object definition for return type. * - * @param array $types - list of method return types - * @param int $mandatory - is mandatory flag + * @param array $types - list of method return types + * @param int $mandatory - is mandatory flag + * * @return array */ private function baseReturnTypeDefinition(array $types, int $mandatory = 0): array @@ -67,6 +69,7 @@ function ($type) use ($mandatory) { * * @param array $types - list of method return types * @param int $collection - is collection flag + * * @return array */ private function variableReturnTypeDefinition(array $types, int $collection = 0): array @@ -189,7 +192,7 @@ public function typesProvider(): array /** * @dataProvider typesProvider * - * @param array $returnTypes + * @param array $returnTypes * @param string $expected */ public function testShouldResolveCompatibleTypeForBaseTypes(array $returnTypes, string $expected): void @@ -228,7 +231,7 @@ public function objectsProvider(): array /** * @dataProvider objectsProvider * - * @param array $returnTypes + * @param array $returnTypes * @param string $expected */ public function testShouldResolveCompatibleTypeForObjects(array $returnTypes, string $expected): void @@ -274,7 +277,7 @@ public function collectionsProvider(): array /** * @dataProvider collectionsProvider * - * @param array $returnTypes + * @param array $returnTypes * @param string $expected */ public function testShouldResolveCompatibleTypeForCollections(array $returnTypes, string $expected): void diff --git a/tests/fixtures/stubs/issues/expected/Exception.zep.php b/tests/fixtures/stubs/issues/expected/Exception.php similarity index 99% rename from tests/fixtures/stubs/issues/expected/Exception.zep.php rename to tests/fixtures/stubs/issues/expected/Exception.php index 758cf09844..b5b716b437 100644 --- a/tests/fixtures/stubs/issues/expected/Exception.zep.php +++ b/tests/fixtures/stubs/issues/expected/Exception.php @@ -14,5 +14,4 @@ class Exception extends \Exception implements \Throwable public function __construct() { } - } diff --git a/tests/fixtures/stubs/issues/expected/Issue_1778.zep.php b/tests/fixtures/stubs/issues/expected/Issue_1778.php similarity index 99% rename from tests/fixtures/stubs/issues/expected/Issue_1778.zep.php rename to tests/fixtures/stubs/issues/expected/Issue_1778.php index 14e6d849ed..6ed24c84f9 100644 --- a/tests/fixtures/stubs/issues/expected/Issue_1778.zep.php +++ b/tests/fixtures/stubs/issues/expected/Issue_1778.php @@ -18,7 +18,6 @@ */ class Issue_1778 { - const PROPERTY_EXAMPLE = 'test_property'; /** @@ -31,7 +30,6 @@ class Issue_1778 */ protected $config; - /** * @param \Psr\Http\Message\RequestInterface $request * @param array $config @@ -49,5 +47,4 @@ public function __construct(\Psr\Http\Message\RequestInterface $request, array $ public function getVar(string $key) { } - } diff --git a/tests/fixtures/stubs/issues/expected/Issue_1900.zep.php b/tests/fixtures/stubs/issues/expected/Issue_1900.php similarity index 99% rename from tests/fixtures/stubs/issues/expected/Issue_1900.zep.php rename to tests/fixtures/stubs/issues/expected/Issue_1900.php index 16fbb38605..00526ac869 100644 --- a/tests/fixtures/stubs/issues/expected/Issue_1900.zep.php +++ b/tests/fixtures/stubs/issues/expected/Issue_1900.php @@ -23,10 +23,8 @@ class Issue_1900 implements AliasedManagerInterface */ private $collect; - static protected $uniqueId = 0; - /** * @return AliasedManagerInterface */ @@ -130,5 +128,4 @@ public function getResources() public function hasListeners(string $type): AliasedManagerInterface { } - } diff --git a/tests/fixtures/stubs/issues/expected/Issue_1900_PHP70.zep.php b/tests/fixtures/stubs/issues/expected/Issue_1900_PHP70.zep.php deleted file mode 100644 index e3ef77abe2..0000000000 --- a/tests/fixtures/stubs/issues/expected/Issue_1900_PHP70.zep.php +++ /dev/null @@ -1,134 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -class Issue_1900 implements AliasedManagerInterface -{ - - public $eventsManager; - - /** - * @var array $collect - descr for collect var. - */ - private $collect; - - - static protected $uniqueId = 0; - - - /** - * @return AliasedManagerInterface - */ - public function getEventsManager(): AliasedManagerInterface - { - } - - /** - * @return \StdClass - */ - public function test01(): \StdClass - { - } - - /** - * Attach a listener to the events manager - * - * @param object|callable $handler - * @param string $eventType - * @param int $priority - * @return void - */ - public function attach(string $eventType, $handler, int $priority = 1) - { - } - - /** - * Returns if priorities are enabled - * - * @return bool - */ - public function arePrioritiesEnabled(): bool - { - } - - /** - * Tells the event manager if it needs to collect all the responses returned - * by every registered listener in a single fire - * - * @param bool $collect - * @param string $eventType - * @param mixed $handler - * @return void - */ - public function collectResponses(bool $collect, string $eventType, $handler) - { - } - - /** - * Fires an event in the events manager causing the active listeners to be - * notified about it - * - * ```php - * $eventsManager->fire("db", $connection); - * ``` - * - * @param object $source - * @param mixed $data - * @return mixed - * @param string $eventType - * @param bool $cancelable - */ - public function fire(string $eventType, $source, $data = null, bool $cancelable = true) - { - } - - /** - * Internal handler to call a queue of events - * - * @return mixed - * @param SplPriorityQueue $queue - * @param \Psr\Http\Message\RequestInterface $event - */ - final public function fireQueue(SplPriorityQueue $queue, \Psr\Http\Message\RequestInterface $event): AliasedManagerInterface - { - } - - /** - * Returns all the attached listeners of a certain type - * - * @param string $type - * @return array - */ - public function getListeners(string $type): array - { - } - - /** - * @return resource - */ - public function getResources() - { - } - - /** - * Check whether certain type of event has listeners - * - * @param string $type - * @return AliasedManagerInterface - */ - public function hasListeners(string $type): AliasedManagerInterface - { - } - -} diff --git a/tests/fixtures/stubs/issues/expected/Issue_1907.zep.php b/tests/fixtures/stubs/issues/expected/Issue_1907.php similarity index 99% rename from tests/fixtures/stubs/issues/expected/Issue_1907.zep.php rename to tests/fixtures/stubs/issues/expected/Issue_1907.php index 7f983586b2..7df22c7477 100644 --- a/tests/fixtures/stubs/issues/expected/Issue_1907.zep.php +++ b/tests/fixtures/stubs/issues/expected/Issue_1907.php @@ -16,5 +16,4 @@ class Issue_1907 extends Exception implements \Throwable public function __construct() { } - } diff --git a/tests/fixtures/stubs/issues/expected/Issue_1922.zep.php b/tests/fixtures/stubs/issues/expected/Issue_1922.php similarity index 100% rename from tests/fixtures/stubs/issues/expected/Issue_1922.zep.php rename to tests/fixtures/stubs/issues/expected/Issue_1922.php index e062b237a4..1f7cb564ba 100644 --- a/tests/fixtures/stubs/issues/expected/Issue_1922.zep.php +++ b/tests/fixtures/stubs/issues/expected/Issue_1922.php @@ -5,6 +5,7 @@ class Issue_1922 { + /** * @param string $key * @return mixed|null @@ -12,5 +13,4 @@ class Issue_1922 public function getVar(string $key) { } - } diff --git a/tests/fixtures/stubs/issues/expected/Issue_1986.zep.php b/tests/fixtures/stubs/issues/expected/Issue_1986.php similarity index 99% rename from tests/fixtures/stubs/issues/expected/Issue_1986.zep.php rename to tests/fixtures/stubs/issues/expected/Issue_1986.php index ec985bae58..6db7ccbcd5 100644 --- a/tests/fixtures/stubs/issues/expected/Issue_1986.zep.php +++ b/tests/fixtures/stubs/issues/expected/Issue_1986.php @@ -9,7 +9,6 @@ class Issue_1986 implements EventsManagerInterface public $eventsManager; - /** * @return EventsManagerInterface */ @@ -27,5 +26,4 @@ public function getEventsManager(): EventsManagerInterface public function attach(string $eventType, $handler): void { } - } diff --git a/tests/fixtures/stubs/issues/expected/Issue_1986_PHP70.zep.php b/tests/fixtures/stubs/issues/expected/Issue_1986_PHP70.zep.php deleted file mode 100644 index 052dd6bb9a..0000000000 --- a/tests/fixtures/stubs/issues/expected/Issue_1986_PHP70.zep.php +++ /dev/null @@ -1,31 +0,0 @@ -&1 >/dev/null } -# Some stubs test requires PHP >= 7.1 -if [ "$PHP_VERSION_ID" -lt "70100" ]; then - test_set_prereq PHP70 -fi - # This test generates Stubs once and all other tests uses this build artifacts test_expect_success "Should generate Stubs" \ "zephir_stubs && test -d ./ide/0.0.1/Stubs" # See: https://github.com/zephir-lang/zephir/issues/1922 test_expect_success "Should properly generate type hint" \ - "test_cmp expected/Issue_1922.zep.php ide/0.0.1/Stubs/Issue_1922.zep.php" + "test_cmp expected/Issue_1922.php ide/0.0.1/Stubs/Issue_1922.php" # See: https://github.com/zephir-lang/zephir/issues/1778 test_expect_success "Should properly namespace imports (use block)" \ - "test_cmp expected/Issue_1778.zep.php ide/0.0.1/Stubs/Issue_1778.zep.php" + "test_cmp expected/Issue_1778.php ide/0.0.1/Stubs/Issue_1778.php" -if test_have_prereq PHP70; then - expected="Issue_1900_PHP70.zep.php" -else - expected="Issue_1900.zep.php" -fi # See: https://github.com/zephir-lang/zephir/issues/1900 test_expect_success "Should properly generate return types for stubs" \ - "test_cmp expected/$expected ide/0.0.1/Stubs/Issue_1900.zep.php" + "test_cmp expected/Issue_1900.php ide/0.0.1/Stubs/Issue_1900.php" # See: https://github.com/zephir-lang/zephir/issues/1907 test_expect_success "Should properly generate Namespace for extends" \ - "test_cmp expected/Exception.zep.php ide/0.0.1/Stubs/Exception.zep.php" + "test_cmp expected/Exception.php ide/0.0.1/Stubs/Exception.php" # See: https://github.com/zephir-lang/zephir/issues/1907 test_expect_success "Should properly generate Namespace for extends (slash)" \ - "test_cmp expected/Issue_1907.zep.php ide/0.0.1/Stubs/Issue_1907.zep.php" + "test_cmp expected/Issue_1907.php ide/0.0.1/Stubs/Issue_1907.php" -if test_have_prereq PHP70; then - expected="Issue_1986_PHP70.zep.php" -else - expected="Issue_1986.zep.php" -fi # See: https://github.com/zephir-lang/zephir/issues/1986 test_expect_success "Should properly generate Aliases for use statements" \ - "test_cmp expected/$expected ide/0.0.1/Stubs/Issue_1986.zep.php" + "test_cmp expected/Issue_1986.php ide/0.0.1/Stubs/Issue_1986.php" # See: https://github.com/zephir-lang/zephir/issues/1896 test_expect_success "Should generate CamelCase folders for stubs" \ - "test $(ls ./ide/0.0.1/Stubs/Events/ManagerInterface.zep.php | sed -e 's~\/~\\~g') = .\ide\0.0.1\Stubs\Events\ManagerInterface.zep.php" + "test $(ls ./ide/0.0.1/Stubs/Events/ManagerInterface.php | sed -e 's~\/~\\~g') = .\ide\0.0.1\Stubs\Events\ManagerInterface.php" # See: https://github.com/zephir-lang/zephir/issues/2026 test_expect_success "Should properly generate return type for Collections" \ - "test_cmp expected/Issue_2026.zep.php ide/0.0.1/Stubs/Issue_2026.zep.php" + "test_cmp expected/Issue_2026.php ide/0.0.1/Stubs/Issue_2026.php" -if test_have_prereq PHP70; then - expected="Issue_2092_PHP70.zep.php" -else - expected="Issue_2092.zep.php" -fi # See: https://github.com/zephir-lang/zephir/issues/2092 test_expect_success "Should properly generate return type for type hinted object" \ - "test_cmp expected/$expected ide/0.0.1/Stubs/Issue_2092.zep.php" + "test_cmp expected/Issue_2092.php ide/0.0.1/Stubs/Issue_2092.php" test_done