diff -Nru haxe-4.2.1/debian/changelog haxe-4.2.4/debian/changelog --- haxe-4.2.1/debian/changelog 2021-02-27 08:52:01.000000000 +0000 +++ haxe-4.2.4/debian/changelog 2021-11-20 03:56:20.000000000 +0000 @@ -1,8 +1,27 @@ -haxe (1:4.2.1-1~ubuntu16.04.1~ppa1) xenial; urgency=medium +haxe (1:4.2.4-1~ubuntu16.04.1~ppa1) xenial; urgency=medium * No-change backport to xenial - -- Andy Li Sat, 27 Feb 2021 16:52:01 +0800 + -- Andy Li Sat, 20 Nov 2021 11:56:20 +0800 + +haxe (1:4.2.4-1) experimental; urgency=medium + + * New upstream version. + + -- Andy Li Sat, 20 Nov 2021 11:23:08 +0800 + +haxe (1:4.2.3-1) experimental; urgency=medium + + * New upstream version. + + -- Andy Li Sat, 03 Jul 2021 17:57:10 +0800 + +haxe (1:4.2.2-1) experimental; urgency=medium + + * New upstream version. + * Update d/watch. + + -- Andy Li Mon, 07 Jun 2021 16:53:59 +0800 haxe (1:4.2.1-1) experimental; urgency=medium diff -Nru haxe-4.2.1/debian/watch haxe-4.2.4/debian/watch --- haxe-4.2.1/debian/watch 2021-02-27 07:43:05.000000000 +0000 +++ haxe-4.2.4/debian/watch 2021-11-20 03:23:08.000000000 +0000 @@ -1,3 +1,3 @@ version=3 opts="uversionmangle=s/-/~/g"\ - https://github.com/HaxeFoundation/haxe/releases/latest .*/archive/(\d\S*)\.tar\.gz + https://github.com/HaxeFoundation/haxe/releases/latest .*/archive/refs/tags/(\d\S*)\.tar\.gz diff -Nru haxe-4.2.1/extra/CHANGES.txt haxe-4.2.4/extra/CHANGES.txt --- haxe-4.2.1/extra/CHANGES.txt 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/extra/CHANGES.txt 2021-11-20 03:16:28.000000000 +0000 @@ -1,3 +1,67 @@ +2021-10-22 4.2.4: + + New features: + + hl : add clipboard support in hl 1.12 (#10320) + + General improvements: + + all : improved error messages upon directory creation failures (#10361) + eval : added `%` operator to `eval.numbers.Int64` and `eval.numbers.UInt64` (#10411) + + Bugfixes: + + all : fixed errors on final vars modification with `+=`, `*=` etc operations (#10325) + all : fixed hanging of MainLoop.add on threaded targets (#10308, #10329) + all : fixed compiler crash when resolving overloads with not enough arguments (#10434) + all : fixed non-static `@:to` methods on `@:multiType` abstracts (#10145) + analyzer : fixed analyzer on overloads (#10405) + analyzer : fixed issues with fields initialization expressions (#10405) + display : improved code completion in anonymous objects declarations (#10414) + js : fixed IntMap for keys greater than 2^31 (#10316) + js : workaround to fix sourcemaps on Firefox in Windows (#10217) + js : delayed truncation of the output file on `Compiler.setCustomJSGenerator` (#10387) + cs/java : fixed rest arguments for cases when only one argument is provided (#10315) + php : fixed type of `php.db.PDO.ATTR_DRIVER_NAME` (#10319) + eval : fixed signature of `eval.luv.Tcp.noDelay` method + lua : fixed `string.length` when `string` has type of a type parameter constrained to `String` (#10343) + jvm : fixed `Reflect.compare()` for different number types (#10350) + python : fixed exceptions on tracing some native values (#10440) + +2021-07-01 4.2.3: + + General improvements: + + all : analyzer optimizations + macro : support maps in `haxe.macro.Context.makeExpr` (#10259) + js : added `-D js-global=globalThis` to customize global object name (#10282) + php : added externs for `quoted_printable_decode`, `quoted_printable_encode`, `Attribute`, `NumberFormat`, `IntlCalendar` and other `Intl*` classes + + Bugfixes: + + all : fixed compiler crash on some unreachable code blocks (#10261) + jvm : fixed `@:native` (#10280) + jvm : fixed `--xml` generation (#10279) + +2021-05-14 4.2.2: + + Bugfixes: + + all : fixed piping stdin/stdout in `--cmd` (#4669, #6726) + all : fixed rest args typing for overloaded functions (#10143) + all : fixed using `var` fields as static extensions (#10144) + all : fixed completion for a type in `expr is Type` (#10167) + all : fixed subtypes in `expr is Module.SubType` expressions (#10174) + all : fixed typing chains of calls with constrained type params (#10198) + all : fixed mixed constraints of anonymous structures and other types (#10162) + all : fixed operator overloading for enum abstracts (#10173) + hl : fixed debugging of `catch` blocks (#10109) + jvm : fixed manifest generation for cases with a lot of jar libraries (#10157) + js : fixed extending extern classes for es5 (#10192) + js : fixed checking `this` before `super` for es6 (#10193) + eval : fixed null pointer exception in `eval.NativeString.fromString(null)` + eval : fixed multiple locks of `sys.thread.Mutex` from the same thread (#10249) + 2021-02-26 4.2.1: General improvements: diff -Nru haxe-4.2.1/extra/github-actions/build-linux.yml haxe-4.2.4/extra/github-actions/build-linux.yml --- haxe-4.2.1/extra/github-actions/build-linux.yml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/extra/github-actions/build-linux.yml 2021-11-20 03:16:28.000000000 +0000 @@ -12,7 +12,7 @@ opam init # --disable-sandboxing opam update opam pin add haxe . --no-action - opam install haxe --deps-only + opam install haxe --deps-only --assume-depexts opam list ocamlopt -v diff -Nru haxe-4.2.1/extra/github-actions/build-mac.yml haxe-4.2.4/extra/github-actions/build-mac.yml --- haxe-4.2.1/extra/github-actions/build-mac.yml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/extra/github-actions/build-mac.yml 2021-11-20 03:16:28.000000000 +0000 @@ -38,7 +38,7 @@ opam env opam pin add ctypes 0.17.1 --yes opam pin add haxe . --no-action - opam install haxe --deps-only + opam install haxe --deps-only --assume-depexts opam list ocamlopt -v diff -Nru haxe-4.2.1/extra/github-actions/test-linux.yml haxe-4.2.4/extra/github-actions/test-linux.yml --- haxe-4.2.1/extra/github-actions/test-linux.yml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/extra/github-actions/test-linux.yml 2021-11-20 03:16:28.000000000 +0000 @@ -29,9 +29,9 @@ sudo apt update -qqy sudo apt install -qqy ${{matrix.APT_PACKAGES}} -- name: Flash setup - if: matrix.target == 'flash9' - run: export DISPLAY=:99.0 +# - name: Flash setup +# if: matrix.target == 'flash9' +# run: export DISPLAY=:99.0 - name: Test if: success() && !(matrix.SAUCE && matrix.SAUCE_ACCESS_KEY) diff -Nru haxe-4.2.1/extra/github-actions/workflows/main.yml haxe-4.2.4/extra/github-actions/workflows/main.yml --- haxe-4.2.1/extra/github-actions/workflows/main.yml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/extra/github-actions/workflows/main.yml 2021-11-20 03:16:28.000000000 +0000 @@ -6,7 +6,7 @@ jobs: cancel: name: "Cancel previous runs" - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 timeout-minutes: 3 steps: - uses: styfle/cancel-workflow-action@0.3.1 @@ -53,7 +53,7 @@ @import build-windows.yml linux-build: - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 env: PLATFORM: linux64 OPAMYES: 1 @@ -132,7 +132,7 @@ linux-test: needs: linux-build - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 env: PLATFORM: linux64 TEST: ${{matrix.target}} @@ -140,7 +140,7 @@ strategy: fail-fast: false matrix: - target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash9, neko] + target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, neko] #flash9 include: - target: js # SAUCE: 1 @@ -152,8 +152,8 @@ APT_PACKAGES: gcc-multilib g++-multilib - target: lua APT_PACKAGES: ncurses-dev - - target: flash9 - APT_PACKAGES: libglib2.0 libfreetype6 xvfb + # - target: flash9 + # APT_PACKAGES: libglib2.0-0 libfreetype6 xvfb steps: - uses: actions/checkout@main with: @@ -175,7 +175,7 @@ strategy: fail-fast: false matrix: - target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash9, neko] + target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, neko] #flash9 include: - target: hl BREW_PACKAGES: ninja @@ -193,7 +193,7 @@ deploy: if: github.event_name != 'pull_request' needs: [linux-test, mac-test, windows-test, windows64-test] - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: # this is only needed for to get `COMMIT_DATE`... # maybe https://github.community/t/expose-commit-timestamp-in-the-github-context-data/16460/3 @@ -265,7 +265,7 @@ deploy_apidoc: if: github.event_name != 'pull_request' # TODO: also only when `GHP_REMOTE` is present needs: [linux-test, mac-test, windows-test, windows64-test] - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Download Haxe uses: actions/download-artifact@v2 diff -Nru haxe-4.2.1/.github/workflows/main.yml haxe-4.2.4/.github/workflows/main.yml --- haxe-4.2.1/.github/workflows/main.yml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/.github/workflows/main.yml 2021-11-20 03:16:28.000000000 +0000 @@ -7,7 +7,7 @@ jobs: cancel: name: "Cancel previous runs" - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 timeout-minutes: 3 steps: - uses: styfle/cancel-workflow-action@0.3.1 @@ -35,7 +35,7 @@ if: ${{ !startsWith(env.PLATFORM, 'windows') }} run: | set -ex - + curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP NEKOPATH=`echo $RUNNER_TEMP/neko-*-*` @@ -45,7 +45,7 @@ sudo ln -s $NEKOPATH/libneko.* /usr/local/lib/ sudo ln -s $NEKOPATH/*.ndll /usr/local/lib/neko/ echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV - + - name: Install Neko using snapshot from S3 (Windows) if: ${{ startsWith(env.PLATFORM, 'windows') }} shell: pwsh @@ -55,10 +55,10 @@ $NEKOPATH = Get-ChildItem $env:RUNNER_TEMP/neko-*-* echo "$NEKOPATH" >> $env:GITHUB_PATH echo "NEKOPATH=$NEKOPATH" >> $env:GITHUB_ENV - + - name: Print Neko version run: neko -version 2>&1 - + - name: choco install nsis uses: nick-invision/retry@v1 with: @@ -71,7 +71,7 @@ - name: Prepend Chocolatey path shell: pwsh run: Write-Host "::add-path::C:\ProgramData\chocolatey\bin" - + - name: Install OCaml and OCaml libraries shell: pwsh run: | @@ -94,16 +94,16 @@ & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'opam install haxe --deps-only --yes 2>&1') & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'opam list') & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'ocamlopt -v') - + - name: Expose mingw dll files shell: pwsh run: Write-Host "::add-path::${env:CYG_ROOT}/usr/$($env:MINGW_ARCH)-w64-mingw32/sys-root/mingw/bin" - + - name: Set ADD_REVISION=1 for non-release if: ${{ !startsWith(github.ref, 'refs/tags/') }} shell: pwsh run: echo "ADD_REVISION=1" >> $Env:GITHUB_ENV - + - name: Build Haxe shell: pwsh run: | @@ -115,13 +115,13 @@ & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxe.exe') & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxelib.exe') & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && ls ./out') - + - name: Upload artifact uses: actions/upload-artifact@v1.0.0 with: name: win${{env.ARCH}}Binaries path: out - + windows-build: runs-on: windows-latest @@ -143,7 +143,7 @@ if: ${{ !startsWith(env.PLATFORM, 'windows') }} run: | set -ex - + curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP NEKOPATH=`echo $RUNNER_TEMP/neko-*-*` @@ -153,7 +153,7 @@ sudo ln -s $NEKOPATH/libneko.* /usr/local/lib/ sudo ln -s $NEKOPATH/*.ndll /usr/local/lib/neko/ echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV - + - name: Install Neko using snapshot from S3 (Windows) if: ${{ startsWith(env.PLATFORM, 'windows') }} shell: pwsh @@ -163,10 +163,10 @@ $NEKOPATH = Get-ChildItem $env:RUNNER_TEMP/neko-*-* echo "$NEKOPATH" >> $env:GITHUB_PATH echo "NEKOPATH=$NEKOPATH" >> $env:GITHUB_ENV - + - name: Print Neko version run: neko -version 2>&1 - + - name: choco install nsis uses: nick-invision/retry@v1 with: @@ -179,7 +179,7 @@ - name: Prepend Chocolatey path shell: pwsh run: Write-Host "::add-path::C:\ProgramData\chocolatey\bin" - + - name: Install OCaml and OCaml libraries shell: pwsh run: | @@ -202,16 +202,16 @@ & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'opam install haxe --deps-only --yes 2>&1') & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'opam list') & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'ocamlopt -v') - + - name: Expose mingw dll files shell: pwsh run: Write-Host "::add-path::${env:CYG_ROOT}/usr/$($env:MINGW_ARCH)-w64-mingw32/sys-root/mingw/bin" - + - name: Set ADD_REVISION=1 for non-release if: ${{ !startsWith(github.ref, 'refs/tags/') }} shell: pwsh run: echo "ADD_REVISION=1" >> $Env:GITHUB_ENV - + - name: Build Haxe shell: pwsh run: | @@ -223,16 +223,16 @@ & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxe.exe') & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && cygcheck ./haxelib.exe') & "$($env:CYG_ROOT)/bin/bash.exe" @('-lc', 'cd "$OLDPWD" && ls ./out') - + - name: Upload artifact uses: actions/upload-artifact@v1.0.0 with: name: win${{env.ARCH}}Binaries path: out - + linux-build: - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 env: PLATFORM: linux64 OPAMYES: 1 @@ -245,7 +245,7 @@ if: ${{ !startsWith(env.PLATFORM, 'windows') }} run: | set -ex - + curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP NEKOPATH=`echo $RUNNER_TEMP/neko-*-*` @@ -255,7 +255,7 @@ sudo ln -s $NEKOPATH/libneko.* /usr/local/lib/ sudo ln -s $NEKOPATH/*.ndll /usr/local/lib/neko/ echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV - + - name: Install Neko using snapshot from S3 (Windows) if: ${{ startsWith(env.PLATFORM, 'windows') }} shell: pwsh @@ -265,10 +265,10 @@ $NEKOPATH = Get-ChildItem $env:RUNNER_TEMP/neko-*-* echo "$NEKOPATH" >> $env:GITHUB_PATH echo "NEKOPATH=$NEKOPATH" >> $env:GITHUB_ENV - + - name: Print Neko version run: neko -version 2>&1 - + - name: Install dependencies run: | set -ex @@ -276,21 +276,21 @@ sudo add-apt-repository ppa:haxe/ocaml -y # provides newer version of mbedtls sudo apt-get update -qqy sudo apt-get install -qqy ocaml-nox camlp5 opam libpcre3-dev zlib1g-dev libgtk2.0-dev libmbedtls-dev ninja-build libstring-shellquote-perl - + - name: Install OCaml libraries run: | set -ex opam init # --disable-sandboxing opam update opam pin add haxe . --no-action - opam install haxe --deps-only + opam install haxe --deps-only --assume-depexts opam list ocamlopt -v - + - name: Set ADD_REVISION=1 for non-release if: ${{ !startsWith(github.ref, 'refs/tags/') }} run: echo "ADD_REVISION=1" >> $GITHUB_ENV - + - name: Build Haxe run: | set -ex @@ -301,13 +301,13 @@ ls -l out ldd -v ./haxe ldd -v ./haxelib - + # https://stackoverflow.com/questions/58033366/how-to-get-current-branch-within-github-actions - name: Extract branch name id: extract_branch shell: bash run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" - + - name: Build xmldoc run: | set -ex @@ -318,19 +318,19 @@ "branch": "${{ steps.extract_branch.outputs.branch }}" } EOL - + - name: Upload xmldoc artifact uses: actions/upload-artifact@v1.0.0 with: name: xmldoc path: extra/doc - + - name: Upload artifact uses: actions/upload-artifact@v1.0.0 with: name: linuxBinaries path: out - + mac-build: runs-on: macos-latest @@ -347,7 +347,7 @@ if: ${{ !startsWith(env.PLATFORM, 'windows') }} run: | set -ex - + curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP NEKOPATH=`echo $RUNNER_TEMP/neko-*-*` @@ -357,7 +357,7 @@ sudo ln -s $NEKOPATH/libneko.* /usr/local/lib/ sudo ln -s $NEKOPATH/*.ndll /usr/local/lib/neko/ echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV - + - name: Install Neko using snapshot from S3 (Windows) if: ${{ startsWith(env.PLATFORM, 'windows') }} shell: pwsh @@ -367,10 +367,10 @@ $NEKOPATH = Get-ChildItem $env:RUNNER_TEMP/neko-*-* echo "$NEKOPATH" >> $env:GITHUB_PATH echo "NEKOPATH=$NEKOPATH" >> $env:GITHUB_ENV - + - name: Print Neko version run: neko -version 2>&1 - + - name: Install dependencies env: ZLIB_VERSION: 1.2.11 @@ -399,8 +399,8 @@ cd pcre-$PCRE_VERSION ./configure --enable-utf8 --enable-pcre8 --enable-pcre16 --enable-pcre32 --enable-unicode-properties --enable-pcregrep-libz --enable-pcregrep-libbz2 --enable-jit make && make install - - + + - name: Install OCaml libraries run: | set -ex @@ -411,14 +411,14 @@ opam env opam pin add ctypes 0.17.1 --yes opam pin add haxe . --no-action - opam install haxe --deps-only + opam install haxe --deps-only --assume-depexts opam list ocamlopt -v - + - name: Set ADD_REVISION=1 for non-release if: ${{ !startsWith(github.ref, 'refs/tags/') }} run: echo "ADD_REVISION=1" >> $GITHUB_ENV - + - name: Build Haxe run: | set -ex @@ -429,13 +429,13 @@ ls -l out otool -L ./haxe otool -L ./haxelib - + - name: Upload artifact uses: actions/upload-artifact@v1.0.0 with: name: macBinaries path: out - + windows64-test: needs: windows64-build @@ -463,7 +463,7 @@ if: ${{ !startsWith(env.PLATFORM, 'windows') }} run: | set -ex - + curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP NEKOPATH=`echo $RUNNER_TEMP/neko-*-*` @@ -473,7 +473,7 @@ sudo ln -s $NEKOPATH/libneko.* /usr/local/lib/ sudo ln -s $NEKOPATH/*.ndll /usr/local/lib/neko/ echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV - + - name: Install Neko using snapshot from S3 (Windows) if: ${{ startsWith(env.PLATFORM, 'windows') }} shell: pwsh @@ -483,17 +483,17 @@ $NEKOPATH = Get-ChildItem $env:RUNNER_TEMP/neko-*-* echo "$NEKOPATH" >> $env:GITHUB_PATH echo "NEKOPATH=$NEKOPATH" >> $env:GITHUB_ENV - + - name: Print Neko version run: neko -version 2>&1 - + # - name: Quick test # shell: pwsh # run: | # $DOWNLOADDIR="./win$($env:ARCH)Binaries" # new-item -Name $DOWNLOADDIR -ItemType directory # Invoke-WebRequest https://build.haxe.org/builds/haxe/$env:PLATFORM/haxe_latest.zip -OutFile $DOWNLOADDIR/haxe_bin.zip - + - name: Setup Haxe shell: pwsh run: | @@ -503,11 +503,11 @@ $HAXEPATH = Get-ChildItem $DOWNLOADDIR/haxe_*_* -Directory Write-Host "::add-path::$HAXEPATH" Write-Host "::set-env name=HAXELIB_ROOT::$HAXEPATH\lib" - + - name: Print Haxe version shell: pwsh run: haxe -version - + - name: "Make Python 3 be available as python3 in the cmdline" shell: pwsh run: | @@ -516,7 +516,7 @@ $py3path = $pypath.replace("python.exe","python3.exe") cmd /c mklink $py3path $pypath python3 -V - + - name: Install hererocks if: matrix.target == 'lua' shell: cmd @@ -524,18 +524,18 @@ pip install hererocks hererocks lua53 -l5.3 -rlatest call lua53/bin/activate - + - name: Setup haxelib shell: pwsh run: | mkdir "$env:HAXELIB_ROOT" haxelib setup "$env:HAXELIB_ROOT" - + - name: Test shell: pwsh run: haxe RunCi.hxml working-directory: ${{github.workspace}}/tests - + windows-test: needs: windows-build @@ -564,7 +564,7 @@ if: ${{ !startsWith(env.PLATFORM, 'windows') }} run: | set -ex - + curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP NEKOPATH=`echo $RUNNER_TEMP/neko-*-*` @@ -574,7 +574,7 @@ sudo ln -s $NEKOPATH/libneko.* /usr/local/lib/ sudo ln -s $NEKOPATH/*.ndll /usr/local/lib/neko/ echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV - + - name: Install Neko using snapshot from S3 (Windows) if: ${{ startsWith(env.PLATFORM, 'windows') }} shell: pwsh @@ -584,17 +584,17 @@ $NEKOPATH = Get-ChildItem $env:RUNNER_TEMP/neko-*-* echo "$NEKOPATH" >> $env:GITHUB_PATH echo "NEKOPATH=$NEKOPATH" >> $env:GITHUB_ENV - + - name: Print Neko version run: neko -version 2>&1 - + # - name: Quick test # shell: pwsh # run: | # $DOWNLOADDIR="./win$($env:ARCH)Binaries" # new-item -Name $DOWNLOADDIR -ItemType directory # Invoke-WebRequest https://build.haxe.org/builds/haxe/$env:PLATFORM/haxe_latest.zip -OutFile $DOWNLOADDIR/haxe_bin.zip - + - name: Setup Haxe shell: pwsh run: | @@ -604,11 +604,11 @@ $HAXEPATH = Get-ChildItem $DOWNLOADDIR/haxe_*_* -Directory Write-Host "::add-path::$HAXEPATH" Write-Host "::set-env name=HAXELIB_ROOT::$HAXEPATH\lib" - + - name: Print Haxe version shell: pwsh run: haxe -version - + - name: "Make Python 3 be available as python3 in the cmdline" shell: pwsh run: | @@ -617,7 +617,7 @@ $py3path = $pypath.replace("python.exe","python3.exe") cmd /c mklink $py3path $pypath python3 -V - + - name: Install hererocks if: matrix.target == 'lua' shell: cmd @@ -625,22 +625,22 @@ pip install hererocks hererocks lua53 -l5.3 -rlatest call lua53/bin/activate - + - name: Setup haxelib shell: pwsh run: | mkdir "$env:HAXELIB_ROOT" haxelib setup "$env:HAXELIB_ROOT" - + - name: Test shell: pwsh run: haxe RunCi.hxml working-directory: ${{github.workspace}}/tests - + linux-test: needs: linux-build - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 env: PLATFORM: linux64 TEST: ${{matrix.target}} @@ -648,7 +648,7 @@ strategy: fail-fast: false matrix: - target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash9, neko] + target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, neko] #flash9 include: - target: js # SAUCE: 1 @@ -660,8 +660,8 @@ APT_PACKAGES: gcc-multilib g++-multilib - target: lua APT_PACKAGES: ncurses-dev - - target: flash9 - APT_PACKAGES: libglib2.0 libfreetype6 xvfb + # - target: flash9 + # APT_PACKAGES: libglib2.0-0 libfreetype6 xvfb steps: - uses: actions/checkout@main with: @@ -674,7 +674,7 @@ if: ${{ !startsWith(env.PLATFORM, 'windows') }} run: | set -ex - + curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP NEKOPATH=`echo $RUNNER_TEMP/neko-*-*` @@ -684,7 +684,7 @@ sudo ln -s $NEKOPATH/libneko.* /usr/local/lib/ sudo ln -s $NEKOPATH/*.ndll /usr/local/lib/neko/ echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV - + - name: Install Neko using snapshot from S3 (Windows) if: ${{ startsWith(env.PLATFORM, 'windows') }} shell: pwsh @@ -694,17 +694,17 @@ $NEKOPATH = Get-ChildItem $env:RUNNER_TEMP/neko-*-* echo "$NEKOPATH" >> $env:GITHUB_PATH echo "NEKOPATH=$NEKOPATH" >> $env:GITHUB_ENV - + - name: Print Neko version run: neko -version 2>&1 - + - name: Setup Haxe run: | # mkdir ./linuxBinaries # curl -sSL https://build.haxe.org/builds/haxe/linux64/haxe_latest.tar.gz -o ./linuxBinaries/haxe_bin.tar.gz - + sudo apt install -qqy libmbedtls-dev - + set -ex tar -xf linuxBinaries/*_bin.tar.gz -C linuxBinaries --strip-components=1 sudo mkdir -p /usr/local/bin/ @@ -712,39 +712,39 @@ sudo ln -s `pwd`/linuxBinaries/haxe /usr/local/bin/haxe sudo ln -s `pwd`/linuxBinaries/haxelib /usr/local/bin/haxelib sudo ln -s `pwd`/linuxBinaries/std /usr/local/share/haxe/std - + - name: Print Haxe version run: haxe -version - + - name: Setup haxelib run: | set -ex mkdir ~/haxelib haxelib setup ~/haxelib - + - name: Install apt packages if: matrix.APT_PACKAGES run: | set -ex sudo apt update -qqy sudo apt install -qqy ${{matrix.APT_PACKAGES}} - - - name: Flash setup - if: matrix.target == 'flash9' - run: export DISPLAY=:99.0 - + + # - name: Flash setup + # if: matrix.target == 'flash9' + # run: export DISPLAY=:99.0 + - name: Test if: success() && !(matrix.SAUCE && matrix.SAUCE_ACCESS_KEY) run: haxe RunCi.hxml working-directory: ${{github.workspace}}/tests - + - name: Test (with SauceLabs) if: matrix.target == 'js' && success() && matrix.SAUCE && matrix.SAUCE_ACCESS_KEY run: haxe RunCi.hxml working-directory: ${{github.workspace}}/tests env: SAUCE_ACCESS_KEY: matrix.SAUCE_ACCESS_KEY - + mac-test: needs: mac-build @@ -756,7 +756,7 @@ strategy: fail-fast: false matrix: - target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash9, neko] + target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, neko] #flash9 include: - target: hl BREW_PACKAGES: ninja @@ -772,7 +772,7 @@ if: ${{ !startsWith(env.PLATFORM, 'windows') }} run: | set -ex - + curl -sSL https://build.haxe.org/builds/neko/$PLATFORM/neko_latest.tar.gz -o $RUNNER_TEMP/neko_latest.tar.gz tar -xf $RUNNER_TEMP/neko_latest.tar.gz -C $RUNNER_TEMP NEKOPATH=`echo $RUNNER_TEMP/neko-*-*` @@ -782,7 +782,7 @@ sudo ln -s $NEKOPATH/libneko.* /usr/local/lib/ sudo ln -s $NEKOPATH/*.ndll /usr/local/lib/neko/ echo "NEKOPATH=$NEKOPATH" >> $GITHUB_ENV - + - name: Install Neko using snapshot from S3 (Windows) if: ${{ startsWith(env.PLATFORM, 'windows') }} shell: pwsh @@ -792,15 +792,15 @@ $NEKOPATH = Get-ChildItem $env:RUNNER_TEMP/neko-*-* echo "$NEKOPATH" >> $env:GITHUB_PATH echo "NEKOPATH=$NEKOPATH" >> $env:GITHUB_ENV - + - name: Print Neko version run: neko -version 2>&1 - + - name: Setup Haxe run: | # mkdir ./macBinaries # curl -sSL https://build.haxe.org/builds/haxe/mac/haxe_latest.tar.gz -o ./macBinaries/haxe_bin.tar.gz - + set -ex tar -xf macBinaries/*_bin.tar.gz -C macBinaries --strip-components=1 sudo mkdir -p /usr/local/bin/ @@ -808,32 +808,32 @@ sudo ln -s `pwd`/macBinaries/haxe /usr/local/bin/haxe sudo ln -s `pwd`/macBinaries/haxelib /usr/local/bin/haxelib sudo ln -s `pwd`/macBinaries/std /usr/local/share/haxe/std - + - name: Print Haxe version run: haxe -version - + - name: Setup haxelib run: | set -ex mkdir ~/haxelib haxelib setup ~/haxelib - + - name: Install homebrew packages if: matrix.BREW_PACKAGES run: brew install ${{matrix.BREW_PACKAGES}} - + - name: Test run: | # disable invalid Unicode filenames on APFS echo "" > sys/compile-fs.hxml haxe RunCi.hxml working-directory: ${{github.workspace}}/tests - + deploy: if: github.event_name != 'pull_request' needs: [linux-test, mac-test, windows-test, windows64-test] - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: # this is only needed for to get `COMMIT_DATE`... # maybe https://github.community/t/expose-commit-timestamp-in-the-github-context-data/16460/3 @@ -905,7 +905,7 @@ deploy_apidoc: if: github.event_name != 'pull_request' # TODO: also only when `GHP_REMOTE` is present needs: [linux-test, mac-test, windows-test, windows64-test] - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Download Haxe uses: actions/download-artifact@v2 diff -Nru haxe-4.2.1/opam haxe-4.2.4/opam --- haxe-4.2.1/opam 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/opam 2021-11-20 03:16:28.000000000 +0000 @@ -1,6 +1,6 @@ opam-version: "2.0" name: "haxe" -version: "4.2.1" +version: "4.2.4" synopsis: "Multi-target universal programming language" description: """ Haxe is an open source toolkit based on a modern, @@ -32,5 +32,5 @@ "conf-zlib" "conf-mbedtls" "conf-neko" - "luv" + "luv" {<= "0.5.8"} (* see https://github.com/aantron/luv/issues/121 *) ] \ No newline at end of file diff -Nru haxe-4.2.1/src/codegen/gencommon/castDetect.ml haxe-4.2.4/src/codegen/gencommon/castDetect.ml --- haxe-4.2.1/src/codegen/gencommon/castDetect.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/codegen/gencommon/castDetect.ml 2021-11-20 03:16:28.000000000 +0000 @@ -667,6 +667,7 @@ is_overload, List.find check_cf ctors, sup, ret_stl let change_rest tfun elist = + let expects_rest_args = ref false in let rec loop acc arglist elist = match arglist, elist with | (_,_,t) as arg :: [], elist when ExtType.is_rest t -> (match elist with @@ -679,8 +680,11 @@ Type.fast_eq (Abstract.follow_with_abstracts t) (Abstract.follow_with_abstracts e.etype) in (match elist with - | [e] when is_rest_array e -> List.rev (("rest",false,t) :: acc) - | _ -> List.rev (List.map (fun _ -> "rest",false,t1) elist @ acc) + | [e] when is_rest_array e -> + List.rev (("rest",false,t) :: acc) + | _ -> + expects_rest_args := true; + List.rev (List.map (fun _ -> "rest",false,t1) elist @ acc) ) | _ -> die "" __LOC__) ) @@ -690,7 +694,8 @@ List.rev acc in let args,ret = get_fun tfun in - TFun(loop [] args elist, ret) + let args_types = loop [] args elist in + !expects_rest_args,TFun(args_types, ret) let fastcast_if_needed gen expr real_to_t real_from_t = if Common.defined gen.gcon Define.FastCast then begin @@ -848,7 +853,7 @@ in (* take off Rest param *) - let actual_t = change_rest actual_t elist in + let _,actual_t = change_rest actual_t elist in (* set the real (selected) class field *) let f = match f with | FInstance(c,tl,_) -> FInstance(c,tl,cf) @@ -866,7 +871,7 @@ (* infer arguments *) (* let called_t = TFun(List.map (fun e -> "arg",false,e.etype) elist, ecall.etype) in *) let called_t = match follow e1.etype with | TFun _ -> e1.etype | _ -> TFun(List.map (fun e -> "arg",false,e.etype) elist, ecall.etype) in (* workaround for issue #1742 *) - let called_t = change_rest called_t elist in + let expects_rest_args,called_t = change_rest called_t elist in let original = (get_fun (apply_params cl.cl_params params actual_t)) in let applied = (get_fun called_t) in let fparams = infer_params ecall.epos original applied cf.cf_params calls_parameters_explicitly in @@ -885,7 +890,7 @@ let applied = elist in (* check types list *) let new_ecall, elist = try - let elist = List.map2 (fun applied (_,_,funct) -> + let fn = fun funct applied -> match is_overload || real_fparams <> [], applied.eexpr with | true, TConst TNull -> mk_castfast (gen.greal_type funct) applied @@ -896,7 +901,27 @@ | _ -> local_mk_cast (funct) ret) | _ -> handle_cast gen applied (funct) (gen.greal_type applied.etype) - ) applied args_ft in + in + let rec loop args_ft applied = + match args_ft, applied with + | [], [] -> [] + | [(_,_,funct)], _ when expects_rest_args -> + (match funct, applied with + | _,[{ eexpr = TUnop(Spread,Prefix,a) }] + | _,[{ eexpr = TParenthesis({ eexpr = TUnop(Spread,Prefix,a) }) }] -> + [fn funct a] + | TInst({ cl_path = (_,"NativeArray") },[funct]),_ -> + List.map (fn funct) applied + | _, a :: applied -> + (fn funct a) :: loop args_ft applied + | _, [] -> + [] + ) + | (_,_,funct)::args_ft, a::applied -> + (fn funct a) :: loop args_ft applied + | _ -> raise (Invalid_argument "Args length mismatch") + in + let elist = loop args_ft applied in { ecall with eexpr = TCall( { e1 with eexpr = TField(!ef, f) }, diff -Nru haxe-4.2.1/src/codegen/gencommon/reflectionCFs.ml haxe-4.2.4/src/codegen/gencommon/reflectionCFs.ml --- haxe-4.2.1/src/codegen/gencommon/reflectionCFs.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/codegen/gencommon/reflectionCFs.ml 2021-11-20 03:16:28.000000000 +0000 @@ -1182,6 +1182,12 @@ mk_this_call cf (List.map (fun (name,optional,t) -> let idx = make_int ctx.rcf_gen.gcon.basic !i pos in let ret = { eexpr = TArray(dyn_arg_local, idx); etype = t_dynamic; epos = pos } in + let ret = + if ExtType.is_rest t then + { ret with eexpr = TUnop(Spread,Prefix,{ ret with etype = t }) } + else + ret + in incr i; if optional then let condition = binop OpGt dyn_arg_length idx ctx.rcf_gen.gcon.basic.tbool pos in diff -Nru haxe-4.2.1/src/codegen/javaModern.ml haxe-4.2.4/src/codegen/javaModern.ml --- haxe-4.2.1/src/codegen/javaModern.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/codegen/javaModern.ml 2021-11-20 03:16:28.000000000 +0000 @@ -903,6 +903,9 @@ let known_sigs = Hashtbl.create 0 in let should_generate jf = not (AccessFlags.has_flag jf.jf_flags MPrivate) + (* We might need member synthetics for proper call resolution, but we should never need static ones (issue #10279). *) + && (not (AccessFlags.has_flag jf.jf_flags MSynthetic) || not (AccessFlags.has_flag jf.jf_flags MStatic)) + && jf.jf_name <> "" in if jc.jc_path <> (["java";"lang"], "CharSequence") then begin List.iter (fun jf -> diff -Nru haxe-4.2.1/src/codegen/overloads.ml haxe-4.2.4/src/codegen/overloads.ml --- haxe-4.2.1/src/codegen/overloads.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/codegen/overloads.ml 2021-11-20 03:16:28.000000000 +0000 @@ -249,19 +249,29 @@ | [] -> [] | [v] -> [v] | compatible -> + let rate_arg t e = match e.eexpr with + (* if the argument is an implicit cast, we need to start with a penalty *) + (* The penalty should be higher than any other implicit cast - other than Dynamic *) + (* since Dynamic has a penalty of max_int, we'll impose max_int - 1 to it *) + | TMeta( (Meta.ImplicitCast,_,_), _) -> (max_int - 1, 0) + | _ -> rate_conv 0 t e.etype + in (* convert compatible into ( rate * compatible_type ) list *) let rec mk_rate acc elist args = match elist, args with | [], [] -> acc | _ :: elist, (_,true,_) :: args -> mk_rate acc elist args + | elist, [n,o,t] when ExtType.is_rest (follow t) -> + let t = match follow t with + | TAbstract({a_path=["haxe"],"Rest"},[t]) -> t + | _ -> die "" __LOC__ + in + let rates = List.map (rate_arg t) elist in + acc @ rates | e :: elist, (n,o,t) :: args -> - (* if the argument is an implicit cast, we need to start with a penalty *) - (* The penalty should be higher than any other implicit cast - other than Dynamic *) - (* since Dynamic has a penalty of max_int, we'll impose max_int - 1 to it *) - (match e.eexpr with - | TMeta( (Meta.ImplicitCast,_,_), _) -> - mk_rate ((max_int - 1, 0) :: acc) elist args - | _ -> - mk_rate (rate_conv 0 t e.etype :: acc) elist args) + mk_rate ((rate_arg t e) :: acc) elist args + | [],_ -> + (* this can happen on pf_pad_nulls = false targets, see #10434 *) + acc | _ -> die "" __LOC__ in diff -Nru haxe-4.2.1/src/compiler/haxe.ml haxe-4.2.4/src/compiler/haxe.ml --- haxe-4.2.1/src/compiler/haxe.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/compiler/haxe.ml 2021-11-20 03:16:28.000000000 +0000 @@ -158,27 +158,36 @@ let t = Timer.timer ["command"] in let cmd = expand_env ~h:(Some h) cmd in let len = String.length cmd in - if len > 3 && String.sub cmd 0 3 = "cd " then begin - Sys.chdir (String.sub cmd 3 (len - 3)); - 0 - end else - let binary_string s = - if not Globals.is_windows then s else String.concat "\n" (Str.split (Str.regexp "\r\n") s) + let result = + if len > 3 && String.sub cmd 0 3 = "cd " then begin + Sys.chdir (String.sub cmd 3 (len - 3)); + 0 + (* Emit stderr as a server message in server mode *) + end else if CompilationServer.runs() then begin + let binary_string s = + if not Globals.is_windows then s else String.concat "\n" (Str.split (Str.regexp "\r\n") s) + in + let pout, pin, perr = Unix.open_process_full cmd (Unix.environment()) in + let bout = Buffer.create 0 in + let berr = Buffer.create 0 in + let read_content channel buf = + Buffer.add_string buf (IO.read_all (IO.input_channel channel)); + in + let tout = Thread.create (fun() -> read_content pout bout) () in + read_content perr berr; + Thread.join tout; + let result = (match Unix.close_process_full (pout,pin,perr) with Unix.WEXITED c | Unix.WSIGNALED c | Unix.WSTOPPED c -> c) in + let serr = binary_string (Buffer.contents berr) in + let sout = binary_string (Buffer.contents bout) in + if serr <> "" then ctx.messages <- CMError((if serr.[String.length serr - 1] = '\n' then String.sub serr 0 (String.length serr - 1) else serr),null_pos) :: ctx.messages; + if sout <> "" then ctx.com.print (sout ^ "\n"); + result + (* Direct pass-through of std streams for normal compilation *) + end else begin + match Unix.system cmd with + | WEXITED c | WSIGNALED c | WSTOPPED c -> c + end in - let pout, pin, perr = Unix.open_process_full cmd (Unix.environment()) in - let bout = Buffer.create 0 in - let berr = Buffer.create 0 in - let read_content channel buf = - Buffer.add_string buf (IO.read_all (IO.input_channel channel)); - in - let tout = Thread.create (fun() -> read_content pout bout) () in - read_content perr berr; - Thread.join tout; - let result = (match Unix.close_process_full (pout,pin,perr) with Unix.WEXITED c | Unix.WSIGNALED c | Unix.WSTOPPED c -> c) in - let serr = binary_string (Buffer.contents berr) in - let sout = binary_string (Buffer.contents bout) in - if serr <> "" then ctx.messages <- CMError((if serr.[String.length serr - 1] = '\n' then String.sub serr 0 (String.length serr - 1) else serr),null_pos) :: ctx.messages; - if sout <> "" then ctx.com.print (sout ^ "\n"); t(); result diff -Nru haxe-4.2.1/src/context/abstractCast.ml haxe-4.2.4/src/context/abstractCast.ml --- haxe-4.2.1/src/context/abstractCast.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/context/abstractCast.ml 2021-11-20 03:16:28.000000000 +0000 @@ -42,7 +42,7 @@ rec_stack_loop cast_stack cf f () in let make (a,tl,(tcf,cf)) = - if (Meta.has Meta.MultiType a.a_meta) then + if (Meta.has Meta.MultiType cf.cf_meta) then mk_cast eright tleft p else match a.a_impl with | Some c -> recurse cf (fun () -> diff -Nru haxe-4.2.1/src/context/common.ml haxe-4.2.4/src/context/common.ml --- haxe-4.2.1/src/context/common.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/context/common.ml 2021-11-20 03:16:28.000000000 +0000 @@ -541,6 +541,7 @@ pf_overload = true; pf_supports_threads = true; pf_supports_rest_args = true; + pf_this_before_super = false; pf_exceptions = { ec_native_throws = [ ["cs";"system"],"Exception"; @@ -643,7 +644,7 @@ let m = Type.mk_mono() in let defines = PMap.add "true" "1" ( - PMap.add "source-header" ("Generated by Haxe " ^ s_version) PMap.empty + PMap.add "source_header" ("Generated by Haxe " ^ s_version) PMap.empty ) in { diff -Nru haxe-4.2.1/src/context/display/displayFields.ml haxe-4.2.4/src/context/display/displayFields.ml --- haxe-4.2.1/src/context/display/displayFields.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/context/display/displayFields.ml 2021-11-20 03:16:28.000000000 +0000 @@ -137,7 +137,7 @@ in match follow t with | TMono m -> - begin match Monomorph.classify_constraints m with + let rec fold_constraints items = function | CStructural(fields,is_open) -> if not is_open then begin Monomorph.close m; @@ -151,7 +151,10 @@ items | CUnknown -> items - end + | CMixed l -> + List.fold_left fold_constraints items l + in + fold_constraints items (Monomorph.classify_down_constraints m) | TInst ({cl_kind = KTypeParameter tl},_) -> (* Type parameters can access the fields of their constraints *) List.fold_left (fun acc t -> loop acc t) items tl diff -Nru haxe-4.2.1/src/core/globals.ml haxe-4.2.4/src/core/globals.ml --- haxe-4.2.1/src/core/globals.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/core/globals.ml 2021-11-20 03:16:28.000000000 +0000 @@ -24,7 +24,7 @@ | Hl | Eval -let version = 4201 +let version = 4204 let version_major = version / 1000 let version_minor = (version mod 1000) / 100 let version_revision = (version mod 100) diff -Nru haxe-4.2.1/src/core/path.ml haxe-4.2.4/src/core/path.ml --- haxe-4.2.1/src/core/path.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/core/path.ml 2021-11-20 03:16:28.000000000 +0000 @@ -351,7 +351,11 @@ Unix.mkdir path 0o755; mkdir_recursive (if (path = "") then "/" else path) remaining -let mkdir_from_path path = +(** + Recursively creates `path`. + Raises `Unix.Unix_error` exceptions as-is. +*) +let mkdir_from_path_unix_err path = let parts = Str.split_delim (Str.regexp "[\\/]+") path in match parts with | [] -> (* path was "" *) () @@ -359,6 +363,16 @@ let dir_list = List.rev (List.tl (List.rev parts)) in mkdir_recursive "" dir_list +(** + Recursively creates `path`. + Converts all `Unix.Unix_error` exceptions to human-readable `Failure msg`. +*) +let mkdir_from_path path = + try + mkdir_from_path_unix_err path + with Unix.Unix_error(err,_,args) -> + raise (Failure (Printf.sprintf "%s (%s)" (Unix.error_message err) args)) + let full_dot_path pack mname tname = if tname = mname then (pack,mname) else (pack @ [mname],tname) diff -Nru haxe-4.2.1/src/core/tPrinting.ml haxe-4.2.4/src/core/tPrinting.ml --- haxe-4.2.1/src/core/tPrinting.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/core/tPrinting.ml 2021-11-20 03:16:28.000000000 +0000 @@ -39,10 +39,15 @@ with Not_found -> let id = List.length !ctx in ctx := (t,id) :: !ctx; - let s_const = match !monomorph_classify_constraints_ref r with + let s_const = + let rec loop = function | CUnknown -> "" - | CTypes tl -> " : " ^ String.concat " & " (List.map (fun (t,_) -> s_type ctx t) tl) - | CStructural(fields,_) -> " : " ^ s_type ctx (mk_anon ~fields (ref Closed)) + | CTypes tl -> String.concat " & " (List.map (fun (t,_) -> s_type ctx t) tl) + | CStructural(fields,_) -> s_type ctx (mk_anon ~fields (ref Closed)) + | CMixed l -> String.concat " & " (List.map loop l) + in + let s = loop (!monomorph_classify_constraints_ref r) in + if s = "" then s else " : " ^ s in Printf.sprintf "Unknown<%d>%s" id s_const end diff -Nru haxe-4.2.1/src/core/tType.ml haxe-4.2.4/src/core/tType.ml --- haxe-4.2.1/src/core/tType.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/core/tType.ml 2021-11-20 03:16:28.000000000 +0000 @@ -44,7 +44,15 @@ and tmono = { mutable tm_type : t option; - mutable tm_constraints : tmono_constraint list; + (* + ``` + function fn() {} + ``` + `A` is a down-constraint for `B` + `B` is an up-constraint for `A` + *) + mutable tm_down_constraints : tmono_constraint list; + mutable tm_up_constraints : (t * string option) list; } and tmono_constraint = @@ -57,6 +65,7 @@ and tmono_constraint_kind = | CUnknown | CStructural of (string,tclass_field) PMap.t * bool + | CMixed of tmono_constraint_kind list | CTypes of (t * string option) list and tlazy = diff -Nru haxe-4.2.1/src/core/tUnification.ml haxe-4.2.4/src/core/tUnification.ml --- haxe-4.2.1/src/core/tUnification.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/core/tUnification.ml 2021-11-20 03:16:28.000000000 +0000 @@ -64,13 +64,23 @@ module Monomorph = struct let create () = { tm_type = None; - tm_constraints = []; + tm_down_constraints = []; + tm_up_constraints = [] } (* constraining *) - let add_constraint m constr = - m.tm_constraints <- constr :: m.tm_constraints + let add_up_constraint m ((t,name) as constr) = + m.tm_up_constraints <- constr :: m.tm_up_constraints; + match t with + | TMono m2 -> m2.tm_down_constraints <- MMono (m2,name) :: m2.tm_down_constraints + | _ -> () + + let add_down_constraint m constr = + m.tm_down_constraints <- constr :: m.tm_down_constraints; + match constr with + | MMono (m2,s) -> m2.tm_up_constraints <- (TMono m,s) :: m.tm_up_constraints + | _ -> () let constraint_of_type name t = match follow t with | TMono m2 -> @@ -85,11 +95,11 @@ [MType(t,name)] let constrain_to_type m name t = - List.iter (add_constraint m) (constraint_of_type name t) + List.iter (add_down_constraint m) (constraint_of_type name t) (* Note: This function is called by printing and others and should thus not modify state. *) - let rec classify_constraints' m = + let rec classify_down_constraints' m = let types = DynArray.create () in let fields = ref PMap.empty in let is_open = ref false in @@ -98,7 +108,7 @@ | MMono(m2,name) -> begin match m2.tm_type with | None -> - let more_monos,kind = classify_constraints' m2 in + let more_monos,kind = classify_down_constraints' m2 in monos := !monos @ more_monos; begin match kind with | CUnknown -> @@ -106,7 +116,7 @@ monos := m2 :: !monos; | _ -> (* Recursively inherit constraints. *) - List.iter check m2.tm_constraints + List.iter check m2.tm_down_constraints end | Some t -> List.iter (fun constr -> check constr) (constraint_of_type name t) @@ -119,20 +129,27 @@ | MEmptyStructure -> is_open := true in - List.iter check m.tm_constraints; + List.iter check m.tm_down_constraints; let kind = - if DynArray.length types > 0 then - CTypes (DynArray.to_list types) - else if not (PMap.is_empty !fields) || !is_open then - CStructural(!fields,!is_open) + let k1 = + if DynArray.length types > 0 then + CTypes (DynArray.to_list types) + else + CUnknown + in + if not (PMap.is_empty !fields) || !is_open then + let k2 = CStructural(!fields,!is_open) in + match k1 with + | CTypes _ -> CMixed [k1; k2] + | _ -> k2 else - CUnknown + k1 in !monos,kind - let classify_constraints m = snd (classify_constraints' m) + let classify_down_constraints m = snd (classify_down_constraints' m) - let check_constraints constr t = + let rec check_down_constraints constr t = match constr with | CUnknown -> () @@ -146,17 +163,47 @@ | CStructural(fields,is_open) -> let t2 = mk_anon ~fields (ref Closed) in (!unify_ref) default_unification_context t t2 + | CMixed l -> + List.iter (fun constr -> check_down_constraints constr t) l + + let rec collect_up_constraints m = + let rec collect m acc = + List.fold_left (fun acc (t,name) -> + match t with + | TMono m2 -> + (match m2.tm_type with + | Some t -> + (match follow t with + | TMono _ -> acc + | _ -> (t,name) :: acc) + | None -> collect m2 acc + ) + | _ -> (t,name) :: acc + ) acc m.tm_up_constraints + in + collect m [] + + let check_up_constraints m t = + List.iter (fun (t2,constraint_name) -> + let check() = + (!unify_ref) default_unification_context t2 t + in + match constraint_name with + | Some name -> check_constraint name check + | None -> check() + ) (collect_up_constraints m) (* binding *) let do_bind m t = (* assert(m.tm_type = None); *) (* TODO: should be here, but matcher.ml does some weird bind handling at the moment. *) m.tm_type <- Some t; - m.tm_constraints <- [] + m.tm_down_constraints <- []; + m.tm_up_constraints <- [] let rec bind m t = begin match t with - | TAnon _ when List.mem MOpenStructure m.tm_constraints -> + | TAnon _ when List.mem MOpenStructure m.tm_down_constraints -> (* If we assign an open structure monomorph to another structure, the semantics want us to merge the fields. This is kinda weird, but that's how it has always worked. *) constrain_to_type m None t; @@ -164,34 +211,32 @@ | TMono m2 -> if m != m2 then begin match m2.tm_type with | None -> - List.iter (fun constr -> m2.tm_constraints <- constr :: m2.tm_constraints) m.tm_constraints; + List.iter (add_down_constraint m2) m.tm_down_constraints; + List.iter (add_up_constraint m2) m.tm_up_constraints; do_bind m t; | Some t -> bind m t end | _ -> + check_up_constraints m t; (* Due to recursive constraints like in #9603, we tentatively bind the monomorph to the type we're checking against before checking the constraints. *) m.tm_type <- Some t; - let monos,kind = classify_constraints' m in - Std.finally (fun () -> m.tm_type <- None) (fun () -> check_constraints kind t) (); - (* If the monomorph we're binding to has other yet unbound monomorphs, constrain them to our target type (issue #9640) .*) - List.iter (fun m2 -> - constrain_to_type m2 None t; - ) monos; + let kind = classify_down_constraints m in + Std.finally (fun () -> m.tm_type <- None) (fun () -> check_down_constraints kind t) (); do_bind m t end and close m = match m.tm_type with | Some _ -> () - | None -> match classify_constraints m with + | None -> match classify_down_constraints m with | CUnknown -> () | CTypes [(t,_)] -> do_bind m t; () - | CTypes _ -> + | CTypes _ | CMixed _ -> () | CStructural(fields,_) -> let check_recursion cf = @@ -216,7 +261,7 @@ let spawn_constrained_monos map params = let checks = DynArray.create () in let monos = List.map (fun (s,t) -> - let mono = create() in + let mono = create () in begin match follow t with | TInst ({ cl_kind = KTypeParameter constr; cl_path = path },_) when constr <> [] -> DynArray.add checks (mono,constr,s_type_path path) @@ -1142,4 +1187,4 @@ ;; unify_ref := unify_custom;; unify_min_ref := UnifyMinT.unify_min;; -monomorph_classify_constraints_ref := Monomorph.classify_constraints +monomorph_classify_constraints_ref := Monomorph.classify_down_constraints diff -Nru haxe-4.2.1/src/filters/exceptions.ml haxe-4.2.4/src/filters/exceptions.ml --- haxe-4.2.1/src/filters/exceptions.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/filters/exceptions.ml 2021-11-20 03:16:28.000000000 +0000 @@ -76,7 +76,7 @@ | TFun(_,t) -> t | _ -> error ("Std.isOfType is not a function and cannot be called") p in - let type_expr = { eexpr = TTypeExpr(module_type_of_type t); etype = t; epos = null_pos } in + let type_expr = { eexpr = TTypeExpr(module_type_of_type t); etype = t; epos = p } in make_static_call ctx.typer std_cls isOfType_field (fun t -> t) [e; type_expr] return_type p (** @@ -188,50 +188,47 @@ class catch ctx catch_local catch_pos = object (self) - (* val mutable hx_exception_var = None *) - val mutable hx_exception_local = None - (* val mutable unwrapped_var = None *) - val mutable unwrapped_local = None + val mutable hx_exception_var = None + val mutable unwrapped_var = None - method get_haxe_exception = - match hx_exception_local with + method get_haxe_exception p = + let v = + match hx_exception_var with + | None -> + let v = alloc_var VGenerated "`" ctx.haxe_exception_type p in + hx_exception_var <- Some v; + v + | Some v -> v + in + mk (TLocal v) v.v_type p + + method unwrap p = + let v = + match unwrapped_var with + | None -> + let v = alloc_var VGenerated "`" t_dynamic p in + unwrapped_var <- Some v; + (* unwrapped_local <- Some e; *) + v + | Some e -> e + in + mk (TLocal v) v.v_type p + + method declare_haxe_exception p = + match hx_exception_var with + | Some v -> + let caught = haxe_exception_static_call ctx "caught" [catch_local] p in + mk (TVar (v, Some caught)) ctx.basic.tvoid p | None -> - let v = alloc_var VGenerated "`" ctx.haxe_exception_type null_pos in - let e = mk (TLocal v) v.v_type null_pos in - (* hx_exception_var <- Some v; *) - hx_exception_local <- Some e; - e - | Some e -> e + mk (TBlock[]) ctx.basic.tvoid p - method unwrap = - match unwrapped_local with + method declare_unwrap p = + match unwrapped_var with + | Some v -> + let unwrap = haxe_exception_instance_call ctx (self#get_haxe_exception p) "unwrap" [] p in + mk (TVar (v, Some unwrap)) ctx.basic.tvoid p | None -> - let v = alloc_var VGenerated "`" t_dynamic null_pos in - let e = mk (TLocal v) v.v_type null_pos in - (* unwrapped_var <- Some v; *) - unwrapped_local <- Some e; - e - | Some e -> e - - method declare_haxe_exception = - match hx_exception_local with - | Some { eexpr = TLocal v } -> - let caught = haxe_exception_static_call ctx "caught" [catch_local] null_pos in - mk (TVar (v, Some caught)) ctx.basic.tvoid null_pos - | None -> - mk (TBlock[]) ctx.basic.tvoid null_pos; - | _ -> - die ~p:catch_pos "Unexpected expression generated for catch variable" __LOC__ - - method declare_unwrap = - match unwrapped_local with - | Some { eexpr = TLocal v } -> - let unwrap = haxe_exception_instance_call ctx self#get_haxe_exception "unwrap" [] null_pos in - mk (TVar (v, Some unwrap)) ctx.basic.tvoid null_pos - | None -> - mk (TBlock[]) ctx.basic.tvoid null_pos; - | _ -> - die ~p:catch_pos "Unexpected expression generated for catch unwrap variable" __LOC__ + mk (TBlock[]) ctx.basic.tvoid p end (** @@ -273,10 +270,10 @@ && not (fast_eq ctx.haxe_exception_type (follow v.v_type)) -> current :: (transform rest) (* Everything else falls into `if(Std.is(e, ExceptionType)`-fest *) - | rest -> - let catch_var = alloc_var VGenerated "`" ctx.wildcard_catch_type null_pos in + | ((first_v, first_body) :: _) as rest -> + let catch_var = alloc_var VGenerated "`" ctx.wildcard_catch_type first_v.v_pos in add_var_flag catch_var VCaught; - let catch_local = mk (TLocal catch_var) catch_var.v_type null_pos in + let catch_local = mk (TLocal catch_var) catch_var.v_type catch_var.v_pos in let body = let catch = new catch ctx catch_local p in let rec transform = function @@ -290,14 +287,14 @@ if fast_eq ctx.haxe_exception_type current_t then mk (TConst (TBool true)) ctx.basic.tbool v.v_pos else begin - std_is ctx catch#get_haxe_exception v.v_type v.v_pos + std_is ctx (catch#get_haxe_exception v.v_pos) v.v_type v.v_pos end in let body = if var_used then mk (TBlock [ (* var v:ExceptionType = cast haxe_exception_local; *) - mk (TVar (v, Some (mk_cast catch#get_haxe_exception v.v_type null_pos))) ctx.basic.tvoid null_pos; + mk (TVar (v, Some (mk_cast (catch#get_haxe_exception v.v_pos) v.v_type v.v_pos))) ctx.basic.tvoid v.v_pos; body ]) body.etype body.epos else @@ -314,9 +311,9 @@ mk (TBlock [ (* var v:Dynamic = haxe_exception_local.unwrap(); *) if var_used then - mk (TVar (v, Some catch#unwrap)) ctx.basic.tvoid null_pos + mk (TVar (v, Some (catch#unwrap v.v_pos))) ctx.basic.tvoid v.v_pos else - mk (TBlock[]) ctx.basic.tvoid null_pos; + mk (TBlock[]) ctx.basic.tvoid v.v_pos; body ]) body.etype body.epos in @@ -332,9 +329,9 @@ mk (TBlock [ (* var v:NativeWildcardException = catch_var; *) if var_used then - mk (TVar (v, Some catch_local)) ctx.basic.tvoid null_pos + mk (TVar (v, Some catch_local)) ctx.basic.tvoid v.v_pos else - mk (TBlock[]) ctx.basic.tvoid null_pos; + mk (TBlock[]) ctx.basic.tvoid v.v_pos; body ]) body.etype body.epos in @@ -345,15 +342,15 @@ set_needs_exception_stack catch_var; let condition = (* Std.isOfType(haxe_exception_local.unwrap(), ExceptionType) *) - std_is ctx catch#unwrap v.v_type v.v_pos + std_is ctx (catch#unwrap v.v_pos) v.v_type v.v_pos in let body = mk (TBlock [ (* var v:ExceptionType = cast haxe_exception_local.unwrap() *) if var_used then - mk (TVar (v, Some (mk_cast catch#unwrap v.v_type null_pos))) ctx.basic.tvoid null_pos + mk (TVar (v, Some (mk_cast (catch#unwrap v.v_pos) v.v_type v.v_pos))) ctx.basic.tvoid v.v_pos else - mk (TBlock[]) ctx.basic.tvoid null_pos; + mk (TBlock[]) ctx.basic.tvoid v.v_pos; body ]) body.etype body.epos in @@ -372,9 +369,9 @@ (* haxe.Exception.caught(catch_var) *) let exprs = [ (* var haxe_exception_local = haxe.Exception.caught(catch_var); *) - catch#declare_haxe_exception; + catch#declare_haxe_exception catch_var.v_pos; (* var unwrapped_local = haxe_exception_local.unwrap(); *) - catch#declare_unwrap; + catch#declare_unwrap catch_var.v_pos; transformed_catches ] in mk (TBlock exprs) t p @@ -481,13 +478,13 @@ | TFun(_,t) -> t | _ -> error ("haxe.NativeStackTrace." ^ method_field.cf_name ^ " is not a function and cannot be called") null_pos in - let catch_local = mk (TLocal catch_var) catch_var.v_type null_pos in + let catch_local = mk (TLocal catch_var) catch_var.v_type catch_var.v_pos in begin add_dependency tctx.curclass.cl_module native_stack_trace_cls.cl_module; - make_static_call tctx native_stack_trace_cls method_field (fun t -> t) [catch_local] return_type null_pos + make_static_call tctx native_stack_trace_cls method_field (fun t -> t) [catch_local] return_type catch_var.v_pos end else - mk (TBlock[]) tctx.t.tvoid null_pos + mk (TBlock[]) tctx.t.tvoid catch_var.v_pos in let rec run e = match e.eexpr with diff -Nru haxe-4.2.1/src/generators/genhl.ml haxe-4.2.4/src/generators/genhl.ml --- haxe-4.2.1/src/generators/genhl.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/generators/genhl.ml 2021-11-20 03:16:28.000000000 +0000 @@ -1327,7 +1327,7 @@ (match a, follow ethis.etype with | FStatic (c,({ cf_kind = Var _ | Method MethDynamic } as f)), _ -> let g, t = class_global ctx c in - AStaticVar (g, t, (match t with HObj o -> (try fst (get_index f.cf_name o) with Not_found -> die "" __LOC__) | _ -> die "" __LOC__)) + AStaticVar (g, t, (match t with HObj o -> (try fst (get_index f.cf_name o) with Not_found -> die ~p:e.epos "" __LOC__) | _ -> die ~p:e.epos "" __LOC__)) | FStatic (c,({ cf_kind = Method _ } as f)), _ -> AStaticFun (alloc_fid ctx c f) | FClosure (Some (cdef,pl), f), TInst (c,_) diff -Nru haxe-4.2.1/src/generators/genjs.ml haxe-4.2.4/src/generators/genjs.ml --- haxe-4.2.1/src/generators/genjs.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/generators/genjs.ml 2021-11-20 03:16:28.000000000 +0000 @@ -43,7 +43,7 @@ type ctx = { com : Common.context; buf : Rbuffer.t; - chan : out_channel; + mutable chan : out_channel option; packages : (string list,unit) Hashtbl.t; smap : sourcemap option; js_modern : bool; @@ -261,7 +261,15 @@ ) ctx.smap let flush ctx = - Rbuffer.output_buffer ctx.chan ctx.buf; + let chan = + match ctx.chan with + | Some chan -> chan + | None -> + let chan = open_out_bin ctx.com.file in + ctx.chan <- Some chan; + chan + in + Rbuffer.output_buffer chan ctx.buf; Rbuffer.clear ctx.buf let spr ctx s = @@ -287,9 +295,9 @@ output_string channel "{\n"; output_string channel "\"version\":3,\n"; output_string channel ("\"file\":\"" ^ (String.concat "\\\\" (ExtString.String.nsplit basefile "\\")) ^ "\",\n"); - output_string channel ("\"sourceRoot\":\"file:///\",\n"); + output_string channel ("\"sourceRoot\":\"\",\n"); output_string channel ("\"sources\":[" ^ - (String.concat "," (List.map (fun s -> "\"" ^ to_url s ^ "\"") sources)) ^ + (String.concat "," (List.map (fun s -> "\"file:///" ^ to_url s ^ "\"") sources)) ^ "],\n"); if Common.defined ctx.com Define.SourceMapContent then begin output_string channel ("\"sourcesContent\":[" ^ @@ -1243,6 +1251,8 @@ let can_gen_class_field ctx = function | { cf_expr = (None | Some { eexpr = TConst TNull }) } when not (has_feature ctx "Type.getInstanceFields") -> false + | f when has_class_field_flag f CfExtern -> + false | f -> is_physical_field f @@ -1766,7 +1776,7 @@ let ctx = { com = com; buf = Rbuffer.create 16000; - chan = open_out_bin com.file; + chan = None; packages = Hashtbl.create 0; smap = smap; js_modern = not (Common.defined com Define.JsClassic); @@ -1887,19 +1897,24 @@ | _ -> () ) include_files; - let var_console = ( - "console", - "typeof console != \"undefined\" ? console : {log:function(){}}" - ) in + let defined_global_value = Common.defined_value_safe com Define.JsGlobal in + + let defined_global = defined_global_value <> "" in + + let rec typeof_join = function + | x :: [] -> x + | x :: l -> "typeof " ^ x ^ " != \"undefined\" ? " ^ x ^ " : " ^ (typeof_join l) + | _ -> "" + in let var_exports = ( "$hx_exports", - "typeof exports != \"undefined\" ? exports : typeof window != \"undefined\" ? window : typeof self != \"undefined\" ? self : this" + typeof_join (if defined_global then ["exports"; defined_global_value] else ["exports"; "window"; "self"; "this"]) ) in let var_global = ( "$global", - "typeof window != \"undefined\" ? window : typeof global != \"undefined\" ? global : typeof self != \"undefined\" ? self : this" + typeof_join (if defined_global then [defined_global_value] else ["window"; "global"; "self"; "this"]) ) in let closureArgs = [var_global] in @@ -1910,7 +1925,7 @@ in (* Provide console for environments that may not have it. *) let closureArgs = if ctx.es_version < 5 then - var_console :: closureArgs + ("console", typeof_join ["console"; "{log:function(){}}"]) :: closureArgs else closureArgs in @@ -2065,7 +2080,7 @@ | Some e -> gen_expr ctx e; newline ctx); if ctx.js_modern then begin let closureArgs = - if has_feature ctx "js.Lib.global" then + if has_feature ctx "js.Lib.global" || defined_global then closureArgs else (* no need for `typeof window != "undefined" ? window : typeof global != "undefined" ? <...>` *) @@ -2096,5 +2111,6 @@ | Some smap -> write_mappings ctx smap | None -> try Sys.remove (com.file ^ ".map") with _ -> ()); flush ctx; - close_out ctx.chan) + Option.may (fun chan -> close_out chan) ctx.chan + ) diff -Nru haxe-4.2.1/src/generators/genjvm.ml haxe-4.2.4/src/generators/genjvm.ml --- haxe-4.2.1/src/generators/genjvm.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/generators/genjvm.ml 2021-11-20 03:16:28.000000000 +0000 @@ -2796,10 +2796,7 @@ List.exists (fun mt -> snd (t_infos mt).mt_path = snd m.m_path) m.m_types let check_path mt = - (* don't rewrite if there's an explicit @:native *) - if Meta.has Meta.Native mt.mt_meta then - () - else if mt.mt_private && has_primary_type mt.mt_module then begin + if mt.mt_private && has_primary_type mt.mt_module && not (Meta.has Meta.Native mt.mt_meta) then begin let m = mt.mt_module in let pack = match fst m.m_path with | [] -> ["haxe";"root"] @@ -2924,7 +2921,7 @@ output_string ch_out b; close_in ch_in; close_out ch_out; - Some (Printf.sprintf "lib/%s" name) + Some (Printf.sprintf "lib/%s \n" name) end ) com.native_libs.java_libs in Hashtbl.iter (fun name v -> @@ -2945,11 +2942,11 @@ let manifest_content = "Manifest-Version: 1.0\n" ^ - (match class_paths with [] -> "" | _ -> "Class-Path: " ^ (String.concat " " class_paths ^ "\n")) ^ "Created-By: Haxe (Haxe Foundation)" ^ (Option.map_default (fun (cl,_) -> "\nMain-Class: " ^ (s_type_path cl.cl_path)) "" entry_point) ^ + (match class_paths with [] -> "" | _ -> "\nClass-Path: " ^ (String.concat " " class_paths)) ^ "\n\n" in Zip.add_entry ~level:gctx.jar_compression_level manifest_content gctx.jar "META-INF/MANIFEST.MF"; - Zip.close_out gctx.jar \ No newline at end of file + Zip.close_out gctx.jar diff -Nru haxe-4.2.1/src/generators/genlua.ml haxe-4.2.4/src/generators/genlua.ml --- haxe-4.2.1/src/generators/genlua.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/generators/genlua.ml 2021-11-20 03:16:28.000000000 +0000 @@ -273,6 +273,7 @@ (* from genphp *) let rec is_string_type t = match follow t with + | TInst ({cl_kind = KTypeParameter constraints}, _) -> List.exists is_string_type constraints | TInst ({cl_path = ([], "String")}, _) -> true | TAnon a -> (match !(a.a_status) with diff -Nru haxe-4.2.1/src/macro/eval/evalDebugSocket.ml haxe-4.2.4/src/macro/eval/evalDebugSocket.ml --- haxe-4.2.1/src/macro/eval/evalDebugSocket.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/macro/eval/evalDebugSocket.ml 2021-11-20 03:16:28.000000000 +0000 @@ -316,7 +316,7 @@ (s,v) :: acc ) h [] | VInstance {ikind = IMutex mutex} -> - ["owner",match mutex.mowner with None -> vnull | Some id -> vint id] + ["owner",match mutex.mowner with None -> vnull | Some (id,_) -> vint id] | VInstance {ikind = IThread thread} -> ["id",vint (Thread.id thread.tthread)] | VInstance vi -> diff -Nru haxe-4.2.1/src/macro/eval/evalMain.ml haxe-4.2.4/src/macro/eval/evalMain.ml --- haxe-4.2.1/src/macro/eval/evalMain.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/macro/eval/evalMain.ml 2021-11-20 03:16:28.000000000 +0000 @@ -431,6 +431,10 @@ in make_path mt in + let make_map_entry e_key v = + let e_value = value_to_expr v p in + (EBinop(OpArrow,e_key,e_value),p) + in match vresolve v with | VNull -> (EConst (Ident "null"),p) | VTrue -> (EConst (Ident "true"),p) @@ -464,6 +468,24 @@ let args = List.map (fun v -> value_to_expr v p) (Array.to_list e.eargs) in (ECall (epath, args), p) end + | VInstance {ikind = IIntMap m} -> + let el = IntHashtbl.fold (fun k v acc -> + let e_key = (EConst (Int (string_of_int k)),p) in + (make_map_entry e_key v) :: acc + ) m [] in + (EArrayDecl el,p) + | VInstance {ikind = IStringMap m} -> + let el = StringHashtbl.fold (fun k (_,v) acc -> + let e_key = (EConst (String(k,SDoubleQuotes)),p) in + (make_map_entry e_key v) :: acc + ) m [] in + (EArrayDecl el,p) + | VInstance {ikind = IObjectMap m} -> + let el = Hashtbl.fold (fun k v acc -> + let e_key = value_to_expr k p in + (make_map_entry e_key v) :: acc + ) m [] in + (EArrayDecl el,p) | _ -> exc_string ("Cannot convert " ^ (value_string v) ^ " to expr") let encode_obj = encode_obj_s diff -Nru haxe-4.2.1/src/macro/eval/evalStdLib.ml haxe-4.2.4/src/macro/eval/evalStdLib.ml --- haxe-4.2.1/src/macro/eval/evalStdLib.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/macro/eval/evalStdLib.ml 2021-11-20 03:16:28.000000000 +0000 @@ -1187,7 +1187,7 @@ else remove_trailing_slash s let createDirectory = vfun1 (fun path -> - catch_unix_error Path.mkdir_from_path (Path.add_trailing_slash (decode_string path)); + catch_unix_error Path.mkdir_from_path_unix_err (Path.add_trailing_slash (decode_string path)); vnull ) @@ -1741,25 +1741,47 @@ let acquire = vifun0 (fun vthis -> let mutex = this vthis in - Mutex.lock mutex.mmutex; - mutex.mowner <- Some (Thread.id (Thread.self())); + let thread_id = Thread.id (Thread.self()) in + (match mutex.mowner with + | None -> + Mutex.lock mutex.mmutex; + mutex.mowner <- Some (thread_id,1) + | Some (id,n) -> + if id = thread_id then + mutex.mowner <- Some (thread_id,n + 1) + else begin + Mutex.lock mutex.mmutex; + mutex.mowner <- Some (thread_id,1) + end + ); vnull ) let release = vifun0 (fun vthis -> let mutex = this vthis in - mutex.mowner <- None; - Mutex.unlock mutex.mmutex; + (match mutex.mowner with + | Some (id,n) when n > 1 -> + mutex.mowner <- Some (id,n - 1) + | _ -> + mutex.mowner <- None; + Mutex.unlock mutex.mmutex; + ); vnull ) let tryAcquire = vifun0 (fun vthis -> let mutex = this vthis in - if Mutex.try_lock mutex.mmutex then begin - mutex.mowner <- Some (Thread.id (Thread.self())); + let thread_id = Thread.id (Thread.self()) in + match mutex.mowner with + | Some (id,n) when id = thread_id -> + mutex.mowner <- Some (thread_id,n + 1); vtrue - end else - vfalse + | _ -> + if Mutex.try_lock mutex.mmutex then begin + mutex.mowner <- Some (thread_id,1); + vtrue + end else + vfalse ) end @@ -3075,8 +3097,9 @@ module StdNativeString = struct let from_string = vfun1 (fun v -> - let s = decode_vstring v in - vnative_string s.sstring + match decode_optional decode_vstring v with + | None -> vnull + | Some s -> vnative_string s.sstring ) let from_bytes = vfun1 (fun v -> diff -Nru haxe-4.2.1/src/macro/eval/evalValue.ml haxe-4.2.4/src/macro/eval/evalValue.ml --- haxe-4.2.1/src/macro/eval/evalValue.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/macro/eval/evalValue.ml 2021-11-20 03:16:28.000000000 +0000 @@ -252,7 +252,7 @@ and vmutex = { mmutex : Mutex.t; - mutable mowner : int option; (* thread ID *) + mutable mowner : (int * int) option; (* thread ID * same thread lock count *) } and vlock = { diff -Nru haxe-4.2.1/src/optimization/analyzer.ml haxe-4.2.4/src/optimization/analyzer.ml --- haxe-4.2.1/src/optimization/analyzer.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/optimization/analyzer.ml 2021-11-20 03:16:28.000000000 +0000 @@ -126,13 +126,13 @@ else match e.eexpr with | TLocal v -> let v' = local ctx e v edge.cfg_from in - add_ssa_edge ctx.graph v' bb true i; + add_ssa_edge ctx.graph v' bb (LUPhi i); {e with eexpr = TLocal v'} | _ -> die "" __LOC__ ) el edge.cfg_to.bb_incoming in let ephi = {ecall with eexpr = TCall(ephi,el)} in - set_var_value ctx.graph v0 bb true i; + set_var_value ctx.graph v0 bb (LUPhi i); {e with eexpr = TBinop(OpAssign,e1,ephi)} | _ -> Type.map_expr (loop i) e @@ -140,7 +140,7 @@ dynarray_mapi loop bb.bb_phi let rec rename_in_block ctx bb = - let write_var v is_phi i = + let write_var v luk = update_reaching_def ctx v bb; let v' = alloc_var v.v_kind v.v_name v.v_type v.v_pos in declare_var ctx.graph v' bb; @@ -149,30 +149,31 @@ add_var_def ctx.graph bb v'; set_reaching_def ctx.graph v' (get_reaching_def ctx.graph v); set_reaching_def ctx.graph v (Some v'); - set_var_value ctx.graph v' bb is_phi i; + set_var_value ctx.graph v' bb luk; add_var_origin ctx.graph v' v; v' in - let rec loop is_phi i e = match e.eexpr with + let rec loop luk e = match e.eexpr with | TLocal v -> let v' = local ctx e v bb in - add_ssa_edge ctx.graph v' bb is_phi i; + add_ssa_edge ctx.graph v' bb luk; {e with eexpr = TLocal v'} | TVar(v,Some e1) -> - let e1 = (loop is_phi i) e1 in - let v' = write_var v is_phi i in + let e1 = (loop luk) e1 in + let v' = write_var v luk in {e with eexpr = TVar(v',Some e1)} | TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) -> - let e2 = (loop is_phi i) e2 in - let v' = write_var v is_phi i in + let e2 = (loop luk) e2 in + let v' = write_var v luk in {e with eexpr = TBinop(OpAssign,{e1 with eexpr = TLocal v'},e2)}; | TCall({eexpr = TConst (TString "phi")},_) -> e | _ -> - Type.map_expr (loop is_phi i) e + Type.map_expr (loop luk) e in - dynarray_mapi (loop true) bb.bb_phi; - dynarray_mapi (loop false) bb.bb_el; + dynarray_mapi (fun i e -> loop (LUPhi i) e) bb.bb_phi; + dynarray_mapi (fun i e -> loop (LUEl i) e) bb.bb_el; + bb.bb_terminator <- BasicBlock.terminator_map (loop LUTerm) bb.bb_terminator; List.iter (update_phi ctx) bb.bb_outgoing; List.iter (rename_in_block ctx) bb.bb_dominated @@ -253,13 +254,13 @@ if List.exists (fun edge -> has_flag edge M.flag) bb.bb_incoming then set_lattice_cell v (M.transfer ctx bb e) in - let visit_expression bb e = + let visit_expression bb cond_branch e = match e.eexpr with | TBinop(OpAssign,{eexpr = TLocal v},e2) | TVar(v,Some e2) -> visit_assignment bb v e2; false - | TMeta((Meta.Custom ":cond-branch",_,_),e1) when M.conditional -> - let e1 = M.transfer ctx bb e1 in + | _ when M.conditional && cond_branch -> + let e1 = M.transfer ctx bb e in let edges = if e1 == M.bottom || e1 == M.top then bb.bb_outgoing else begin @@ -293,8 +294,17 @@ in let visit_expressions bb = let b = DynArray.fold_left (fun b e -> - visit_expression bb e || b + visit_expression bb false e || b ) false bb.bb_el in + let b = match bb.bb_terminator with + | TermCondBranch e1 -> + visit_expression bb true e1 || b + | TermReturnValue(e1,_) + | TermThrow(e1,_) -> + visit_expression bb false e1 + | _ -> + b + in if not b then List.iter add_cfg_edge bb.bb_outgoing in let visit_phis bb = @@ -320,10 +330,10 @@ end end; loop(); - | [],((bb,is_phi,i) :: edges) -> + | [],((bb,luk) :: edges) -> ssa_work_list := edges; - let e = get_texpr bb is_phi i in - ignore(visit_expression bb e); + let e = get_texpr bb luk in + ignore(visit_expression bb (match luk with LUTerm -> true | _ -> false) e); loop() | [],[] -> () @@ -510,7 +520,8 @@ in Graph.iter_dom_tree ctx.graph (fun bb -> if not (List.exists (fun edge -> has_flag edge FlagExecutable) bb.bb_incoming) then bb.bb_dominator <- ctx.graph.Graph.g_unreachable; - dynarray_map commit bb.bb_el + dynarray_map commit bb.bb_el; + bb.bb_terminator <- terminator_map commit bb.bb_terminator; ); end) @@ -606,7 +617,8 @@ Type.map_expr (commit bb) e in Graph.iter_dom_tree ctx.graph (fun bb -> - dynarray_map (commit bb) bb.bb_el + dynarray_map (commit bb) bb.bb_el; + bb.bb_terminator <- terminator_map (commit bb) bb.bb_terminator; ); end) @@ -677,6 +689,7 @@ bb_marked := bb :: !bb_marked; DynArray.iter expr bb.bb_el; DynArray.iter expr bb.bb_phi; + terminator_iter expr bb.bb_terminator; List.iter (fun edge -> if not (has_flag edge FlagDce) then begin edge.cfg_flags <- FlagDce :: edge.cfg_flags; @@ -698,7 +711,8 @@ Type.map_expr sweep e in List.iter (fun bb -> - dynarray_map sweep bb.bb_el + dynarray_map sweep bb.bb_el; + bb.bb_terminator <- terminator_map sweep bb.bb_terminator; ) !bb_marked; end @@ -767,7 +781,7 @@ edge bb_then "then"; edge bb_else "else"; edge bb_next "next"; - | SEWhile(bb_head,bb_body,bb_next) -> + | SEWhile(bb_head,bb_body,bb_next,_) -> edge bb_head "loop-head"; edge bb_body "loop-body"; edge bb_next "next"; @@ -792,14 +806,14 @@ let generate_cfg_ssa ch g = Printf.fprintf ch "\tnode [shape=plaintext];\n"; - let expr_name b i = Printf.sprintf "e%s%i" (if b then "p" else "") i in + let expr_name luk = Printf.sprintf "e%s" (match luk with | LUPhi i -> Printf.sprintf "p%i" i | LUEl i -> Printf.sprintf "%i" i | LUTerm -> "t") in List.iter (fun bb -> Printf.fprintf ch "n%i[label=<\n\t\n" bb.bb_id bb.bb_id (BasicBlock.s_block_kind bb.bb_kind); - let s_expr b i e = - Printf.fprintf ch "\t\n" (expr_name b i) (s_escape (htmlescape (s_expr_pretty e))) + let s_expr luk e = + Printf.fprintf ch "\t\n" (expr_name luk) (s_escape (htmlescape (s_expr_pretty e))) in - DynArray.iteri (s_expr true) bb.bb_phi; - DynArray.iteri (s_expr false) bb.bb_el; + DynArray.iteri (fun i e -> s_expr (LUPhi i) e) bb.bb_phi; + DynArray.iteri (fun i e -> s_expr (LUEl i) e) bb.bb_el; Printf.fprintf ch "\t\n
(%i) %s
%s
%s
>];\n"; ) g.g_nodes; Graph.iter_edges g (fun edge -> @@ -807,11 +821,11 @@ ); DynArray.iter (fun vi -> begin try - let (bb,is_phi,i) = match vi.vi_value with None -> raise Not_found | Some i -> i in - let n1 = Printf.sprintf "n%i:%s" bb.bb_id (expr_name is_phi i) in - List.iter (fun (bb',is_phi',i') -> + let (bb,luk) = match vi.vi_value with None -> raise Not_found | Some i -> i in + let n1 = Printf.sprintf "n%i:%s" bb.bb_id (expr_name luk) in + List.iter (fun (bb',luk') -> if bb != bb' then begin (* intra-node edges look stupid in dot *) - let n2 = Printf.sprintf "n%i:%s" bb'.bb_id (expr_name is_phi' i') in + let n2 = Printf.sprintf "n%i:%s" bb'.bb_id (expr_name luk') in Printf.fprintf ch "%s -> %s[color=lightblue,constraint=false];\n" n1 n2; end ) vi.vi_ssa_edges; @@ -871,18 +885,18 @@ f(); let ch,f = start_graph "-ssa-edges.dot" in let nodes = ref PMap.empty in - let node_name bb is_phi i = Printf.sprintf "e%i_%b_%i" bb.bb_id is_phi i in - let node_name2 bb is_phi i = - let n = node_name bb is_phi i in + let node_name bb luk = Printf.sprintf "e%i_%s" bb.bb_id (match luk with LUPhi i -> Printf.sprintf "phi_%i" i | LUEl i -> Printf.sprintf "el%i" i | LUTerm -> "term") in + let node_name2 bb luk = + let n = node_name bb luk in nodes := PMap.add n true !nodes; n in DynArray.iter (fun vi -> begin try - let (bb,is_phi,i) = match vi.vi_value with None -> raise Not_found | Some i -> i in - let n1 = node_name2 bb is_phi i in - List.iter (fun (bb',is_phi',i') -> - let n2 = node_name2 bb' is_phi' i' in + let (bb,luk) = match vi.vi_value with None -> raise Not_found | Some i -> i in + let n1 = node_name2 bb luk in + List.iter (fun (bb',luk') -> + let n2 = node_name2 bb' luk' in Printf.fprintf ch "%s -> %s;\n" n1 n2 ) vi.vi_ssa_edges with Not_found -> @@ -890,15 +904,15 @@ end ) g.g_var_infos; List.iter (fun bb -> - let f is_phi acc i e = - let n = node_name bb is_phi i in - (i + 1),if PMap.mem n !nodes then + let f luk acc e = + let n = node_name bb luk in + if PMap.mem n !nodes then (n,s_expr_pretty e) :: acc else acc in - let _,active_nodes = DynArray.fold_left (fun (i,acc) -> f true acc i) (0,[]) bb.bb_phi in - let _,active_nodes = DynArray.fold_left (fun (i,acc) -> f false acc i) (0,active_nodes) bb.bb_el in + let _,active_nodes = DynArray.fold_left (fun (i,acc) e -> (i + 1),f (LUPhi i) acc e) (0,[]) bb.bb_phi in + let _,active_nodes = DynArray.fold_left (fun (i,acc) e -> (i + 1),f (LUEl i) acc e) (0,active_nodes) bb.bb_el in if active_nodes <> [] then begin Printf.fprintf ch "subgraph cluster_%i {\n" bb.bb_id; Printf.fprintf ch "label=%i;\n" bb.bb_id; @@ -1071,6 +1085,10 @@ cf.cf_expr <- Some e; | _ -> () + let run_on_field ctx config c cf = + run_on_field ctx config c cf; + List.iter (run_on_field ctx config c) cf.cf_overloads + let run_on_class ctx config c = let config = update_config_from_meta ctx.Typecore.com config c.cl_meta in let process_field stat cf = match cf.cf_kind with diff -Nru haxe-4.2.1/src/optimization/analyzerTexprTransformer.ml haxe-4.2.4/src/optimization/analyzerTexprTransformer.ml --- haxe-4.2.1/src/optimization/analyzerTexprTransformer.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/optimization/analyzerTexprTransformer.ml 2021-11-20 03:16:28.000000000 +0000 @@ -46,10 +46,6 @@ let bb_exit = create_node BKFunctionEnd tf.tf_expr.etype tf.tf_expr.epos in add_function g tf t p bb_root; add_cfg_edge bb bb_root CFGFunction; - let make_block_meta b = - let e = mk (TConst (TInt (Int32.of_int b.bb_id))) ctx.com.basic.tint b.bb_pos in - wrap_meta ":block" e - in let bb_breaks = ref [] in let bb_continue = ref None in let b_try_stack = ref [] in @@ -76,9 +72,9 @@ b_try_stack := List.tl !b_try_stack ) in - let add_terminator bb e = - add_texpr bb e; - close_node g bb; + let add_terminator bb term = + bb.bb_terminator <- term; + close_node bb; g.g_unreachable in let check_unbound_call s el = @@ -170,7 +166,7 @@ let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in add_cfg_edge bb bb_next CFGGoto; set_syntax_edge bb (SEMerge bb_next); - close_node g bb; + close_node bb; add_cfg_edge bb_func_end bb_next CFGGoto; bb_next,ec | TConst _ | TTypeExpr _ -> @@ -297,8 +293,8 @@ and block_element_plus bb (e,efinal) f = let bb = block_element bb e in let bb = match efinal with - | None -> bb - | Some e -> block_element bb (f e) + | Some e when bb != g.g_unreachable -> block_element bb (f e) + | _ -> bb in bb and block_element_value bb e f = @@ -371,17 +367,17 @@ | TBlock el -> let bb_sub = create_node BKSub e.etype e.epos in add_cfg_edge bb bb_sub CFGGoto; - close_node g bb; + close_node bb; let bb_sub_next = block_el bb_sub el in if bb_sub_next != g.g_unreachable then begin let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in set_syntax_edge bb (SESubBlock(bb_sub,bb_next)); add_cfg_edge bb_sub_next bb_next CFGGoto; - close_node g bb_sub_next; + close_node bb_sub_next; bb_next; end else begin set_syntax_edge bb (SEMerge bb_sub); - close_node g bb_sub_next; + close_node bb_sub_next; bb_sub_next end | TIf(e1,e2,None) -> @@ -390,15 +386,15 @@ bb else begin let bb_then = create_node BKConditional e2.etype e2.epos in - add_texpr bb (wrap_meta ":cond-branch" e1); + bb.bb_terminator <- TermCondBranch e1; add_cfg_edge bb bb_then (CFGCondBranch (mk (TConst (TBool true)) ctx.com.basic.tbool e2.epos)); let bb_then_next = block bb_then e2 in let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in set_syntax_edge bb (SEIfThen(bb_then,bb_next,e.epos)); add_cfg_edge bb bb_next CFGCondElse; - close_node g bb; + close_node bb; add_cfg_edge bb_then_next bb_next CFGGoto; - close_node g bb_then_next; + close_node bb_then_next; bb_next end | TIf(e1,e2,Some e3) -> @@ -408,10 +404,10 @@ else begin let bb_then = create_node BKConditional e2.etype e2.epos in let bb_else = create_node BKConditional e3.etype e3.epos in - add_texpr bb (wrap_meta ":cond-branch" e1); + bb.bb_terminator <- TermCondBranch e1; add_cfg_edge bb bb_then (CFGCondBranch (mk (TConst (TBool true)) ctx.com.basic.tbool e2.epos)); add_cfg_edge bb bb_else CFGCondElse; - close_node g bb; + close_node bb; let bb_then_next = block bb_then e2 in let bb_else_next = block bb_else e3 in if bb_then_next == g.g_unreachable && bb_else_next == g.g_unreachable then begin @@ -422,22 +418,22 @@ set_syntax_edge bb (SEIfThenElse(bb_then,bb_else,bb_next,e.etype,e.epos)); add_cfg_edge bb_then_next bb_next CFGGoto; add_cfg_edge bb_else_next bb_next CFGGoto; - close_node g bb_then_next; - close_node g bb_else_next; + close_node bb_then_next; + close_node bb_else_next; bb_next end end | TSwitch(e1,cases,edef) -> let is_exhaustive = edef <> None || is_exhaustive e1 in let bb,e1 = bind_to_temp bb false e1 in - add_texpr bb (wrap_meta ":cond-branch" e1); + bb.bb_terminator <- TermCondBranch e1; let reachable = ref [] in let make_case e = let bb_case = create_node BKConditional e.etype e.epos in let bb_case_next = block bb_case e in if bb_case_next != g.g_unreachable then reachable := bb_case_next :: !reachable; - close_node g bb_case_next; + close_node bb_case_next; bb_case in let cases = List.map (fun (el,e) -> @@ -455,21 +451,21 @@ in if is_exhaustive && !reachable = [] then begin set_syntax_edge bb (SESwitch(cases,def,g.g_unreachable,e.epos)); - close_node g bb; + close_node bb; g.g_unreachable; end else begin let bb_next = create_node BKNormal bb.bb_type bb.bb_pos in if not is_exhaustive then add_cfg_edge bb bb_next CFGGoto; List.iter (fun bb -> add_cfg_edge bb bb_next CFGGoto) !reachable; set_syntax_edge bb (SESwitch(cases,def,bb_next,e.epos)); - close_node g bb; + close_node bb; bb_next end | TWhile(e1,e2,NormalWhile) -> let bb_loop_pre = create_node BKNormal e1.etype e1.epos in add_cfg_edge bb bb_loop_pre CFGGoto; set_syntax_edge bb (SEMerge bb_loop_pre); - close_node g bb; + close_node bb; let bb_loop_head = create_node BKLoopHead e1.etype e1.epos in add_cfg_edge bb_loop_pre bb_loop_head CFGGoto; let close = begin_loop bb bb_loop_head in @@ -485,13 +481,13 @@ create_node BKNormal bb.bb_type bb.bb_pos in List.iter (fun bb -> add_cfg_edge bb bb_next CFGGoto) bb_breaks; - set_syntax_edge bb_loop_pre (SEWhile(bb_loop_head,bb_loop_body,bb_next)); - close_node g bb_loop_pre; - add_texpr bb_loop_pre {e with eexpr = TWhile(e1,make_block_meta bb_loop_body,NormalWhile)}; + set_syntax_edge bb_loop_pre (SEWhile(bb_loop_head,bb_loop_body,bb_next,e.epos)); + close_node bb_loop_pre; + bb_loop_pre.bb_terminator <- TermCondBranch e1; if bb_loop_body_next != g.g_unreachable then add_cfg_edge bb_loop_body_next bb_loop_head CFGGoto; add_cfg_edge bb_loop_head bb_loop_body CFGGoto; - close_node g bb_loop_body_next; - close_node g bb_loop_head; + close_node bb_loop_body_next; + close_node bb_loop_head; bb_next; | TTry(e1,catches) -> let bb_try = create_node BKNormal e1.etype e1.epos in @@ -513,19 +509,19 @@ let bb_next = if !is_reachable then create_node BKNormal bb.bb_type bb.bb_pos else g.g_unreachable in let catches = List.map (fun (v,bb_catch,bb_catch_next) -> if bb_catch_next != g.g_unreachable then add_cfg_edge bb_catch_next bb_next CFGGoto; - close_node g bb_catch_next; + close_node bb_catch_next; v,bb_catch ) catches in set_syntax_edge bb (SETry(bb_try,bb_exc,catches,bb_next,e.epos)); if bb_try_next != g.g_unreachable then add_cfg_edge bb_try_next bb_next CFGGoto; - close_node g bb_try_next; - close_node g bb_exc; - close_node g bb; + close_node bb_try_next; + close_node bb_exc; + close_node bb; bb_next (* control flow *) | TReturn None -> add_cfg_edge bb bb_exit CFGGoto; - add_terminator bb e + add_terminator bb (TermReturn e.epos) | TReturn (Some e1) when ExtType.is_void (follow e1.etype) -> let bb = block_element bb e1 in block_element bb (mk (TReturn None) t_dynamic e.epos) @@ -536,17 +532,17 @@ with Exit -> let bb,e1 = value bb e1 in add_cfg_edge bb bb_exit CFGGoto; - add_terminator bb {e with eexpr = TReturn(Some e1)}; + add_terminator bb (TermReturnValue(e1,e.epos)) end | TBreak -> bb_breaks := bb :: !bb_breaks; - add_terminator bb e + add_terminator bb (TermBreak e.epos) | TContinue -> begin match !bb_continue with | Some bb_continue -> add_cfg_edge bb bb_continue CFGGoto | _ -> die "" __LOC__ end; - add_terminator bb e + add_terminator bb (TermContinue e.epos) | TThrow e1 -> begin try let mk_throw e1 = @@ -559,7 +555,7 @@ | [] -> add_cfg_edge bb bb_exit CFGGoto | _ -> List.iter (fun bb_exc -> add_cfg_edge bb bb_exc CFGGoto) !b_try_stack; end; - add_terminator bb {e with eexpr = TThrow e1}; + add_terminator bb (TermThrow(e1,e.epos)) end (* side_effects *) | TCall({eexpr = TIdent s},el) when is_really_unbound s -> @@ -643,7 +639,7 @@ add_cfg_edge bb bb' CFGGoto; List.iter (fun bb_exc -> add_cfg_edge bb bb_exc CFGMaybeThrow) bbl; set_syntax_edge bb (SEMerge bb'); - close_node g bb; + close_node bb; block_element bb' e end in if bb == g.g_unreachable then bb else loop bb el @@ -657,53 +653,67 @@ block_el bb el in let bb_last = block bb_root tf.tf_expr in - close_node g bb_last; + close_node bb_last; add_cfg_edge bb_last bb_exit CFGGoto; (* implied return *) - close_node g bb_exit; + close_node bb_exit; bb_root,bb_exit let from_tfunction ctx tf t p = let g = ctx.graph in let bb_func,bb_exit = func ctx g.g_root tf t p in ctx.entry <- bb_func; - close_node g g.g_root; + close_node g.g_root; g.g_exit <- bb_exit +let terminator_to_texpr_maybe = function + | TermReturn p -> Some (mk (TReturn None) t_dynamic p) + | TermBreak p -> Some (mk TBreak t_dynamic p) + | TermContinue p -> Some (mk TContinue t_dynamic p) + | TermReturnValue(e1,p) -> Some (mk (TReturn (Some e1)) t_dynamic p) + | TermThrow(e1,p) -> Some (mk (TThrow e1) t_dynamic p) + | TermCondBranch e1 -> Some e1 (* TODO: this shouldn't be here *) + | _ -> None + let rec block_to_texpr_el ctx bb = if bb.bb_dominator == ctx.graph.g_unreachable then [] else begin let block bb = block_to_texpr ctx bb in let rec loop bb se = - let el = List.rev (DynArray.to_list bb.bb_el) in - match el,se with - | el,SESubBlock(bb_sub,bb_next) -> - Some bb_next,(block bb_sub) :: el - | el,SEMerge bb_next -> - Some bb_next,el - | el,SENone -> - None,el - | {eexpr = TWhile(e1,_,flag)} as e :: el,(SEWhile(_,bb_body,bb_next)) -> - let e2 = block bb_body in - Some bb_next,{e with eexpr = TWhile(e1,e2,flag)} :: el - | el,SETry(bb_try,_,bbl,bb_next,p) -> - Some bb_next,(mk (TTry(block bb_try,List.map (fun (v,bb) -> v,block bb) bbl)) ctx.com.basic.tvoid p) :: el - | e1 :: el,se -> - let e1 = Texpr.skip e1 in + match se with + | SESubBlock(bb_sub,bb_next) -> + Some bb_next,Some (block bb_sub) + | SEMerge bb_next -> + Some bb_next,None + | SENone -> + None,terminator_to_texpr_maybe bb.bb_terminator + | SETry(bb_try,_,bbl,bb_next,p) -> + Some bb_next,Some (mk (TTry(block bb_try,List.map (fun (v,bb) -> v,block bb) bbl)) ctx.com.basic.tvoid p) + | se -> + let e1 = match bb.bb_terminator with + | TermCondBranch e1 -> e1 + | _ -> die "" __LOC__ + in let bb_next,e1_def,t,p = match se with | SEIfThen(bb_then,bb_next,p) -> Some bb_next,TIf(e1,block bb_then,None),ctx.com.basic.tvoid,p | SEIfThenElse(bb_then,bb_else,bb_next,t,p) -> Some bb_next,TIf(e1,block bb_then,Some (block bb_else)),t,p | SESwitch(bbl,bo,bb_next,p) -> Some bb_next,TSwitch(e1,List.map (fun (el,bb) -> el,block bb) bbl,Option.map block bo),ctx.com.basic.tvoid,p + | SEWhile(_,bb_body,bb_next,p) -> + let e2 = block bb_body in + Some bb_next,TWhile(e1,e2,NormalWhile),ctx.com.basic.tvoid,p | _ -> abort (Printf.sprintf "Invalid node exit: %s" (s_expr_pretty e1)) bb.bb_pos in - bb_next,(mk e1_def t p) :: el - | [],_ -> - None,[] + bb_next,Some (mk e1_def t p) + in + let bb_next,e_term = loop bb bb.bb_syntax_edge in + let el = DynArray.to_list bb.bb_el in + let el = match e_term with + | None -> el + | Some e -> el @ [e] in - let bb_next,el = loop bb bb.bb_syntax_edge in let el = match bb_next with | None -> el - | Some bb -> (block_to_texpr_el ctx bb) @ el + | Some bb -> el @ (block_to_texpr_el ctx bb) in el end @@ -711,7 +721,7 @@ and block_to_texpr ctx bb = assert(bb.bb_closed); let el = block_to_texpr_el ctx bb in - let e = mk (TBlock (List.rev el)) bb.bb_type bb.bb_pos in + let e = mk (TBlock el) bb.bb_type bb.bb_pos in e and func ctx i = diff -Nru haxe-4.2.1/src/optimization/analyzerTypes.ml haxe-4.2.4/src/optimization/analyzerTypes.ml --- haxe-4.2.1/src/optimization/analyzerTypes.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/optimization/analyzerTypes.ml 2021-11-20 03:16:28.000000000 +0000 @@ -67,11 +67,26 @@ | SEIfThenElse of t * t * t * Type.t * pos (* `if` with "then", "else" and "next" *) | SESwitch of (texpr list * t) list * t option * t * pos (* `switch` with cases, "default" and "next" *) | SETry of t * t * (tvar * t) list * t * pos (* `try` with "exc", catches and "next" *) - | SEWhile of t * t * t (* `while` with "head", "body" and "next" *) + | SEWhile of t * t * t * pos (* `while` with "head", "body" and "next" *) | SESubBlock of t * t (* "sub" with "next" *) | SEMerge of t (* Merge to same block *) | SENone (* No syntax exit *) + and suspend_call = { + efun : texpr; (* coroutine function expression *) + args : texpr list; (* call arguments without the continuation *) + pos : pos; (* call position *) + } + + and terminator_kind = + | TermNone + | TermCondBranch of texpr + | TermReturn of pos + | TermReturnValue of texpr * pos + | TermBreak of pos + | TermContinue of pos + | TermThrow of texpr * pos + and t = { bb_id : int; (* The unique ID of the block *) bb_type : Type.t; (* The block type *) @@ -81,6 +96,7 @@ (* elements *) bb_el : texpr DynArray.t; (* The block expressions *) bb_phi : texpr DynArray.t; (* SSA-phi expressions *) + mutable bb_terminator : terminator_kind; (* relations *) mutable bb_outgoing : cfg_edge list; (* Outgoing edges *) mutable bb_incoming : cfg_edge list; (* Incoming edges *) @@ -94,6 +110,11 @@ mutable bb_var_writes : tvar list; (* List of assigned variables *) } + type texpr_lookup_target = + | LUPhi of int + | LUEl of int + | LUTerm + let s_block_kind = function | BKRoot -> "BKRoot" | BKNormal -> "BKNormal" @@ -121,8 +142,21 @@ let add_texpr bb e = DynArray.add bb.bb_el e - let get_texpr bb is_phi i = - DynArray.get (if is_phi then bb.bb_phi else bb.bb_el) i + let get_texpr bb luk = match luk with + | LUPhi i -> + DynArray.get bb.bb_phi i + | LUEl i -> + DynArray.get bb.bb_el i + | LUTerm -> match bb.bb_terminator with + | TermCondBranch e1 + | TermReturnValue(e1,_) + | TermThrow(e1,_) -> + e1 + | TermNone + | TermReturn _ + | TermBreak _ + | TermContinue _ -> + die "" __LOC__ (* edges *) @@ -145,6 +179,7 @@ bb_closed = false; bb_el = DynArray.create(); bb_phi = DynArray.create(); + bb_terminator = TermNone; bb_outgoing = []; bb_incoming = []; bb_dominator = bb; @@ -160,6 +195,30 @@ let in_scope bb bb' = match bb'.bb_scopes with | [] -> abort (Printf.sprintf "Scope-less block (kind: %s)" (s_block_kind bb'.bb_kind)) bb'.bb_pos | scope :: _ -> List.mem scope bb.bb_scopes + + let terminator_map f term = match term with + | TermCondBranch e1 -> + TermCondBranch (f e1) + | TermReturnValue(e1,p) -> + TermReturnValue (f e1,p) + | TermThrow(e1,p) -> + TermThrow (f e1,p) + | TermNone + | TermReturn _ + | TermBreak _ + | TermContinue _ -> + term + + let terminator_iter f term = match term with + | TermCondBranch e1 + | TermReturnValue(e1,_) + | TermThrow(e1,_) -> + f e1 + | TermNone + | TermReturn _ + | TermBreak _ + | TermContinue _ -> + () end (* @@ -169,8 +228,8 @@ module Graph = struct open BasicBlock - type texpr_lookup = BasicBlock.t * bool * int type tfunc_info = BasicBlock.t * Type.t * pos * tfunc + type texpr_lookup = BasicBlock.t * texpr_lookup_target type var_write = BasicBlock.t list type 'a itbl = (int,'a) Hashtbl.t @@ -230,16 +289,16 @@ vi.vi_writes <- bb :: vi.vi_writes; end - let set_var_value g v bb is_phi i = - (get_var_info g v).vi_value <- Some (bb,is_phi,i) + let set_var_value g v bb luk = + (get_var_info g v).vi_value <- Some (bb,luk) let get_var_value g v = let value = (get_var_info g v).vi_value in - let bb,is_phi,i = match value with + let bb,luk = match value with | None -> raise Not_found | Some l -> l in - match (get_texpr bb is_phi i).eexpr with + match (get_texpr bb luk).eexpr with | TVar(_,Some e) | TBinop(OpAssign,_,e) -> e | _ -> die "" __LOC__ @@ -249,9 +308,9 @@ let get_var_origin g v = (get_var_info g v).vi_origin - let add_ssa_edge g v bb is_phi i = + let add_ssa_edge g v bb luk = let vi = get_var_info g v in - vi.vi_ssa_edges <- (bb,is_phi,i) :: vi.vi_ssa_edges + vi.vi_ssa_edges <- (bb,luk) :: vi.vi_ssa_edges (* nodes *) @@ -270,7 +329,7 @@ g.g_nodes <- bb :: g.g_nodes; bb - let close_node g bb = + let close_node bb = if bb.bb_id > 0 then begin assert(not bb.bb_closed); bb.bb_closed <- true @@ -456,15 +515,17 @@ | _ -> () end; - DynArray.iter (fun e -> match e.eexpr with - | TVar(v,eo) -> - declare_var g v bb; - if eo <> None then add_var_def g bb v; - | TBinop(OpAssign,{eexpr = TLocal v},_) -> - add_var_def g bb v - | _ -> - () - ) bb.bb_el + let infer e = match e.eexpr with + | TVar(v,eo) -> + declare_var g v bb; + if eo <> None then add_var_def g bb v; + | TBinop(OpAssign,{eexpr = TLocal v},_) -> + add_var_def g bb v + | _ -> + () + in + DynArray.iter infer bb.bb_el; + terminator_iter infer bb.bb_terminator; ) (* Infers the scopes of all reachable blocks. This function can be run multiple times @@ -495,7 +556,7 @@ loop scopes' bb_exc; List.iter (fun (_,bb_catch) -> loop (next_scope scopes) bb_catch) catches; loop scopes bb_next - | SEWhile(bb_head,bb_body,bb_next) -> + | SEWhile(bb_head,bb_body,bb_next,_) -> let scopes' = next_scope scopes in loop scopes' bb_head; loop scopes' bb_body; diff -Nru haxe-4.2.1/src/typing/calls.ml haxe-4.2.4/src/typing/calls.ml --- haxe-4.2.1/src/typing/calls.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/typing/calls.ml 2021-11-20 03:16:28.000000000 +0000 @@ -254,18 +254,18 @@ let eparam = sea.se_this in dispatch#field_call sea.se_access [eparam] el | AKResolve(sea,name) -> - dispatch#expr_call (dispatch#resolve_call sea name) el + dispatch#expr_call (dispatch#resolve_call sea name) [] el | AKNo _ | AKAccess _ -> ignore(acc_get ctx acc p); error ("Unexpected access mode, please report this: " ^ (s_access_kind acc)) p | AKAccessor fa -> let e = dispatch#field_call fa [] [] in - dispatch#expr_call e el + dispatch#expr_call e [] el | AKUsingAccessor sea -> let e = dispatch#field_call sea.se_access [sea.se_this] [] in - dispatch#expr_call e el + dispatch#expr_call e [] el | AKExpr e -> - dispatch#expr_call e el + dispatch#expr_call e [] el let rec needs_temp_var e = match e.eexpr with diff -Nru haxe-4.2.1/src/typing/callUnification.ml haxe-4.2.4/src/typing/callUnification.ml --- haxe-4.2.1/src/typing/callUnification.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/typing/callUnification.ml 2021-11-20 03:16:28.000000000 +0000 @@ -80,13 +80,18 @@ skipped := (name,ul,p) :: !skipped; default_value name t in + let handle_errors fn = + try + fn() + with Error(l,p) when (match l with Call_error _ | Module_not_found _ -> false | _ -> true) -> + raise (WithTypeError (l,p)) + in (* let force_inline, is_extern = match cf with Some(TInst(c,_),f) -> is_forced_inline (Some c) f, (has_class_flag c CExtern) | _ -> false, false in *) let type_against name t e = - try + handle_errors (fun() -> let e = type_expr ctx e (WithType.with_argument t name) in !cast_or_unify_raise_ref ctx t e e.epos - with Error(l,p) when (match l with Call_error _ | Module_not_found _ -> false | _ -> true) -> - raise (WithTypeError (l,p)) + ) in let rec loop el args = match el,args with | [],[] -> @@ -120,11 +125,8 @@ | _ when ExtType.is_mono (follow arg_t) -> (try let el = type_rest mk_mono in - try - Type.unify arg_t (unify_min ctx el); - el - with Unify_error _ -> - die ~p:callp "Unexpected unification error" __LOC__ + unify ctx (unify_min ctx el) arg_t (punion_el (List.map (fun e -> ((),e.epos)) el)); + el with WithTypeError(ul,p) -> arg_error ul name false p) | _ -> @@ -222,6 +224,32 @@ | OverloadMeta (* @:overload(function() {}) *) | OverloadNone +(** + Unifies `el_typed` against the types from `args` list starting at the beginning + of `args` list. + + Returns a tuple of a part of `args` covered by `el_typed`, and a part of `args` + not used for `el_typed` unification. +*) +let unify_typed_args ctx tmap args el_typed call_pos = + let rec loop acc_args tmap args el = + match args,el with + | [], _ :: _ -> + let call_error = Call_error(Too_many_arguments) in + raise(Error(call_error,call_pos)) + | _, [] -> + List.rev acc_args,args + | ((_,opt,t0) as arg) :: args,e :: el -> + begin try + unify_raise ctx (tmap e.etype) t0 e.epos; + with Error(Unify _ as msg,p) -> + let call_error = Call_error(Could_not_unify msg) in + raise(Error(call_error,p)) + end; + loop (arg :: acc_args) (fun t -> t) args el + in + loop [] tmap args el_typed + let unify_field_call ctx fa el_typed el p inline = let expand_overloads cf = cf :: cf.cf_overloads @@ -300,22 +328,7 @@ let t = map (apply_params cf.cf_params monos cf.cf_type) in match follow t with | TFun(args,ret) -> - let rec loop acc_el acc_args tmap args el_typed = match args,el_typed with - | ((_,opt,t0) as arg) :: args,e :: el_typed -> - begin try - unify_raise ctx (tmap e.etype) t0 e.epos; - with Error(Unify _ as msg,p) -> - let call_error = Call_error(Could_not_unify msg) in - raise(Error(call_error,p)) - end; - loop (e :: acc_el) (arg :: acc_args) (fun t -> t) args el_typed - | [],_ :: _ -> - let call_error = Call_error(Too_many_arguments) in - raise(Error(call_error,p)) - | _ -> - List.rev acc_el,List.rev acc_args,args - in - let el_typed,args_typed,args = loop [] [] tmap args el_typed in + let args_typed,args = unify_typed_args ctx tmap args el_typed p in let el,_ = try unify_call_args ctx el args ret p inline is_forced_inline in_overload @@ -347,7 +360,7 @@ | [] -> [],[] | cf :: candidates -> let known_monos = List.map (fun (m,_) -> - m,m.tm_type,m.tm_constraints + m,m.tm_type,m.tm_down_constraints ) ctx.monomorphs.perfunction in let current_monos = ctx.monomorphs.perfunction in begin try @@ -361,7 +374,7 @@ with Error ((Call_error cerr as err),p) -> List.iter (fun (m,t,constr) -> if t != m.tm_type then m.tm_type <- t; - if constr != m.tm_constraints then m.tm_constraints <- constr; + if constr != m.tm_down_constraints then m.tm_down_constraints <- constr; ) known_monos; ctx.monomorphs.perfunction <- current_monos; maybe_raise_unknown_ident cerr p; @@ -515,22 +528,24 @@ (* Calls `e` with arguments `el`. Does not inspect the callee expression, so it should only be used with actual expression calls and not with something like field calls. *) - method expr_call (e : texpr) (el : expr list) = + method expr_call (e : texpr) (el_typed : texpr list) (el : expr list) = check_assign(); let rec loop t = match follow t with | TFun (args,r) -> - let el, tfunc = unify_call_args ctx el args r p false false false in + let args_typed,args_left = unify_typed_args ctx (fun t -> t) args el_typed p in + let el, tfunc = unify_call_args ctx el args_left r p false false false in + let el = el_typed @ el in let r = match tfunc with TFun(_,r) -> r | _ -> die "" __LOC__ in mk (TCall (e,el)) r p | TAbstract(a,tl) when Meta.has Meta.Callable a.a_meta -> loop (Abstract.get_underlying_type a tl) | TMono _ -> let t = mk_mono() in - let el = List.map (fun e -> type_expr ctx e WithType.value) el in + let el = el_typed @ List.map (fun e -> type_expr ctx e WithType.value) el in unify ctx (tfun (List.map (fun e -> e.etype) el) t) e.etype e.epos; mk (TCall (e,el)) t p | t -> - let el = List.map (fun e -> type_expr ctx e WithType.value) el in + let el = el_typed @ List.map (fun e -> type_expr ctx e WithType.value) el in let t = if t == t_dynamic then t_dynamic else if ctx.untyped then @@ -602,7 +617,7 @@ | AccCall -> self#accessor_call fa el_typed el | _ -> - self#expr_call (FieldAccess.get_field_expr fa FCall) el + self#expr_call (FieldAccess.get_field_expr fa FCall) el_typed el end end diff -Nru haxe-4.2.1/src/typing/fields.ml haxe-4.2.4/src/typing/fields.ml --- haxe-4.2.1/src/typing/fields.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/typing/fields.ml 2021-11-20 03:16:28.000000000 +0000 @@ -354,7 +354,7 @@ (mk_field i (mk_mono()) p null_pos) with cf_kind = Var { v_read = AccNormal; v_write = if is_set then AccNormal else AccNo } } in - (match Monomorph.classify_constraints r with + let rec check_constr = function | CStructural (fields,is_open) -> (try let f = PMap.find i fields in @@ -365,7 +365,7 @@ field_access f FHAnon with Not_found when is_open -> let f = mk_field() in - Monomorph.add_constraint r (MField f); + Monomorph.add_down_constraint r (MField f); field_access f FHAnon ) | CTypes tl -> @@ -374,10 +374,21 @@ if not (List.exists (fun (m,_) -> m == r) ctx.monomorphs.perfunction) && not (ctx.untyped && ctx.com.platform = Neko) then ctx.monomorphs.perfunction <- (r,p) :: ctx.monomorphs.perfunction; let f = mk_field() in - Monomorph.add_constraint r (MField f); - Monomorph.add_constraint r MOpenStructure; + Monomorph.add_down_constraint r (MField f); + Monomorph.add_down_constraint r MOpenStructure; field_access f FHAnon - ) + | CMixed l -> + let rec loop_constraints l = + match l with + | [] -> + raise Not_found + | constr :: l -> + try check_constr constr + with Not_found -> loop_constraints l + in + loop_constraints l + in + check_constr (Monomorph.classify_down_constraints r) | TAbstract (a,tl) -> (try let c = find_some a.a_impl in @@ -477,7 +488,7 @@ match t with | TType (td,tl) -> type_field_by_typedef type_field_by_module_extension e td tl | TMono r -> - (match Monomorph.classify_constraints r with + (match Monomorph.classify_down_constraints r with | CStructural (_,is_open) when not is_open -> type_field_by_extension() | _ -> raise Not_found ) diff -Nru haxe-4.2.1/src/typing/operators.ml haxe-4.2.4/src/typing/operators.ml --- haxe-4.2.1/src/typing/operators.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/typing/operators.ml 2021-11-20 03:16:28.000000000 +0000 @@ -191,7 +191,7 @@ | TAnon a -> (try is_dynamic (PMap.find f a.a_fields).cf_type with Not_found -> false) | TMono m -> - begin match Monomorph.classify_constraints m with + begin match Monomorph.classify_down_constraints m with | CStructural(fields,_) -> (try is_dynamic (PMap.find f fields).cf_type with Not_found -> false) | _ -> @@ -668,6 +668,7 @@ field_rhs_by_name op cf.cf_name ev (WithType.with_type cf.cf_type) in let assign vr e r_rhs = + check_assign ctx e; let assign e_rhs = let e_rhs = AbstractCast.cast_or_unify ctx e.etype e_rhs p in match e_rhs.eexpr with diff -Nru haxe-4.2.1/src/typing/typeloadFields.ml haxe-4.2.4/src/typing/typeloadFields.ml --- haxe-4.2.1/src/typing/typeloadFields.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/typing/typeloadFields.ml 2021-11-20 03:16:28.000000000 +0000 @@ -853,11 +853,6 @@ let e = if ctx.com.display.dms_display && ctx.com.display.dms_error_policy <> EPCollect then e else begin - let e = Optimizer.reduce_loop ctx (maybe_run_analyzer e) in - let e = (match Optimizer.make_constant_expression ctx e with - | Some e -> e - | None -> e - ) in let rec check_this e = match e.eexpr with | TConst TThis -> display_error ctx "Cannot access this or other member field in variable initialization" e.epos; @@ -1049,9 +1044,12 @@ | TMono _ when (match t with TFun(_,r) -> r == t_dynamic | _ -> false) -> t_dynamic | m -> m in + let is_multitype_cast = Meta.has Meta.MultiType a.a_meta && not fctx.is_abstract_member in + if is_multitype_cast && not (Meta.has Meta.MultiType cf.cf_meta) then + cf.cf_meta <- (Meta.MultiType,[],null_pos) :: cf.cf_meta; let r = exc_protect ctx (fun r -> r := lazy_processing (fun () -> t); - let args = if Meta.has Meta.MultiType a.a_meta then begin + let args = if is_multitype_cast then begin let ctor = try PMap.find "_new" c.cl_statics with Not_found -> diff -Nru haxe-4.2.1/src/typing/typeloadFunction.ml haxe-4.2.4/src/typing/typeloadFunction.ml --- haxe-4.2.1/src/typing/typeloadFunction.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/typing/typeloadFunction.ml 2021-11-20 03:16:28.000000000 +0000 @@ -154,7 +154,7 @@ { e with eexpr = TBlock (ev :: l) } else begin let rec has_v e = match e.eexpr with - | TLocal v' when v == v -> true + | TLocal v' when v' == v -> true | _ -> check_expr has_v e in let rec loop el = match el with diff -Nru haxe-4.2.1/src/typing/typerDisplay.ml haxe-4.2.4/src/typing/typerDisplay.ml --- haxe-4.2.1/src/typing/typerDisplay.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/typing/typerDisplay.ml 2021-11-20 03:16:28.000000000 +0000 @@ -491,47 +491,6 @@ in raise_fields fields (CRField(item,e.epos,iterator,keyValueIterator)) (make_subject None (DisplayPosition.display_position#with_pos p)) -let handle_structure_display ctx e fields origin = - let p = pos e in - let fields = PMap.foldi (fun _ cf acc -> cf :: acc) fields [] in - let fields = List.sort (fun cf1 cf2 -> -compare cf1.cf_pos.pmin cf2.cf_pos.pmin) fields in - let tpair ?(values=PMap.empty) t = - let ct = CompletionType.from_type (get_import_status ctx) ~values t in - (t,ct) - in - let make_field_item cf = - make_ci_class_field (CompletionClassField.make cf CFSMember origin true) (tpair ~values:(get_value_meta cf.cf_meta) cf.cf_type) - in - match fst e with - | EObjectDecl fl -> - let fields = ref fields in - let rec loop subj fl = match fl with - | [] -> subj - | ((n,p,_),_) :: fl -> - let subj = if DisplayPosition.display_position#enclosed_in p then - Some(n,p) - else begin - fields := List.filter (fun cf -> cf.cf_name <> n) !fields; - subj - end in - loop subj fl - in - let subj = loop None fl in - let name,pinsert = match subj with - | None -> None,DisplayPosition.display_position#with_pos (pos e) - | Some(name,p) -> Some name,p - in - let fields = List.map make_field_item !fields in - raise_fields fields CRStructureField (make_subject name pinsert) - | EBlock [] -> - let fields = List.fold_left (fun acc cf -> - (make_field_item cf) :: acc - ) [] fields in - let pinsert = DisplayPosition.display_position#with_pos (pos e) in - raise_fields fields CRStructureField (make_subject None pinsert) - | _ -> - error "Expected object expression" p - let handle_display ctx e_ast dk mode with_type = let old = ctx.in_display,ctx.in_call_args in ctx.in_display <- true; @@ -661,6 +620,57 @@ end else f() +let handle_structure_display ctx e fields origin = + let p = pos e in + let fields = PMap.foldi (fun _ cf acc -> cf :: acc) fields [] in + let fields = List.sort (fun cf1 cf2 -> -compare cf1.cf_pos.pmin cf2.cf_pos.pmin) fields in + let tpair ?(values=PMap.empty) t = + let ct = CompletionType.from_type (get_import_status ctx) ~values t in + (t,ct) + in + let make_field_item cf = + make_ci_class_field (CompletionClassField.make cf CFSMember origin true) (tpair ~values:(get_value_meta cf.cf_meta) cf.cf_type) + in + match fst e with + | EObjectDecl fl -> + let fields = ref fields in + let rec loop subj fl = match fl with + | [] -> subj + | ((n,p,_),e) :: fl -> + let subj = if DisplayPosition.display_position#enclosed_in p then + Some(n,p) + else begin + if DisplayPosition.display_position#enclosed_in ({ (pos e) with pmin = p.pmax + 1 }) then begin + let e = fst e, { (pos e) with pmin = p.pmax + 1 } in + let wt = + try + let cf = List.find (fun { cf_name = name } -> name = n) !fields in + WithType.with_type cf.cf_type + with Not_found -> WithType.value + in + ignore(handle_display ctx e DKMarked MGet wt) + end; + fields := List.filter (fun cf -> cf.cf_name <> n) !fields; + subj + end in + loop subj fl + in + let subj = loop None fl in + let name,pinsert = match subj with + | None -> None,DisplayPosition.display_position#with_pos (pos e) + | Some(name,p) -> Some name,p + in + let fields = List.map make_field_item !fields in + raise_fields fields CRStructureField (make_subject name pinsert) + | EBlock [] -> + let fields = List.fold_left (fun acc cf -> + (make_field_item cf) :: acc + ) [] fields in + let pinsert = DisplayPosition.display_position#with_pos (pos e) in + raise_fields fields CRStructureField (make_subject None pinsert) + | _ -> + error "Expected object expression" p + let handle_edisplay ctx e dk mode with_type = let handle_display ctx e dk with_type = handle_display ctx e dk mode with_type diff -Nru haxe-4.2.1/src/typing/typer.ml haxe-4.2.4/src/typing/typer.ml --- haxe-4.2.1/src/typing/typer.ml 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src/typing/typer.ml 2021-11-20 03:16:28.000000000 +0000 @@ -108,11 +108,7 @@ (try Type.unify t' t with Unify_error _ -> ()); AKExpr e | _ -> - if iscall then - AKExpr e - else begin - AKExpr (AbstractCast.cast_or_unify ctx t e e.epos) - end + AKExpr e end | _ -> e (* ??? *) end @@ -1808,7 +1804,10 @@ | CTPath tp -> if tp.tparams <> [] then display_error ctx "Type parameters are not supported for the `is` operator" p_t; let e = type_expr ctx e WithType.value in - let e_t = type_type ctx (tp.tpackage,tp.tname) p_t in + let mt = Typeload.load_type_def ctx p_t tp in + if ctx.in_display && DisplayPosition.display_position#enclosed_in p_t then + DisplayEmitter.display_module_type ctx mt p_t; + let e_t = type_module_type ctx mt None p_t in let e_Std_isOfType = match Typeload.load_type_raise ctx ([],"Std") "Std" p with | TClassDecl c -> diff -Nru haxe-4.2.1/src-json/define.json haxe-4.2.4/src-json/define.json --- haxe-4.2.1/src-json/define.json 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/src-json/define.json 2021-11-20 03:16:28.000000000 +0000 @@ -319,6 +319,12 @@ "platforms": ["js"] }, { + "name": "JsGlobal", + "define": "js_global", + "doc": "Customizes the global object name.", + "platforms": ["js"] + }, + { "name": "JsUnflatten", "define": "js_unflatten", "doc": "Generate nested objects for packages and types.", diff -Nru haxe-4.2.1/std/eval/integers/Int64.hx haxe-4.2.4/std/eval/integers/Int64.hx --- haxe-4.2.1/std/eval/integers/Int64.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/std/eval/integers/Int64.hx 2021-11-20 03:16:28.000000000 +0000 @@ -100,6 +100,7 @@ @:op(A - B) inline function _sub(u:Int64):Int64 return this.sub(u); @:op(A * B) inline function _mul(u:Int64):Int64 return this.mul(u); @:op(A / B) inline function _div(u:Int64):Int64 return this.div(u); + @:op(A % B) inline function _mod(u:Int64):Int64 return this.remainder(u); @:op(A & B) inline function _logand(u:Int64):Int64 return this.logand(u); @:op(A | B) inline function _logor(u:Int64):Int64 return this.logor(u); @:op(A ^ B) inline function _logxor(u:Int64):Int64 return this.logxor(u); diff -Nru haxe-4.2.1/std/eval/integers/UInt64.hx haxe-4.2.4/std/eval/integers/UInt64.hx --- haxe-4.2.1/std/eval/integers/UInt64.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/std/eval/integers/UInt64.hx 2021-11-20 03:16:28.000000000 +0000 @@ -93,6 +93,7 @@ @:op(A - B) inline function _sub(u:UInt64):UInt64 return this.sub(u); @:op(A * B) inline function _mul(u:UInt64):UInt64 return this.mul(u); @:op(A / B) inline function _div(u:UInt64):UInt64 return this.div(u); + @:op(A % B) inline function _mod(u:UInt64):UInt64 return this.remainder(u); @:op(A & B) inline function _logand(u:UInt64):UInt64 return this.logand(u); @:op(A | B) inline function _logor(u:UInt64):UInt64 return this.logor(u); @:op(A ^ B) inline function _logxor(u:UInt64):UInt64 return this.logxor(u); diff -Nru haxe-4.2.1/std/eval/luv/Tcp.hx haxe-4.2.4/std/eval/luv/Tcp.hx --- haxe-4.2.1/std/eval/luv/Tcp.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/std/eval/luv/Tcp.hx 2021-11-20 03:16:28.000000000 +0000 @@ -23,7 +23,7 @@ /** Sets TCP_NODELAY. **/ - public function noDelay():Result; + public function noDelay(enable:Bool):Result; /** Sets the TCP keepalive. diff -Nru haxe-4.2.1/std/haxe/MainLoop.hx haxe-4.2.4/std/haxe/MainLoop.hx --- haxe-4.2.1/std/haxe/MainLoop.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/std/haxe/MainLoop.hx 2021-11-20 03:16:28.000000000 +0000 @@ -110,11 +110,11 @@ static function injectIntoEventLoop(waitMs:Int) { #if (target.threaded && !cppia) mutex.acquire(); - if(eventLoopHandler != null) { + if(eventLoopHandler != null) mainThread.events.cancel(eventLoopHandler); - } eventLoopHandler = mainThread.events.repeat( () -> { + mainThread.events.cancel(eventLoopHandler); var wait = tick(); if(hasEvents()) { injectIntoEventLoop(Std.int(wait * 1000)); diff -Nru haxe-4.2.1/std/hl/UI.hx haxe-4.2.4/std/hl/UI.hx --- haxe-4.2.1/std/hl/UI.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/std/hl/UI.hx 2021-11-20 03:16:28.000000000 +0000 @@ -214,4 +214,37 @@ static function _chooseFile(forSave:Bool, obj:Dynamic):hl.Bytes { return null; } + + #if (hl_ver >= version("1.12.0")) + public static function setClipboardText(text:String):Bool { + if(text == null) + return false; + return @:privateAccess _setClipboardText(text.toUtf8()); + } + + @:hlNative("?ui", "ui_set_clipboard_text") + static function _setClipboardText(text:hl.Bytes):Bool { + return false; + } + + public static function getClipboardText():String { + var t = _getClipboardText(); + if( t == null ) + return null; + return @:privateAccess String.fromUTF8(t); + } + + @:hlNative("?ui", "ui_get_clipboard_text") + static function _getClipboardText():hl.Bytes { + return null; + } + #else + public static function setClipboardText(text:String):Bool { + return false; + } + public static function getClipboardText():String { + return null; + } + #end + } diff -Nru haxe-4.2.1/std/js/_std/haxe/ds/IntMap.hx haxe-4.2.4/std/js/_std/haxe/ds/IntMap.hx --- haxe-4.2.1/std/js/_std/haxe/ds/IntMap.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/std/js/_std/haxe/ds/IntMap.hx 2021-11-20 03:16:28.000000000 +0000 @@ -50,7 +50,7 @@ public function keys():Iterator { var a = []; - js.Syntax.code("for( var key in {0} ) if({0}.hasOwnProperty(key)) {1}.push(key | 0)", h, a); + js.Syntax.code("for( var key in {0} ) if({0}.hasOwnProperty(key)) {1}.push(+key)", h, a); return a.iterator(); } diff -Nru haxe-4.2.1/std/jvm/_std/Reflect.hx haxe-4.2.4/std/jvm/_std/Reflect.hx --- haxe-4.2.1/std/jvm/_std/Reflect.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/std/jvm/_std/Reflect.hx 2021-11-20 03:16:28.000000000 +0000 @@ -22,6 +22,15 @@ import jvm.Jvm; +import java.lang.Number; +import java.lang.Long.LongClass; +import java.lang.Double.DoubleClass; +import java.lang.Float.FloatClass; +import java.math.BigDecimal; +import java.math.BigInteger; + +using jvm.NativeTools.NativeClassTools; + @:coreApi class Reflect { public static function hasField(o:Dynamic, field:String):Bool { @@ -100,8 +109,27 @@ if (b == null) { return 1; } - if (Jvm.instanceof(a, java.lang.Number) && Jvm.instanceof(b, java.lang.Number)) { - return java.lang.Long.compare((cast a : java.lang.Number).longValue(), (cast b : java.lang.Number).longValue()); + if (Jvm.instanceof(a, Number) && Jvm.instanceof(b, Number)) { + var a = (cast a:Number); + var b = (cast b:Number); + inline function isBig(v:Number) + return Jvm.instanceof(v, BigDecimal) || Jvm.instanceof(v, BigInteger); + inline function cmpLongTo(long:Number, another:Number) { + if(Jvm.instanceof(another, DoubleClass)) { + return new BigDecimal(long.longValue()).compareTo(new BigDecimal(another.doubleValue())); + } else if(Jvm.instanceof(another, FloatClass)) { + return new BigDecimal(long.longValue()).compareTo(new BigDecimal(another.floatValue())); + } else { + return LongClass.compare(long.longValue(), another.longValue()); + } + } + if(isBig(a) || isBig(b)) + return new BigDecimal((cast a:java.lang.Object).toString()).compareTo((cast a:java.lang.Object).toString()); + if(Jvm.instanceof(a, LongClass)) + return cmpLongTo(a, b); + if(Jvm.instanceof(b, LongClass)) + return -1 * cmpLongTo(b, a); + return DoubleClass.compare(a.doubleValue(), b.doubleValue()); } if (Jvm.instanceof(a, java.NativeString)) { if (!Jvm.instanceof(b, java.NativeString)) { diff -Nru haxe-4.2.1/std/php/Attribute.hx haxe-4.2.4/std/php/Attribute.hx --- haxe-4.2.1/std/php/Attribute.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/std/php/Attribute.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,38 @@ +/* + * Copyright (C)2005-2021 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package php; + +/** + @see https://www.php.net/manual/en/language.attributes.php +**/ +@:native("Attribute") +extern final class Attribute { + @:phpClassConst static final IS_REPEATABLE: Int; + @:phpClassConst static final TARGET_ALL: Int; + @:phpClassConst static final TARGET_CLASS_CONSTANT: Int; + @:phpClassConst static final TARGET_CLASS: Int; + @:phpClassConst static final TARGET_FUNCTION: Int; + @:phpClassConst static final TARGET_METHOD: Int; + @:phpClassConst static final TARGET_PARAMETER: Int; + @:phpClassConst static final TARGET_PROPERTY: Int; +} diff -Nru haxe-4.2.1/std/php/db/PDO.hx haxe-4.2.4/std/php/db/PDO.hx --- haxe-4.2.1/std/php/db/PDO.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/std/php/db/PDO.hx 2021-11-20 03:16:28.000000000 +0000 @@ -61,7 +61,7 @@ @:phpClassConst static final ATTR_CASE:Int; @:phpClassConst static final ATTR_CURSOR_NAME:Int; @:phpClassConst static final ATTR_CURSOR:Int; - @:phpClassConst static final ATTR_DRIVER_NAME:String; + @:phpClassConst static final ATTR_DRIVER_NAME:Int; @:phpClassConst static final ATTR_ORACLE_NULLS:Int; @:phpClassConst static final ATTR_PERSISTENT:Int; @:phpClassConst static final ATTR_STATEMENT_CLASS:Int; diff -Nru haxe-4.2.1/std/php/Global.hx haxe-4.2.4/std/php/Global.hx --- haxe-4.2.1/std/php/Global.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/std/php/Global.hx 2021-11-20 03:16:28.000000000 +0000 @@ -927,6 +927,26 @@ static function hash(algo:String, str:String, raw_output:Bool = false):String; /** + @see http://php.net/manual/en/function.hash-algos.php + **/ + static function hash_algos():NativeIndexedArray; + + /** + @see http://php.net/manual/en/function.hash-hmac.php + **/ + static function hash_hmac(algo:String, data:String, key:String, binary:Bool = false):EitherType; + + /** + @see http://php.net/manual/en/function.hash-hmac-algos.php + **/ + static function hash_hmac_algos():NativeIndexedArray; + + /** + @see http://php.net/manual/en/function.hash-hmac-file.php + **/ + static function hash_hmac_file(algo:String, data:String, key:String, binary:Bool = false):EitherType; + + /** @see http://php.net/manual/en/function.pack.php **/ static function pack(format:String, args:Rest):String; @@ -1844,4 +1864,8 @@ **/ static function number_format(num:Float, ?decimals:Int, ?decimal_separator:String, ?thousands_separator:String):String; + /** + @see http://php.net/manual/en/function.empty.php + **/ + static function empty(variable:Any):Bool; } diff -Nru haxe-4.2.1/std/php/IntlCalendar.hx haxe-4.2.4/std/php/IntlCalendar.hx --- haxe-4.2.1/std/php/IntlCalendar.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/std/php/IntlCalendar.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,120 @@ +/* + * Copyright (C)2005-2021 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package php; + +import haxe.extern.EitherType; + +/** + @see https://www.php.net/manual/en/class.intlcalendar.php +**/ +@:native("IntlCalendar") +extern class IntlCalendar { + @:phpClassConst static final DOW_FRIDAY: Int; + @:phpClassConst static final DOW_MONDAY: Int; + @:phpClassConst static final DOW_SATURDAY: Int; + @:phpClassConst static final DOW_SUNDAY: Int; + @:phpClassConst static final DOW_THURSDAY: Int; + @:phpClassConst static final DOW_TUESDAY: Int; + @:phpClassConst static final DOW_TYPE_WEEKDAY: Int; + @:phpClassConst static final DOW_TYPE_WEEKEND_CEASE: Int; + @:phpClassConst static final DOW_TYPE_WEEKEND_OFFSET: Int; + @:phpClassConst static final DOW_TYPE_WEEKEND: Int; + @:phpClassConst static final DOW_WEDNESDAY: Int; + @:phpClassConst static final FIELD_AM_PM: Int; + @:phpClassConst static final FIELD_DATE: Int; + @:phpClassConst static final FIELD_DAY_OF_MONTH: Int; + @:phpClassConst static final FIELD_DAY_OF_WEEK_IN_MONTH: Int; + @:phpClassConst static final FIELD_DAY_OF_WEEK: Int; + @:phpClassConst static final FIELD_DAY_OF_YEAR: Int; + @:phpClassConst static final FIELD_DOW_LOCAL: Int; + @:phpClassConst static final FIELD_DST_OFFSET: Int; + @:phpClassConst static final FIELD_ERA: Int; + @:phpClassConst static final FIELD_EXTENDED_YEAR: Int; + @:phpClassConst static final FIELD_FIELD_COUNT: Int; + @:phpClassConst static final FIELD_HOUR_OF_DAY: Int; + @:phpClassConst static final FIELD_HOUR: Int; + @:phpClassConst static final FIELD_IS_LEAP_MONTH: Int; + @:phpClassConst static final FIELD_JULIAN_DAY: Int; + @:phpClassConst static final FIELD_MILLISECOND: Int; + @:phpClassConst static final FIELD_MILLISECONDS_IN_DAY: Int; + @:phpClassConst static final FIELD_MINUTE: Int; + @:phpClassConst static final FIELD_MONTH: Int; + @:phpClassConst static final FIELD_SECOND: Int; + @:phpClassConst static final FIELD_WEEK_OF_MONTH: Int; + @:phpClassConst static final FIELD_WEEK_OF_YEAR: Int; + @:phpClassConst static final FIELD_YEAR_WOY: Int; + @:phpClassConst static final FIELD_YEAR: Int; + @:phpClassConst static final FIELD_ZONE_OFFSET: Int; + @:phpClassConst static final WALLTIME_FIRST: Int; + @:phpClassConst static final WALLTIME_LAST: Int; + @:phpClassConst static final WALLTIME_NEXT_VALID: Int; + + static function createInstance(timeZone: EitherType, EitherType> = null, locale: Null = ""): Null; + static function fromDateTime(dateTime: EitherType): Null; + static function getAvailableLocales(): NativeIndexedArray; + static function getKeywordValuesForLocale(key: String, locale: String, commonlyUsed: Bool): EitherType, Bool>; + static function getNow(): Float; + + function add(field: Int, amount: Int): Bool; + function after(other: IntlCalendar): Bool; + function before(other: IntlCalendar): Bool; + function clear(field: Null = null): Bool; + function equals(other: IntlCalendar): Bool; + function fieldDifference(when: Float, field: Int): EitherType; + function get(field: Int): Int; + function getActualMaximum(field: Int): EitherType; + function getActualMinimum(field: Int): EitherType; + function getDayOfWeekType(dayOfWeek: Int): EitherType; + function getErrorCode(): Int; + function getErrorMessage(): String; + function getFirstDayOfWeek(): EitherType; + function getGreatestMinimum(field: Int): EitherType; + function getLeastMaximum(field: Int): EitherType; + function getLocale(localeType: Int): EitherType; + function getMaximum(field: Int): EitherType; + function getMinimalDaysInFirstWeek(): EitherType; + function getMinimum(field: Int): EitherType; + function getRepeatedWallTimeOption(): Int; + function getSkippedWallTimeOption(): Int; + function getTime(): Float; + function getTimeZone(): IntlTimeZone; + function getType(): String; + function getWeekendTransition(dayOfWeek: Int): EitherType; + function inDaylightTime(): Bool; + function isEquivalentTo(other: IntlCalendar): Bool; + function isLenient(): Bool; + function isSet(field: Int): Bool; + function isWeekend(date: Null = null): Bool; + function roll(field: Int, amountOrUpOrDown: EitherType): Bool; + function setFirstDayOfWeek(dayOfWeek: Int): Bool; + function setLenient(isLenient: Bool): Bool; + function setMinimalDaysInFirstWeek(minimalDays: Int): Bool; + function setRepeatedWallTimeOption(wallTimeOption: Int): Bool; + function setSkippedWallTimeOption(wallTimeOption: Int): Bool; + function setTime(date: Float): Bool; + function setTimeZone(timeZone: EitherType, EitherType>): Bool; + function toDateTime(): EitherType; + + @:overload(function(year: Int, month: Int, dayOfMonth: Null = null, hour: Null = null, minute: Null = null, second: Null = null): Bool {}) + function set(field: Int, value: Int): Bool; +} diff -Nru haxe-4.2.1/std/php/IntlDateFormatter.hx haxe-4.2.4/std/php/IntlDateFormatter.hx --- haxe-4.2.1/std/php/IntlDateFormatter.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/std/php/IntlDateFormatter.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * Copyright (C)2005-2021 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package php; + +import haxe.extern.EitherType; + +/** + @see https://www.php.net/manual/en/class.intldateformatter.php +**/ +@:native("IntlDateFormatter") +extern class IntlDateFormatter { + @:phpClassConst static final FULL: Int; + @:phpClassConst static final GREGORIAN: Int; + @:phpClassConst static final LONG: Int; + @:phpClassConst static final MEDIUM: Int; + @:phpClassConst static final NONE: Int; + @:phpClassConst static final RELATIVE_FULL: Int; + @:phpClassConst static final RELATIVE_LONG: Int; + @:phpClassConst static final RELATIVE_MEDIUM: Int; + @:phpClassConst static final RELATIVE_SHORT: Int; + @:phpClassConst static final SHORT: Int; + @:phpClassConst static final TRADITIONAL: Int; + + function new(locale: Null, dateType: Int, timeType: Int, timezone: EitherType> = null, + calendar: EitherType = null, pattern: String = ""); + + static function create(locale: Null, dateType: Int, timeType: Int, + timezone: EitherType> = null, + calendar: EitherType = null, pattern: String = ""): Null; + + static function formatObject(datetime: EitherType, format: EitherType, String>> = null, + locale: String = null): EitherType; + + function format(datetime: EitherType>>>>>): EitherType; + function getCalendar(): EitherType; + function getCalendarObject(): EitherType, Bool>; + function getDateType(): EitherType; + function getErrorCode(): Int; + function getErrorMessage(): String; + function getLocale(?type: Int): EitherType; + function getPattern(): EitherType; + function getTimeType(): EitherType; + function getTimeZone(): EitherType; + function getTimeZoneId(): EitherType; + function isLenient(): Bool; + function localtime(string: String, offset: Ref = null): EitherType, Bool>; + function parse(string: String, offset: Ref = null): EitherType>; + function setCalendar(calendar: EitherType, Int>): Bool; + function setLenient(lenient: Bool): Bool; + function setPattern(pattern: String): Bool; + function setTimeZone(timezone: EitherType, EitherType>): Null; +} diff -Nru haxe-4.2.1/std/php/IntlIterator.hx haxe-4.2.4/std/php/IntlIterator.hx --- haxe-4.2.1/std/php/IntlIterator.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/std/php/IntlIterator.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,35 @@ +/* + * Copyright (C)2005-2021 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package php; + +/** + @see https://www.php.net/manual/en/class.intliterator.php +**/ +@:native("IntlIterator") +extern class IntlIterator implements NativeIterator { + function current(): V; + function key(): K; + function next(): Void; + function rewind(): Void; + function valid(): Bool; +} diff -Nru haxe-4.2.1/std/php/IntlTimeZone.hx haxe-4.2.4/std/php/IntlTimeZone.hx --- haxe-4.2.1/std/php/IntlTimeZone.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/std/php/IntlTimeZone.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright (C)2005-2021 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package php; + +import haxe.extern.EitherType; + +/** + @see https://www.php.net/manual/en/class.intltimezone.php +**/ +@:native("IntlTimeZone") +extern class IntlTimeZone { + @:phpClassConst static final DISPLAY_LONG: Int; + @:phpClassConst static final DISPLAY_SHORT: Int; + + static function countEquivalentIDs(zoneId: String): Int; + static function createDefault(): IntlTimeZone; + static function createEnumeration(countryOrRawOffset: Any): IntlIterator; + static function createTimeZone(zoneId: String): IntlTimeZone; + static function createTimeZoneIDEnumeration(zoneType: Int, ?region: String, ?rawOffset: Int): EitherType, Bool>; + static function fromDateTimeZone(zoneId: DateTimeZone): IntlTimeZone; + static function getCanonicalID(zoneId: String, isSystemID: Ref): String; + static function getEquivalentID(zoneId: String, index: Int): String; + static function getGMT(): IntlTimeZone; + static function getIDForWindowsID(timezone: String, ?region: String): EitherType; + static function getRegion(zoneId: String): EitherType; + static function getTZDataVersion(): String; + static function getUnknown(): Null; + static function getWindowsID(timezone: String): EitherType; + + function getDisplayName(?isDaylight: Bool, ?style: Int, ?locale: String): String; + function getDSTSavings(): Int; + function getErrorCode(): Int; + function getErrorMessage(): String; + function getID(): String; + function getOffset(date: Float, local: Bool, rawOffset: Ref, dstOffset: Ref): Bool; + function getRawOffset(): Int; + function hasSameRules(otherTimeZone: IntlTimeZone): Bool; + function toDateTimeZone(): DateTimeZone; + function useDaylightTime(): Bool; +} diff -Nru haxe-4.2.1/std/php/NumberFormatter.hx haxe-4.2.4/std/php/NumberFormatter.hx --- haxe-4.2.1/std/php/NumberFormatter.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/std/php/NumberFormatter.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,126 @@ +/* + * Copyright (C)2005-2021 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package php; + +import haxe.extern.EitherType; + +/** + @see https://www.php.net/manual/en/class.numberformatter.php +**/ +@:native("NumberFormatter") +extern class NumberFormatter { + @:phpClassConst static final CURRENCY: Int; + @:phpClassConst static final CURRENCY_ACCOUNTING: Int; + @:phpClassConst static final CURRENCY_CODE: Int; + @:phpClassConst static final CURRENCY_SYMBOL: Int; + @:phpClassConst static final DECIMAL: Int; + @:phpClassConst static final DECIMAL_ALWAYS_SHOWN: Int; + @:phpClassConst static final DECIMAL_SEPARATOR_SYMBOL: Int; + @:phpClassConst static final DEFAULT_RULESET: Int; + @:phpClassConst static final DEFAULT_STYLE: Int; + @:phpClassConst static final DIGIT_SYMBOL: Int; + @:phpClassConst static final DURATION: Int; + @:phpClassConst static final EXPONENTIAL_SYMBOL: Int; + @:phpClassConst static final FORMAT_WIDTH: Int; + @:phpClassConst static final FRACTION_DIGITS: Int; + @:phpClassConst static final GROUPING_SEPARATOR_SYMBOL: Int; + @:phpClassConst static final GROUPING_SIZE: Int; + @:phpClassConst static final GROUPING_USED: Int; + @:phpClassConst static final IGNORE: Int; + @:phpClassConst static final INFINITY_SYMBOL: Int; + @:phpClassConst static final INTEGER_DIGITS: Int; + @:phpClassConst static final INTL_CURRENCY_SYMBOL: Int; + @:phpClassConst static final LENIENT_PARSE: Int; + @:phpClassConst static final MAX_FRACTION_DIGITS: Int; + @:phpClassConst static final MAX_INTEGER_DIGITS: Int; + @:phpClassConst static final MAX_SIGNIFICANT_DIGITS: Int; + @:phpClassConst static final MIN_FRACTION_DIGITS: Int; + @:phpClassConst static final MIN_INTEGER_DIGITS: Int; + @:phpClassConst static final MIN_SIGNIFICANT_DIGITS: Int; + @:phpClassConst static final MINUS_SIGN_SYMBOL: Int; + @:phpClassConst static final MONETARY_GROUPING_SEPARATOR_SYMBOL: Int; + @:phpClassConst static final MONETARY_SEPARATOR_SYMBOL: Int; + @:phpClassConst static final MULTIPLIER: Int; + @:phpClassConst static final NAN_SYMBOL: Int; + @:phpClassConst static final NEGATIVE_PREFIX: Int; + @:phpClassConst static final NEGATIVE_SUFFIX: Int; + @:phpClassConst static final ORDINAL: Int; + @:phpClassConst static final PAD_AFTER_PREFIX: Int; + @:phpClassConst static final PAD_AFTER_SUFFIX: Int; + @:phpClassConst static final PAD_BEFORE_PREFIX: Int; + @:phpClassConst static final PAD_BEFORE_SUFFIX: Int; + @:phpClassConst static final PAD_ESCAPE_SYMBOL: Int; + @:phpClassConst static final PADDING_CHARACTER: Int; + @:phpClassConst static final PADDING_POSITION: Int; + @:phpClassConst static final PARSE_INT_ONLY: Int; + @:phpClassConst static final PATTERN_DECIMAL: Int; + @:phpClassConst static final PATTERN_RULEBASED: Int; + @:phpClassConst static final PATTERN_SEPARATOR_SYMBOL: Int; + @:phpClassConst static final PERCENT: Int; + @:phpClassConst static final PERCENT_SYMBOL: Int; + @:phpClassConst static final PERMILL_SYMBOL: Int; + @:phpClassConst static final PLUS_SIGN_SYMBOL: Int; + @:phpClassConst static final POSITIVE_PREFIX: Int; + @:phpClassConst static final POSITIVE_SUFFIX: Int; + @:phpClassConst static final PUBLIC_RULESETS: Int; + @:phpClassConst static final ROUND_CEILING: Int; + @:phpClassConst static final ROUND_DOWN: Int; + @:phpClassConst static final ROUND_FLOOR: Int; + @:phpClassConst static final ROUND_HALFDOWN: Int; + @:phpClassConst static final ROUND_HALFEVEN: Int; + @:phpClassConst static final ROUND_HALFUP: Int; + @:phpClassConst static final ROUND_UP: Int; + @:phpClassConst static final ROUNDING_INCREMENT: Int; + @:phpClassConst static final ROUNDING_MODE: Int; + @:phpClassConst static final SCIENTIFIC: Int; + @:phpClassConst static final SECONDARY_GROUPING_SIZE: Int; + @:phpClassConst static final SIGNIFICANT_DIGIT_SYMBOL: Int; + @:phpClassConst static final SIGNIFICANT_DIGITS_USED: Int; + @:phpClassConst static final SPELLOUT: Int; + @:phpClassConst static final TYPE_CURRENCY: Int; + @:phpClassConst static final TYPE_DEFAULT: Int; + @:phpClassConst static final TYPE_DOUBLE: Int; + @:phpClassConst static final TYPE_INT32: Int; + @:phpClassConst static final TYPE_INT64: Int; + @:phpClassConst static final ZERO_DIGIT_SYMBOL: Int; + + function new(locale: String, style: Int, ?pattern: String); + + static function create(locale: String, style: Int, ?pattern: String): EitherType; + + function formatCurrency(value: Float, currency: String): EitherType; + function format(value: EitherType, ?type: Int): EitherType; + function getAttribute(attr: Int): EitherType; + function getErrorCode(): Int; + function getErrorMessage(): String; + function getLocale(?type: Int): String; + function getPattern(): EitherType; + function getSymbol(attr: Int): EitherType; + function getTextAttribute(attr: Int): EitherType; + function parseCurrency(value: String, currency: Ref, ?position: Ref): EitherType; + function parse(value: String, ?type: Int, ?position: Ref): EitherType>>; + function setAttribute(attr: Int, value: Int): Bool; + function setPattern(pattern: String): Bool; + function setSymbol(attr: Int, value: String): Bool; + function setTextAttribute(attr: Int, value: String): Bool; +} diff -Nru haxe-4.2.1/std/python/Boot.hx haxe-4.2.4/std/python/Boot.hx --- haxe-4.2.1/std/python/Boot.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/std/python/Boot.hx 2021-11-20 03:16:28.000000000 +0000 @@ -223,7 +223,7 @@ } static inline function isMetaType(v:Dynamic, t:Dynamic):Bool { - return python.Syntax.binop(v, "==", t); + return Syntax.binop(Syntax.binop(Syntax.call(UBuiltins.type, [v]), "==", UBuiltins.type), "and", Syntax.binop(v, "==", t)); } @:analyzer(no_local_dce) diff -Nru haxe-4.2.1/std/sys/db/Sqlite.hx haxe-4.2.4/std/sys/db/Sqlite.hx --- haxe-4.2.1/std/sys/db/Sqlite.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/std/sys/db/Sqlite.hx 2021-11-20 03:16:28.000000000 +0000 @@ -31,8 +31,8 @@ Also note that this will try to open an assembly named `Mono.Data.Sqlite` if it wasn't loaded yet. - (java) You will need a SQLite JDBC driver (e.g. - https://bitbucket.org/xerial/sqlite-jdbc). + (java) You will need a SQLite JDBC driver (e.g. + https://github.com/xerial/sqlite-jdbc/releases). **/ public static function open(file:String):Connection { throw "Not implemented for this platform"; diff -Nru haxe-4.2.1/tests/display/src/cases/Issue5172.hx haxe-4.2.4/tests/display/src/cases/Issue5172.hx --- haxe-4.2.1/tests/display/src/cases/Issue5172.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/tests/display/src/cases/Issue5172.hx 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -package cases; - -class Issue5172 extends DisplayTestCase { - /** - class Main { - static function main() { - for ({-3-}i{-1-} in 0...10) { - {-4-}i{-2-}; - } - } - } - **/ - function test() { - eq("Int", type(pos(1))); - eq("Int", type(pos(2))); - eq(range(3, 1), position(pos(1))); - arrayEq([range(4, 2)], usage(pos(1))); - } -} diff -Nru haxe-4.2.1/tests/display/src/cases/Issue5172.hx.disabled haxe-4.2.4/tests/display/src/cases/Issue5172.hx.disabled --- haxe-4.2.1/tests/display/src/cases/Issue5172.hx.disabled 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/display/src/cases/Issue5172.hx.disabled 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,19 @@ +package cases; + +class Issue5172 extends DisplayTestCase { + /** + class Main { + static function main() { + for ({-3-}i{-1-} in 0...10) { + {-4-}i{-2-}; + } + } + } + **/ + function test() { + eq("Int", type(pos(1))); + eq("Int", type(pos(2))); + eq(range(3, 1), position(pos(1))); + arrayEq([range(4, 2)], usage(pos(1))); + } +} diff -Nru haxe-4.2.1/tests/misc/compiler_loops/projects/Issue10308/compile.hxml haxe-4.2.4/tests/misc/compiler_loops/projects/Issue10308/compile.hxml --- haxe-4.2.1/tests/misc/compiler_loops/projects/Issue10308/compile.hxml 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/compiler_loops/projects/Issue10308/compile.hxml 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,2 @@ +--main Main +--interp \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/compiler_loops/projects/Issue10308/Main.hx haxe-4.2.4/tests/misc/compiler_loops/projects/Issue10308/Main.hx --- haxe-4.2.1/tests/misc/compiler_loops/projects/Issue10308/Main.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/compiler_loops/projects/Issue10308/Main.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,10 @@ +class Main{ + static public function main(){ + var event = null; + event = haxe.MainLoop.add( + () -> { + event.stop(); + } + ); + } +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/compiler_loops/projects/Issue10329/compile.hxml haxe-4.2.4/tests/misc/compiler_loops/projects/Issue10329/compile.hxml --- haxe-4.2.1/tests/misc/compiler_loops/projects/Issue10329/compile.hxml 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/compiler_loops/projects/Issue10329/compile.hxml 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,2 @@ +--main Main +--interp \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/compiler_loops/projects/Issue10329/Main.hx haxe-4.2.4/tests/misc/compiler_loops/projects/Issue10329/Main.hx --- haxe-4.2.1/tests/misc/compiler_loops/projects/Issue10329/Main.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/compiler_loops/projects/Issue10329/Main.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,14 @@ +import haxe.MainLoop; + +class Main { + static function main() { + var e1 = null; + var e2 = null; + e1 = MainLoop.add(() -> { + e1.stop(); + }); + e2 = MainLoop.add(() -> { + e2.stop(); + }); + } +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/java/projects/Issue10280/compile.hxml haxe-4.2.4/tests/misc/java/projects/Issue10280/compile.hxml --- haxe-4.2.1/tests/misc/java/projects/Issue10280/compile.hxml 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/java/projects/Issue10280/compile.hxml 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,3 @@ +-main Main +--jvm jvm.jar +-cmd java -jar jvm.jar \ No newline at end of file Binary files /tmp/tmpwfigmo7d/Jo2wY2KEq6/haxe-4.2.1/tests/misc/java/projects/Issue10280/jvm.jar and /tmp/tmpwfigmo7d/BP6rmvB6sE/haxe-4.2.4/tests/misc/java/projects/Issue10280/jvm.jar differ diff -Nru haxe-4.2.1/tests/misc/java/projects/Issue10280/Main.hx haxe-4.2.4/tests/misc/java/projects/Issue10280/Main.hx --- haxe-4.2.1/tests/misc/java/projects/Issue10280/Main.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/java/projects/Issue10280/Main.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,40 @@ +import haxe.macro.Compiler; +import haxe.macro.Context; +import haxe.macro.Expr; +import haxe.macro.Expr.Field; +class Main { + static function main() OldClass.define(); +} + +#if !macro +@:build(OldClass.build()) +#end +@:native("NewClass") +class OldClass { + #if !macro + public function new() {}; + #end + + macro public static function define():Expr return macro new OldClass(); + + macro static function build():Array + { + var defined = false; + + Context.onAfterTyping(_ -> { + if (defined) return; + + Context.defineType( + macro class NewClass { + public function new() {} + } + ); + + Compiler.exclude('OldClass'); + + defined = true; + }); + + return null; + } +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/js/projects/Issue10434/compile-fail.hxml haxe-4.2.4/tests/misc/js/projects/Issue10434/compile-fail.hxml --- haxe-4.2.1/tests/misc/js/projects/Issue10434/compile-fail.hxml 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/js/projects/Issue10434/compile-fail.hxml 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1 @@ +--run Main diff -Nru haxe-4.2.1/tests/misc/js/projects/Issue10434/compile-fail.hxml.stderr haxe-4.2.4/tests/misc/js/projects/Issue10434/compile-fail.hxml.stderr --- haxe-4.2.1/tests/misc/js/projects/Issue10434/compile-fail.hxml.stderr 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/js/projects/Issue10434/compile-fail.hxml.stderr 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,3 @@ +Main.hx:7: characters 2-24 : Ambiguous overload, candidates follow +Main.hx:2: characters 27-37 : ... (?flags : Null>) -> Void +Main.hx:3: characters 27-37 : ... (?flags : Null) -> Void \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/js/projects/Issue10434/Main.hx haxe-4.2.4/tests/misc/js/projects/Issue10434/Main.hx --- haxe-4.2.1/tests/misc/js/projects/Issue10434/Main.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/js/projects/Issue10434/Main.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,8 @@ +extern class ToolCache { + overload static function extractTar(?flags:Array):Void; + overload static function extractTar(?flags:String):Void; +} + +function main() { + ToolCache.extractTar(); +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10198/compile4.hxml haxe-4.2.4/tests/misc/projects/Issue10198/compile4.hxml --- haxe-4.2.1/tests/misc/projects/Issue10198/compile4.hxml 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10198/compile4.hxml 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1 @@ +--main Main4 \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10198/compile5.hxml haxe-4.2.4/tests/misc/projects/Issue10198/compile5.hxml --- haxe-4.2.1/tests/misc/projects/Issue10198/compile5.hxml 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10198/compile5.hxml 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1 @@ +--main Main5 \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10198/compile6-fail.hxml haxe-4.2.4/tests/misc/projects/Issue10198/compile6-fail.hxml --- haxe-4.2.1/tests/misc/projects/Issue10198/compile6-fail.hxml 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10198/compile6-fail.hxml 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1 @@ +--main Main6 \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10198/compile6-fail.hxml.stderr haxe-4.2.4/tests/misc/projects/Issue10198/compile6-fail.hxml.stderr --- haxe-4.2.1/tests/misc/projects/Issue10198/compile6-fail.hxml.stderr 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10198/compile6-fail.hxml.stderr 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1 @@ +Main6.hx:6: characters 3-61 : _Main6.GrandParent should be _Main6.Parent \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10198/Main4.hx haxe-4.2.4/tests/misc/projects/Issue10198/Main4.hx --- haxe-4.2.1/tests/misc/projects/Issue10198/Main4.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10198/Main4.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,9 @@ +class Main4 { + static function main() { + var n = null; + fn1(1, n); + n = 1.2; + } + + static function fn1(r:R, t:Null) {} +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10198/Main5.hx haxe-4.2.4/tests/misc/projects/Issue10198/Main5.hx --- haxe-4.2.1/tests/misc/projects/Issue10198/Main5.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10198/Main5.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,15 @@ +class Main5 { + static function fn2(r:R, fn:()->T):T + return null; + + static function main() { + var a:Parent = fn2((null:Child), () -> new Parent()); + var a:GrandParent = fn2((null:Child), () -> new GrandParent()); + } +} + +private class GrandParent { + public function new() {} +} +private class Parent extends GrandParent {} +private class Child extends Parent {} \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10198/Main6.hx haxe-4.2.4/tests/misc/projects/Issue10198/Main6.hx --- haxe-4.2.1/tests/misc/projects/Issue10198/Main6.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10198/Main6.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,15 @@ +class Main6 { + static function fn2(r:R, fn:()->T):T + return null; + + static function test() { + var a:Parent = fn2((null:Child), () -> new GrandParent()); + } + +} + +private class GrandParent { + public function new() {} +} +private class Parent extends GrandParent {} +private class Child extends Parent {} \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10205/compile-fail.hxml haxe-4.2.4/tests/misc/projects/Issue10205/compile-fail.hxml --- haxe-4.2.1/tests/misc/projects/Issue10205/compile-fail.hxml 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10205/compile-fail.hxml 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1 @@ +--main Main \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10205/compile-fail.hxml.stderr haxe-4.2.4/tests/misc/projects/Issue10205/compile-fail.hxml.stderr --- haxe-4.2.1/tests/misc/projects/Issue10205/compile-fail.hxml.stderr 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10205/compile-fail.hxml.stderr 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,3 @@ +Main.hx:3: characters 3-16 : Ambiguous overload, candidates follow +Main.hx:6: characters 41-45 : ... (s : String) -> Void +Main.hx:7: characters 41-45 : ... (s : String, r : haxe.Rest) -> Void \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10205/Main.hx haxe-4.2.4/tests/misc/projects/Issue10205/Main.hx --- haxe-4.2.1/tests/misc/projects/Issue10205/Main.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10205/Main.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,8 @@ +class Main { + static function main() { + test('hello'); + } + + overload extern static inline function test(s:String) {} + overload extern static inline function test(s:String, ...r:String) {} +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10325/compile-fail.hxml haxe-4.2.4/tests/misc/projects/Issue10325/compile-fail.hxml --- haxe-4.2.1/tests/misc/projects/Issue10325/compile-fail.hxml 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10325/compile-fail.hxml 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1 @@ +--main Main \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10325/compile-fail.hxml.stderr haxe-4.2.4/tests/misc/projects/Issue10325/compile-fail.hxml.stderr --- haxe-4.2.1/tests/misc/projects/Issue10325/compile-fail.hxml.stderr 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10325/compile-fail.hxml.stderr 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1 @@ +Main.hx:4: characters 3-4 : Cannot assign to final \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue10325/Main.hx haxe-4.2.4/tests/misc/projects/Issue10325/Main.hx --- haxe-4.2.1/tests/misc/projects/Issue10325/Main.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue10325/Main.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,7 @@ +class Main { + static function main() { + final a = 2 + Std.random(10); + a += 1; + trace(a); + } +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/misc/projects/Issue9640/compile-fail.hxml.stderr haxe-4.2.4/tests/misc/projects/Issue9640/compile-fail.hxml.stderr --- haxe-4.2.1/tests/misc/projects/Issue9640/compile-fail.hxml.stderr 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/tests/misc/projects/Issue9640/compile-fail.hxml.stderr 2021-11-20 03:16:28.000000000 +0000 @@ -1,3 +1,5 @@ -Main.hx:5: characters 9-13 : Warning : Mono : Foo> -Main.hx:8: characters 3-36 : BarLike should be Foo -Main.hx:10: characters 9-13 : Warning : Mono : Foo> \ No newline at end of file +Main.hx:5: characters 9-13 : Warning : Mono> +Main.hx:8: characters 3-36 : Constraint check failure for new.B +Main.hx:8: characters 3-36 : ... Foo should be BarLike +Main.hx:8: characters 3-36 : ... Foo has no field bar +Main.hx:10: characters 9-13 : Warning : Mono> diff -Nru haxe-4.2.1/tests/server/src/cases/display/issues/Issue10167.hx haxe-4.2.4/tests/server/src/cases/display/issues/Issue10167.hx --- haxe-4.2.1/tests/server/src/cases/display/issues/Issue10167.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/server/src/cases/display/issues/Issue10167.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,19 @@ +package cases.display.issues; + +class Issue10167 extends DisplayTestCase { + /** + class Main { + static function main() { + [] is {-1-}Ar{-2-}ray{-3-}; + } + } + **/ + function test(_) { + runHaxeJson([], DisplayMethods.Hover, { + file: file, + offset: offset(2) + }); + var result = parseHover(); + Assert.same(range(1, 3), result.result.range); + } +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/server/src/cases/display/issues/Issue10414.hx haxe-4.2.4/tests/server/src/cases/display/issues/Issue10414.hx --- haxe-4.2.1/tests/server/src/cases/display/issues/Issue10414.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/server/src/cases/display/issues/Issue10414.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,26 @@ +package cases.display.issues; + +class Issue10414 extends DisplayTestCase { + /** + class Main { + static function main() { + var a = 1; + var obj:{ + foo:Int, + bar:Bool + } = { + foo:{-1-} + bar: true + } + } + } + **/ + function test(_) { + runHaxeJson([], DisplayMethods.Completion, { + file: file, + offset: offset(1), + wasAutoTriggered: true + }); + assertHasCompletion(parseCompletion(), item -> item.args.name == 'a'); + } +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/threads/src/cases/TestMutex.hx haxe-4.2.4/tests/threads/src/cases/TestMutex.hx --- haxe-4.2.1/tests/threads/src/cases/TestMutex.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/threads/src/cases/TestMutex.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,15 @@ +package cases; + +import sys.thread.Mutex; + +class TestMutex extends utest.Test { + function testIssue10249() { + var m = new Mutex(); + m.acquire(); + m.acquire(); + isTrue(m.tryAcquire()); + m.release(); + m.release(); + m.release(); + } +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10143.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10143.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10143.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10143.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,34 @@ +package unit.issues; + +//targets with pf_supports_rest_args = true +#if (js || lua || php || cs || java || python || flash) + +class Issue10143 extends Test { + function test1() { + noAssert(); + eq('String', HelperMacros.typeString(Win.test('hello'))); + eq('Bool', HelperMacros.typeString(Win.test({field:'world'}))); + eq('String', HelperMacros.typeString(Win.test(('hello':AString)))); + } +} + +private extern class Win { + overload static function test(items:...T):Bool; + overload static function test(items:...String):String; +} + +private abstract AString(String) from String { + @:to public function toString():String { + return this; + } +} + +private abstract AObj({field:String}) from {field:String} { + @:to public function toObj():{field:String} { + return this; + } +} + +#else +class Issue10143 extends Test {} +#end \ No newline at end of file diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10144.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10144.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10144.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10144.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,11 @@ +package unit.issues; + +using unit.issues.Issue10144; + +class Issue10144 extends Test { + static final foo = (a:Int) -> a * 2; + + function test() { + eq(10, 5.foo()); + } +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10145.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10145.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10145.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10145.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,43 @@ +package unit.issues; + +// whatever +#if !erase_generics +private interface I { + function get():T; +} + +private class C implements I { + public var value:T; + + public function new(value:T) { + this.value = value; + } + + public function get():T { + return value; + } +} + +@:multiType(T) +private abstract A(I) { + public function new(value:T); + + @:to static function ofInt(_:I, value:Int):C { + return new C(value); + } + + @:to function toT():T { + return this.get(); + } +} +#end + +class Issue10145 extends unit.Test { + #if !erase_generics + function test() { + var x = new A(10); + var y:Int = x; + eq(10, y); + } + #end +} diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10173.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10173.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10173.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10173.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,23 @@ +package unit.issues; + +class Issue10173 extends Test { + function test() { + var foo:Foo = Bar; + var i = 9999; + t(foo == i); + foo = Baz; + f(foo == i); + } +} + +private enum abstract Foo(Int) to Int { + var Bar; + var Baz; + + @:op(A == B) public static function eqInt(lhs:Foo, rhs:Int):Bool { + return switch lhs { + case Bar: true; + case Baz: false; + } + } +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10174.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10174.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10174.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10174.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,9 @@ +package unit.issues; + +class Issue10174 extends Test { + function test() { + //should be parsed and typed without errors + "" is unit.issues.misc.Issue10174Foo.Bar; + noAssert(); + } +} diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10193.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10193.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10193.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10193.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,36 @@ +package unit.issues; + +class Issue10193 extends Test { + #if (js || (cs && !no_root) || java) + function test() { + var c = new C(42); + eq(42, c.a); + eq(42, c.f()); + } + #end +} + +#if (js || (cs && !no_root) || java) // some targets are not happy with this for some reason... +@:keep +@:native("Issue10193E") +private class EImpl { + public var a:Int; + public function new(a:Int) { + this.a = a; + } +} + +@:native("Issue10193E") +private extern class E { + var a:Int; + function new(a:Int); +} + +private class C extends E { + public var f:()->Int; + public function new(a:Int) { + super(a); + this.f = () -> this.a; + } +} +#end diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10259.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10259.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10259.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10259.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,17 @@ +package unit.issues; + +import unit.issues.misc.Issue10259Macro; +import utest.Assert; + +class Issue10259 extends Test { + function test() { + final maps = Issue10259Macro.getMaps(); + + Assert.same([1 => 2], maps.intMap); + Assert.same(["1" => 2], maps.stringMap); + for (key => value in maps.objectMap) { + eq(1, key.x); + eq(2, value); + } + } +} diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10261.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10261.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10261.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10261.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,20 @@ +package unit.issues; + +import utest.Assert; + +class Issue10261 extends Test { + function call(x:Int) { + return ""; + } + + function write() { + return { + while (true) {} + call(0); + } + } + + function test() { + Assert.pass(); + } +} diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10315.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10315.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10315.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10315.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,17 @@ +package unit.issues; + +class Issue10315 extends Test { + function test() { + var o = new Obj(); + eq('a', o.call('a')); + eq('b', o.call(('b':Dynamic))); + } +} + + +private class Obj { + public function new() {} + public function call(...args:Any) { + return args[0]; + } +} \ No newline at end of file diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10335.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10335.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10335.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10335.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,22 @@ +package unit.issues; + +private class NotMain { + public final prop = { + var testvalue = 1; + { + get: () -> testvalue, + set: v -> testvalue = v, + } + } + + public function new() {} +} + +class Issue10335 extends unit.Test { + function test() { + final inst = new NotMain(); + eq(1, inst.prop.get()); + inst.prop.set(2); + eq(2, inst.prop.get()); + } +} diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10343.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10343.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10343.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10343.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,13 @@ +package unit.issues; + +class Issue10343 extends Test { + function test() { + final str = "hello"; + eq(str.length, foo(str)); + } + + @:pure(false) + public function foo(str:T):Int { + return str.length; + } +} diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10350.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10350.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10350.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10350.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,8 @@ +package unit.issues; + +class Issue10350 extends Test { + function test() { + t(Reflect.compare(0.1, 0.2) < 0); + t(Reflect.compare(0.2, 0.1) > 0); + } +} diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/Issue10405.hx haxe-4.2.4/tests/unit/src/unit/issues/Issue10405.hx --- haxe-4.2.1/tests/unit/src/unit/issues/Issue10405.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/Issue10405.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,17 @@ +package unit.issues; + +import utest.Assert; + +class Issue10405 extends Test { + #if jvm + public overload function onEvent(v:Int):Void {} + + public overload function onEvent() { + var b = Math.random() > 0.5 ? 1 : throw "no"; + } + + function test() { + Assert.pass(); + } + #end +} diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/misc/Issue10174Foo.hx haxe-4.2.4/tests/unit/src/unit/issues/misc/Issue10174Foo.hx --- haxe-4.2.1/tests/unit/src/unit/issues/misc/Issue10174Foo.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/misc/Issue10174Foo.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,3 @@ +package unit.issues.misc; + +class Bar {} \ No newline at end of file diff -Nru haxe-4.2.1/tests/unit/src/unit/issues/misc/Issue10259Macro.hx haxe-4.2.4/tests/unit/src/unit/issues/misc/Issue10259Macro.hx --- haxe-4.2.1/tests/unit/src/unit/issues/misc/Issue10259Macro.hx 1970-01-01 00:00:00.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/issues/misc/Issue10259Macro.hx 2021-11-20 03:16:28.000000000 +0000 @@ -0,0 +1,22 @@ +package unit.issues.misc; + +import haxe.macro.Context; +import haxe.macro.Expr; + +class Issue10259Macro { + macro static public function getMaps() { + final p = Context.currentPos(); + final intMap = Context.makeExpr([1 => 2], p); + final stringMap = Context.makeExpr(["1" => 2], p); + final objectMap = Context.makeExpr([ + {x: 1} + => 2 + ], p); + + return macro { + intMap: $intMap, + stringMap: $stringMap, + objectMap: $objectMap + } + } +} diff -Nru haxe-4.2.1/tests/unit/src/unit/TestDCE.hx haxe-4.2.4/tests/unit/src/unit/TestDCE.hx --- haxe-4.2.1/tests/unit/src/unit/TestDCE.hx 2021-02-27 07:44:53.000000000 +0000 +++ haxe-4.2.4/tests/unit/src/unit/TestDCE.hx 2021-11-20 03:16:28.000000000 +0000 @@ -190,6 +190,16 @@ var c = Type.getClass(me); hf(c, "get_bar"); } + + public function testIssue10162() { + eq('bar', foo(ClassWithBar)); + } + static function foo & { function bar():String; }>(cls:T) + return cls.bar(); +} + +class ClassWithBar { + static public function bar() return 'bar'; } class UsedConstructed {